1.1 --- a/CMakeLists.txt Mon Sep 28 15:53:20 2009 +0200
1.2 +++ b/CMakeLists.txt Thu Nov 05 10:27:17 2009 +0100
1.3 @@ -35,6 +35,8 @@
1.4 CHECK_TYPE_SIZE("long long" LONG_LONG)
1.5 SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
1.6
1.7 +INCLUDE(FindPythonInterp)
1.8 +
1.9 ENABLE_TESTING()
1.10
1.11 ADD_SUBDIRECTORY(lemon)
2.1 --- a/Makefile.am Mon Sep 28 15:53:20 2009 +0200
2.2 +++ b/Makefile.am Thu Nov 05 10:27:17 2009 +0100
2.3 @@ -17,6 +17,7 @@
2.4 cmake/FindCPLEX.cmake \
2.5 cmake/FindGLPK.cmake \
2.6 cmake/FindCOIN.cmake \
2.7 + cmake/LEMONConfig.cmake.in \
2.8 cmake/version.cmake.in \
2.9 cmake/version.cmake \
2.10 cmake/nsis/lemon.ico \
3.1 --- a/configure.ac Mon Sep 28 15:53:20 2009 +0200
3.2 +++ b/configure.ac Thu Nov 05 10:27:17 2009 +0100
3.3 @@ -41,6 +41,7 @@
3.4 AC_PROG_LIBTOOL
3.5
3.6 AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
3.7 +AC_CHECK_PROG([python_found],[python],[yes],[no])
3.8 AC_CHECK_PROG([gs_found],[gs],[yes],[no])
3.9
3.10 dnl Detect Intel compiler.
4.1 --- a/doc/CMakeLists.txt Mon Sep 28 15:53:20 2009 +0200
4.2 +++ b/doc/CMakeLists.txt Thu Nov 05 10:27:17 2009 +0100
4.3 @@ -9,7 +9,7 @@
4.4 @ONLY
4.5 )
4.6
4.7 -IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
4.8 +IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
4.9 FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
4.10 SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
4.11 ADD_CUSTOM_TARGET(html
4.12 @@ -28,6 +28,7 @@
4.13 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
4.14 COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
4.15 COMMAND ${CMAKE_COMMAND} -E remove_directory html
4.16 + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
4.17 COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
4.18 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
4.19 )
5.1 --- a/doc/Doxyfile.in Mon Sep 28 15:53:20 2009 +0200
5.2 +++ b/doc/Doxyfile.in Thu Nov 05 10:27:17 2009 +0100
5.3 @@ -1,4 +1,4 @@
5.4 -# Doxyfile 1.5.7.1
5.5 +# Doxyfile 1.5.9
5.6
5.7 #---------------------------------------------------------------------------
5.8 # Project related configuration options
5.9 @@ -21,7 +21,6 @@
5.10 JAVADOC_AUTOBRIEF = NO
5.11 QT_AUTOBRIEF = NO
5.12 MULTILINE_CPP_IS_BRIEF = NO
5.13 -DETAILS_AT_TOP = YES
5.14 INHERIT_DOCS = NO
5.15 SEPARATE_MEMBER_PAGES = NO
5.16 TAB_SIZE = 8
5.17 @@ -91,7 +90,8 @@
5.18 "@abs_top_srcdir@/lemon/concepts" \
5.19 "@abs_top_srcdir@/demo" \
5.20 "@abs_top_srcdir@/tools" \
5.21 - "@abs_top_srcdir@/test/test_tools.h"
5.22 + "@abs_top_srcdir@/test/test_tools.h" \
5.23 + "@abs_top_builddir@/doc/references.dox"
5.24 INPUT_ENCODING = UTF-8
5.25 FILE_PATTERNS = *.h \
5.26 *.cc \
5.27 @@ -223,7 +223,7 @@
5.28 EXPAND_AS_DEFINED =
5.29 SKIP_FUNCTION_MACROS = YES
5.30 #---------------------------------------------------------------------------
5.31 -# Configuration::additions related to external references
5.32 +# Options related to the search engine
5.33 #---------------------------------------------------------------------------
5.34 TAGFILES = "@abs_top_srcdir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/ "
5.35 GENERATE_TAGFILE = html/lemon.tag
6.1 --- a/doc/Makefile.am Mon Sep 28 15:53:20 2009 +0200
6.2 +++ b/doc/Makefile.am Thu Nov 05 10:27:17 2009 +0100
6.3 @@ -66,7 +66,19 @@
6.4 exit 1; \
6.5 fi
6.6
6.7 -html-local: $(DOC_PNG_IMAGES)
6.8 +references.dox: doc/references.bib
6.9 + if test ${python_found} = yes; then \
6.10 + cd doc; \
6.11 + python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
6.12 + cd ..; \
6.13 + else \
6.14 + echo; \
6.15 + echo "Python not found."; \
6.16 + echo; \
6.17 + exit 1; \
6.18 + fi
6.19 +
6.20 +html-local: $(DOC_PNG_IMAGES) references.dox
6.21 if test ${doxygen_found} = yes; then \
6.22 cd doc; \
6.23 doxygen Doxyfile; \
7.1 --- a/doc/groups.dox Mon Sep 28 15:53:20 2009 +0200
7.2 +++ b/doc/groups.dox Thu Nov 05 10:27:17 2009 +0100
7.3 @@ -316,7 +316,8 @@
7.4 \brief Common graph search algorithms.
7.5
7.6 This group contains the common graph search algorithms, namely
7.7 -\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
7.8 +\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
7.9 +\ref clrs01algorithms.
7.10 */
7.11
7.12 /**
7.13 @@ -324,7 +325,8 @@
7.14 @ingroup algs
7.15 \brief Algorithms for finding shortest paths.
7.16
7.17 -This group contains the algorithms for finding shortest paths in digraphs.
7.18 +This group contains the algorithms for finding shortest paths in digraphs
7.19 +\ref clrs01algorithms.
7.20
7.21 - \ref Dijkstra algorithm for finding shortest paths from a source node
7.22 when all arc lengths are non-negative.
7.23 @@ -346,7 +348,7 @@
7.24 \brief Algorithms for finding minimum cost spanning trees and arborescences.
7.25
7.26 This group contains the algorithms for finding minimum cost spanning
7.27 -trees and arborescences.
7.28 +trees and arborescences \ref clrs01algorithms.
7.29 */
7.30
7.31 /**
7.32 @@ -355,7 +357,7 @@
7.33 \brief Algorithms for finding maximum flows.
7.34
7.35 This group contains the algorithms for finding maximum flows and
7.36 -feasible circulations.
7.37 +feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
7.38
7.39 The \e maximum \e flow \e problem is to find a flow of maximum value between
7.40 a single source and a single target. Formally, there is a \f$G=(V,A)\f$
7.41 @@ -370,12 +372,16 @@
7.42 \f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
7.43
7.44 LEMON contains several algorithms for solving maximum flow problems:
7.45 -- \ref EdmondsKarp Edmonds-Karp algorithm.
7.46 -- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
7.47 -- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
7.48 -- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
7.49 +- \ref EdmondsKarp Edmonds-Karp algorithm
7.50 + \ref edmondskarp72theoretical.
7.51 +- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
7.52 + \ref goldberg88newapproach.
7.53 +- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
7.54 + \ref dinic70algorithm, \ref sleator83dynamic.
7.55 +- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
7.56 + \ref goldberg88newapproach, \ref sleator83dynamic.
7.57
7.58 -In most cases the \ref Preflow "Preflow" algorithm provides the
7.59 +In most cases the \ref Preflow algorithm provides the
7.60 fastest method for computing a maximum flow. All implementations
7.61 also provide functions to query the minimum cut, which is the dual
7.62 problem of maximum flow.
7.63 @@ -393,18 +399,22 @@
7.64 \brief Algorithms for finding minimum cost flows and circulations.
7.65
7.66 This group contains the algorithms for finding minimum cost flows and
7.67 -circulations. For more information about this problem and its dual
7.68 -solution see \ref min_cost_flow "Minimum Cost Flow Problem".
7.69 +circulations \ref amo93networkflows. For more information about this
7.70 +problem and its dual solution, see \ref min_cost_flow
7.71 +"Minimum Cost Flow Problem".
7.72
7.73 LEMON contains several algorithms for this problem.
7.74 - \ref NetworkSimplex Primal Network Simplex algorithm with various
7.75 - pivot strategies.
7.76 + pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
7.77 - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
7.78 - cost scaling.
7.79 + cost scaling \ref goldberg90approximation, \ref goldberg97efficient,
7.80 + \ref bunnagel98efficient.
7.81 - \ref CapacityScaling Successive Shortest %Path algorithm with optional
7.82 - capacity scaling.
7.83 - - \ref CancelAndTighten The Cancel and Tighten algorithm.
7.84 - - \ref CycleCanceling Cycle-Canceling algorithms.
7.85 + capacity scaling \ref edmondskarp72theoretical.
7.86 + - \ref CancelAndTighten The Cancel and Tighten algorithm
7.87 + \ref goldberg89cyclecanceling.
7.88 + - \ref CycleCanceling Cycle-Canceling algorithms
7.89 + \ref klein67primal, \ref goldberg89cyclecanceling.
7.90
7.91 In general NetworkSimplex is the most efficient implementation,
7.92 but in special cases other algorithms could be faster.
7.93 @@ -443,6 +453,43 @@
7.94 */
7.95
7.96 /**
7.97 +@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
7.98 +@ingroup algs
7.99 +\brief Algorithms for finding minimum mean cycles.
7.100 +
7.101 +This group contains the algorithms for finding minimum mean cycles
7.102 +\ref clrs01algorithms, \ref amo93networkflows.
7.103 +
7.104 +The \e minimum \e mean \e cycle \e problem is to find a directed cycle
7.105 +of minimum mean length (cost) in a digraph.
7.106 +The mean length of a cycle is the average length of its arcs, i.e. the
7.107 +ratio between the total length of the cycle and the number of arcs on it.
7.108 +
7.109 +This problem has an important connection to \e conservative \e length
7.110 +\e functions, too. A length function on the arcs of a digraph is called
7.111 +conservative if and only if there is no directed cycle of negative total
7.112 +length. For an arbitrary length function, the negative of the minimum
7.113 +cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
7.114 +arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
7.115 +function.
7.116 +
7.117 +LEMON contains three algorithms for solving the minimum mean cycle problem:
7.118 +- \ref Karp "Karp"'s original algorithm \ref amo93networkflows,
7.119 + \ref dasdan98minmeancycle.
7.120 +- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
7.121 + version of Karp's algorithm \ref dasdan98minmeancycle.
7.122 +- \ref Howard "Howard"'s policy iteration algorithm
7.123 + \ref dasdan98minmeancycle.
7.124 +
7.125 +In practice, the Howard algorithm proved to be by far the most efficient
7.126 +one, though the best known theoretical bound on its running time is
7.127 +exponential.
7.128 +Both Karp and HartmannOrlin algorithms run in time O(ne) and use space
7.129 +O(n<sup>2</sup>+e), but the latter one is typically faster due to the
7.130 +applied early termination scheme.
7.131 +*/
7.132 +
7.133 +/**
7.134 @defgroup matching Matching Algorithms
7.135 @ingroup algs
7.136 \brief Algorithms for finding matchings in graphs and bipartite graphs.
7.137 @@ -534,13 +581,16 @@
7.138 */
7.139
7.140 /**
7.141 -@defgroup lp_group Lp and Mip Solvers
7.142 +@defgroup lp_group LP and MIP Solvers
7.143 @ingroup gen_opt_group
7.144 -\brief Lp and Mip solver interfaces for LEMON.
7.145 +\brief LP and MIP solver interfaces for LEMON.
7.146
7.147 -This group contains Lp and Mip solver interfaces for LEMON. The
7.148 -various LP solvers could be used in the same manner with this
7.149 -interface.
7.150 +This group contains LP and MIP solver interfaces for LEMON.
7.151 +Various LP solvers could be used in the same manner with this
7.152 +high-level interface.
7.153 +
7.154 +The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
7.155 +\ref cplex, \ref soplex.
7.156 */
7.157
7.158 /**
7.159 @@ -679,8 +729,8 @@
7.160 @ingroup concept
7.161 \brief Skeleton and concept checking classes for graph structures
7.162
7.163 -This group contains the skeletons and concept checking classes of LEMON's
7.164 -graph structures and helper classes used to implement these.
7.165 +This group contains the skeletons and concept checking classes of
7.166 +graph structures.
7.167 */
7.168
7.169 /**
8.1 --- a/doc/mainpage.dox Mon Sep 28 15:53:20 2009 +0200
8.2 +++ b/doc/mainpage.dox Thu Nov 05 10:27:17 2009 +0100
8.3 @@ -21,14 +21,11 @@
8.4
8.5 \section intro Introduction
8.6
8.7 -\subsection whatis What is LEMON
8.8 -
8.9 -LEMON stands for <b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
8.10 -and <b>O</b>ptimization in <b>N</b>etworks.
8.11 -It is a C++ template
8.12 -library aimed at combinatorial optimization tasks which
8.13 -often involve in working
8.14 -with graphs.
8.15 +<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
8.16 +and <b>O</b>ptimization in <b>N</b>etworks</i>.
8.17 +It is a C++ template library providing efficient implementation of common
8.18 +data structures and algorithms with focus on combinatorial optimization
8.19 +problems in graphs and networks.
8.20
8.21 <b>
8.22 LEMON is an <a class="el" href="http://opensource.org/">open source</a>
8.23 @@ -38,7 +35,16 @@
8.24 \ref license "license terms".
8.25 </b>
8.26
8.27 -\subsection howtoread How to read the documentation
8.28 +The project is maintained by the
8.29 +<a href="http://www.cs.elte.hu/egres/">Egerváry Research Group on
8.30 +Combinatorial Optimization</a> \ref egres
8.31 +at the Operations Research Department of the
8.32 +<a href="http://www.elte.hu/">Eötvös Loránd University,
8.33 +Budapest</a>, Hungary.
8.34 +LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
8.35 +initiative \ref coinor.
8.36 +
8.37 +\section howtoread How to Read the Documentation
8.38
8.39 If you would like to get to know the library, see
8.40 <a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
9.1 --- a/doc/min_cost_flow.dox Mon Sep 28 15:53:20 2009 +0200
9.2 +++ b/doc/min_cost_flow.dox Thu Nov 05 10:27:17 2009 +0100
9.3 @@ -26,7 +26,7 @@
9.4 The \e minimum \e cost \e flow \e problem is to find a feasible flow of
9.5 minimum total cost from a set of supply nodes to a set of demand nodes
9.6 in a network with capacity constraints (lower and upper bounds)
9.7 -and arc costs.
9.8 +and arc costs \ref amo93networkflows.
9.9
9.10 Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
9.11 \f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/doc/references.bib Thu Nov 05 10:27:17 2009 +0100
10.3 @@ -0,0 +1,301 @@
10.4 +%%%%% Defining LEMON %%%%%
10.5 +
10.6 +@misc{lemon,
10.7 + key = {LEMON},
10.8 + title = {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
10.9 + {O}ptimization in {N}etworks},
10.10 + howpublished = {\url{http://lemon.cs.elte.hu/}},
10.11 + year = 2009
10.12 +}
10.13 +
10.14 +@misc{egres,
10.15 + key = {EGRES},
10.16 + title = {{EGRES} -- {E}gerv{\'a}ry {R}esearch {G}roup on
10.17 + {C}ombinatorial {O}ptimization},
10.18 + url = {http://www.cs.elte.hu/egres/}
10.19 +}
10.20 +
10.21 +@misc{coinor,
10.22 + key = {COIN-OR},
10.23 + title = {{COIN-OR} -- {C}omputational {I}nfrastructure for
10.24 + {O}perations {R}esearch},
10.25 + url = {http://www.coin-or.org/}
10.26 +}
10.27 +
10.28 +
10.29 +%%%%% Other libraries %%%%%%
10.30 +
10.31 +@misc{boost,
10.32 + key = {Boost},
10.33 + title = {{B}oost {C++} {L}ibraries},
10.34 + url = {http://www.boost.org/}
10.35 +}
10.36 +
10.37 +@book{bglbook,
10.38 + author = {Jeremy G. Siek and Lee-Quan Lee and Andrew
10.39 + Lumsdaine},
10.40 + title = {The Boost Graph Library: User Guide and Reference
10.41 + Manual},
10.42 + publisher = {Addison-Wesley},
10.43 + year = 2002
10.44 +}
10.45 +
10.46 +@misc{leda,
10.47 + key = {LEDA},
10.48 + title = {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
10.49 + {A}lgorithms},
10.50 + url = {http://www.algorithmic-solutions.com/}
10.51 +}
10.52 +
10.53 +@book{ledabook,
10.54 + author = {Kurt Mehlhorn and Stefan N{\"a}her},
10.55 + title = {{LEDA}: {A} platform for combinatorial and geometric
10.56 + computing},
10.57 + isbn = {0-521-56329-1},
10.58 + publisher = {Cambridge University Press},
10.59 + address = {New York, NY, USA},
10.60 + year = 1999
10.61 +}
10.62 +
10.63 +
10.64 +%%%%% Tools that LEMON depends on %%%%%
10.65 +
10.66 +@misc{cmake,
10.67 + key = {CMake},
10.68 + title = {{CMake} -- {C}ross {P}latform {M}ake},
10.69 + url = {http://www.cmake.org/}
10.70 +}
10.71 +
10.72 +@misc{doxygen,
10.73 + key = {Doxygen},
10.74 + title = {{Doxygen} -- {S}ource code documentation generator
10.75 + tool},
10.76 + url = {http://www.doxygen.org/}
10.77 +}
10.78 +
10.79 +
10.80 +%%%%% LP/MIP libraries %%%%%
10.81 +
10.82 +@misc{glpk,
10.83 + key = {GLPK},
10.84 + title = {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
10.85 + url = {http://www.gnu.org/software/glpk/}
10.86 +}
10.87 +
10.88 +@misc{clp,
10.89 + key = {Clp},
10.90 + title = {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
10.91 + url = {http://projects.coin-or.org/Clp/}
10.92 +}
10.93 +
10.94 +@misc{cbc,
10.95 + key = {Cbc},
10.96 + title = {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
10.97 + url = {http://projects.coin-or.org/Cbc/}
10.98 +}
10.99 +
10.100 +@misc{cplex,
10.101 + key = {CPLEX},
10.102 + title = {{ILOG} {CPLEX}},
10.103 + url = {http://www.ilog.com/}
10.104 +}
10.105 +
10.106 +@misc{soplex,
10.107 + key = {SoPlex},
10.108 + title = {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
10.109 + {S}implex},
10.110 + url = {http://soplex.zib.de/}
10.111 +}
10.112 +
10.113 +
10.114 +%%%%% General books %%%%%
10.115 +
10.116 +@book{amo93networkflows,
10.117 + author = {Ravindra K. Ahuja and Thomas L. Magnanti and James
10.118 + B. Orlin},
10.119 + title = {Network Flows: Theory, Algorithms, and Applications},
10.120 + publisher = {Prentice-Hall, Inc.},
10.121 + year = 1993,
10.122 + month = feb,
10.123 + isbn = {978-0136175490}
10.124 +}
10.125 +
10.126 +@book{schrijver03combinatorial,
10.127 + author = {Alexander Schrijver},
10.128 + title = {Combinatorial Optimization: Polyhedra and Efficiency},
10.129 + publisher = {Springer-Verlag},
10.130 + year = 2003,
10.131 + isbn = {978-3540443896}
10.132 +}
10.133 +
10.134 +@book{clrs01algorithms,
10.135 + author = {Thomas H. Cormen and Charles E. Leiserson and Ronald
10.136 + L. Rivest and Clifford Stein},
10.137 + title = {Introduction to Algorithms},
10.138 + publisher = {The MIT Press},
10.139 + year = 2001,
10.140 + edition = {2nd}
10.141 +}
10.142 +
10.143 +@book{stroustrup00cpp,
10.144 + author = {Bjarne Stroustrup},
10.145 + title = {The C++ Programming Language},
10.146 + edition = {3rd},
10.147 + publisher = {Addison-Wesley Professional},
10.148 + isbn = 0201700735,
10.149 + month = {February},
10.150 + year = 2000
10.151 +}
10.152 +
10.153 +
10.154 +%%%%% Maximum flow algorithms %%%%%
10.155 +
10.156 +@article{edmondskarp72theoretical,
10.157 + author = {Jack Edmonds and Richard M. Karp},
10.158 + title = {Theoretical improvements in algorithmic efficiency
10.159 + for network flow problems},
10.160 + journal = {Journal of the ACM},
10.161 + year = 1972,
10.162 + volume = 19,
10.163 + number = 2,
10.164 + pages = {248-264}
10.165 +}
10.166 +
10.167 +@article{goldberg88newapproach,
10.168 + author = {Andrew V. Goldberg and Robert E. Tarjan},
10.169 + title = {A new approach to the maximum flow problem},
10.170 + journal = {Journal of the ACM},
10.171 + year = 1988,
10.172 + volume = 35,
10.173 + number = 4,
10.174 + pages = {921-940}
10.175 +}
10.176 +
10.177 +@article{dinic70algorithm,
10.178 + author = {E. A. Dinic},
10.179 + title = {Algorithm for solution of a problem of maximum flow
10.180 + in a network with power estimation},
10.181 + journal = {Soviet Math. Doklady},
10.182 + year = 1970,
10.183 + volume = 11,
10.184 + pages = {1277-1280}
10.185 +}
10.186 +
10.187 +@article{goldberg08partial,
10.188 + author = {Andrew V. Goldberg},
10.189 + title = {The Partial Augment-Relabel Algorithm for the
10.190 + Maximum Flow Problem},
10.191 + journal = {16th Annual European Symposium on Algorithms},
10.192 + year = 2008,
10.193 + pages = {466-477}
10.194 +}
10.195 +
10.196 +@article{sleator83dynamic,
10.197 + author = {Daniel D. Sleator and Robert E. Tarjan},
10.198 + title = {A data structure for dynamic trees},
10.199 + journal = {Journal of Computer and System Sciences},
10.200 + year = 1983,
10.201 + volume = 26,
10.202 + number = 3,
10.203 + pages = {362-391}
10.204 +}
10.205 +
10.206 +
10.207 +%%%%% Minimum mean cycle algorithms %%%%%
10.208 +
10.209 +@article{karp78characterization,
10.210 + author = {Richard M. Karp},
10.211 + title = {A characterization of the minimum cycle mean in a
10.212 + digraph},
10.213 + journal = {Discrete Math.},
10.214 + year = 1978,
10.215 + volume = 23,
10.216 + pages = {309-311}
10.217 +}
10.218 +
10.219 +@article{dasdan98minmeancycle,
10.220 + author = {Ali Dasdan and Rajesh K. Gupta},
10.221 + title = {Faster Maximum and Minimum Mean Cycle Alogrithms for
10.222 + System Performance Analysis},
10.223 + journal = {IEEE Transactions on Computer-Aided Design of
10.224 + Integrated Circuits and Systems},
10.225 + year = 1998,
10.226 + volume = 17,
10.227 + number = 10,
10.228 + pages = {889-899}
10.229 +}
10.230 +
10.231 +
10.232 +%%%%% Minimum cost flow algorithms %%%%%
10.233 +
10.234 +@article{klein67primal,
10.235 + author = {Morton Klein},
10.236 + title = {A primal method for minimal cost flows with
10.237 + applications to the assignment and transportation
10.238 + problems},
10.239 + journal = {Management Science},
10.240 + year = 1967,
10.241 + volume = 14,
10.242 + pages = {205-220}
10.243 +}
10.244 +
10.245 +@article{goldberg89cyclecanceling,
10.246 + author = {Andrew V. Goldberg and Robert E. Tarjan},
10.247 + title = {Finding minimum-cost circulations by canceling
10.248 + negative cycles},
10.249 + journal = {Journal of the ACM},
10.250 + year = 1989,
10.251 + volume = 36,
10.252 + number = 4,
10.253 + pages = {873-886}
10.254 +}
10.255 +
10.256 +@article{goldberg90approximation,
10.257 + author = {Andrew V. Goldberg and Robert E. Tarjan},
10.258 + title = {Finding Minimum-Cost Circulations by Successive
10.259 + Approximation},
10.260 + journal = {Mathematics of Operations Research},
10.261 + year = 1990,
10.262 + volume = 15,
10.263 + number = 3,
10.264 + pages = {430-466}
10.265 +}
10.266 +
10.267 +@article{goldberg97efficient,
10.268 + author = {Andrew V. Goldberg},
10.269 + title = {An Efficient Implementation of a Scaling
10.270 + Minimum-Cost Flow Algorithm},
10.271 + journal = {Journal of Algorithms},
10.272 + year = 1997,
10.273 + volume = 22,
10.274 + number = 1,
10.275 + pages = {1-29}
10.276 +}
10.277 +
10.278 +@article{bunnagel98efficient,
10.279 + author = {Ursula B{\"u}nnagel and Bernhard Korte and Jens
10.280 + Vygen},
10.281 + title = {Efficient implementation of the {G}oldberg-{T}arjan
10.282 + minimum-cost flow algorithm},
10.283 + journal = {Optimization Methods and Software},
10.284 + year = 1998,
10.285 + volume = 10,
10.286 + pages = {157-174}
10.287 +}
10.288 +
10.289 +@book{dantzig63linearprog,
10.290 + author = {George B. Dantzig},
10.291 + title = {Linear Programming and Extensions},
10.292 + publisher = {Princeton University Press},
10.293 + year = 1963
10.294 +}
10.295 +
10.296 +@mastersthesis{kellyoneill91netsimplex,
10.297 + author = {Damian J. Kelly and Garrett M. O'Neill},
10.298 + title = {The Minimum Cost Flow Problem and The Network
10.299 + Simplex Method},
10.300 + school = {University College},
10.301 + address = {Dublin, Ireland},
10.302 + year = 1991,
10.303 + month = sep,
10.304 +}
11.1 --- a/lemon/Makefile.am Mon Sep 28 15:53:20 2009 +0200
11.2 +++ b/lemon/Makefile.am Thu Nov 05 10:27:17 2009 +0100
11.3 @@ -86,7 +86,10 @@
11.4 lemon/gomory_hu.h \
11.5 lemon/graph_to_eps.h \
11.6 lemon/grid_graph.h \
11.7 + lemon/hartmann_orlin.h \
11.8 + lemon/howard.h \
11.9 lemon/hypercube_graph.h \
11.10 + lemon/karp.h \
11.11 lemon/kary_heap.h \
11.12 lemon/kruskal.h \
11.13 lemon/hao_orlin.h \
11.14 @@ -110,6 +113,7 @@
11.15 lemon/random.h \
11.16 lemon/smart_graph.h \
11.17 lemon/soplex.h \
11.18 + lemon/static_graph.h \
11.19 lemon/suurballe.h \
11.20 lemon/time_measure.h \
11.21 lemon/tolerance.h \
12.1 --- a/lemon/bits/graph_extender.h Mon Sep 28 15:53:20 2009 +0200
12.2 +++ b/lemon/bits/graph_extender.h Thu Nov 05 10:27:17 2009 +0100
12.3 @@ -56,11 +56,11 @@
12.4 return Parent::maxArcId();
12.5 }
12.6
12.7 - Node fromId(int id, Node) const {
12.8 + static Node fromId(int id, Node) {
12.9 return Parent::nodeFromId(id);
12.10 }
12.11
12.12 - Arc fromId(int id, Arc) const {
12.13 + static Arc fromId(int id, Arc) {
12.14 return Parent::arcFromId(id);
12.15 }
12.16
12.17 @@ -355,15 +355,15 @@
12.18 return Parent::maxEdgeId();
12.19 }
12.20
12.21 - Node fromId(int id, Node) const {
12.22 + static Node fromId(int id, Node) {
12.23 return Parent::nodeFromId(id);
12.24 }
12.25
12.26 - Arc fromId(int id, Arc) const {
12.27 + static Arc fromId(int id, Arc) {
12.28 return Parent::arcFromId(id);
12.29 }
12.30
12.31 - Edge fromId(int id, Edge) const {
12.32 + static Edge fromId(int id, Edge) {
12.33 return Parent::edgeFromId(id);
12.34 }
12.35
13.1 --- a/lemon/cbc.cc Mon Sep 28 15:53:20 2009 +0200
13.2 +++ b/lemon/cbc.cc Thu Nov 05 10:27:17 2009 +0100
13.3 @@ -94,6 +94,18 @@
13.4 return _prob->numberRows() - 1;
13.5 }
13.6
13.7 + int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
13.8 + std::vector<int> indexes;
13.9 + std::vector<Value> values;
13.10 +
13.11 + for(ExprIterator it = b; it != e; ++it) {
13.12 + indexes.push_back(it->first);
13.13 + values.push_back(it->second);
13.14 + }
13.15 +
13.16 + _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
13.17 + return _prob->numberRows() - 1;
13.18 + }
13.19
13.20 void CbcMip::_eraseCol(int i) {
13.21 _prob->deleteColumn(i);
14.1 --- a/lemon/cbc.h Mon Sep 28 15:53:20 2009 +0200
14.2 +++ b/lemon/cbc.h Thu Nov 05 10:27:17 2009 +0100
14.3 @@ -62,6 +62,7 @@
14.4
14.5 virtual int _addCol();
14.6 virtual int _addRow();
14.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
14.8
14.9 virtual void _eraseCol(int i);
14.10 virtual void _eraseRow(int i);
15.1 --- a/lemon/clp.cc Mon Sep 28 15:53:20 2009 +0200
15.2 +++ b/lemon/clp.cc Thu Nov 05 10:27:17 2009 +0100
15.3 @@ -78,6 +78,19 @@
15.4 return _prob->numberRows() - 1;
15.5 }
15.6
15.7 + int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
15.8 + std::vector<int> indexes;
15.9 + std::vector<Value> values;
15.10 +
15.11 + for(ExprIterator it = b; it != e; ++it) {
15.12 + indexes.push_back(it->first);
15.13 + values.push_back(it->second);
15.14 + }
15.15 +
15.16 + _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
15.17 + return _prob->numberRows() - 1;
15.18 + }
15.19 +
15.20
15.21 void ClpLp::_eraseCol(int c) {
15.22 _col_names_ref.erase(_prob->getColumnName(c));
16.1 --- a/lemon/clp.h Mon Sep 28 15:53:20 2009 +0200
16.2 +++ b/lemon/clp.h Thu Nov 05 10:27:17 2009 +0100
16.3 @@ -75,6 +75,7 @@
16.4
16.5 virtual int _addCol();
16.6 virtual int _addRow();
16.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
16.8
16.9 virtual void _eraseCol(int i);
16.10 virtual void _eraseRow(int i);
17.1 --- a/lemon/concepts/digraph.h Mon Sep 28 15:53:20 2009 +0200
17.2 +++ b/lemon/concepts/digraph.h Thu Nov 05 10:27:17 2009 +0100
17.3 @@ -35,46 +35,40 @@
17.4 ///
17.5 /// \brief Class describing the concept of directed graphs.
17.6 ///
17.7 - /// This class describes the \ref concept "concept" of the
17.8 - /// immutable directed digraphs.
17.9 + /// This class describes the common interface of all directed
17.10 + /// graphs (digraphs).
17.11 ///
17.12 - /// Note that actual digraph implementation like @ref ListDigraph or
17.13 - /// @ref SmartDigraph may have several additional functionality.
17.14 + /// Like all concept classes, it only provides an interface
17.15 + /// without any sensible implementation. So any general algorithm for
17.16 + /// directed graphs should compile with this class, but it will not
17.17 + /// run properly, of course.
17.18 + /// An actual digraph implementation like \ref ListDigraph or
17.19 + /// \ref SmartDigraph may have additional functionality.
17.20 ///
17.21 - /// \sa concept
17.22 + /// \sa Graph
17.23 class Digraph {
17.24 private:
17.25 - ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
17.26 + /// Diraphs are \e not copy constructible. Use DigraphCopy instead.
17.27 + Digraph(const Digraph &) {}
17.28 + /// \brief Assignment of a digraph to another one is \e not allowed.
17.29 + /// Use DigraphCopy instead.
17.30 + void operator=(const Digraph &) {}
17.31
17.32 - ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
17.33 - ///
17.34 - Digraph(const Digraph &) {};
17.35 - ///\brief Assignment of \ref Digraph "Digraph"s to another ones are
17.36 - ///\e not allowed. Use DigraphCopy() instead.
17.37 + public:
17.38 + /// Default constructor.
17.39 + Digraph() { }
17.40
17.41 - ///Assignment of \ref Digraph "Digraph"s to another ones are
17.42 - ///\e not allowed. Use DigraphCopy() instead.
17.43 -
17.44 - void operator=(const Digraph &) {}
17.45 - public:
17.46 - ///\e
17.47 -
17.48 - /// Defalult constructor.
17.49 -
17.50 - /// Defalult constructor.
17.51 - ///
17.52 - Digraph() { }
17.53 - /// Class for identifying a node of the digraph
17.54 + /// The node type of the digraph
17.55
17.56 /// This class identifies a node of the digraph. It also serves
17.57 /// as a base class of the node iterators,
17.58 - /// thus they will convert to this type.
17.59 + /// thus they convert to this type.
17.60 class Node {
17.61 public:
17.62 /// Default constructor
17.63
17.64 - /// @warning The default constructor sets the iterator
17.65 - /// to an undefined value.
17.66 + /// Default constructor.
17.67 + /// \warning It sets the object to an undefined value.
17.68 Node() { }
17.69 /// Copy constructor.
17.70
17.71 @@ -82,40 +76,39 @@
17.72 ///
17.73 Node(const Node&) { }
17.74
17.75 - /// Invalid constructor \& conversion.
17.76 + /// %Invalid constructor \& conversion.
17.77
17.78 - /// This constructor initializes the iterator to be invalid.
17.79 + /// Initializes the object to be invalid.
17.80 /// \sa Invalid for more details.
17.81 Node(Invalid) { }
17.82 /// Equality operator
17.83
17.84 + /// Equality operator.
17.85 + ///
17.86 /// Two iterators are equal if and only if they point to the
17.87 - /// same object or both are invalid.
17.88 + /// same object or both are \c INVALID.
17.89 bool operator==(Node) const { return true; }
17.90
17.91 /// Inequality operator
17.92
17.93 - /// \sa operator==(Node n)
17.94 - ///
17.95 + /// Inequality operator.
17.96 bool operator!=(Node) const { return true; }
17.97
17.98 /// Artificial ordering operator.
17.99
17.100 - /// To allow the use of digraph descriptors as key type in std::map or
17.101 - /// similar associative container we require this.
17.102 + /// Artificial ordering operator.
17.103 ///
17.104 - /// \note This operator only have to define some strict ordering of
17.105 - /// the items; this order has nothing to do with the iteration
17.106 - /// ordering of the items.
17.107 + /// \note This operator only has to define some strict ordering of
17.108 + /// the nodes; this order has nothing to do with the iteration
17.109 + /// ordering of the nodes.
17.110 bool operator<(Node) const { return false; }
17.111 -
17.112 };
17.113
17.114 - /// This iterator goes through each node.
17.115 + /// Iterator class for the nodes.
17.116
17.117 - /// This iterator goes through each node.
17.118 + /// This iterator goes through each node of the digraph.
17.119 /// Its usage is quite simple, for example you can count the number
17.120 - /// of nodes in digraph \c g of type \c Digraph like this:
17.121 + /// of nodes in a digraph \c g of type \c %Digraph like this:
17.122 ///\code
17.123 /// int count=0;
17.124 /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
17.125 @@ -124,30 +117,28 @@
17.126 public:
17.127 /// Default constructor
17.128
17.129 - /// @warning The default constructor sets the iterator
17.130 - /// to an undefined value.
17.131 + /// Default constructor.
17.132 + /// \warning It sets the iterator to an undefined value.
17.133 NodeIt() { }
17.134 /// Copy constructor.
17.135
17.136 /// Copy constructor.
17.137 ///
17.138 NodeIt(const NodeIt& n) : Node(n) { }
17.139 - /// Invalid constructor \& conversion.
17.140 + /// %Invalid constructor \& conversion.
17.141
17.142 - /// Initialize the iterator to be invalid.
17.143 + /// Initializes the iterator to be invalid.
17.144 /// \sa Invalid for more details.
17.145 NodeIt(Invalid) { }
17.146 /// Sets the iterator to the first node.
17.147
17.148 - /// Sets the iterator to the first node of \c g.
17.149 + /// Sets the iterator to the first node of the given digraph.
17.150 ///
17.151 - NodeIt(const Digraph&) { }
17.152 - /// Node -> NodeIt conversion.
17.153 + explicit NodeIt(const Digraph&) { }
17.154 + /// Sets the iterator to the given node.
17.155
17.156 - /// Sets the iterator to the node of \c the digraph pointed by
17.157 - /// the trivial iterator.
17.158 - /// This feature necessitates that each time we
17.159 - /// iterate the arc-set, the iteration order is the same.
17.160 + /// Sets the iterator to the given node of the given digraph.
17.161 + ///
17.162 NodeIt(const Digraph&, const Node&) { }
17.163 /// Next node.
17.164
17.165 @@ -157,7 +148,7 @@
17.166 };
17.167
17.168
17.169 - /// Class for identifying an arc of the digraph
17.170 + /// The arc type of the digraph
17.171
17.172 /// This class identifies an arc of the digraph. It also serves
17.173 /// as a base class of the arc iterators,
17.174 @@ -166,207 +157,214 @@
17.175 public:
17.176 /// Default constructor
17.177
17.178 - /// @warning The default constructor sets the iterator
17.179 - /// to an undefined value.
17.180 + /// Default constructor.
17.181 + /// \warning It sets the object to an undefined value.
17.182 Arc() { }
17.183 /// Copy constructor.
17.184
17.185 /// Copy constructor.
17.186 ///
17.187 Arc(const Arc&) { }
17.188 - /// Initialize the iterator to be invalid.
17.189 + /// %Invalid constructor \& conversion.
17.190
17.191 - /// Initialize the iterator to be invalid.
17.192 - ///
17.193 + /// Initializes the object to be invalid.
17.194 + /// \sa Invalid for more details.
17.195 Arc(Invalid) { }
17.196 /// Equality operator
17.197
17.198 + /// Equality operator.
17.199 + ///
17.200 /// Two iterators are equal if and only if they point to the
17.201 - /// same object or both are invalid.
17.202 + /// same object or both are \c INVALID.
17.203 bool operator==(Arc) const { return true; }
17.204 /// Inequality operator
17.205
17.206 - /// \sa operator==(Arc n)
17.207 - ///
17.208 + /// Inequality operator.
17.209 bool operator!=(Arc) const { return true; }
17.210
17.211 /// Artificial ordering operator.
17.212
17.213 - /// To allow the use of digraph descriptors as key type in std::map or
17.214 - /// similar associative container we require this.
17.215 + /// Artificial ordering operator.
17.216 ///
17.217 - /// \note This operator only have to define some strict ordering of
17.218 - /// the items; this order has nothing to do with the iteration
17.219 - /// ordering of the items.
17.220 + /// \note This operator only has to define some strict ordering of
17.221 + /// the arcs; this order has nothing to do with the iteration
17.222 + /// ordering of the arcs.
17.223 bool operator<(Arc) const { return false; }
17.224 };
17.225
17.226 - /// This iterator goes trough the outgoing arcs of a node.
17.227 + /// Iterator class for the outgoing arcs of a node.
17.228
17.229 /// This iterator goes trough the \e outgoing arcs of a certain node
17.230 /// of a digraph.
17.231 /// Its usage is quite simple, for example you can count the number
17.232 /// of outgoing arcs of a node \c n
17.233 - /// in digraph \c g of type \c Digraph as follows.
17.234 + /// in a digraph \c g of type \c %Digraph as follows.
17.235 ///\code
17.236 /// int count=0;
17.237 - /// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
17.238 + /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
17.239 ///\endcode
17.240 -
17.241 class OutArcIt : public Arc {
17.242 public:
17.243 /// Default constructor
17.244
17.245 - /// @warning The default constructor sets the iterator
17.246 - /// to an undefined value.
17.247 + /// Default constructor.
17.248 + /// \warning It sets the iterator to an undefined value.
17.249 OutArcIt() { }
17.250 /// Copy constructor.
17.251
17.252 /// Copy constructor.
17.253 ///
17.254 OutArcIt(const OutArcIt& e) : Arc(e) { }
17.255 - /// Initialize the iterator to be invalid.
17.256 + /// %Invalid constructor \& conversion.
17.257
17.258 - /// Initialize the iterator to be invalid.
17.259 + /// Initializes the iterator to be invalid.
17.260 + /// \sa Invalid for more details.
17.261 + OutArcIt(Invalid) { }
17.262 + /// Sets the iterator to the first outgoing arc.
17.263 +
17.264 + /// Sets the iterator to the first outgoing arc of the given node.
17.265 ///
17.266 - OutArcIt(Invalid) { }
17.267 - /// This constructor sets the iterator to the first outgoing arc.
17.268 + OutArcIt(const Digraph&, const Node&) { }
17.269 + /// Sets the iterator to the given arc.
17.270
17.271 - /// This constructor sets the iterator to the first outgoing arc of
17.272 - /// the node.
17.273 - OutArcIt(const Digraph&, const Node&) { }
17.274 - /// Arc -> OutArcIt conversion
17.275 -
17.276 - /// Sets the iterator to the value of the trivial iterator.
17.277 - /// This feature necessitates that each time we
17.278 - /// iterate the arc-set, the iteration order is the same.
17.279 + /// Sets the iterator to the given arc of the given digraph.
17.280 + ///
17.281 OutArcIt(const Digraph&, const Arc&) { }
17.282 - ///Next outgoing arc
17.283 + /// Next outgoing arc
17.284
17.285 /// Assign the iterator to the next
17.286 /// outgoing arc of the corresponding node.
17.287 OutArcIt& operator++() { return *this; }
17.288 };
17.289
17.290 - /// This iterator goes trough the incoming arcs of a node.
17.291 + /// Iterator class for the incoming arcs of a node.
17.292
17.293 /// This iterator goes trough the \e incoming arcs of a certain node
17.294 /// of a digraph.
17.295 /// Its usage is quite simple, for example you can count the number
17.296 - /// of outgoing arcs of a node \c n
17.297 - /// in digraph \c g of type \c Digraph as follows.
17.298 + /// of incoming arcs of a node \c n
17.299 + /// in a digraph \c g of type \c %Digraph as follows.
17.300 ///\code
17.301 /// int count=0;
17.302 - /// for(Digraph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
17.303 + /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
17.304 ///\endcode
17.305 -
17.306 class InArcIt : public Arc {
17.307 public:
17.308 /// Default constructor
17.309
17.310 - /// @warning The default constructor sets the iterator
17.311 - /// to an undefined value.
17.312 + /// Default constructor.
17.313 + /// \warning It sets the iterator to an undefined value.
17.314 InArcIt() { }
17.315 /// Copy constructor.
17.316
17.317 /// Copy constructor.
17.318 ///
17.319 InArcIt(const InArcIt& e) : Arc(e) { }
17.320 - /// Initialize the iterator to be invalid.
17.321 + /// %Invalid constructor \& conversion.
17.322
17.323 - /// Initialize the iterator to be invalid.
17.324 + /// Initializes the iterator to be invalid.
17.325 + /// \sa Invalid for more details.
17.326 + InArcIt(Invalid) { }
17.327 + /// Sets the iterator to the first incoming arc.
17.328 +
17.329 + /// Sets the iterator to the first incoming arc of the given node.
17.330 ///
17.331 - InArcIt(Invalid) { }
17.332 - /// This constructor sets the iterator to first incoming arc.
17.333 + InArcIt(const Digraph&, const Node&) { }
17.334 + /// Sets the iterator to the given arc.
17.335
17.336 - /// This constructor set the iterator to the first incoming arc of
17.337 - /// the node.
17.338 - InArcIt(const Digraph&, const Node&) { }
17.339 - /// Arc -> InArcIt conversion
17.340 -
17.341 - /// Sets the iterator to the value of the trivial iterator \c e.
17.342 - /// This feature necessitates that each time we
17.343 - /// iterate the arc-set, the iteration order is the same.
17.344 + /// Sets the iterator to the given arc of the given digraph.
17.345 + ///
17.346 InArcIt(const Digraph&, const Arc&) { }
17.347 /// Next incoming arc
17.348
17.349 - /// Assign the iterator to the next inarc of the corresponding node.
17.350 - ///
17.351 + /// Assign the iterator to the next
17.352 + /// incoming arc of the corresponding node.
17.353 InArcIt& operator++() { return *this; }
17.354 };
17.355 - /// This iterator goes through each arc.
17.356
17.357 - /// This iterator goes through each arc of a digraph.
17.358 + /// Iterator class for the arcs.
17.359 +
17.360 + /// This iterator goes through each arc of the digraph.
17.361 /// Its usage is quite simple, for example you can count the number
17.362 - /// of arcs in a digraph \c g of type \c Digraph as follows:
17.363 + /// of arcs in a digraph \c g of type \c %Digraph as follows:
17.364 ///\code
17.365 /// int count=0;
17.366 - /// for(Digraph::ArcIt e(g); e!=INVALID; ++e) ++count;
17.367 + /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
17.368 ///\endcode
17.369 class ArcIt : public Arc {
17.370 public:
17.371 /// Default constructor
17.372
17.373 - /// @warning The default constructor sets the iterator
17.374 - /// to an undefined value.
17.375 + /// Default constructor.
17.376 + /// \warning It sets the iterator to an undefined value.
17.377 ArcIt() { }
17.378 /// Copy constructor.
17.379
17.380 /// Copy constructor.
17.381 ///
17.382 ArcIt(const ArcIt& e) : Arc(e) { }
17.383 - /// Initialize the iterator to be invalid.
17.384 + /// %Invalid constructor \& conversion.
17.385
17.386 - /// Initialize the iterator to be invalid.
17.387 + /// Initializes the iterator to be invalid.
17.388 + /// \sa Invalid for more details.
17.389 + ArcIt(Invalid) { }
17.390 + /// Sets the iterator to the first arc.
17.391 +
17.392 + /// Sets the iterator to the first arc of the given digraph.
17.393 ///
17.394 - ArcIt(Invalid) { }
17.395 - /// This constructor sets the iterator to the first arc.
17.396 + explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
17.397 + /// Sets the iterator to the given arc.
17.398
17.399 - /// This constructor sets the iterator to the first arc of \c g.
17.400 - ///@param g the digraph
17.401 - ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
17.402 - /// Arc -> ArcIt conversion
17.403 -
17.404 - /// Sets the iterator to the value of the trivial iterator \c e.
17.405 - /// This feature necessitates that each time we
17.406 - /// iterate the arc-set, the iteration order is the same.
17.407 + /// Sets the iterator to the given arc of the given digraph.
17.408 + ///
17.409 ArcIt(const Digraph&, const Arc&) { }
17.410 - ///Next arc
17.411 + /// Next arc
17.412
17.413 /// Assign the iterator to the next arc.
17.414 + ///
17.415 ArcIt& operator++() { return *this; }
17.416 };
17.417 - ///Gives back the target node of an arc.
17.418
17.419 - ///Gives back the target node of an arc.
17.420 + /// \brief The source node of the arc.
17.421 ///
17.422 - Node target(Arc) const { return INVALID; }
17.423 - ///Gives back the source node of an arc.
17.424 -
17.425 - ///Gives back the source node of an arc.
17.426 - ///
17.427 + /// Returns the source node of the given arc.
17.428 Node source(Arc) const { return INVALID; }
17.429
17.430 - /// \brief Returns the ID of the node.
17.431 + /// \brief The target node of the arc.
17.432 + ///
17.433 + /// Returns the target node of the given arc.
17.434 + Node target(Arc) const { return INVALID; }
17.435 +
17.436 + /// \brief The ID of the node.
17.437 + ///
17.438 + /// Returns the ID of the given node.
17.439 int id(Node) const { return -1; }
17.440
17.441 - /// \brief Returns the ID of the arc.
17.442 + /// \brief The ID of the arc.
17.443 + ///
17.444 + /// Returns the ID of the given arc.
17.445 int id(Arc) const { return -1; }
17.446
17.447 - /// \brief Returns the node with the given ID.
17.448 + /// \brief The node with the given ID.
17.449 ///
17.450 - /// \pre The argument should be a valid node ID in the graph.
17.451 + /// Returns the node with the given ID.
17.452 + /// \pre The argument should be a valid node ID in the digraph.
17.453 Node nodeFromId(int) const { return INVALID; }
17.454
17.455 - /// \brief Returns the arc with the given ID.
17.456 + /// \brief The arc with the given ID.
17.457 ///
17.458 - /// \pre The argument should be a valid arc ID in the graph.
17.459 + /// Returns the arc with the given ID.
17.460 + /// \pre The argument should be a valid arc ID in the digraph.
17.461 Arc arcFromId(int) const { return INVALID; }
17.462
17.463 - /// \brief Returns an upper bound on the node IDs.
17.464 + /// \brief An upper bound on the node IDs.
17.465 + ///
17.466 + /// Returns an upper bound on the node IDs.
17.467 int maxNodeId() const { return -1; }
17.468
17.469 - /// \brief Returns an upper bound on the arc IDs.
17.470 + /// \brief An upper bound on the arc IDs.
17.471 + ///
17.472 + /// Returns an upper bound on the arc IDs.
17.473 int maxArcId() const { return -1; }
17.474
17.475 void first(Node&) const {}
17.476 @@ -392,45 +390,46 @@
17.477 // Dummy parameter.
17.478 int maxId(Arc) const { return -1; }
17.479
17.480 + /// \brief The opposite node on the arc.
17.481 + ///
17.482 + /// Returns the opposite node on the given arc.
17.483 + Node oppositeNode(Node, Arc) const { return INVALID; }
17.484 +
17.485 /// \brief The base node of the iterator.
17.486 ///
17.487 - /// Gives back the base node of the iterator.
17.488 - /// It is always the target of the pointed arc.
17.489 - Node baseNode(const InArcIt&) const { return INVALID; }
17.490 + /// Returns the base node of the given outgoing arc iterator
17.491 + /// (i.e. the source node of the corresponding arc).
17.492 + Node baseNode(OutArcIt) const { return INVALID; }
17.493
17.494 /// \brief The running node of the iterator.
17.495 ///
17.496 - /// Gives back the running node of the iterator.
17.497 - /// It is always the source of the pointed arc.
17.498 - Node runningNode(const InArcIt&) const { return INVALID; }
17.499 + /// Returns the running node of the given outgoing arc iterator
17.500 + /// (i.e. the target node of the corresponding arc).
17.501 + Node runningNode(OutArcIt) const { return INVALID; }
17.502
17.503 /// \brief The base node of the iterator.
17.504 ///
17.505 - /// Gives back the base node of the iterator.
17.506 - /// It is always the source of the pointed arc.
17.507 - Node baseNode(const OutArcIt&) const { return INVALID; }
17.508 + /// Returns the base node of the given incomming arc iterator
17.509 + /// (i.e. the target node of the corresponding arc).
17.510 + Node baseNode(InArcIt) const { return INVALID; }
17.511
17.512 /// \brief The running node of the iterator.
17.513 ///
17.514 - /// Gives back the running node of the iterator.
17.515 - /// It is always the target of the pointed arc.
17.516 - Node runningNode(const OutArcIt&) const { return INVALID; }
17.517 + /// Returns the running node of the given incomming arc iterator
17.518 + /// (i.e. the source node of the corresponding arc).
17.519 + Node runningNode(InArcIt) const { return INVALID; }
17.520
17.521 - /// \brief The opposite node on the given arc.
17.522 + /// \brief Standard graph map type for the nodes.
17.523 ///
17.524 - /// Gives back the opposite node on the given arc.
17.525 - Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
17.526 -
17.527 - /// \brief Reference map of the nodes to type \c T.
17.528 - ///
17.529 - /// Reference map of the nodes to type \c T.
17.530 + /// Standard graph map type for the nodes.
17.531 + /// It conforms to the ReferenceMap concept.
17.532 template<class T>
17.533 class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
17.534 public:
17.535
17.536 - ///\e
17.537 - NodeMap(const Digraph&) { }
17.538 - ///\e
17.539 + /// Constructor
17.540 + explicit NodeMap(const Digraph&) { }
17.541 + /// Constructor with given initial value
17.542 NodeMap(const Digraph&, T) { }
17.543
17.544 private:
17.545 @@ -445,17 +444,19 @@
17.546 }
17.547 };
17.548
17.549 - /// \brief Reference map of the arcs to type \c T.
17.550 + /// \brief Standard graph map type for the arcs.
17.551 ///
17.552 - /// Reference map of the arcs to type \c T.
17.553 + /// Standard graph map type for the arcs.
17.554 + /// It conforms to the ReferenceMap concept.
17.555 template<class T>
17.556 class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
17.557 public:
17.558
17.559 - ///\e
17.560 - ArcMap(const Digraph&) { }
17.561 - ///\e
17.562 + /// Constructor
17.563 + explicit ArcMap(const Digraph&) { }
17.564 + /// Constructor with given initial value
17.565 ArcMap(const Digraph&, T) { }
17.566 +
17.567 private:
17.568 ///Copy constructor
17.569 ArcMap(const ArcMap& em) :
18.1 --- a/lemon/concepts/graph.h Mon Sep 28 15:53:20 2009 +0200
18.2 +++ b/lemon/concepts/graph.h Thu Nov 05 10:27:17 2009 +0100
18.3 @@ -18,12 +18,14 @@
18.4
18.5 ///\ingroup graph_concepts
18.6 ///\file
18.7 -///\brief The concept of Undirected Graphs.
18.8 +///\brief The concept of undirected graphs.
18.9
18.10 #ifndef LEMON_CONCEPTS_GRAPH_H
18.11 #define LEMON_CONCEPTS_GRAPH_H
18.12
18.13 #include <lemon/concepts/graph_components.h>
18.14 +#include <lemon/concepts/maps.h>
18.15 +#include <lemon/concept_check.h>
18.16 #include <lemon/core.h>
18.17
18.18 namespace lemon {
18.19 @@ -31,63 +33,74 @@
18.20
18.21 /// \ingroup graph_concepts
18.22 ///
18.23 - /// \brief Class describing the concept of Undirected Graphs.
18.24 + /// \brief Class describing the concept of undirected graphs.
18.25 ///
18.26 - /// This class describes the common interface of all Undirected
18.27 - /// Graphs.
18.28 + /// This class describes the common interface of all undirected
18.29 + /// graphs.
18.30 ///
18.31 - /// As all concept describing classes it provides only interface
18.32 - /// without any sensible implementation. So any algorithm for
18.33 - /// undirected graph should compile with this class, but it will not
18.34 + /// Like all concept classes, it only provides an interface
18.35 + /// without any sensible implementation. So any general algorithm for
18.36 + /// undirected graphs should compile with this class, but it will not
18.37 /// run properly, of course.
18.38 + /// An actual graph implementation like \ref ListGraph or
18.39 + /// \ref SmartGraph may have additional functionality.
18.40 ///
18.41 - /// The LEMON undirected graphs also fulfill the concept of
18.42 - /// directed graphs (\ref lemon::concepts::Digraph "Digraph
18.43 - /// Concept"). Each edges can be seen as two opposite
18.44 - /// directed arc and consequently the undirected graph can be
18.45 - /// seen as the direceted graph of these directed arcs. The
18.46 - /// Graph has the Edge inner class for the edges and
18.47 - /// the Arc type for the directed arcs. The Arc type is
18.48 - /// convertible to Edge or inherited from it so from a directed
18.49 - /// arc we can get the represented edge.
18.50 + /// The undirected graphs also fulfill the concept of \ref Digraph
18.51 + /// "directed graphs", since each edge can also be regarded as two
18.52 + /// oppositely directed arcs.
18.53 + /// Undirected graphs provide an Edge type for the undirected edges and
18.54 + /// an Arc type for the directed arcs. The Arc type is convertible to
18.55 + /// Edge or inherited from it, i.e. the corresponding edge can be
18.56 + /// obtained from an arc.
18.57 + /// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt
18.58 + /// and ArcMap classes can be used for the arcs (just like in digraphs).
18.59 + /// Both InArcIt and OutArcIt iterates on the same edges but with
18.60 + /// opposite direction. IncEdgeIt also iterates on the same edges
18.61 + /// as OutArcIt and InArcIt, but it is not convertible to Arc,
18.62 + /// only to Edge.
18.63 ///
18.64 - /// In the sense of the LEMON each edge has a default
18.65 - /// direction (it should be in every computer implementation,
18.66 - /// because the order of edge's nodes defines an
18.67 - /// orientation). With the default orientation we can define that
18.68 - /// the directed arc is forward or backward directed. With the \c
18.69 - /// direction() and \c direct() function we can get the direction
18.70 - /// of the directed arc and we can direct an edge.
18.71 + /// In LEMON, each undirected edge has an inherent orientation.
18.72 + /// Thus it can defined if an arc is forward or backward oriented in
18.73 + /// an undirected graph with respect to this default oriantation of
18.74 + /// the represented edge.
18.75 + /// With the direction() and direct() functions the direction
18.76 + /// of an arc can be obtained and set, respectively.
18.77 ///
18.78 - /// The EdgeIt is an iterator for the edges. We can use
18.79 - /// the EdgeMap to map values for the edges. The InArcIt and
18.80 - /// OutArcIt iterates on the same edges but with opposite
18.81 - /// direction. The IncEdgeIt iterates also on the same edges
18.82 - /// as the OutArcIt and InArcIt but it is not convertible to Arc just
18.83 - /// to Edge.
18.84 + /// Only nodes and edges can be added to or removed from an undirected
18.85 + /// graph and the corresponding arcs are added or removed automatically.
18.86 + ///
18.87 + /// \sa Digraph
18.88 class Graph {
18.89 + private:
18.90 + /// Graphs are \e not copy constructible. Use DigraphCopy instead.
18.91 + Graph(const Graph&) {}
18.92 + /// \brief Assignment of a graph to another one is \e not allowed.
18.93 + /// Use DigraphCopy instead.
18.94 + void operator=(const Graph&) {}
18.95 +
18.96 public:
18.97 - /// \brief The undirected graph should be tagged by the
18.98 - /// UndirectedTag.
18.99 + /// Default constructor.
18.100 + Graph() {}
18.101 +
18.102 + /// \brief Undirected graphs should be tagged with \c UndirectedTag.
18.103 ///
18.104 - /// The undirected graph should be tagged by the UndirectedTag. This
18.105 - /// tag helps the enable_if technics to make compile time
18.106 + /// Undirected graphs should be tagged with \c UndirectedTag.
18.107 + ///
18.108 + /// This tag helps the \c enable_if technics to make compile time
18.109 /// specializations for undirected graphs.
18.110 typedef True UndirectedTag;
18.111
18.112 - /// \brief The base type of node iterators,
18.113 - /// or in other words, the trivial node iterator.
18.114 - ///
18.115 - /// This is the base type of each node iterator,
18.116 - /// thus each kind of node iterator converts to this.
18.117 - /// More precisely each kind of node iterator should be inherited
18.118 - /// from the trivial node iterator.
18.119 + /// The node type of the graph
18.120 +
18.121 + /// This class identifies a node of the graph. It also serves
18.122 + /// as a base class of the node iterators,
18.123 + /// thus they convert to this type.
18.124 class Node {
18.125 public:
18.126 /// Default constructor
18.127
18.128 - /// @warning The default constructor sets the iterator
18.129 - /// to an undefined value.
18.130 + /// Default constructor.
18.131 + /// \warning It sets the object to an undefined value.
18.132 Node() { }
18.133 /// Copy constructor.
18.134
18.135 @@ -95,40 +108,40 @@
18.136 ///
18.137 Node(const Node&) { }
18.138
18.139 - /// Invalid constructor \& conversion.
18.140 + /// %Invalid constructor \& conversion.
18.141
18.142 - /// This constructor initializes the iterator to be invalid.
18.143 + /// Initializes the object to be invalid.
18.144 /// \sa Invalid for more details.
18.145 Node(Invalid) { }
18.146 /// Equality operator
18.147
18.148 + /// Equality operator.
18.149 + ///
18.150 /// Two iterators are equal if and only if they point to the
18.151 - /// same object or both are invalid.
18.152 + /// same object or both are \c INVALID.
18.153 bool operator==(Node) const { return true; }
18.154
18.155 /// Inequality operator
18.156
18.157 - /// \sa operator==(Node n)
18.158 - ///
18.159 + /// Inequality operator.
18.160 bool operator!=(Node) const { return true; }
18.161
18.162 /// Artificial ordering operator.
18.163
18.164 - /// To allow the use of graph descriptors as key type in std::map or
18.165 - /// similar associative container we require this.
18.166 + /// Artificial ordering operator.
18.167 ///
18.168 - /// \note This operator only have to define some strict ordering of
18.169 + /// \note This operator only has to define some strict ordering of
18.170 /// the items; this order has nothing to do with the iteration
18.171 /// ordering of the items.
18.172 bool operator<(Node) const { return false; }
18.173
18.174 };
18.175
18.176 - /// This iterator goes through each node.
18.177 + /// Iterator class for the nodes.
18.178
18.179 - /// This iterator goes through each node.
18.180 + /// This iterator goes through each node of the graph.
18.181 /// Its usage is quite simple, for example you can count the number
18.182 - /// of nodes in graph \c g of type \c Graph like this:
18.183 + /// of nodes in a graph \c g of type \c %Graph like this:
18.184 ///\code
18.185 /// int count=0;
18.186 /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
18.187 @@ -137,30 +150,28 @@
18.188 public:
18.189 /// Default constructor
18.190
18.191 - /// @warning The default constructor sets the iterator
18.192 - /// to an undefined value.
18.193 + /// Default constructor.
18.194 + /// \warning It sets the iterator to an undefined value.
18.195 NodeIt() { }
18.196 /// Copy constructor.
18.197
18.198 /// Copy constructor.
18.199 ///
18.200 NodeIt(const NodeIt& n) : Node(n) { }
18.201 - /// Invalid constructor \& conversion.
18.202 + /// %Invalid constructor \& conversion.
18.203
18.204 - /// Initialize the iterator to be invalid.
18.205 + /// Initializes the iterator to be invalid.
18.206 /// \sa Invalid for more details.
18.207 NodeIt(Invalid) { }
18.208 /// Sets the iterator to the first node.
18.209
18.210 - /// Sets the iterator to the first node of \c g.
18.211 + /// Sets the iterator to the first node of the given digraph.
18.212 ///
18.213 - NodeIt(const Graph&) { }
18.214 - /// Node -> NodeIt conversion.
18.215 + explicit NodeIt(const Graph&) { }
18.216 + /// Sets the iterator to the given node.
18.217
18.218 - /// Sets the iterator to the node of \c the graph pointed by
18.219 - /// the trivial iterator.
18.220 - /// This feature necessitates that each time we
18.221 - /// iterate the arc-set, the iteration order is the same.
18.222 + /// Sets the iterator to the given node of the given digraph.
18.223 + ///
18.224 NodeIt(const Graph&, const Node&) { }
18.225 /// Next node.
18.226
18.227 @@ -170,54 +181,55 @@
18.228 };
18.229
18.230
18.231 - /// The base type of the edge iterators.
18.232 + /// The edge type of the graph
18.233
18.234 - /// The base type of the edge iterators.
18.235 - ///
18.236 + /// This class identifies an edge of the graph. It also serves
18.237 + /// as a base class of the edge iterators,
18.238 + /// thus they will convert to this type.
18.239 class Edge {
18.240 public:
18.241 /// Default constructor
18.242
18.243 - /// @warning The default constructor sets the iterator
18.244 - /// to an undefined value.
18.245 + /// Default constructor.
18.246 + /// \warning It sets the object to an undefined value.
18.247 Edge() { }
18.248 /// Copy constructor.
18.249
18.250 /// Copy constructor.
18.251 ///
18.252 Edge(const Edge&) { }
18.253 - /// Initialize the iterator to be invalid.
18.254 + /// %Invalid constructor \& conversion.
18.255
18.256 - /// Initialize the iterator to be invalid.
18.257 - ///
18.258 + /// Initializes the object to be invalid.
18.259 + /// \sa Invalid for more details.
18.260 Edge(Invalid) { }
18.261 /// Equality operator
18.262
18.263 + /// Equality operator.
18.264 + ///
18.265 /// Two iterators are equal if and only if they point to the
18.266 - /// same object or both are invalid.
18.267 + /// same object or both are \c INVALID.
18.268 bool operator==(Edge) const { return true; }
18.269 /// Inequality operator
18.270
18.271 - /// \sa operator==(Edge n)
18.272 - ///
18.273 + /// Inequality operator.
18.274 bool operator!=(Edge) const { return true; }
18.275
18.276 /// Artificial ordering operator.
18.277
18.278 - /// To allow the use of graph descriptors as key type in std::map or
18.279 - /// similar associative container we require this.
18.280 + /// Artificial ordering operator.
18.281 ///
18.282 - /// \note This operator only have to define some strict ordering of
18.283 - /// the items; this order has nothing to do with the iteration
18.284 - /// ordering of the items.
18.285 + /// \note This operator only has to define some strict ordering of
18.286 + /// the edges; this order has nothing to do with the iteration
18.287 + /// ordering of the edges.
18.288 bool operator<(Edge) const { return false; }
18.289 };
18.290
18.291 - /// This iterator goes through each edge.
18.292 + /// Iterator class for the edges.
18.293
18.294 - /// This iterator goes through each edge of a graph.
18.295 + /// This iterator goes through each edge of the graph.
18.296 /// Its usage is quite simple, for example you can count the number
18.297 - /// of edges in a graph \c g of type \c Graph as follows:
18.298 + /// of edges in a graph \c g of type \c %Graph as follows:
18.299 ///\code
18.300 /// int count=0;
18.301 /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
18.302 @@ -226,290 +238,285 @@
18.303 public:
18.304 /// Default constructor
18.305
18.306 - /// @warning The default constructor sets the iterator
18.307 - /// to an undefined value.
18.308 + /// Default constructor.
18.309 + /// \warning It sets the iterator to an undefined value.
18.310 EdgeIt() { }
18.311 /// Copy constructor.
18.312
18.313 /// Copy constructor.
18.314 ///
18.315 EdgeIt(const EdgeIt& e) : Edge(e) { }
18.316 - /// Initialize the iterator to be invalid.
18.317 + /// %Invalid constructor \& conversion.
18.318
18.319 - /// Initialize the iterator to be invalid.
18.320 + /// Initializes the iterator to be invalid.
18.321 + /// \sa Invalid for more details.
18.322 + EdgeIt(Invalid) { }
18.323 + /// Sets the iterator to the first edge.
18.324 +
18.325 + /// Sets the iterator to the first edge of the given graph.
18.326 ///
18.327 - EdgeIt(Invalid) { }
18.328 - /// This constructor sets the iterator to the first edge.
18.329 + explicit EdgeIt(const Graph&) { }
18.330 + /// Sets the iterator to the given edge.
18.331
18.332 - /// This constructor sets the iterator to the first edge.
18.333 - EdgeIt(const Graph&) { }
18.334 - /// Edge -> EdgeIt conversion
18.335 -
18.336 - /// Sets the iterator to the value of the trivial iterator.
18.337 - /// This feature necessitates that each time we
18.338 - /// iterate the edge-set, the iteration order is the
18.339 - /// same.
18.340 + /// Sets the iterator to the given edge of the given graph.
18.341 + ///
18.342 EdgeIt(const Graph&, const Edge&) { }
18.343 /// Next edge
18.344
18.345 /// Assign the iterator to the next edge.
18.346 + ///
18.347 EdgeIt& operator++() { return *this; }
18.348 };
18.349
18.350 - /// \brief This iterator goes trough the incident undirected
18.351 - /// arcs of a node.
18.352 - ///
18.353 - /// This iterator goes trough the incident edges
18.354 - /// of a certain node of a graph. You should assume that the
18.355 - /// loop arcs will be iterated twice.
18.356 - ///
18.357 + /// Iterator class for the incident edges of a node.
18.358 +
18.359 + /// This iterator goes trough the incident undirected edges
18.360 + /// of a certain node of a graph.
18.361 /// Its usage is quite simple, for example you can compute the
18.362 - /// degree (i.e. count the number of incident arcs of a node \c n
18.363 - /// in graph \c g of type \c Graph as follows.
18.364 + /// degree (i.e. the number of incident edges) of a node \c n
18.365 + /// in a graph \c g of type \c %Graph as follows.
18.366 ///
18.367 ///\code
18.368 /// int count=0;
18.369 /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
18.370 ///\endcode
18.371 + ///
18.372 + /// \warning Loop edges will be iterated twice.
18.373 class IncEdgeIt : public Edge {
18.374 public:
18.375 /// Default constructor
18.376
18.377 - /// @warning The default constructor sets the iterator
18.378 - /// to an undefined value.
18.379 + /// Default constructor.
18.380 + /// \warning It sets the iterator to an undefined value.
18.381 IncEdgeIt() { }
18.382 /// Copy constructor.
18.383
18.384 /// Copy constructor.
18.385 ///
18.386 IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
18.387 - /// Initialize the iterator to be invalid.
18.388 + /// %Invalid constructor \& conversion.
18.389
18.390 - /// Initialize the iterator to be invalid.
18.391 + /// Initializes the iterator to be invalid.
18.392 + /// \sa Invalid for more details.
18.393 + IncEdgeIt(Invalid) { }
18.394 + /// Sets the iterator to the first incident edge.
18.395 +
18.396 + /// Sets the iterator to the first incident edge of the given node.
18.397 ///
18.398 - IncEdgeIt(Invalid) { }
18.399 - /// This constructor sets the iterator to first incident arc.
18.400 + IncEdgeIt(const Graph&, const Node&) { }
18.401 + /// Sets the iterator to the given edge.
18.402
18.403 - /// This constructor set the iterator to the first incident arc of
18.404 - /// the node.
18.405 - IncEdgeIt(const Graph&, const Node&) { }
18.406 - /// Edge -> IncEdgeIt conversion
18.407 + /// Sets the iterator to the given edge of the given graph.
18.408 + ///
18.409 + IncEdgeIt(const Graph&, const Edge&) { }
18.410 + /// Next incident edge
18.411
18.412 - /// Sets the iterator to the value of the trivial iterator \c e.
18.413 - /// This feature necessitates that each time we
18.414 - /// iterate the arc-set, the iteration order is the same.
18.415 - IncEdgeIt(const Graph&, const Edge&) { }
18.416 - /// Next incident arc
18.417 -
18.418 - /// Assign the iterator to the next incident arc
18.419 + /// Assign the iterator to the next incident edge
18.420 /// of the corresponding node.
18.421 IncEdgeIt& operator++() { return *this; }
18.422 };
18.423
18.424 - /// The directed arc type.
18.425 + /// The arc type of the graph
18.426
18.427 - /// The directed arc type. It can be converted to the
18.428 - /// edge or it should be inherited from the undirected
18.429 - /// edge.
18.430 + /// This class identifies a directed arc of the graph. It also serves
18.431 + /// as a base class of the arc iterators,
18.432 + /// thus they will convert to this type.
18.433 class Arc {
18.434 public:
18.435 /// Default constructor
18.436
18.437 - /// @warning The default constructor sets the iterator
18.438 - /// to an undefined value.
18.439 + /// Default constructor.
18.440 + /// \warning It sets the object to an undefined value.
18.441 Arc() { }
18.442 /// Copy constructor.
18.443
18.444 /// Copy constructor.
18.445 ///
18.446 Arc(const Arc&) { }
18.447 - /// Initialize the iterator to be invalid.
18.448 + /// %Invalid constructor \& conversion.
18.449
18.450 - /// Initialize the iterator to be invalid.
18.451 - ///
18.452 + /// Initializes the object to be invalid.
18.453 + /// \sa Invalid for more details.
18.454 Arc(Invalid) { }
18.455 /// Equality operator
18.456
18.457 + /// Equality operator.
18.458 + ///
18.459 /// Two iterators are equal if and only if they point to the
18.460 - /// same object or both are invalid.
18.461 + /// same object or both are \c INVALID.
18.462 bool operator==(Arc) const { return true; }
18.463 /// Inequality operator
18.464
18.465 - /// \sa operator==(Arc n)
18.466 - ///
18.467 + /// Inequality operator.
18.468 bool operator!=(Arc) const { return true; }
18.469
18.470 /// Artificial ordering operator.
18.471
18.472 - /// To allow the use of graph descriptors as key type in std::map or
18.473 - /// similar associative container we require this.
18.474 + /// Artificial ordering operator.
18.475 ///
18.476 - /// \note This operator only have to define some strict ordering of
18.477 - /// the items; this order has nothing to do with the iteration
18.478 - /// ordering of the items.
18.479 + /// \note This operator only has to define some strict ordering of
18.480 + /// the arcs; this order has nothing to do with the iteration
18.481 + /// ordering of the arcs.
18.482 bool operator<(Arc) const { return false; }
18.483
18.484 - /// Converison to Edge
18.485 + /// Converison to \c Edge
18.486 +
18.487 + /// Converison to \c Edge.
18.488 + ///
18.489 operator Edge() const { return Edge(); }
18.490 };
18.491 - /// This iterator goes through each directed arc.
18.492
18.493 - /// This iterator goes through each arc of a graph.
18.494 + /// Iterator class for the arcs.
18.495 +
18.496 + /// This iterator goes through each directed arc of the graph.
18.497 /// Its usage is quite simple, for example you can count the number
18.498 - /// of arcs in a graph \c g of type \c Graph as follows:
18.499 + /// of arcs in a graph \c g of type \c %Graph as follows:
18.500 ///\code
18.501 /// int count=0;
18.502 - /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
18.503 + /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
18.504 ///\endcode
18.505 class ArcIt : public Arc {
18.506 public:
18.507 /// Default constructor
18.508
18.509 - /// @warning The default constructor sets the iterator
18.510 - /// to an undefined value.
18.511 + /// Default constructor.
18.512 + /// \warning It sets the iterator to an undefined value.
18.513 ArcIt() { }
18.514 /// Copy constructor.
18.515
18.516 /// Copy constructor.
18.517 ///
18.518 ArcIt(const ArcIt& e) : Arc(e) { }
18.519 - /// Initialize the iterator to be invalid.
18.520 + /// %Invalid constructor \& conversion.
18.521
18.522 - /// Initialize the iterator to be invalid.
18.523 + /// Initializes the iterator to be invalid.
18.524 + /// \sa Invalid for more details.
18.525 + ArcIt(Invalid) { }
18.526 + /// Sets the iterator to the first arc.
18.527 +
18.528 + /// Sets the iterator to the first arc of the given graph.
18.529 ///
18.530 - ArcIt(Invalid) { }
18.531 - /// This constructor sets the iterator to the first arc.
18.532 + explicit ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
18.533 + /// Sets the iterator to the given arc.
18.534
18.535 - /// This constructor sets the iterator to the first arc of \c g.
18.536 - ///@param g the graph
18.537 - ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
18.538 - /// Arc -> ArcIt conversion
18.539 -
18.540 - /// Sets the iterator to the value of the trivial iterator \c e.
18.541 - /// This feature necessitates that each time we
18.542 - /// iterate the arc-set, the iteration order is the same.
18.543 + /// Sets the iterator to the given arc of the given graph.
18.544 + ///
18.545 ArcIt(const Graph&, const Arc&) { }
18.546 - ///Next arc
18.547 + /// Next arc
18.548
18.549 /// Assign the iterator to the next arc.
18.550 + ///
18.551 ArcIt& operator++() { return *this; }
18.552 };
18.553
18.554 - /// This iterator goes trough the outgoing directed arcs of a node.
18.555 + /// Iterator class for the outgoing arcs of a node.
18.556
18.557 - /// This iterator goes trough the \e outgoing arcs of a certain node
18.558 - /// of a graph.
18.559 + /// This iterator goes trough the \e outgoing directed arcs of a
18.560 + /// certain node of a graph.
18.561 /// Its usage is quite simple, for example you can count the number
18.562 /// of outgoing arcs of a node \c n
18.563 - /// in graph \c g of type \c Graph as follows.
18.564 + /// in a graph \c g of type \c %Graph as follows.
18.565 ///\code
18.566 /// int count=0;
18.567 - /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
18.568 + /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
18.569 ///\endcode
18.570 -
18.571 class OutArcIt : public Arc {
18.572 public:
18.573 /// Default constructor
18.574
18.575 - /// @warning The default constructor sets the iterator
18.576 - /// to an undefined value.
18.577 + /// Default constructor.
18.578 + /// \warning It sets the iterator to an undefined value.
18.579 OutArcIt() { }
18.580 /// Copy constructor.
18.581
18.582 /// Copy constructor.
18.583 ///
18.584 OutArcIt(const OutArcIt& e) : Arc(e) { }
18.585 - /// Initialize the iterator to be invalid.
18.586 + /// %Invalid constructor \& conversion.
18.587
18.588 - /// Initialize the iterator to be invalid.
18.589 + /// Initializes the iterator to be invalid.
18.590 + /// \sa Invalid for more details.
18.591 + OutArcIt(Invalid) { }
18.592 + /// Sets the iterator to the first outgoing arc.
18.593 +
18.594 + /// Sets the iterator to the first outgoing arc of the given node.
18.595 ///
18.596 - OutArcIt(Invalid) { }
18.597 - /// This constructor sets the iterator to the first outgoing arc.
18.598 -
18.599 - /// This constructor sets the iterator to the first outgoing arc of
18.600 - /// the node.
18.601 - ///@param n the node
18.602 - ///@param g the graph
18.603 OutArcIt(const Graph& n, const Node& g) {
18.604 ignore_unused_variable_warning(n);
18.605 ignore_unused_variable_warning(g);
18.606 }
18.607 - /// Arc -> OutArcIt conversion
18.608 + /// Sets the iterator to the given arc.
18.609
18.610 - /// Sets the iterator to the value of the trivial iterator.
18.611 - /// This feature necessitates that each time we
18.612 - /// iterate the arc-set, the iteration order is the same.
18.613 + /// Sets the iterator to the given arc of the given graph.
18.614 + ///
18.615 OutArcIt(const Graph&, const Arc&) { }
18.616 - ///Next outgoing arc
18.617 + /// Next outgoing arc
18.618
18.619 /// Assign the iterator to the next
18.620 /// outgoing arc of the corresponding node.
18.621 OutArcIt& operator++() { return *this; }
18.622 };
18.623
18.624 - /// This iterator goes trough the incoming directed arcs of a node.
18.625 + /// Iterator class for the incoming arcs of a node.
18.626
18.627 - /// This iterator goes trough the \e incoming arcs of a certain node
18.628 - /// of a graph.
18.629 + /// This iterator goes trough the \e incoming directed arcs of a
18.630 + /// certain node of a graph.
18.631 /// Its usage is quite simple, for example you can count the number
18.632 - /// of outgoing arcs of a node \c n
18.633 - /// in graph \c g of type \c Graph as follows.
18.634 + /// of incoming arcs of a node \c n
18.635 + /// in a graph \c g of type \c %Graph as follows.
18.636 ///\code
18.637 /// int count=0;
18.638 - /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
18.639 + /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
18.640 ///\endcode
18.641 -
18.642 class InArcIt : public Arc {
18.643 public:
18.644 /// Default constructor
18.645
18.646 - /// @warning The default constructor sets the iterator
18.647 - /// to an undefined value.
18.648 + /// Default constructor.
18.649 + /// \warning It sets the iterator to an undefined value.
18.650 InArcIt() { }
18.651 /// Copy constructor.
18.652
18.653 /// Copy constructor.
18.654 ///
18.655 InArcIt(const InArcIt& e) : Arc(e) { }
18.656 - /// Initialize the iterator to be invalid.
18.657 + /// %Invalid constructor \& conversion.
18.658
18.659 - /// Initialize the iterator to be invalid.
18.660 + /// Initializes the iterator to be invalid.
18.661 + /// \sa Invalid for more details.
18.662 + InArcIt(Invalid) { }
18.663 + /// Sets the iterator to the first incoming arc.
18.664 +
18.665 + /// Sets the iterator to the first incoming arc of the given node.
18.666 ///
18.667 - InArcIt(Invalid) { }
18.668 - /// This constructor sets the iterator to first incoming arc.
18.669 -
18.670 - /// This constructor set the iterator to the first incoming arc of
18.671 - /// the node.
18.672 - ///@param n the node
18.673 - ///@param g the graph
18.674 InArcIt(const Graph& g, const Node& n) {
18.675 ignore_unused_variable_warning(n);
18.676 ignore_unused_variable_warning(g);
18.677 }
18.678 - /// Arc -> InArcIt conversion
18.679 + /// Sets the iterator to the given arc.
18.680
18.681 - /// Sets the iterator to the value of the trivial iterator \c e.
18.682 - /// This feature necessitates that each time we
18.683 - /// iterate the arc-set, the iteration order is the same.
18.684 + /// Sets the iterator to the given arc of the given graph.
18.685 + ///
18.686 InArcIt(const Graph&, const Arc&) { }
18.687 /// Next incoming arc
18.688
18.689 - /// Assign the iterator to the next inarc of the corresponding node.
18.690 - ///
18.691 + /// Assign the iterator to the next
18.692 + /// incoming arc of the corresponding node.
18.693 InArcIt& operator++() { return *this; }
18.694 };
18.695
18.696 - /// \brief Reference map of the nodes to type \c T.
18.697 + /// \brief Standard graph map type for the nodes.
18.698 ///
18.699 - /// Reference map of the nodes to type \c T.
18.700 + /// Standard graph map type for the nodes.
18.701 + /// It conforms to the ReferenceMap concept.
18.702 template<class T>
18.703 class NodeMap : public ReferenceMap<Node, T, T&, const T&>
18.704 {
18.705 public:
18.706
18.707 - ///\e
18.708 - NodeMap(const Graph&) { }
18.709 - ///\e
18.710 + /// Constructor
18.711 + explicit NodeMap(const Graph&) { }
18.712 + /// Constructor with given initial value
18.713 NodeMap(const Graph&, T) { }
18.714
18.715 private:
18.716 @@ -524,18 +531,20 @@
18.717 }
18.718 };
18.719
18.720 - /// \brief Reference map of the arcs to type \c T.
18.721 + /// \brief Standard graph map type for the arcs.
18.722 ///
18.723 - /// Reference map of the arcs to type \c T.
18.724 + /// Standard graph map type for the arcs.
18.725 + /// It conforms to the ReferenceMap concept.
18.726 template<class T>
18.727 class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
18.728 {
18.729 public:
18.730
18.731 - ///\e
18.732 - ArcMap(const Graph&) { }
18.733 - ///\e
18.734 + /// Constructor
18.735 + explicit ArcMap(const Graph&) { }
18.736 + /// Constructor with given initial value
18.737 ArcMap(const Graph&, T) { }
18.738 +
18.739 private:
18.740 ///Copy constructor
18.741 ArcMap(const ArcMap& em) :
18.742 @@ -548,18 +557,20 @@
18.743 }
18.744 };
18.745
18.746 - /// Reference map of the edges to type \c T.
18.747 -
18.748 - /// Reference map of the edges to type \c T.
18.749 + /// \brief Standard graph map type for the edges.
18.750 + ///
18.751 + /// Standard graph map type for the edges.
18.752 + /// It conforms to the ReferenceMap concept.
18.753 template<class T>
18.754 class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
18.755 {
18.756 public:
18.757
18.758 - ///\e
18.759 - EdgeMap(const Graph&) { }
18.760 - ///\e
18.761 + /// Constructor
18.762 + explicit EdgeMap(const Graph&) { }
18.763 + /// Constructor with given initial value
18.764 EdgeMap(const Graph&, T) { }
18.765 +
18.766 private:
18.767 ///Copy constructor
18.768 EdgeMap(const EdgeMap& em) :
18.769 @@ -572,107 +583,124 @@
18.770 }
18.771 };
18.772
18.773 - /// \brief Direct the given edge.
18.774 + /// \brief The first node of the edge.
18.775 ///
18.776 - /// Direct the given edge. The returned arc source
18.777 - /// will be the given node.
18.778 - Arc direct(const Edge&, const Node&) const {
18.779 - return INVALID;
18.780 - }
18.781 -
18.782 - /// \brief Direct the given edge.
18.783 + /// Returns the first node of the given edge.
18.784 ///
18.785 - /// Direct the given edge. The returned arc
18.786 - /// represents the given edge and the direction comes
18.787 - /// from the bool parameter. The source of the edge and
18.788 - /// the directed arc is the same when the given bool is true.
18.789 - Arc direct(const Edge&, bool) const {
18.790 - return INVALID;
18.791 - }
18.792 -
18.793 - /// \brief Returns true if the arc has default orientation.
18.794 - ///
18.795 - /// Returns whether the given directed arc is same orientation as
18.796 - /// the corresponding edge's default orientation.
18.797 - bool direction(Arc) const { return true; }
18.798 -
18.799 - /// \brief Returns the opposite directed arc.
18.800 - ///
18.801 - /// Returns the opposite directed arc.
18.802 - Arc oppositeArc(Arc) const { return INVALID; }
18.803 -
18.804 - /// \brief Opposite node on an arc
18.805 - ///
18.806 - /// \return The opposite of the given node on the given edge.
18.807 - Node oppositeNode(Node, Edge) const { return INVALID; }
18.808 -
18.809 - /// \brief First node of the edge.
18.810 - ///
18.811 - /// \return The first node of the given edge.
18.812 - ///
18.813 - /// Naturally edges don't have direction and thus
18.814 - /// don't have source and target node. However we use \c u() and \c v()
18.815 - /// methods to query the two nodes of the arc. The direction of the
18.816 - /// arc which arises this way is called the inherent direction of the
18.817 - /// edge, and is used to define the "default" direction
18.818 - /// of the directed versions of the arcs.
18.819 + /// Edges don't have source and target nodes, however methods
18.820 + /// u() and v() are used to query the two end-nodes of an edge.
18.821 + /// The orientation of an edge that arises this way is called
18.822 + /// the inherent direction, it is used to define the default
18.823 + /// direction for the corresponding arcs.
18.824 /// \sa v()
18.825 /// \sa direction()
18.826 Node u(Edge) const { return INVALID; }
18.827
18.828 - /// \brief Second node of the edge.
18.829 + /// \brief The second node of the edge.
18.830 ///
18.831 - /// \return The second node of the given edge.
18.832 + /// Returns the second node of the given edge.
18.833 ///
18.834 - /// Naturally edges don't have direction and thus
18.835 - /// don't have source and target node. However we use \c u() and \c v()
18.836 - /// methods to query the two nodes of the arc. The direction of the
18.837 - /// arc which arises this way is called the inherent direction of the
18.838 - /// edge, and is used to define the "default" direction
18.839 - /// of the directed versions of the arcs.
18.840 + /// Edges don't have source and target nodes, however methods
18.841 + /// u() and v() are used to query the two end-nodes of an edge.
18.842 + /// The orientation of an edge that arises this way is called
18.843 + /// the inherent direction, it is used to define the default
18.844 + /// direction for the corresponding arcs.
18.845 /// \sa u()
18.846 /// \sa direction()
18.847 Node v(Edge) const { return INVALID; }
18.848
18.849 - /// \brief Source node of the directed arc.
18.850 + /// \brief The source node of the arc.
18.851 + ///
18.852 + /// Returns the source node of the given arc.
18.853 Node source(Arc) const { return INVALID; }
18.854
18.855 - /// \brief Target node of the directed arc.
18.856 + /// \brief The target node of the arc.
18.857 + ///
18.858 + /// Returns the target node of the given arc.
18.859 Node target(Arc) const { return INVALID; }
18.860
18.861 - /// \brief Returns the id of the node.
18.862 + /// \brief The ID of the node.
18.863 + ///
18.864 + /// Returns the ID of the given node.
18.865 int id(Node) const { return -1; }
18.866
18.867 - /// \brief Returns the id of the edge.
18.868 + /// \brief The ID of the edge.
18.869 + ///
18.870 + /// Returns the ID of the given edge.
18.871 int id(Edge) const { return -1; }
18.872
18.873 - /// \brief Returns the id of the arc.
18.874 + /// \brief The ID of the arc.
18.875 + ///
18.876 + /// Returns the ID of the given arc.
18.877 int id(Arc) const { return -1; }
18.878
18.879 - /// \brief Returns the node with the given id.
18.880 + /// \brief The node with the given ID.
18.881 ///
18.882 - /// \pre The argument should be a valid node id in the graph.
18.883 + /// Returns the node with the given ID.
18.884 + /// \pre The argument should be a valid node ID in the graph.
18.885 Node nodeFromId(int) const { return INVALID; }
18.886
18.887 - /// \brief Returns the edge with the given id.
18.888 + /// \brief The edge with the given ID.
18.889 ///
18.890 - /// \pre The argument should be a valid edge id in the graph.
18.891 + /// Returns the edge with the given ID.
18.892 + /// \pre The argument should be a valid edge ID in the graph.
18.893 Edge edgeFromId(int) const { return INVALID; }
18.894
18.895 - /// \brief Returns the arc with the given id.
18.896 + /// \brief The arc with the given ID.
18.897 ///
18.898 - /// \pre The argument should be a valid arc id in the graph.
18.899 + /// Returns the arc with the given ID.
18.900 + /// \pre The argument should be a valid arc ID in the graph.
18.901 Arc arcFromId(int) const { return INVALID; }
18.902
18.903 - /// \brief Returns an upper bound on the node IDs.
18.904 + /// \brief An upper bound on the node IDs.
18.905 + ///
18.906 + /// Returns an upper bound on the node IDs.
18.907 int maxNodeId() const { return -1; }
18.908
18.909 - /// \brief Returns an upper bound on the edge IDs.
18.910 + /// \brief An upper bound on the edge IDs.
18.911 + ///
18.912 + /// Returns an upper bound on the edge IDs.
18.913 int maxEdgeId() const { return -1; }
18.914
18.915 - /// \brief Returns an upper bound on the arc IDs.
18.916 + /// \brief An upper bound on the arc IDs.
18.917 + ///
18.918 + /// Returns an upper bound on the arc IDs.
18.919 int maxArcId() const { return -1; }
18.920
18.921 + /// \brief The direction of the arc.
18.922 + ///
18.923 + /// Returns \c true if the direction of the given arc is the same as
18.924 + /// the inherent orientation of the represented edge.
18.925 + bool direction(Arc) const { return true; }
18.926 +
18.927 + /// \brief Direct the edge.
18.928 + ///
18.929 + /// Direct the given edge. The returned arc
18.930 + /// represents the given edge and its direction comes
18.931 + /// from the bool parameter. If it is \c true, then the direction
18.932 + /// of the arc is the same as the inherent orientation of the edge.
18.933 + Arc direct(Edge, bool) const {
18.934 + return INVALID;
18.935 + }
18.936 +
18.937 + /// \brief Direct the edge.
18.938 + ///
18.939 + /// Direct the given edge. The returned arc represents the given
18.940 + /// edge and its source node is the given node.
18.941 + Arc direct(Edge, Node) const {
18.942 + return INVALID;
18.943 + }
18.944 +
18.945 + /// \brief The oppositely directed arc.
18.946 + ///
18.947 + /// Returns the oppositely directed arc representing the same edge.
18.948 + Arc oppositeArc(Arc) const { return INVALID; }
18.949 +
18.950 + /// \brief The opposite node on the edge.
18.951 + ///
18.952 + /// Returns the opposite node on the given edge.
18.953 + Node oppositeNode(Node, Edge) const { return INVALID; }
18.954 +
18.955 void first(Node&) const {}
18.956 void next(Node&) const {}
18.957
18.958 @@ -705,47 +733,39 @@
18.959 // Dummy parameter.
18.960 int maxId(Arc) const { return -1; }
18.961
18.962 - /// \brief Base node of the iterator
18.963 + /// \brief The base node of the iterator.
18.964 ///
18.965 - /// Returns the base node (the source in this case) of the iterator
18.966 - Node baseNode(OutArcIt e) const {
18.967 - return source(e);
18.968 - }
18.969 - /// \brief Running node of the iterator
18.970 + /// Returns the base node of the given incident edge iterator.
18.971 + Node baseNode(IncEdgeIt) const { return INVALID; }
18.972 +
18.973 + /// \brief The running node of the iterator.
18.974 ///
18.975 - /// Returns the running node (the target in this case) of the
18.976 - /// iterator
18.977 - Node runningNode(OutArcIt e) const {
18.978 - return target(e);
18.979 - }
18.980 + /// Returns the running node of the given incident edge iterator.
18.981 + Node runningNode(IncEdgeIt) const { return INVALID; }
18.982
18.983 - /// \brief Base node of the iterator
18.984 + /// \brief The base node of the iterator.
18.985 ///
18.986 - /// Returns the base node (the target in this case) of the iterator
18.987 - Node baseNode(InArcIt e) const {
18.988 - return target(e);
18.989 - }
18.990 - /// \brief Running node of the iterator
18.991 + /// Returns the base node of the given outgoing arc iterator
18.992 + /// (i.e. the source node of the corresponding arc).
18.993 + Node baseNode(OutArcIt) const { return INVALID; }
18.994 +
18.995 + /// \brief The running node of the iterator.
18.996 ///
18.997 - /// Returns the running node (the source in this case) of the
18.998 - /// iterator
18.999 - Node runningNode(InArcIt e) const {
18.1000 - return source(e);
18.1001 - }
18.1002 + /// Returns the running node of the given outgoing arc iterator
18.1003 + /// (i.e. the target node of the corresponding arc).
18.1004 + Node runningNode(OutArcIt) const { return INVALID; }
18.1005
18.1006 - /// \brief Base node of the iterator
18.1007 + /// \brief The base node of the iterator.
18.1008 ///
18.1009 - /// Returns the base node of the iterator
18.1010 - Node baseNode(IncEdgeIt) const {
18.1011 - return INVALID;
18.1012 - }
18.1013 + /// Returns the base node of the given incomming arc iterator
18.1014 + /// (i.e. the target node of the corresponding arc).
18.1015 + Node baseNode(InArcIt) const { return INVALID; }
18.1016
18.1017 - /// \brief Running node of the iterator
18.1018 + /// \brief The running node of the iterator.
18.1019 ///
18.1020 - /// Returns the running node of the iterator
18.1021 - Node runningNode(IncEdgeIt) const {
18.1022 - return INVALID;
18.1023 - }
18.1024 + /// Returns the running node of the given incomming arc iterator
18.1025 + /// (i.e. the source node of the corresponding arc).
18.1026 + Node runningNode(InArcIt) const { return INVALID; }
18.1027
18.1028 template <typename _Graph>
18.1029 struct Constraints {
19.1 --- a/lemon/concepts/graph_components.h Mon Sep 28 15:53:20 2009 +0200
19.2 +++ b/lemon/concepts/graph_components.h Thu Nov 05 10:27:17 2009 +0100
19.3 @@ -92,7 +92,7 @@
19.4 /// It makes possible to use graph item types as key types in
19.5 /// associative containers (e.g. \c std::map).
19.6 ///
19.7 - /// \note This operator only have to define some strict ordering of
19.8 + /// \note This operator only has to define some strict ordering of
19.9 /// the items; this order has nothing to do with the iteration
19.10 /// ordering of the items.
19.11 bool operator<(const GraphItem&) const { return false; }
20.1 --- a/lemon/cplex.cc Mon Sep 28 15:53:20 2009 +0200
20.2 +++ b/lemon/cplex.cc Thu Nov 05 10:27:17 2009 +0100
20.3 @@ -111,6 +111,39 @@
20.4 return i;
20.5 }
20.6
20.7 + int CplexBase::_addRow(Value lb, ExprIterator b,
20.8 + ExprIterator e, Value ub) {
20.9 + int i = CPXgetnumrows(cplexEnv(), _prob);
20.10 + if (lb == -INF) {
20.11 + const char s = 'L';
20.12 + CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
20.13 + } else if (ub == INF) {
20.14 + const char s = 'G';
20.15 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
20.16 + } else if (lb == ub){
20.17 + const char s = 'E';
20.18 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
20.19 + } else {
20.20 + const char s = 'R';
20.21 + double len = ub - lb;
20.22 + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
20.23 + }
20.24 +
20.25 + std::vector<int> indices;
20.26 + std::vector<int> rowlist;
20.27 + std::vector<Value> values;
20.28 +
20.29 + for(ExprIterator it=b; it!=e; ++it) {
20.30 + indices.push_back(it->first);
20.31 + values.push_back(it->second);
20.32 + rowlist.push_back(i);
20.33 + }
20.34 +
20.35 + CPXchgcoeflist(cplexEnv(), _prob, values.size(),
20.36 + &rowlist.front(), &indices.front(), &values.front());
20.37 +
20.38 + return i;
20.39 + }
20.40
20.41 void CplexBase::_eraseCol(int i) {
20.42 CPXdelcols(cplexEnv(), _prob, i, i);
21.1 --- a/lemon/cplex.h Mon Sep 28 15:53:20 2009 +0200
21.2 +++ b/lemon/cplex.h Thu Nov 05 10:27:17 2009 +0100
21.3 @@ -93,6 +93,7 @@
21.4
21.5 virtual int _addCol();
21.6 virtual int _addRow();
21.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
21.8
21.9 virtual void _eraseCol(int i);
21.10 virtual void _eraseRow(int i);
22.1 --- a/lemon/edge_set.h Mon Sep 28 15:53:20 2009 +0200
22.2 +++ b/lemon/edge_set.h Thu Nov 05 10:27:17 2009 +0100
22.3 @@ -867,7 +867,7 @@
22.4 arc.id = arcs.size() - 1;
22.5 }
22.6
22.7 - void next(Arc& arc) const {
22.8 + static void next(Arc& arc) {
22.9 --arc.id;
22.10 }
22.11
22.12 @@ -1173,7 +1173,7 @@
22.13 arc.id = arcs.size() - 1;
22.14 }
22.15
22.16 - void next(Arc& arc) const {
22.17 + static void next(Arc& arc) {
22.18 --arc.id;
22.19 }
22.20
22.21 @@ -1181,7 +1181,7 @@
22.22 arc.id = arcs.size() / 2 - 1;
22.23 }
22.24
22.25 - void next(Edge& arc) const {
22.26 + static void next(Edge& arc) {
22.27 --arc.id;
22.28 }
22.29
23.1 --- a/lemon/full_graph.h Mon Sep 28 15:53:20 2009 +0200
23.2 +++ b/lemon/full_graph.h Thu Nov 05 10:27:17 2009 +0100
23.3 @@ -24,7 +24,7 @@
23.4
23.5 ///\ingroup graphs
23.6 ///\file
23.7 -///\brief FullGraph and FullDigraph classes.
23.8 +///\brief FullDigraph and FullGraph classes.
23.9
23.10 namespace lemon {
23.11
23.12 @@ -51,7 +51,7 @@
23.13 typedef True ArcNumTag;
23.14
23.15 Node operator()(int ix) const { return Node(ix); }
23.16 - int index(const Node& node) const { return node._id; }
23.17 + static int index(const Node& node) { return node._id; }
23.18
23.19 Arc arc(const Node& s, const Node& t) const {
23.20 return Arc(s._id * _node_num + t._id);
23.21 @@ -148,24 +148,26 @@
23.22
23.23 /// \ingroup graphs
23.24 ///
23.25 - /// \brief A full digraph class.
23.26 + /// \brief A directed full graph class.
23.27 ///
23.28 - /// This is a simple and fast directed full graph implementation.
23.29 - /// From each node go arcs to each node (including the source node),
23.30 - /// therefore the number of the arcs in the digraph is the square of
23.31 - /// the node number. This digraph type is completely static, so you
23.32 - /// can neither add nor delete either arcs or nodes, and it needs
23.33 - /// constant space in memory.
23.34 + /// FullDigraph is a simple and fast implmenetation of directed full
23.35 + /// (complete) graphs. It contains an arc from each node to each node
23.36 + /// (including a loop for each node), therefore the number of arcs
23.37 + /// is the square of the number of nodes.
23.38 + /// This class is completely static and it needs constant memory space.
23.39 + /// Thus you can neither add nor delete nodes or arcs, however
23.40 + /// the structure can be resized using resize().
23.41 ///
23.42 - /// This class fully conforms to the \ref concepts::Digraph
23.43 - /// "Digraph concept".
23.44 + /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
23.45 + /// Most of its member functions and nested classes are documented
23.46 + /// only in the concept class.
23.47 ///
23.48 - /// The \c FullDigraph and \c FullGraph classes are very similar,
23.49 + /// \note FullDigraph and FullGraph classes are very similar,
23.50 /// but there are two differences. While this class conforms only
23.51 - /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph
23.52 - /// class conforms to the \ref concepts::Graph "Graph" concept,
23.53 - /// moreover \c FullGraph does not contain a loop arc for each
23.54 - /// node as \c FullDigraph does.
23.55 + /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
23.56 + /// conforms to the \ref concepts::Graph "Graph" concept,
23.57 + /// moreover FullGraph does not contain a loop for each
23.58 + /// node as this class does.
23.59 ///
23.60 /// \sa FullGraph
23.61 class FullDigraph : public ExtendedFullDigraphBase {
23.62 @@ -173,7 +175,9 @@
23.63
23.64 public:
23.65
23.66 - /// \brief Constructor
23.67 + /// \brief Default constructor.
23.68 + ///
23.69 + /// Default constructor. The number of nodes and arcs will be zero.
23.70 FullDigraph() { construct(0); }
23.71
23.72 /// \brief Constructor
23.73 @@ -184,8 +188,8 @@
23.74
23.75 /// \brief Resizes the digraph
23.76 ///
23.77 - /// Resizes the digraph. The function will fully destroy and
23.78 - /// rebuild the digraph. This cause that the maps of the digraph will
23.79 + /// This function resizes the digraph. It fully destroys and
23.80 + /// rebuilds the structure, therefore the maps of the digraph will be
23.81 /// reallocated automatically and the previous values will be lost.
23.82 void resize(int n) {
23.83 Parent::notifier(Arc()).clear();
23.84 @@ -197,24 +201,24 @@
23.85
23.86 /// \brief Returns the node with the given index.
23.87 ///
23.88 - /// Returns the node with the given index. Since it is a static
23.89 - /// digraph its nodes can be indexed with integers from the range
23.90 - /// <tt>[0..nodeNum()-1]</tt>.
23.91 + /// Returns the node with the given index. Since this structure is
23.92 + /// completely static, the nodes can be indexed with integers from
23.93 + /// the range <tt>[0..nodeNum()-1]</tt>.
23.94 /// \sa index()
23.95 Node operator()(int ix) const { return Parent::operator()(ix); }
23.96
23.97 /// \brief Returns the index of the given node.
23.98 ///
23.99 - /// Returns the index of the given node. Since it is a static
23.100 - /// digraph its nodes can be indexed with integers from the range
23.101 - /// <tt>[0..nodeNum()-1]</tt>.
23.102 - /// \sa operator()
23.103 - int index(const Node& node) const { return Parent::index(node); }
23.104 + /// Returns the index of the given node. Since this structure is
23.105 + /// completely static, the nodes can be indexed with integers from
23.106 + /// the range <tt>[0..nodeNum()-1]</tt>.
23.107 + /// \sa operator()()
23.108 + static int index(const Node& node) { return Parent::index(node); }
23.109
23.110 /// \brief Returns the arc connecting the given nodes.
23.111 ///
23.112 /// Returns the arc connecting the given nodes.
23.113 - Arc arc(const Node& u, const Node& v) const {
23.114 + Arc arc(Node u, Node v) const {
23.115 return Parent::arc(u, v);
23.116 }
23.117
23.118 @@ -283,7 +287,7 @@
23.119 public:
23.120
23.121 Node operator()(int ix) const { return Node(ix); }
23.122 - int index(const Node& node) const { return node._id; }
23.123 + static int index(const Node& node) { return node._id; }
23.124
23.125 Edge edge(const Node& u, const Node& v) const {
23.126 if (u._id < v._id) {
23.127 @@ -520,21 +524,23 @@
23.128 ///
23.129 /// \brief An undirected full graph class.
23.130 ///
23.131 - /// This is a simple and fast undirected full graph
23.132 - /// implementation. From each node go edge to each other node,
23.133 - /// therefore the number of edges in the graph is \f$n(n-1)/2\f$.
23.134 - /// This graph type is completely static, so you can neither
23.135 - /// add nor delete either edges or nodes, and it needs constant
23.136 - /// space in memory.
23.137 + /// FullGraph is a simple and fast implmenetation of undirected full
23.138 + /// (complete) graphs. It contains an edge between every distinct pair
23.139 + /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
23.140 + /// This class is completely static and it needs constant memory space.
23.141 + /// Thus you can neither add nor delete nodes or edges, however
23.142 + /// the structure can be resized using resize().
23.143 ///
23.144 - /// This class fully conforms to the \ref concepts::Graph "Graph concept".
23.145 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
23.146 + /// Most of its member functions and nested classes are documented
23.147 + /// only in the concept class.
23.148 ///
23.149 - /// The \c FullGraph and \c FullDigraph classes are very similar,
23.150 - /// but there are two differences. While the \c FullDigraph class
23.151 + /// \note FullDigraph and FullGraph classes are very similar,
23.152 + /// but there are two differences. While FullDigraph
23.153 /// conforms only to the \ref concepts::Digraph "Digraph" concept,
23.154 /// this class conforms to the \ref concepts::Graph "Graph" concept,
23.155 - /// moreover \c FullGraph does not contain a loop arc for each
23.156 - /// node as \c FullDigraph does.
23.157 + /// moreover this class does not contain a loop for each
23.158 + /// node as FullDigraph does.
23.159 ///
23.160 /// \sa FullDigraph
23.161 class FullGraph : public ExtendedFullGraphBase {
23.162 @@ -542,7 +548,9 @@
23.163
23.164 public:
23.165
23.166 - /// \brief Constructor
23.167 + /// \brief Default constructor.
23.168 + ///
23.169 + /// Default constructor. The number of nodes and edges will be zero.
23.170 FullGraph() { construct(0); }
23.171
23.172 /// \brief Constructor
23.173 @@ -553,8 +561,8 @@
23.174
23.175 /// \brief Resizes the graph
23.176 ///
23.177 - /// Resizes the graph. The function will fully destroy and
23.178 - /// rebuild the graph. This cause that the maps of the graph will
23.179 + /// This function resizes the graph. It fully destroys and
23.180 + /// rebuilds the structure, therefore the maps of the graph will be
23.181 /// reallocated automatically and the previous values will be lost.
23.182 void resize(int n) {
23.183 Parent::notifier(Arc()).clear();
23.184 @@ -568,31 +576,31 @@
23.185
23.186 /// \brief Returns the node with the given index.
23.187 ///
23.188 - /// Returns the node with the given index. Since it is a static
23.189 - /// graph its nodes can be indexed with integers from the range
23.190 - /// <tt>[0..nodeNum()-1]</tt>.
23.191 + /// Returns the node with the given index. Since this structure is
23.192 + /// completely static, the nodes can be indexed with integers from
23.193 + /// the range <tt>[0..nodeNum()-1]</tt>.
23.194 /// \sa index()
23.195 Node operator()(int ix) const { return Parent::operator()(ix); }
23.196
23.197 /// \brief Returns the index of the given node.
23.198 ///
23.199 - /// Returns the index of the given node. Since it is a static
23.200 - /// graph its nodes can be indexed with integers from the range
23.201 - /// <tt>[0..nodeNum()-1]</tt>.
23.202 - /// \sa operator()
23.203 - int index(const Node& node) const { return Parent::index(node); }
23.204 + /// Returns the index of the given node. Since this structure is
23.205 + /// completely static, the nodes can be indexed with integers from
23.206 + /// the range <tt>[0..nodeNum()-1]</tt>.
23.207 + /// \sa operator()()
23.208 + static int index(const Node& node) { return Parent::index(node); }
23.209
23.210 /// \brief Returns the arc connecting the given nodes.
23.211 ///
23.212 /// Returns the arc connecting the given nodes.
23.213 - Arc arc(const Node& s, const Node& t) const {
23.214 + Arc arc(Node s, Node t) const {
23.215 return Parent::arc(s, t);
23.216 }
23.217
23.218 - /// \brief Returns the edge connects the given nodes.
23.219 + /// \brief Returns the edge connecting the given nodes.
23.220 ///
23.221 - /// Returns the edge connects the given nodes.
23.222 - Edge edge(const Node& u, const Node& v) const {
23.223 + /// Returns the edge connecting the given nodes.
23.224 + Edge edge(Node u, Node v) const {
23.225 return Parent::edge(u, v);
23.226 }
23.227
24.1 --- a/lemon/glpk.cc Mon Sep 28 15:53:20 2009 +0200
24.2 +++ b/lemon/glpk.cc Thu Nov 05 10:27:17 2009 +0100
24.3 @@ -59,6 +59,42 @@
24.4 return i;
24.5 }
24.6
24.7 + int GlpkBase::_addRow(Value lo, ExprIterator b,
24.8 + ExprIterator e, Value up) {
24.9 + int i = glp_add_rows(lp, 1);
24.10 +
24.11 + if (lo == -INF) {
24.12 + if (up == INF) {
24.13 + glp_set_row_bnds(lp, i, GLP_FR, lo, up);
24.14 + } else {
24.15 + glp_set_row_bnds(lp, i, GLP_UP, lo, up);
24.16 + }
24.17 + } else {
24.18 + if (up == INF) {
24.19 + glp_set_row_bnds(lp, i, GLP_LO, lo, up);
24.20 + } else if (lo != up) {
24.21 + glp_set_row_bnds(lp, i, GLP_DB, lo, up);
24.22 + } else {
24.23 + glp_set_row_bnds(lp, i, GLP_FX, lo, up);
24.24 + }
24.25 + }
24.26 +
24.27 + std::vector<int> indexes;
24.28 + std::vector<Value> values;
24.29 +
24.30 + indexes.push_back(0);
24.31 + values.push_back(0);
24.32 +
24.33 + for(ExprIterator it = b; it != e; ++it) {
24.34 + indexes.push_back(it->first);
24.35 + values.push_back(it->second);
24.36 + }
24.37 +
24.38 + glp_set_mat_row(lp, i, values.size() - 1,
24.39 + &indexes.front(), &values.front());
24.40 + return i;
24.41 + }
24.42 +
24.43 void GlpkBase::_eraseCol(int i) {
24.44 int ca[2];
24.45 ca[1] = i;
25.1 --- a/lemon/glpk.h Mon Sep 28 15:53:20 2009 +0200
25.2 +++ b/lemon/glpk.h Thu Nov 05 10:27:17 2009 +0100
25.3 @@ -54,6 +54,7 @@
25.4
25.5 virtual int _addCol();
25.6 virtual int _addRow();
25.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
25.8
25.9 virtual void _eraseCol(int i);
25.10 virtual void _eraseRow(int i);
26.1 --- a/lemon/grid_graph.h Mon Sep 28 15:53:20 2009 +0200
26.2 +++ b/lemon/grid_graph.h Thu Nov 05 10:27:17 2009 +0100
26.3 @@ -470,18 +470,22 @@
26.4 ///
26.5 /// \brief Grid graph class
26.6 ///
26.7 - /// This class implements a special graph type. The nodes of the
26.8 - /// graph can be indexed by two integer \c (i,j) value where \c i is
26.9 - /// in the \c [0..width()-1] range and j is in the \c
26.10 - /// [0..height()-1] range. Two nodes are connected in the graph if
26.11 - /// the indexes differ exactly on one position and exactly one is
26.12 - /// the difference. The nodes of the graph can be indexed by position
26.13 - /// with the \c operator()() function. The positions of the nodes can be
26.14 - /// get with \c pos(), \c col() and \c row() members. The outgoing
26.15 + /// GridGraph implements a special graph type. The nodes of the
26.16 + /// graph can be indexed by two integer values \c (i,j) where \c i is
26.17 + /// in the range <tt>[0..width()-1]</tt> and j is in the range
26.18 + /// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
26.19 + /// the indices differ exactly on one position and the difference is
26.20 + /// also exactly one. The nodes of the graph can be obtained by position
26.21 + /// using the \c operator()() function and the indices of the nodes can
26.22 + /// be obtained using \c pos(), \c col() and \c row() members. The outgoing
26.23 /// arcs can be retrieved with the \c right(), \c up(), \c left()
26.24 /// and \c down() functions, where the bottom-left corner is the
26.25 /// origin.
26.26 ///
26.27 + /// This class is completely static and it needs constant memory space.
26.28 + /// Thus you can neither add nor delete nodes or edges, however
26.29 + /// the structure can be resized using resize().
26.30 + ///
26.31 /// \image html grid_graph.png
26.32 /// \image latex grid_graph.eps "Grid graph" width=\textwidth
26.33 ///
26.34 @@ -496,16 +500,19 @@
26.35 /// }
26.36 ///\endcode
26.37 ///
26.38 - /// This graph type fully conforms to the \ref concepts::Graph
26.39 - /// "Graph concept".
26.40 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
26.41 + /// Most of its member functions and nested classes are documented
26.42 + /// only in the concept class.
26.43 class GridGraph : public ExtendedGridGraphBase {
26.44 typedef ExtendedGridGraphBase Parent;
26.45
26.46 public:
26.47
26.48 - /// \brief Map to get the indices of the nodes as dim2::Point<int>.
26.49 + /// \brief Map to get the indices of the nodes as \ref dim2::Point
26.50 + /// "dim2::Point<int>".
26.51 ///
26.52 - /// Map to get the indices of the nodes as dim2::Point<int>.
26.53 + /// Map to get the indices of the nodes as \ref dim2::Point
26.54 + /// "dim2::Point<int>".
26.55 class IndexMap {
26.56 public:
26.57 /// \brief The key type of the map
26.58 @@ -514,13 +521,9 @@
26.59 typedef dim2::Point<int> Value;
26.60
26.61 /// \brief Constructor
26.62 - ///
26.63 - /// Constructor
26.64 IndexMap(const GridGraph& graph) : _graph(graph) {}
26.65
26.66 /// \brief The subscript operator
26.67 - ///
26.68 - /// The subscript operator.
26.69 Value operator[](Key key) const {
26.70 return _graph.pos(key);
26.71 }
26.72 @@ -540,13 +543,9 @@
26.73 typedef int Value;
26.74
26.75 /// \brief Constructor
26.76 - ///
26.77 - /// Constructor
26.78 ColMap(const GridGraph& graph) : _graph(graph) {}
26.79
26.80 /// \brief The subscript operator
26.81 - ///
26.82 - /// The subscript operator.
26.83 Value operator[](Key key) const {
26.84 return _graph.col(key);
26.85 }
26.86 @@ -566,13 +565,9 @@
26.87 typedef int Value;
26.88
26.89 /// \brief Constructor
26.90 - ///
26.91 - /// Constructor
26.92 RowMap(const GridGraph& graph) : _graph(graph) {}
26.93
26.94 /// \brief The subscript operator
26.95 - ///
26.96 - /// The subscript operator.
26.97 Value operator[](Key key) const {
26.98 return _graph.row(key);
26.99 }
26.100 @@ -583,15 +578,14 @@
26.101
26.102 /// \brief Constructor
26.103 ///
26.104 - /// Construct a grid graph with given size.
26.105 + /// Construct a grid graph with the given size.
26.106 GridGraph(int width, int height) { construct(width, height); }
26.107
26.108 - /// \brief Resize the graph
26.109 + /// \brief Resizes the graph
26.110 ///
26.111 - /// Resize the graph. The function will fully destroy and rebuild
26.112 - /// the graph. This cause that the maps of the graph will
26.113 - /// reallocated automatically and the previous values will be
26.114 - /// lost.
26.115 + /// This function resizes the graph. It fully destroys and
26.116 + /// rebuilds the structure, therefore the maps of the graph will be
26.117 + /// reallocated automatically and the previous values will be lost.
26.118 void resize(int width, int height) {
26.119 Parent::notifier(Arc()).clear();
26.120 Parent::notifier(Edge()).clear();
26.121 @@ -609,42 +603,42 @@
26.122 return Parent::operator()(i, j);
26.123 }
26.124
26.125 - /// \brief Gives back the column index of the node.
26.126 + /// \brief The column index of the node.
26.127 ///
26.128 /// Gives back the column index of the node.
26.129 int col(Node n) const {
26.130 return Parent::col(n);
26.131 }
26.132
26.133 - /// \brief Gives back the row index of the node.
26.134 + /// \brief The row index of the node.
26.135 ///
26.136 /// Gives back the row index of the node.
26.137 int row(Node n) const {
26.138 return Parent::row(n);
26.139 }
26.140
26.141 - /// \brief Gives back the position of the node.
26.142 + /// \brief The position of the node.
26.143 ///
26.144 /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
26.145 dim2::Point<int> pos(Node n) const {
26.146 return Parent::pos(n);
26.147 }
26.148
26.149 - /// \brief Gives back the number of the columns.
26.150 + /// \brief The number of the columns.
26.151 ///
26.152 /// Gives back the number of the columns.
26.153 int width() const {
26.154 return Parent::width();
26.155 }
26.156
26.157 - /// \brief Gives back the number of the rows.
26.158 + /// \brief The number of the rows.
26.159 ///
26.160 /// Gives back the number of the rows.
26.161 int height() const {
26.162 return Parent::height();
26.163 }
26.164
26.165 - /// \brief Gives back the arc goes right from the node.
26.166 + /// \brief The arc goes right from the node.
26.167 ///
26.168 /// Gives back the arc goes right from the node. If there is not
26.169 /// outgoing arc then it gives back INVALID.
26.170 @@ -652,7 +646,7 @@
26.171 return Parent::right(n);
26.172 }
26.173
26.174 - /// \brief Gives back the arc goes left from the node.
26.175 + /// \brief The arc goes left from the node.
26.176 ///
26.177 /// Gives back the arc goes left from the node. If there is not
26.178 /// outgoing arc then it gives back INVALID.
26.179 @@ -660,7 +654,7 @@
26.180 return Parent::left(n);
26.181 }
26.182
26.183 - /// \brief Gives back the arc goes up from the node.
26.184 + /// \brief The arc goes up from the node.
26.185 ///
26.186 /// Gives back the arc goes up from the node. If there is not
26.187 /// outgoing arc then it gives back INVALID.
26.188 @@ -668,7 +662,7 @@
26.189 return Parent::up(n);
26.190 }
26.191
26.192 - /// \brief Gives back the arc goes down from the node.
26.193 + /// \brief The arc goes down from the node.
26.194 ///
26.195 /// Gives back the arc goes down from the node. If there is not
26.196 /// outgoing arc then it gives back INVALID.
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/lemon/hartmann_orlin.h Thu Nov 05 10:27:17 2009 +0100
27.3 @@ -0,0 +1,640 @@
27.4 +/* -*- C++ -*-
27.5 + *
27.6 + * This file is a part of LEMON, a generic C++ optimization library
27.7 + *
27.8 + * Copyright (C) 2003-2008
27.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
27.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
27.11 + *
27.12 + * Permission to use, modify and distribute this software is granted
27.13 + * provided that this copyright notice appears in all copies. For
27.14 + * precise terms see the accompanying LICENSE file.
27.15 + *
27.16 + * This software is provided "AS IS" with no warranty of any kind,
27.17 + * express or implied, and with no claim as to its suitability for any
27.18 + * purpose.
27.19 + *
27.20 + */
27.21 +
27.22 +#ifndef LEMON_HARTMANN_ORLIN_H
27.23 +#define LEMON_HARTMANN_ORLIN_H
27.24 +
27.25 +/// \ingroup min_mean_cycle
27.26 +///
27.27 +/// \file
27.28 +/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
27.29 +
27.30 +#include <vector>
27.31 +#include <limits>
27.32 +#include <lemon/core.h>
27.33 +#include <lemon/path.h>
27.34 +#include <lemon/tolerance.h>
27.35 +#include <lemon/connectivity.h>
27.36 +
27.37 +namespace lemon {
27.38 +
27.39 + /// \brief Default traits class of HartmannOrlin algorithm.
27.40 + ///
27.41 + /// Default traits class of HartmannOrlin algorithm.
27.42 + /// \tparam GR The type of the digraph.
27.43 + /// \tparam LEN The type of the length map.
27.44 + /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
27.45 +#ifdef DOXYGEN
27.46 + template <typename GR, typename LEN>
27.47 +#else
27.48 + template <typename GR, typename LEN,
27.49 + bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
27.50 +#endif
27.51 + struct HartmannOrlinDefaultTraits
27.52 + {
27.53 + /// The type of the digraph
27.54 + typedef GR Digraph;
27.55 + /// The type of the length map
27.56 + typedef LEN LengthMap;
27.57 + /// The type of the arc lengths
27.58 + typedef typename LengthMap::Value Value;
27.59 +
27.60 + /// \brief The large value type used for internal computations
27.61 + ///
27.62 + /// The large value type used for internal computations.
27.63 + /// It is \c long \c long if the \c Value type is integer,
27.64 + /// otherwise it is \c double.
27.65 + /// \c Value must be convertible to \c LargeValue.
27.66 + typedef double LargeValue;
27.67 +
27.68 + /// The tolerance type used for internal computations
27.69 + typedef lemon::Tolerance<LargeValue> Tolerance;
27.70 +
27.71 + /// \brief The path type of the found cycles
27.72 + ///
27.73 + /// The path type of the found cycles.
27.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
27.75 + /// and it must have an \c addFront() function.
27.76 + typedef lemon::Path<Digraph> Path;
27.77 + };
27.78 +
27.79 + // Default traits class for integer value types
27.80 + template <typename GR, typename LEN>
27.81 + struct HartmannOrlinDefaultTraits<GR, LEN, true>
27.82 + {
27.83 + typedef GR Digraph;
27.84 + typedef LEN LengthMap;
27.85 + typedef typename LengthMap::Value Value;
27.86 +#ifdef LEMON_HAVE_LONG_LONG
27.87 + typedef long long LargeValue;
27.88 +#else
27.89 + typedef long LargeValue;
27.90 +#endif
27.91 + typedef lemon::Tolerance<LargeValue> Tolerance;
27.92 + typedef lemon::Path<Digraph> Path;
27.93 + };
27.94 +
27.95 +
27.96 + /// \addtogroup min_mean_cycle
27.97 + /// @{
27.98 +
27.99 + /// \brief Implementation of the Hartmann-Orlin algorithm for finding
27.100 + /// a minimum mean cycle.
27.101 + ///
27.102 + /// This class implements the Hartmann-Orlin algorithm for finding
27.103 + /// a directed cycle of minimum mean length (cost) in a digraph
27.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
27.105 + /// It is an improved version of \ref Karp "Karp"'s original algorithm,
27.106 + /// it applies an efficient early termination scheme.
27.107 + /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
27.108 + ///
27.109 + /// \tparam GR The type of the digraph the algorithm runs on.
27.110 + /// \tparam LEN The type of the length map. The default
27.111 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
27.112 +#ifdef DOXYGEN
27.113 + template <typename GR, typename LEN, typename TR>
27.114 +#else
27.115 + template < typename GR,
27.116 + typename LEN = typename GR::template ArcMap<int>,
27.117 + typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
27.118 +#endif
27.119 + class HartmannOrlin
27.120 + {
27.121 + public:
27.122 +
27.123 + /// The type of the digraph
27.124 + typedef typename TR::Digraph Digraph;
27.125 + /// The type of the length map
27.126 + typedef typename TR::LengthMap LengthMap;
27.127 + /// The type of the arc lengths
27.128 + typedef typename TR::Value Value;
27.129 +
27.130 + /// \brief The large value type
27.131 + ///
27.132 + /// The large value type used for internal computations.
27.133 + /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
27.134 + /// it is \c long \c long if the \c Value type is integer,
27.135 + /// otherwise it is \c double.
27.136 + typedef typename TR::LargeValue LargeValue;
27.137 +
27.138 + /// The tolerance type
27.139 + typedef typename TR::Tolerance Tolerance;
27.140 +
27.141 + /// \brief The path type of the found cycles
27.142 + ///
27.143 + /// The path type of the found cycles.
27.144 + /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
27.145 + /// it is \ref lemon::Path "Path<Digraph>".
27.146 + typedef typename TR::Path Path;
27.147 +
27.148 + /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
27.149 + typedef TR Traits;
27.150 +
27.151 + private:
27.152 +
27.153 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
27.154 +
27.155 + // Data sturcture for path data
27.156 + struct PathData
27.157 + {
27.158 + LargeValue dist;
27.159 + Arc pred;
27.160 + PathData(LargeValue d, Arc p = INVALID) :
27.161 + dist(d), pred(p) {}
27.162 + };
27.163 +
27.164 + typedef typename Digraph::template NodeMap<std::vector<PathData> >
27.165 + PathDataNodeMap;
27.166 +
27.167 + private:
27.168 +
27.169 + // The digraph the algorithm runs on
27.170 + const Digraph &_gr;
27.171 + // The length of the arcs
27.172 + const LengthMap &_length;
27.173 +
27.174 + // Data for storing the strongly connected components
27.175 + int _comp_num;
27.176 + typename Digraph::template NodeMap<int> _comp;
27.177 + std::vector<std::vector<Node> > _comp_nodes;
27.178 + std::vector<Node>* _nodes;
27.179 + typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
27.180 +
27.181 + // Data for the found cycles
27.182 + bool _curr_found, _best_found;
27.183 + LargeValue _curr_length, _best_length;
27.184 + int _curr_size, _best_size;
27.185 + Node _curr_node, _best_node;
27.186 + int _curr_level, _best_level;
27.187 +
27.188 + Path *_cycle_path;
27.189 + bool _local_path;
27.190 +
27.191 + // Node map for storing path data
27.192 + PathDataNodeMap _data;
27.193 + // The processed nodes in the last round
27.194 + std::vector<Node> _process;
27.195 +
27.196 + Tolerance _tolerance;
27.197 +
27.198 + // Infinite constant
27.199 + const LargeValue INF;
27.200 +
27.201 + public:
27.202 +
27.203 + /// \name Named Template Parameters
27.204 + /// @{
27.205 +
27.206 + template <typename T>
27.207 + struct SetLargeValueTraits : public Traits {
27.208 + typedef T LargeValue;
27.209 + typedef lemon::Tolerance<T> Tolerance;
27.210 + };
27.211 +
27.212 + /// \brief \ref named-templ-param "Named parameter" for setting
27.213 + /// \c LargeValue type.
27.214 + ///
27.215 + /// \ref named-templ-param "Named parameter" for setting \c LargeValue
27.216 + /// type. It is used for internal computations in the algorithm.
27.217 + template <typename T>
27.218 + struct SetLargeValue
27.219 + : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
27.220 + typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
27.221 + };
27.222 +
27.223 + template <typename T>
27.224 + struct SetPathTraits : public Traits {
27.225 + typedef T Path;
27.226 + };
27.227 +
27.228 + /// \brief \ref named-templ-param "Named parameter" for setting
27.229 + /// \c %Path type.
27.230 + ///
27.231 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
27.232 + /// type of the found cycles.
27.233 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
27.234 + /// and it must have an \c addFront() function.
27.235 + template <typename T>
27.236 + struct SetPath
27.237 + : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
27.238 + typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
27.239 + };
27.240 +
27.241 + /// @}
27.242 +
27.243 + public:
27.244 +
27.245 + /// \brief Constructor.
27.246 + ///
27.247 + /// The constructor of the class.
27.248 + ///
27.249 + /// \param digraph The digraph the algorithm runs on.
27.250 + /// \param length The lengths (costs) of the arcs.
27.251 + HartmannOrlin( const Digraph &digraph,
27.252 + const LengthMap &length ) :
27.253 + _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
27.254 + _best_found(false), _best_length(0), _best_size(1),
27.255 + _cycle_path(NULL), _local_path(false), _data(digraph),
27.256 + INF(std::numeric_limits<LargeValue>::has_infinity ?
27.257 + std::numeric_limits<LargeValue>::infinity() :
27.258 + std::numeric_limits<LargeValue>::max())
27.259 + {}
27.260 +
27.261 + /// Destructor.
27.262 + ~HartmannOrlin() {
27.263 + if (_local_path) delete _cycle_path;
27.264 + }
27.265 +
27.266 + /// \brief Set the path structure for storing the found cycle.
27.267 + ///
27.268 + /// This function sets an external path structure for storing the
27.269 + /// found cycle.
27.270 + ///
27.271 + /// If you don't call this function before calling \ref run() or
27.272 + /// \ref findMinMean(), it will allocate a local \ref Path "path"
27.273 + /// structure. The destuctor deallocates this automatically
27.274 + /// allocated object, of course.
27.275 + ///
27.276 + /// \note The algorithm calls only the \ref lemon::Path::addFront()
27.277 + /// "addFront()" function of the given path structure.
27.278 + ///
27.279 + /// \return <tt>(*this)</tt>
27.280 + HartmannOrlin& cycle(Path &path) {
27.281 + if (_local_path) {
27.282 + delete _cycle_path;
27.283 + _local_path = false;
27.284 + }
27.285 + _cycle_path = &path;
27.286 + return *this;
27.287 + }
27.288 +
27.289 + /// \brief Set the tolerance used by the algorithm.
27.290 + ///
27.291 + /// This function sets the tolerance object used by the algorithm.
27.292 + ///
27.293 + /// \return <tt>(*this)</tt>
27.294 + HartmannOrlin& tolerance(const Tolerance& tolerance) {
27.295 + _tolerance = tolerance;
27.296 + return *this;
27.297 + }
27.298 +
27.299 + /// \brief Return a const reference to the tolerance.
27.300 + ///
27.301 + /// This function returns a const reference to the tolerance object
27.302 + /// used by the algorithm.
27.303 + const Tolerance& tolerance() const {
27.304 + return _tolerance;
27.305 + }
27.306 +
27.307 + /// \name Execution control
27.308 + /// The simplest way to execute the algorithm is to call the \ref run()
27.309 + /// function.\n
27.310 + /// If you only need the minimum mean length, you may call
27.311 + /// \ref findMinMean().
27.312 +
27.313 + /// @{
27.314 +
27.315 + /// \brief Run the algorithm.
27.316 + ///
27.317 + /// This function runs the algorithm.
27.318 + /// It can be called more than once (e.g. if the underlying digraph
27.319 + /// and/or the arc lengths have been modified).
27.320 + ///
27.321 + /// \return \c true if a directed cycle exists in the digraph.
27.322 + ///
27.323 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
27.324 + /// \code
27.325 + /// return mmc.findMinMean() && mmc.findCycle();
27.326 + /// \endcode
27.327 + bool run() {
27.328 + return findMinMean() && findCycle();
27.329 + }
27.330 +
27.331 + /// \brief Find the minimum cycle mean.
27.332 + ///
27.333 + /// This function finds the minimum mean length of the directed
27.334 + /// cycles in the digraph.
27.335 + ///
27.336 + /// \return \c true if a directed cycle exists in the digraph.
27.337 + bool findMinMean() {
27.338 + // Initialization and find strongly connected components
27.339 + init();
27.340 + findComponents();
27.341 +
27.342 + // Find the minimum cycle mean in the components
27.343 + for (int comp = 0; comp < _comp_num; ++comp) {
27.344 + if (!initComponent(comp)) continue;
27.345 + processRounds();
27.346 +
27.347 + // Update the best cycle (global minimum mean cycle)
27.348 + if ( _curr_found && (!_best_found ||
27.349 + _curr_length * _best_size < _best_length * _curr_size) ) {
27.350 + _best_found = true;
27.351 + _best_length = _curr_length;
27.352 + _best_size = _curr_size;
27.353 + _best_node = _curr_node;
27.354 + _best_level = _curr_level;
27.355 + }
27.356 + }
27.357 + return _best_found;
27.358 + }
27.359 +
27.360 + /// \brief Find a minimum mean directed cycle.
27.361 + ///
27.362 + /// This function finds a directed cycle of minimum mean length
27.363 + /// in the digraph using the data computed by findMinMean().
27.364 + ///
27.365 + /// \return \c true if a directed cycle exists in the digraph.
27.366 + ///
27.367 + /// \pre \ref findMinMean() must be called before using this function.
27.368 + bool findCycle() {
27.369 + if (!_best_found) return false;
27.370 + IntNodeMap reached(_gr, -1);
27.371 + int r = _best_level + 1;
27.372 + Node u = _best_node;
27.373 + while (reached[u] < 0) {
27.374 + reached[u] = --r;
27.375 + u = _gr.source(_data[u][r].pred);
27.376 + }
27.377 + r = reached[u];
27.378 + Arc e = _data[u][r].pred;
27.379 + _cycle_path->addFront(e);
27.380 + _best_length = _length[e];
27.381 + _best_size = 1;
27.382 + Node v;
27.383 + while ((v = _gr.source(e)) != u) {
27.384 + e = _data[v][--r].pred;
27.385 + _cycle_path->addFront(e);
27.386 + _best_length += _length[e];
27.387 + ++_best_size;
27.388 + }
27.389 + return true;
27.390 + }
27.391 +
27.392 + /// @}
27.393 +
27.394 + /// \name Query Functions
27.395 + /// The results of the algorithm can be obtained using these
27.396 + /// functions.\n
27.397 + /// The algorithm should be executed before using them.
27.398 +
27.399 + /// @{
27.400 +
27.401 + /// \brief Return the total length of the found cycle.
27.402 + ///
27.403 + /// This function returns the total length of the found cycle.
27.404 + ///
27.405 + /// \pre \ref run() or \ref findMinMean() must be called before
27.406 + /// using this function.
27.407 + LargeValue cycleLength() const {
27.408 + return _best_length;
27.409 + }
27.410 +
27.411 + /// \brief Return the number of arcs on the found cycle.
27.412 + ///
27.413 + /// This function returns the number of arcs on the found cycle.
27.414 + ///
27.415 + /// \pre \ref run() or \ref findMinMean() must be called before
27.416 + /// using this function.
27.417 + int cycleArcNum() const {
27.418 + return _best_size;
27.419 + }
27.420 +
27.421 + /// \brief Return the mean length of the found cycle.
27.422 + ///
27.423 + /// This function returns the mean length of the found cycle.
27.424 + ///
27.425 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
27.426 + /// following code.
27.427 + /// \code
27.428 + /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
27.429 + /// \endcode
27.430 + ///
27.431 + /// \pre \ref run() or \ref findMinMean() must be called before
27.432 + /// using this function.
27.433 + double cycleMean() const {
27.434 + return static_cast<double>(_best_length) / _best_size;
27.435 + }
27.436 +
27.437 + /// \brief Return the found cycle.
27.438 + ///
27.439 + /// This function returns a const reference to the path structure
27.440 + /// storing the found cycle.
27.441 + ///
27.442 + /// \pre \ref run() or \ref findCycle() must be called before using
27.443 + /// this function.
27.444 + const Path& cycle() const {
27.445 + return *_cycle_path;
27.446 + }
27.447 +
27.448 + ///@}
27.449 +
27.450 + private:
27.451 +
27.452 + // Initialization
27.453 + void init() {
27.454 + if (!_cycle_path) {
27.455 + _local_path = true;
27.456 + _cycle_path = new Path;
27.457 + }
27.458 + _cycle_path->clear();
27.459 + _best_found = false;
27.460 + _best_length = 0;
27.461 + _best_size = 1;
27.462 + _cycle_path->clear();
27.463 + for (NodeIt u(_gr); u != INVALID; ++u)
27.464 + _data[u].clear();
27.465 + }
27.466 +
27.467 + // Find strongly connected components and initialize _comp_nodes
27.468 + // and _out_arcs
27.469 + void findComponents() {
27.470 + _comp_num = stronglyConnectedComponents(_gr, _comp);
27.471 + _comp_nodes.resize(_comp_num);
27.472 + if (_comp_num == 1) {
27.473 + _comp_nodes[0].clear();
27.474 + for (NodeIt n(_gr); n != INVALID; ++n) {
27.475 + _comp_nodes[0].push_back(n);
27.476 + _out_arcs[n].clear();
27.477 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
27.478 + _out_arcs[n].push_back(a);
27.479 + }
27.480 + }
27.481 + } else {
27.482 + for (int i = 0; i < _comp_num; ++i)
27.483 + _comp_nodes[i].clear();
27.484 + for (NodeIt n(_gr); n != INVALID; ++n) {
27.485 + int k = _comp[n];
27.486 + _comp_nodes[k].push_back(n);
27.487 + _out_arcs[n].clear();
27.488 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
27.489 + if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
27.490 + }
27.491 + }
27.492 + }
27.493 + }
27.494 +
27.495 + // Initialize path data for the current component
27.496 + bool initComponent(int comp) {
27.497 + _nodes = &(_comp_nodes[comp]);
27.498 + int n = _nodes->size();
27.499 + if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
27.500 + return false;
27.501 + }
27.502 + for (int i = 0; i < n; ++i) {
27.503 + _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
27.504 + }
27.505 + return true;
27.506 + }
27.507 +
27.508 + // Process all rounds of computing path data for the current component.
27.509 + // _data[v][k] is the length of a shortest directed walk from the root
27.510 + // node to node v containing exactly k arcs.
27.511 + void processRounds() {
27.512 + Node start = (*_nodes)[0];
27.513 + _data[start][0] = PathData(0);
27.514 + _process.clear();
27.515 + _process.push_back(start);
27.516 +
27.517 + int k, n = _nodes->size();
27.518 + int next_check = 4;
27.519 + bool terminate = false;
27.520 + for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
27.521 + processNextBuildRound(k);
27.522 + if (k == next_check || k == n) {
27.523 + terminate = checkTermination(k);
27.524 + next_check = next_check * 3 / 2;
27.525 + }
27.526 + }
27.527 + for ( ; k <= n && !terminate; ++k) {
27.528 + processNextFullRound(k);
27.529 + if (k == next_check || k == n) {
27.530 + terminate = checkTermination(k);
27.531 + next_check = next_check * 3 / 2;
27.532 + }
27.533 + }
27.534 + }
27.535 +
27.536 + // Process one round and rebuild _process
27.537 + void processNextBuildRound(int k) {
27.538 + std::vector<Node> next;
27.539 + Node u, v;
27.540 + Arc e;
27.541 + LargeValue d;
27.542 + for (int i = 0; i < int(_process.size()); ++i) {
27.543 + u = _process[i];
27.544 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
27.545 + e = _out_arcs[u][j];
27.546 + v = _gr.target(e);
27.547 + d = _data[u][k-1].dist + _length[e];
27.548 + if (_tolerance.less(d, _data[v][k].dist)) {
27.549 + if (_data[v][k].dist == INF) next.push_back(v);
27.550 + _data[v][k] = PathData(d, e);
27.551 + }
27.552 + }
27.553 + }
27.554 + _process.swap(next);
27.555 + }
27.556 +
27.557 + // Process one round using _nodes instead of _process
27.558 + void processNextFullRound(int k) {
27.559 + Node u, v;
27.560 + Arc e;
27.561 + LargeValue d;
27.562 + for (int i = 0; i < int(_nodes->size()); ++i) {
27.563 + u = (*_nodes)[i];
27.564 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
27.565 + e = _out_arcs[u][j];
27.566 + v = _gr.target(e);
27.567 + d = _data[u][k-1].dist + _length[e];
27.568 + if (_tolerance.less(d, _data[v][k].dist)) {
27.569 + _data[v][k] = PathData(d, e);
27.570 + }
27.571 + }
27.572 + }
27.573 + }
27.574 +
27.575 + // Check early termination
27.576 + bool checkTermination(int k) {
27.577 + typedef std::pair<int, int> Pair;
27.578 + typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
27.579 + typename GR::template NodeMap<LargeValue> pi(_gr);
27.580 + int n = _nodes->size();
27.581 + LargeValue length;
27.582 + int size;
27.583 + Node u;
27.584 +
27.585 + // Search for cycles that are already found
27.586 + _curr_found = false;
27.587 + for (int i = 0; i < n; ++i) {
27.588 + u = (*_nodes)[i];
27.589 + if (_data[u][k].dist == INF) continue;
27.590 + for (int j = k; j >= 0; --j) {
27.591 + if (level[u].first == i && level[u].second > 0) {
27.592 + // A cycle is found
27.593 + length = _data[u][level[u].second].dist - _data[u][j].dist;
27.594 + size = level[u].second - j;
27.595 + if (!_curr_found || length * _curr_size < _curr_length * size) {
27.596 + _curr_length = length;
27.597 + _curr_size = size;
27.598 + _curr_node = u;
27.599 + _curr_level = level[u].second;
27.600 + _curr_found = true;
27.601 + }
27.602 + }
27.603 + level[u] = Pair(i, j);
27.604 + u = _gr.source(_data[u][j].pred);
27.605 + }
27.606 + }
27.607 +
27.608 + // If at least one cycle is found, check the optimality condition
27.609 + LargeValue d;
27.610 + if (_curr_found && k < n) {
27.611 + // Find node potentials
27.612 + for (int i = 0; i < n; ++i) {
27.613 + u = (*_nodes)[i];
27.614 + pi[u] = INF;
27.615 + for (int j = 0; j <= k; ++j) {
27.616 + if (_data[u][j].dist < INF) {
27.617 + d = _data[u][j].dist * _curr_size - j * _curr_length;
27.618 + if (_tolerance.less(d, pi[u])) pi[u] = d;
27.619 + }
27.620 + }
27.621 + }
27.622 +
27.623 + // Check the optimality condition for all arcs
27.624 + bool done = true;
27.625 + for (ArcIt a(_gr); a != INVALID; ++a) {
27.626 + if (_tolerance.less(_length[a] * _curr_size - _curr_length,
27.627 + pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
27.628 + done = false;
27.629 + break;
27.630 + }
27.631 + }
27.632 + return done;
27.633 + }
27.634 + return (k == n);
27.635 + }
27.636 +
27.637 + }; //class HartmannOrlin
27.638 +
27.639 + ///@}
27.640 +
27.641 +} //namespace lemon
27.642 +
27.643 +#endif //LEMON_HARTMANN_ORLIN_H
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/lemon/howard.h Thu Nov 05 10:27:17 2009 +0100
28.3 @@ -0,0 +1,597 @@
28.4 +/* -*- C++ -*-
28.5 + *
28.6 + * This file is a part of LEMON, a generic C++ optimization library
28.7 + *
28.8 + * Copyright (C) 2003-2008
28.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
28.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
28.11 + *
28.12 + * Permission to use, modify and distribute this software is granted
28.13 + * provided that this copyright notice appears in all copies. For
28.14 + * precise terms see the accompanying LICENSE file.
28.15 + *
28.16 + * This software is provided "AS IS" with no warranty of any kind,
28.17 + * express or implied, and with no claim as to its suitability for any
28.18 + * purpose.
28.19 + *
28.20 + */
28.21 +
28.22 +#ifndef LEMON_HOWARD_H
28.23 +#define LEMON_HOWARD_H
28.24 +
28.25 +/// \ingroup min_mean_cycle
28.26 +///
28.27 +/// \file
28.28 +/// \brief Howard's algorithm for finding a minimum mean cycle.
28.29 +
28.30 +#include <vector>
28.31 +#include <limits>
28.32 +#include <lemon/core.h>
28.33 +#include <lemon/path.h>
28.34 +#include <lemon/tolerance.h>
28.35 +#include <lemon/connectivity.h>
28.36 +
28.37 +namespace lemon {
28.38 +
28.39 + /// \brief Default traits class of Howard class.
28.40 + ///
28.41 + /// Default traits class of Howard class.
28.42 + /// \tparam GR The type of the digraph.
28.43 + /// \tparam LEN The type of the length map.
28.44 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
28.45 +#ifdef DOXYGEN
28.46 + template <typename GR, typename LEN>
28.47 +#else
28.48 + template <typename GR, typename LEN,
28.49 + bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
28.50 +#endif
28.51 + struct HowardDefaultTraits
28.52 + {
28.53 + /// The type of the digraph
28.54 + typedef GR Digraph;
28.55 + /// The type of the length map
28.56 + typedef LEN LengthMap;
28.57 + /// The type of the arc lengths
28.58 + typedef typename LengthMap::Value Value;
28.59 +
28.60 + /// \brief The large value type used for internal computations
28.61 + ///
28.62 + /// The large value type used for internal computations.
28.63 + /// It is \c long \c long if the \c Value type is integer,
28.64 + /// otherwise it is \c double.
28.65 + /// \c Value must be convertible to \c LargeValue.
28.66 + typedef double LargeValue;
28.67 +
28.68 + /// The tolerance type used for internal computations
28.69 + typedef lemon::Tolerance<LargeValue> Tolerance;
28.70 +
28.71 + /// \brief The path type of the found cycles
28.72 + ///
28.73 + /// The path type of the found cycles.
28.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
28.75 + /// and it must have an \c addBack() function.
28.76 + typedef lemon::Path<Digraph> Path;
28.77 + };
28.78 +
28.79 + // Default traits class for integer value types
28.80 + template <typename GR, typename LEN>
28.81 + struct HowardDefaultTraits<GR, LEN, true>
28.82 + {
28.83 + typedef GR Digraph;
28.84 + typedef LEN LengthMap;
28.85 + typedef typename LengthMap::Value Value;
28.86 +#ifdef LEMON_HAVE_LONG_LONG
28.87 + typedef long long LargeValue;
28.88 +#else
28.89 + typedef long LargeValue;
28.90 +#endif
28.91 + typedef lemon::Tolerance<LargeValue> Tolerance;
28.92 + typedef lemon::Path<Digraph> Path;
28.93 + };
28.94 +
28.95 +
28.96 + /// \addtogroup min_mean_cycle
28.97 + /// @{
28.98 +
28.99 + /// \brief Implementation of Howard's algorithm for finding a minimum
28.100 + /// mean cycle.
28.101 + ///
28.102 + /// This class implements Howard's policy iteration algorithm for finding
28.103 + /// a directed cycle of minimum mean length (cost) in a digraph
28.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
28.105 + /// This class provides the most efficient algorithm for the
28.106 + /// minimum mean cycle problem, though the best known theoretical
28.107 + /// bound on its running time is exponential.
28.108 + ///
28.109 + /// \tparam GR The type of the digraph the algorithm runs on.
28.110 + /// \tparam LEN The type of the length map. The default
28.111 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
28.112 +#ifdef DOXYGEN
28.113 + template <typename GR, typename LEN, typename TR>
28.114 +#else
28.115 + template < typename GR,
28.116 + typename LEN = typename GR::template ArcMap<int>,
28.117 + typename TR = HowardDefaultTraits<GR, LEN> >
28.118 +#endif
28.119 + class Howard
28.120 + {
28.121 + public:
28.122 +
28.123 + /// The type of the digraph
28.124 + typedef typename TR::Digraph Digraph;
28.125 + /// The type of the length map
28.126 + typedef typename TR::LengthMap LengthMap;
28.127 + /// The type of the arc lengths
28.128 + typedef typename TR::Value Value;
28.129 +
28.130 + /// \brief The large value type
28.131 + ///
28.132 + /// The large value type used for internal computations.
28.133 + /// Using the \ref HowardDefaultTraits "default traits class",
28.134 + /// it is \c long \c long if the \c Value type is integer,
28.135 + /// otherwise it is \c double.
28.136 + typedef typename TR::LargeValue LargeValue;
28.137 +
28.138 + /// The tolerance type
28.139 + typedef typename TR::Tolerance Tolerance;
28.140 +
28.141 + /// \brief The path type of the found cycles
28.142 + ///
28.143 + /// The path type of the found cycles.
28.144 + /// Using the \ref HowardDefaultTraits "default traits class",
28.145 + /// it is \ref lemon::Path "Path<Digraph>".
28.146 + typedef typename TR::Path Path;
28.147 +
28.148 + /// The \ref HowardDefaultTraits "traits class" of the algorithm
28.149 + typedef TR Traits;
28.150 +
28.151 + private:
28.152 +
28.153 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
28.154 +
28.155 + // The digraph the algorithm runs on
28.156 + const Digraph &_gr;
28.157 + // The length of the arcs
28.158 + const LengthMap &_length;
28.159 +
28.160 + // Data for the found cycles
28.161 + bool _curr_found, _best_found;
28.162 + LargeValue _curr_length, _best_length;
28.163 + int _curr_size, _best_size;
28.164 + Node _curr_node, _best_node;
28.165 +
28.166 + Path *_cycle_path;
28.167 + bool _local_path;
28.168 +
28.169 + // Internal data used by the algorithm
28.170 + typename Digraph::template NodeMap<Arc> _policy;
28.171 + typename Digraph::template NodeMap<bool> _reached;
28.172 + typename Digraph::template NodeMap<int> _level;
28.173 + typename Digraph::template NodeMap<LargeValue> _dist;
28.174 +
28.175 + // Data for storing the strongly connected components
28.176 + int _comp_num;
28.177 + typename Digraph::template NodeMap<int> _comp;
28.178 + std::vector<std::vector<Node> > _comp_nodes;
28.179 + std::vector<Node>* _nodes;
28.180 + typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
28.181 +
28.182 + // Queue used for BFS search
28.183 + std::vector<Node> _queue;
28.184 + int _qfront, _qback;
28.185 +
28.186 + Tolerance _tolerance;
28.187 +
28.188 + // Infinite constant
28.189 + const LargeValue INF;
28.190 +
28.191 + public:
28.192 +
28.193 + /// \name Named Template Parameters
28.194 + /// @{
28.195 +
28.196 + template <typename T>
28.197 + struct SetLargeValueTraits : public Traits {
28.198 + typedef T LargeValue;
28.199 + typedef lemon::Tolerance<T> Tolerance;
28.200 + };
28.201 +
28.202 + /// \brief \ref named-templ-param "Named parameter" for setting
28.203 + /// \c LargeValue type.
28.204 + ///
28.205 + /// \ref named-templ-param "Named parameter" for setting \c LargeValue
28.206 + /// type. It is used for internal computations in the algorithm.
28.207 + template <typename T>
28.208 + struct SetLargeValue
28.209 + : public Howard<GR, LEN, SetLargeValueTraits<T> > {
28.210 + typedef Howard<GR, LEN, SetLargeValueTraits<T> > Create;
28.211 + };
28.212 +
28.213 + template <typename T>
28.214 + struct SetPathTraits : public Traits {
28.215 + typedef T Path;
28.216 + };
28.217 +
28.218 + /// \brief \ref named-templ-param "Named parameter" for setting
28.219 + /// \c %Path type.
28.220 + ///
28.221 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
28.222 + /// type of the found cycles.
28.223 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
28.224 + /// and it must have an \c addBack() function.
28.225 + template <typename T>
28.226 + struct SetPath
28.227 + : public Howard<GR, LEN, SetPathTraits<T> > {
28.228 + typedef Howard<GR, LEN, SetPathTraits<T> > Create;
28.229 + };
28.230 +
28.231 + /// @}
28.232 +
28.233 + public:
28.234 +
28.235 + /// \brief Constructor.
28.236 + ///
28.237 + /// The constructor of the class.
28.238 + ///
28.239 + /// \param digraph The digraph the algorithm runs on.
28.240 + /// \param length The lengths (costs) of the arcs.
28.241 + Howard( const Digraph &digraph,
28.242 + const LengthMap &length ) :
28.243 + _gr(digraph), _length(length), _best_found(false),
28.244 + _best_length(0), _best_size(1), _cycle_path(NULL), _local_path(false),
28.245 + _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
28.246 + _comp(digraph), _in_arcs(digraph),
28.247 + INF(std::numeric_limits<LargeValue>::has_infinity ?
28.248 + std::numeric_limits<LargeValue>::infinity() :
28.249 + std::numeric_limits<LargeValue>::max())
28.250 + {}
28.251 +
28.252 + /// Destructor.
28.253 + ~Howard() {
28.254 + if (_local_path) delete _cycle_path;
28.255 + }
28.256 +
28.257 + /// \brief Set the path structure for storing the found cycle.
28.258 + ///
28.259 + /// This function sets an external path structure for storing the
28.260 + /// found cycle.
28.261 + ///
28.262 + /// If you don't call this function before calling \ref run() or
28.263 + /// \ref findMinMean(), it will allocate a local \ref Path "path"
28.264 + /// structure. The destuctor deallocates this automatically
28.265 + /// allocated object, of course.
28.266 + ///
28.267 + /// \note The algorithm calls only the \ref lemon::Path::addBack()
28.268 + /// "addBack()" function of the given path structure.
28.269 + ///
28.270 + /// \return <tt>(*this)</tt>
28.271 + Howard& cycle(Path &path) {
28.272 + if (_local_path) {
28.273 + delete _cycle_path;
28.274 + _local_path = false;
28.275 + }
28.276 + _cycle_path = &path;
28.277 + return *this;
28.278 + }
28.279 +
28.280 + /// \brief Set the tolerance used by the algorithm.
28.281 + ///
28.282 + /// This function sets the tolerance object used by the algorithm.
28.283 + ///
28.284 + /// \return <tt>(*this)</tt>
28.285 + Howard& tolerance(const Tolerance& tolerance) {
28.286 + _tolerance = tolerance;
28.287 + return *this;
28.288 + }
28.289 +
28.290 + /// \brief Return a const reference to the tolerance.
28.291 + ///
28.292 + /// This function returns a const reference to the tolerance object
28.293 + /// used by the algorithm.
28.294 + const Tolerance& tolerance() const {
28.295 + return _tolerance;
28.296 + }
28.297 +
28.298 + /// \name Execution control
28.299 + /// The simplest way to execute the algorithm is to call the \ref run()
28.300 + /// function.\n
28.301 + /// If you only need the minimum mean length, you may call
28.302 + /// \ref findMinMean().
28.303 +
28.304 + /// @{
28.305 +
28.306 + /// \brief Run the algorithm.
28.307 + ///
28.308 + /// This function runs the algorithm.
28.309 + /// It can be called more than once (e.g. if the underlying digraph
28.310 + /// and/or the arc lengths have been modified).
28.311 + ///
28.312 + /// \return \c true if a directed cycle exists in the digraph.
28.313 + ///
28.314 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
28.315 + /// \code
28.316 + /// return mmc.findMinMean() && mmc.findCycle();
28.317 + /// \endcode
28.318 + bool run() {
28.319 + return findMinMean() && findCycle();
28.320 + }
28.321 +
28.322 + /// \brief Find the minimum cycle mean.
28.323 + ///
28.324 + /// This function finds the minimum mean length of the directed
28.325 + /// cycles in the digraph.
28.326 + ///
28.327 + /// \return \c true if a directed cycle exists in the digraph.
28.328 + bool findMinMean() {
28.329 + // Initialize and find strongly connected components
28.330 + init();
28.331 + findComponents();
28.332 +
28.333 + // Find the minimum cycle mean in the components
28.334 + for (int comp = 0; comp < _comp_num; ++comp) {
28.335 + // Find the minimum mean cycle in the current component
28.336 + if (!buildPolicyGraph(comp)) continue;
28.337 + while (true) {
28.338 + findPolicyCycle();
28.339 + if (!computeNodeDistances()) break;
28.340 + }
28.341 + // Update the best cycle (global minimum mean cycle)
28.342 + if ( _curr_found && (!_best_found ||
28.343 + _curr_length * _best_size < _best_length * _curr_size) ) {
28.344 + _best_found = true;
28.345 + _best_length = _curr_length;
28.346 + _best_size = _curr_size;
28.347 + _best_node = _curr_node;
28.348 + }
28.349 + }
28.350 + return _best_found;
28.351 + }
28.352 +
28.353 + /// \brief Find a minimum mean directed cycle.
28.354 + ///
28.355 + /// This function finds a directed cycle of minimum mean length
28.356 + /// in the digraph using the data computed by findMinMean().
28.357 + ///
28.358 + /// \return \c true if a directed cycle exists in the digraph.
28.359 + ///
28.360 + /// \pre \ref findMinMean() must be called before using this function.
28.361 + bool findCycle() {
28.362 + if (!_best_found) return false;
28.363 + _cycle_path->addBack(_policy[_best_node]);
28.364 + for ( Node v = _best_node;
28.365 + (v = _gr.target(_policy[v])) != _best_node; ) {
28.366 + _cycle_path->addBack(_policy[v]);
28.367 + }
28.368 + return true;
28.369 + }
28.370 +
28.371 + /// @}
28.372 +
28.373 + /// \name Query Functions
28.374 + /// The results of the algorithm can be obtained using these
28.375 + /// functions.\n
28.376 + /// The algorithm should be executed before using them.
28.377 +
28.378 + /// @{
28.379 +
28.380 + /// \brief Return the total length of the found cycle.
28.381 + ///
28.382 + /// This function returns the total length of the found cycle.
28.383 + ///
28.384 + /// \pre \ref run() or \ref findMinMean() must be called before
28.385 + /// using this function.
28.386 + LargeValue cycleLength() const {
28.387 + return _best_length;
28.388 + }
28.389 +
28.390 + /// \brief Return the number of arcs on the found cycle.
28.391 + ///
28.392 + /// This function returns the number of arcs on the found cycle.
28.393 + ///
28.394 + /// \pre \ref run() or \ref findMinMean() must be called before
28.395 + /// using this function.
28.396 + int cycleArcNum() const {
28.397 + return _best_size;
28.398 + }
28.399 +
28.400 + /// \brief Return the mean length of the found cycle.
28.401 + ///
28.402 + /// This function returns the mean length of the found cycle.
28.403 + ///
28.404 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
28.405 + /// following code.
28.406 + /// \code
28.407 + /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
28.408 + /// \endcode
28.409 + ///
28.410 + /// \pre \ref run() or \ref findMinMean() must be called before
28.411 + /// using this function.
28.412 + double cycleMean() const {
28.413 + return static_cast<double>(_best_length) / _best_size;
28.414 + }
28.415 +
28.416 + /// \brief Return the found cycle.
28.417 + ///
28.418 + /// This function returns a const reference to the path structure
28.419 + /// storing the found cycle.
28.420 + ///
28.421 + /// \pre \ref run() or \ref findCycle() must be called before using
28.422 + /// this function.
28.423 + const Path& cycle() const {
28.424 + return *_cycle_path;
28.425 + }
28.426 +
28.427 + ///@}
28.428 +
28.429 + private:
28.430 +
28.431 + // Initialize
28.432 + void init() {
28.433 + if (!_cycle_path) {
28.434 + _local_path = true;
28.435 + _cycle_path = new Path;
28.436 + }
28.437 + _queue.resize(countNodes(_gr));
28.438 + _best_found = false;
28.439 + _best_length = 0;
28.440 + _best_size = 1;
28.441 + _cycle_path->clear();
28.442 + }
28.443 +
28.444 + // Find strongly connected components and initialize _comp_nodes
28.445 + // and _in_arcs
28.446 + void findComponents() {
28.447 + _comp_num = stronglyConnectedComponents(_gr, _comp);
28.448 + _comp_nodes.resize(_comp_num);
28.449 + if (_comp_num == 1) {
28.450 + _comp_nodes[0].clear();
28.451 + for (NodeIt n(_gr); n != INVALID; ++n) {
28.452 + _comp_nodes[0].push_back(n);
28.453 + _in_arcs[n].clear();
28.454 + for (InArcIt a(_gr, n); a != INVALID; ++a) {
28.455 + _in_arcs[n].push_back(a);
28.456 + }
28.457 + }
28.458 + } else {
28.459 + for (int i = 0; i < _comp_num; ++i)
28.460 + _comp_nodes[i].clear();
28.461 + for (NodeIt n(_gr); n != INVALID; ++n) {
28.462 + int k = _comp[n];
28.463 + _comp_nodes[k].push_back(n);
28.464 + _in_arcs[n].clear();
28.465 + for (InArcIt a(_gr, n); a != INVALID; ++a) {
28.466 + if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
28.467 + }
28.468 + }
28.469 + }
28.470 + }
28.471 +
28.472 + // Build the policy graph in the given strongly connected component
28.473 + // (the out-degree of every node is 1)
28.474 + bool buildPolicyGraph(int comp) {
28.475 + _nodes = &(_comp_nodes[comp]);
28.476 + if (_nodes->size() < 1 ||
28.477 + (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
28.478 + return false;
28.479 + }
28.480 + for (int i = 0; i < int(_nodes->size()); ++i) {
28.481 + _dist[(*_nodes)[i]] = INF;
28.482 + }
28.483 + Node u, v;
28.484 + Arc e;
28.485 + for (int i = 0; i < int(_nodes->size()); ++i) {
28.486 + v = (*_nodes)[i];
28.487 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
28.488 + e = _in_arcs[v][j];
28.489 + u = _gr.source(e);
28.490 + if (_length[e] < _dist[u]) {
28.491 + _dist[u] = _length[e];
28.492 + _policy[u] = e;
28.493 + }
28.494 + }
28.495 + }
28.496 + return true;
28.497 + }
28.498 +
28.499 + // Find the minimum mean cycle in the policy graph
28.500 + void findPolicyCycle() {
28.501 + for (int i = 0; i < int(_nodes->size()); ++i) {
28.502 + _level[(*_nodes)[i]] = -1;
28.503 + }
28.504 + LargeValue clength;
28.505 + int csize;
28.506 + Node u, v;
28.507 + _curr_found = false;
28.508 + for (int i = 0; i < int(_nodes->size()); ++i) {
28.509 + u = (*_nodes)[i];
28.510 + if (_level[u] >= 0) continue;
28.511 + for (; _level[u] < 0; u = _gr.target(_policy[u])) {
28.512 + _level[u] = i;
28.513 + }
28.514 + if (_level[u] == i) {
28.515 + // A cycle is found
28.516 + clength = _length[_policy[u]];
28.517 + csize = 1;
28.518 + for (v = u; (v = _gr.target(_policy[v])) != u; ) {
28.519 + clength += _length[_policy[v]];
28.520 + ++csize;
28.521 + }
28.522 + if ( !_curr_found ||
28.523 + (clength * _curr_size < _curr_length * csize) ) {
28.524 + _curr_found = true;
28.525 + _curr_length = clength;
28.526 + _curr_size = csize;
28.527 + _curr_node = u;
28.528 + }
28.529 + }
28.530 + }
28.531 + }
28.532 +
28.533 + // Contract the policy graph and compute node distances
28.534 + bool computeNodeDistances() {
28.535 + // Find the component of the main cycle and compute node distances
28.536 + // using reverse BFS
28.537 + for (int i = 0; i < int(_nodes->size()); ++i) {
28.538 + _reached[(*_nodes)[i]] = false;
28.539 + }
28.540 + _qfront = _qback = 0;
28.541 + _queue[0] = _curr_node;
28.542 + _reached[_curr_node] = true;
28.543 + _dist[_curr_node] = 0;
28.544 + Node u, v;
28.545 + Arc e;
28.546 + while (_qfront <= _qback) {
28.547 + v = _queue[_qfront++];
28.548 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
28.549 + e = _in_arcs[v][j];
28.550 + u = _gr.source(e);
28.551 + if (_policy[u] == e && !_reached[u]) {
28.552 + _reached[u] = true;
28.553 + _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
28.554 + _queue[++_qback] = u;
28.555 + }
28.556 + }
28.557 + }
28.558 +
28.559 + // Connect all other nodes to this component and compute node
28.560 + // distances using reverse BFS
28.561 + _qfront = 0;
28.562 + while (_qback < int(_nodes->size())-1) {
28.563 + v = _queue[_qfront++];
28.564 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
28.565 + e = _in_arcs[v][j];
28.566 + u = _gr.source(e);
28.567 + if (!_reached[u]) {
28.568 + _reached[u] = true;
28.569 + _policy[u] = e;
28.570 + _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
28.571 + _queue[++_qback] = u;
28.572 + }
28.573 + }
28.574 + }
28.575 +
28.576 + // Improve node distances
28.577 + bool improved = false;
28.578 + for (int i = 0; i < int(_nodes->size()); ++i) {
28.579 + v = (*_nodes)[i];
28.580 + for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
28.581 + e = _in_arcs[v][j];
28.582 + u = _gr.source(e);
28.583 + LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
28.584 + if (_tolerance.less(delta, _dist[u])) {
28.585 + _dist[u] = delta;
28.586 + _policy[u] = e;
28.587 + improved = true;
28.588 + }
28.589 + }
28.590 + }
28.591 + return improved;
28.592 + }
28.593 +
28.594 + }; //class Howard
28.595 +
28.596 + ///@}
28.597 +
28.598 +} //namespace lemon
28.599 +
28.600 +#endif //LEMON_HOWARD_H
29.1 --- a/lemon/hypercube_graph.h Mon Sep 28 15:53:20 2009 +0200
29.2 +++ b/lemon/hypercube_graph.h Thu Nov 05 10:27:17 2009 +0100
29.3 @@ -262,7 +262,7 @@
29.4 return arc._id >> _dim;
29.5 }
29.6
29.7 - int index(Node node) const {
29.8 + static int index(Node node) {
29.9 return node._id;
29.10 }
29.11
29.12 @@ -282,17 +282,21 @@
29.13 ///
29.14 /// \brief Hypercube graph class
29.15 ///
29.16 - /// This class implements a special graph type. The nodes of the graph
29.17 - /// are indiced with integers with at most \c dim binary digits.
29.18 + /// HypercubeGraph implements a special graph type. The nodes of the
29.19 + /// graph are indexed with integers having at most \c dim binary digits.
29.20 /// Two nodes are connected in the graph if and only if their indices
29.21 /// differ only on one position in the binary form.
29.22 + /// This class is completely static and it needs constant memory space.
29.23 + /// Thus you can neither add nor delete nodes or edges, however
29.24 + /// the structure can be resized using resize().
29.25 + ///
29.26 + /// This type fully conforms to the \ref concepts::Graph "Graph concept".
29.27 + /// Most of its member functions and nested classes are documented
29.28 + /// only in the concept class.
29.29 ///
29.30 /// \note The type of the indices is chosen to \c int for efficiency
29.31 /// reasons. Thus the maximum dimension of this implementation is 26
29.32 /// (assuming that the size of \c int is 32 bit).
29.33 - ///
29.34 - /// This graph type fully conforms to the \ref concepts::Graph
29.35 - /// "Graph concept".
29.36 class HypercubeGraph : public ExtendedHypercubeGraphBase {
29.37 typedef ExtendedHypercubeGraphBase Parent;
29.38
29.39 @@ -303,6 +307,21 @@
29.40 /// Constructs a hypercube graph with \c dim dimensions.
29.41 HypercubeGraph(int dim) { construct(dim); }
29.42
29.43 + /// \brief Resizes the graph
29.44 + ///
29.45 + /// This function resizes the graph. It fully destroys and
29.46 + /// rebuilds the structure, therefore the maps of the graph will be
29.47 + /// reallocated automatically and the previous values will be lost.
29.48 + void resize(int dim) {
29.49 + Parent::notifier(Arc()).clear();
29.50 + Parent::notifier(Edge()).clear();
29.51 + Parent::notifier(Node()).clear();
29.52 + construct(dim);
29.53 + Parent::notifier(Node()).build();
29.54 + Parent::notifier(Edge()).build();
29.55 + Parent::notifier(Arc()).build();
29.56 + }
29.57 +
29.58 /// \brief The number of dimensions.
29.59 ///
29.60 /// Gives back the number of dimensions.
29.61 @@ -320,7 +339,7 @@
29.62 /// \brief The dimension id of an edge.
29.63 ///
29.64 /// Gives back the dimension id of the given edge.
29.65 - /// It is in the [0..dim-1] range.
29.66 + /// It is in the range <tt>[0..dim-1]</tt>.
29.67 int dimension(Edge edge) const {
29.68 return Parent::dimension(edge);
29.69 }
29.70 @@ -328,7 +347,7 @@
29.71 /// \brief The dimension id of an arc.
29.72 ///
29.73 /// Gives back the dimension id of the given arc.
29.74 - /// It is in the [0..dim-1] range.
29.75 + /// It is in the range <tt>[0..dim-1]</tt>.
29.76 int dimension(Arc arc) const {
29.77 return Parent::dimension(arc);
29.78 }
29.79 @@ -337,7 +356,7 @@
29.80 ///
29.81 /// Gives back the index of the given node.
29.82 /// The lower bits of the integer describes the node.
29.83 - int index(Node node) const {
29.84 + static int index(Node node) {
29.85 return Parent::index(node);
29.86 }
29.87
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/lemon/karp.h Thu Nov 05 10:27:17 2009 +0100
30.3 @@ -0,0 +1,582 @@
30.4 +/* -*- C++ -*-
30.5 + *
30.6 + * This file is a part of LEMON, a generic C++ optimization library
30.7 + *
30.8 + * Copyright (C) 2003-2008
30.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
30.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
30.11 + *
30.12 + * Permission to use, modify and distribute this software is granted
30.13 + * provided that this copyright notice appears in all copies. For
30.14 + * precise terms see the accompanying LICENSE file.
30.15 + *
30.16 + * This software is provided "AS IS" with no warranty of any kind,
30.17 + * express or implied, and with no claim as to its suitability for any
30.18 + * purpose.
30.19 + *
30.20 + */
30.21 +
30.22 +#ifndef LEMON_KARP_H
30.23 +#define LEMON_KARP_H
30.24 +
30.25 +/// \ingroup min_mean_cycle
30.26 +///
30.27 +/// \file
30.28 +/// \brief Karp's algorithm for finding a minimum mean cycle.
30.29 +
30.30 +#include <vector>
30.31 +#include <limits>
30.32 +#include <lemon/core.h>
30.33 +#include <lemon/path.h>
30.34 +#include <lemon/tolerance.h>
30.35 +#include <lemon/connectivity.h>
30.36 +
30.37 +namespace lemon {
30.38 +
30.39 + /// \brief Default traits class of Karp algorithm.
30.40 + ///
30.41 + /// Default traits class of Karp algorithm.
30.42 + /// \tparam GR The type of the digraph.
30.43 + /// \tparam LEN The type of the length map.
30.44 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
30.45 +#ifdef DOXYGEN
30.46 + template <typename GR, typename LEN>
30.47 +#else
30.48 + template <typename GR, typename LEN,
30.49 + bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
30.50 +#endif
30.51 + struct KarpDefaultTraits
30.52 + {
30.53 + /// The type of the digraph
30.54 + typedef GR Digraph;
30.55 + /// The type of the length map
30.56 + typedef LEN LengthMap;
30.57 + /// The type of the arc lengths
30.58 + typedef typename LengthMap::Value Value;
30.59 +
30.60 + /// \brief The large value type used for internal computations
30.61 + ///
30.62 + /// The large value type used for internal computations.
30.63 + /// It is \c long \c long if the \c Value type is integer,
30.64 + /// otherwise it is \c double.
30.65 + /// \c Value must be convertible to \c LargeValue.
30.66 + typedef double LargeValue;
30.67 +
30.68 + /// The tolerance type used for internal computations
30.69 + typedef lemon::Tolerance<LargeValue> Tolerance;
30.70 +
30.71 + /// \brief The path type of the found cycles
30.72 + ///
30.73 + /// The path type of the found cycles.
30.74 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
30.75 + /// and it must have an \c addFront() function.
30.76 + typedef lemon::Path<Digraph> Path;
30.77 + };
30.78 +
30.79 + // Default traits class for integer value types
30.80 + template <typename GR, typename LEN>
30.81 + struct KarpDefaultTraits<GR, LEN, true>
30.82 + {
30.83 + typedef GR Digraph;
30.84 + typedef LEN LengthMap;
30.85 + typedef typename LengthMap::Value Value;
30.86 +#ifdef LEMON_HAVE_LONG_LONG
30.87 + typedef long long LargeValue;
30.88 +#else
30.89 + typedef long LargeValue;
30.90 +#endif
30.91 + typedef lemon::Tolerance<LargeValue> Tolerance;
30.92 + typedef lemon::Path<Digraph> Path;
30.93 + };
30.94 +
30.95 +
30.96 + /// \addtogroup min_mean_cycle
30.97 + /// @{
30.98 +
30.99 + /// \brief Implementation of Karp's algorithm for finding a minimum
30.100 + /// mean cycle.
30.101 + ///
30.102 + /// This class implements Karp's algorithm for finding a directed
30.103 + /// cycle of minimum mean length (cost) in a digraph
30.104 + /// \ref amo93networkflows, \ref dasdan98minmeancycle.
30.105 + /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
30.106 + ///
30.107 + /// \tparam GR The type of the digraph the algorithm runs on.
30.108 + /// \tparam LEN The type of the length map. The default
30.109 + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
30.110 +#ifdef DOXYGEN
30.111 + template <typename GR, typename LEN, typename TR>
30.112 +#else
30.113 + template < typename GR,
30.114 + typename LEN = typename GR::template ArcMap<int>,
30.115 + typename TR = KarpDefaultTraits<GR, LEN> >
30.116 +#endif
30.117 + class Karp
30.118 + {
30.119 + public:
30.120 +
30.121 + /// The type of the digraph
30.122 + typedef typename TR::Digraph Digraph;
30.123 + /// The type of the length map
30.124 + typedef typename TR::LengthMap LengthMap;
30.125 + /// The type of the arc lengths
30.126 + typedef typename TR::Value Value;
30.127 +
30.128 + /// \brief The large value type
30.129 + ///
30.130 + /// The large value type used for internal computations.
30.131 + /// Using the \ref KarpDefaultTraits "default traits class",
30.132 + /// it is \c long \c long if the \c Value type is integer,
30.133 + /// otherwise it is \c double.
30.134 + typedef typename TR::LargeValue LargeValue;
30.135 +
30.136 + /// The tolerance type
30.137 + typedef typename TR::Tolerance Tolerance;
30.138 +
30.139 + /// \brief The path type of the found cycles
30.140 + ///
30.141 + /// The path type of the found cycles.
30.142 + /// Using the \ref KarpDefaultTraits "default traits class",
30.143 + /// it is \ref lemon::Path "Path<Digraph>".
30.144 + typedef typename TR::Path Path;
30.145 +
30.146 + /// The \ref KarpDefaultTraits "traits class" of the algorithm
30.147 + typedef TR Traits;
30.148 +
30.149 + private:
30.150 +
30.151 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
30.152 +
30.153 + // Data sturcture for path data
30.154 + struct PathData
30.155 + {
30.156 + LargeValue dist;
30.157 + Arc pred;
30.158 + PathData(LargeValue d, Arc p = INVALID) :
30.159 + dist(d), pred(p) {}
30.160 + };
30.161 +
30.162 + typedef typename Digraph::template NodeMap<std::vector<PathData> >
30.163 + PathDataNodeMap;
30.164 +
30.165 + private:
30.166 +
30.167 + // The digraph the algorithm runs on
30.168 + const Digraph &_gr;
30.169 + // The length of the arcs
30.170 + const LengthMap &_length;
30.171 +
30.172 + // Data for storing the strongly connected components
30.173 + int _comp_num;
30.174 + typename Digraph::template NodeMap<int> _comp;
30.175 + std::vector<std::vector<Node> > _comp_nodes;
30.176 + std::vector<Node>* _nodes;
30.177 + typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
30.178 +
30.179 + // Data for the found cycle
30.180 + LargeValue _cycle_length;
30.181 + int _cycle_size;
30.182 + Node _cycle_node;
30.183 +
30.184 + Path *_cycle_path;
30.185 + bool _local_path;
30.186 +
30.187 + // Node map for storing path data
30.188 + PathDataNodeMap _data;
30.189 + // The processed nodes in the last round
30.190 + std::vector<Node> _process;
30.191 +
30.192 + Tolerance _tolerance;
30.193 +
30.194 + // Infinite constant
30.195 + const LargeValue INF;
30.196 +
30.197 + public:
30.198 +
30.199 + /// \name Named Template Parameters
30.200 + /// @{
30.201 +
30.202 + template <typename T>
30.203 + struct SetLargeValueTraits : public Traits {
30.204 + typedef T LargeValue;
30.205 + typedef lemon::Tolerance<T> Tolerance;
30.206 + };
30.207 +
30.208 + /// \brief \ref named-templ-param "Named parameter" for setting
30.209 + /// \c LargeValue type.
30.210 + ///
30.211 + /// \ref named-templ-param "Named parameter" for setting \c LargeValue
30.212 + /// type. It is used for internal computations in the algorithm.
30.213 + template <typename T>
30.214 + struct SetLargeValue
30.215 + : public Karp<GR, LEN, SetLargeValueTraits<T> > {
30.216 + typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
30.217 + };
30.218 +
30.219 + template <typename T>
30.220 + struct SetPathTraits : public Traits {
30.221 + typedef T Path;
30.222 + };
30.223 +
30.224 + /// \brief \ref named-templ-param "Named parameter" for setting
30.225 + /// \c %Path type.
30.226 + ///
30.227 + /// \ref named-templ-param "Named parameter" for setting the \c %Path
30.228 + /// type of the found cycles.
30.229 + /// It must conform to the \ref lemon::concepts::Path "Path" concept
30.230 + /// and it must have an \c addFront() function.
30.231 + template <typename T>
30.232 + struct SetPath
30.233 + : public Karp<GR, LEN, SetPathTraits<T> > {
30.234 + typedef Karp<GR, LEN, SetPathTraits<T> > Create;
30.235 + };
30.236 +
30.237 + /// @}
30.238 +
30.239 + public:
30.240 +
30.241 + /// \brief Constructor.
30.242 + ///
30.243 + /// The constructor of the class.
30.244 + ///
30.245 + /// \param digraph The digraph the algorithm runs on.
30.246 + /// \param length The lengths (costs) of the arcs.
30.247 + Karp( const Digraph &digraph,
30.248 + const LengthMap &length ) :
30.249 + _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
30.250 + _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
30.251 + _cycle_path(NULL), _local_path(false), _data(digraph),
30.252 + INF(std::numeric_limits<LargeValue>::has_infinity ?
30.253 + std::numeric_limits<LargeValue>::infinity() :
30.254 + std::numeric_limits<LargeValue>::max())
30.255 + {}
30.256 +
30.257 + /// Destructor.
30.258 + ~Karp() {
30.259 + if (_local_path) delete _cycle_path;
30.260 + }
30.261 +
30.262 + /// \brief Set the path structure for storing the found cycle.
30.263 + ///
30.264 + /// This function sets an external path structure for storing the
30.265 + /// found cycle.
30.266 + ///
30.267 + /// If you don't call this function before calling \ref run() or
30.268 + /// \ref findMinMean(), it will allocate a local \ref Path "path"
30.269 + /// structure. The destuctor deallocates this automatically
30.270 + /// allocated object, of course.
30.271 + ///
30.272 + /// \note The algorithm calls only the \ref lemon::Path::addFront()
30.273 + /// "addFront()" function of the given path structure.
30.274 + ///
30.275 + /// \return <tt>(*this)</tt>
30.276 + Karp& cycle(Path &path) {
30.277 + if (_local_path) {
30.278 + delete _cycle_path;
30.279 + _local_path = false;
30.280 + }
30.281 + _cycle_path = &path;
30.282 + return *this;
30.283 + }
30.284 +
30.285 + /// \brief Set the tolerance used by the algorithm.
30.286 + ///
30.287 + /// This function sets the tolerance object used by the algorithm.
30.288 + ///
30.289 + /// \return <tt>(*this)</tt>
30.290 + Karp& tolerance(const Tolerance& tolerance) {
30.291 + _tolerance = tolerance;
30.292 + return *this;
30.293 + }
30.294 +
30.295 + /// \brief Return a const reference to the tolerance.
30.296 + ///
30.297 + /// This function returns a const reference to the tolerance object
30.298 + /// used by the algorithm.
30.299 + const Tolerance& tolerance() const {
30.300 + return _tolerance;
30.301 + }
30.302 +
30.303 + /// \name Execution control
30.304 + /// The simplest way to execute the algorithm is to call the \ref run()
30.305 + /// function.\n
30.306 + /// If you only need the minimum mean length, you may call
30.307 + /// \ref findMinMean().
30.308 +
30.309 + /// @{
30.310 +
30.311 + /// \brief Run the algorithm.
30.312 + ///
30.313 + /// This function runs the algorithm.
30.314 + /// It can be called more than once (e.g. if the underlying digraph
30.315 + /// and/or the arc lengths have been modified).
30.316 + ///
30.317 + /// \return \c true if a directed cycle exists in the digraph.
30.318 + ///
30.319 + /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
30.320 + /// \code
30.321 + /// return mmc.findMinMean() && mmc.findCycle();
30.322 + /// \endcode
30.323 + bool run() {
30.324 + return findMinMean() && findCycle();
30.325 + }
30.326 +
30.327 + /// \brief Find the minimum cycle mean.
30.328 + ///
30.329 + /// This function finds the minimum mean length of the directed
30.330 + /// cycles in the digraph.
30.331 + ///
30.332 + /// \return \c true if a directed cycle exists in the digraph.
30.333 + bool findMinMean() {
30.334 + // Initialization and find strongly connected components
30.335 + init();
30.336 + findComponents();
30.337 +
30.338 + // Find the minimum cycle mean in the components
30.339 + for (int comp = 0; comp < _comp_num; ++comp) {
30.340 + if (!initComponent(comp)) continue;
30.341 + processRounds();
30.342 + updateMinMean();
30.343 + }
30.344 + return (_cycle_node != INVALID);
30.345 + }
30.346 +
30.347 + /// \brief Find a minimum mean directed cycle.
30.348 + ///
30.349 + /// This function finds a directed cycle of minimum mean length
30.350 + /// in the digraph using the data computed by findMinMean().
30.351 + ///
30.352 + /// \return \c true if a directed cycle exists in the digraph.
30.353 + ///
30.354 + /// \pre \ref findMinMean() must be called before using this function.
30.355 + bool findCycle() {
30.356 + if (_cycle_node == INVALID) return false;
30.357 + IntNodeMap reached(_gr, -1);
30.358 + int r = _data[_cycle_node].size();
30.359 + Node u = _cycle_node;
30.360 + while (reached[u] < 0) {
30.361 + reached[u] = --r;
30.362 + u = _gr.source(_data[u][r].pred);
30.363 + }
30.364 + r = reached[u];
30.365 + Arc e = _data[u][r].pred;
30.366 + _cycle_path->addFront(e);
30.367 + _cycle_length = _length[e];
30.368 + _cycle_size = 1;
30.369 + Node v;
30.370 + while ((v = _gr.source(e)) != u) {
30.371 + e = _data[v][--r].pred;
30.372 + _cycle_path->addFront(e);
30.373 + _cycle_length += _length[e];
30.374 + ++_cycle_size;
30.375 + }
30.376 + return true;
30.377 + }
30.378 +
30.379 + /// @}
30.380 +
30.381 + /// \name Query Functions
30.382 + /// The results of the algorithm can be obtained using these
30.383 + /// functions.\n
30.384 + /// The algorithm should be executed before using them.
30.385 +
30.386 + /// @{
30.387 +
30.388 + /// \brief Return the total length of the found cycle.
30.389 + ///
30.390 + /// This function returns the total length of the found cycle.
30.391 + ///
30.392 + /// \pre \ref run() or \ref findMinMean() must be called before
30.393 + /// using this function.
30.394 + LargeValue cycleLength() const {
30.395 + return _cycle_length;
30.396 + }
30.397 +
30.398 + /// \brief Return the number of arcs on the found cycle.
30.399 + ///
30.400 + /// This function returns the number of arcs on the found cycle.
30.401 + ///
30.402 + /// \pre \ref run() or \ref findMinMean() must be called before
30.403 + /// using this function.
30.404 + int cycleArcNum() const {
30.405 + return _cycle_size;
30.406 + }
30.407 +
30.408 + /// \brief Return the mean length of the found cycle.
30.409 + ///
30.410 + /// This function returns the mean length of the found cycle.
30.411 + ///
30.412 + /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
30.413 + /// following code.
30.414 + /// \code
30.415 + /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
30.416 + /// \endcode
30.417 + ///
30.418 + /// \pre \ref run() or \ref findMinMean() must be called before
30.419 + /// using this function.
30.420 + double cycleMean() const {
30.421 + return static_cast<double>(_cycle_length) / _cycle_size;
30.422 + }
30.423 +
30.424 + /// \brief Return the found cycle.
30.425 + ///
30.426 + /// This function returns a const reference to the path structure
30.427 + /// storing the found cycle.
30.428 + ///
30.429 + /// \pre \ref run() or \ref findCycle() must be called before using
30.430 + /// this function.
30.431 + const Path& cycle() const {
30.432 + return *_cycle_path;
30.433 + }
30.434 +
30.435 + ///@}
30.436 +
30.437 + private:
30.438 +
30.439 + // Initialization
30.440 + void init() {
30.441 + if (!_cycle_path) {
30.442 + _local_path = true;
30.443 + _cycle_path = new Path;
30.444 + }
30.445 + _cycle_path->clear();
30.446 + _cycle_length = 0;
30.447 + _cycle_size = 1;
30.448 + _cycle_node = INVALID;
30.449 + for (NodeIt u(_gr); u != INVALID; ++u)
30.450 + _data[u].clear();
30.451 + }
30.452 +
30.453 + // Find strongly connected components and initialize _comp_nodes
30.454 + // and _out_arcs
30.455 + void findComponents() {
30.456 + _comp_num = stronglyConnectedComponents(_gr, _comp);
30.457 + _comp_nodes.resize(_comp_num);
30.458 + if (_comp_num == 1) {
30.459 + _comp_nodes[0].clear();
30.460 + for (NodeIt n(_gr); n != INVALID; ++n) {
30.461 + _comp_nodes[0].push_back(n);
30.462 + _out_arcs[n].clear();
30.463 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
30.464 + _out_arcs[n].push_back(a);
30.465 + }
30.466 + }
30.467 + } else {
30.468 + for (int i = 0; i < _comp_num; ++i)
30.469 + _comp_nodes[i].clear();
30.470 + for (NodeIt n(_gr); n != INVALID; ++n) {
30.471 + int k = _comp[n];
30.472 + _comp_nodes[k].push_back(n);
30.473 + _out_arcs[n].clear();
30.474 + for (OutArcIt a(_gr, n); a != INVALID; ++a) {
30.475 + if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
30.476 + }
30.477 + }
30.478 + }
30.479 + }
30.480 +
30.481 + // Initialize path data for the current component
30.482 + bool initComponent(int comp) {
30.483 + _nodes = &(_comp_nodes[comp]);
30.484 + int n = _nodes->size();
30.485 + if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
30.486 + return false;
30.487 + }
30.488 + for (int i = 0; i < n; ++i) {
30.489 + _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
30.490 + }
30.491 + return true;
30.492 + }
30.493 +
30.494 + // Process all rounds of computing path data for the current component.
30.495 + // _data[v][k] is the length of a shortest directed walk from the root
30.496 + // node to node v containing exactly k arcs.
30.497 + void processRounds() {
30.498 + Node start = (*_nodes)[0];
30.499 + _data[start][0] = PathData(0);
30.500 + _process.clear();
30.501 + _process.push_back(start);
30.502 +
30.503 + int k, n = _nodes->size();
30.504 + for (k = 1; k <= n && int(_process.size()) < n; ++k) {
30.505 + processNextBuildRound(k);
30.506 + }
30.507 + for ( ; k <= n; ++k) {
30.508 + processNextFullRound(k);
30.509 + }
30.510 + }
30.511 +
30.512 + // Process one round and rebuild _process
30.513 + void processNextBuildRound(int k) {
30.514 + std::vector<Node> next;
30.515 + Node u, v;
30.516 + Arc e;
30.517 + LargeValue d;
30.518 + for (int i = 0; i < int(_process.size()); ++i) {
30.519 + u = _process[i];
30.520 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
30.521 + e = _out_arcs[u][j];
30.522 + v = _gr.target(e);
30.523 + d = _data[u][k-1].dist + _length[e];
30.524 + if (_tolerance.less(d, _data[v][k].dist)) {
30.525 + if (_data[v][k].dist == INF) next.push_back(v);
30.526 + _data[v][k] = PathData(d, e);
30.527 + }
30.528 + }
30.529 + }
30.530 + _process.swap(next);
30.531 + }
30.532 +
30.533 + // Process one round using _nodes instead of _process
30.534 + void processNextFullRound(int k) {
30.535 + Node u, v;
30.536 + Arc e;
30.537 + LargeValue d;
30.538 + for (int i = 0; i < int(_nodes->size()); ++i) {
30.539 + u = (*_nodes)[i];
30.540 + for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
30.541 + e = _out_arcs[u][j];
30.542 + v = _gr.target(e);
30.543 + d = _data[u][k-1].dist + _length[e];
30.544 + if (_tolerance.less(d, _data[v][k].dist)) {
30.545 + _data[v][k] = PathData(d, e);
30.546 + }
30.547 + }
30.548 + }
30.549 + }
30.550 +
30.551 + // Update the minimum cycle mean
30.552 + void updateMinMean() {
30.553 + int n = _nodes->size();
30.554 + for (int i = 0; i < n; ++i) {
30.555 + Node u = (*_nodes)[i];
30.556 + if (_data[u][n].dist == INF) continue;
30.557 + LargeValue length, max_length = 0;
30.558 + int size, max_size = 1;
30.559 + bool found_curr = false;
30.560 + for (int k = 0; k < n; ++k) {
30.561 + if (_data[u][k].dist == INF) continue;
30.562 + length = _data[u][n].dist - _data[u][k].dist;
30.563 + size = n - k;
30.564 + if (!found_curr || length * max_size > max_length * size) {
30.565 + found_curr = true;
30.566 + max_length = length;
30.567 + max_size = size;
30.568 + }
30.569 + }
30.570 + if ( found_curr && (_cycle_node == INVALID ||
30.571 + max_length * _cycle_size < _cycle_length * max_size) ) {
30.572 + _cycle_length = max_length;
30.573 + _cycle_size = max_size;
30.574 + _cycle_node = u;
30.575 + }
30.576 + }
30.577 + }
30.578 +
30.579 + }; //class Karp
30.580 +
30.581 + ///@}
30.582 +
30.583 +} //namespace lemon
30.584 +
30.585 +#endif //LEMON_KARP_H
31.1 --- a/lemon/list_graph.h Mon Sep 28 15:53:20 2009 +0200
31.2 +++ b/lemon/list_graph.h Thu Nov 05 10:27:17 2009 +0100
31.3 @@ -21,7 +21,7 @@
31.4
31.5 ///\ingroup graphs
31.6 ///\file
31.7 -///\brief ListDigraph, ListGraph classes.
31.8 +///\brief ListDigraph and ListGraph classes.
31.9
31.10 #include <lemon/core.h>
31.11 #include <lemon/error.h>
31.12 @@ -32,6 +32,8 @@
31.13
31.14 namespace lemon {
31.15
31.16 + class ListDigraph;
31.17 +
31.18 class ListDigraphBase {
31.19
31.20 protected:
31.21 @@ -62,6 +64,7 @@
31.22
31.23 class Node {
31.24 friend class ListDigraphBase;
31.25 + friend class ListDigraph;
31.26 protected:
31.27
31.28 int id;
31.29 @@ -77,6 +80,7 @@
31.30
31.31 class Arc {
31.32 friend class ListDigraphBase;
31.33 + friend class ListDigraph;
31.34 protected:
31.35
31.36 int id;
31.37 @@ -116,20 +120,20 @@
31.38 void first(Arc& arc) const {
31.39 int n;
31.40 for(n = first_node;
31.41 - n!=-1 && nodes[n].first_in == -1;
31.42 + n != -1 && nodes[n].first_out == -1;
31.43 n = nodes[n].next) {}
31.44 - arc.id = (n == -1) ? -1 : nodes[n].first_in;
31.45 + arc.id = (n == -1) ? -1 : nodes[n].first_out;
31.46 }
31.47
31.48 void next(Arc& arc) const {
31.49 - if (arcs[arc.id].next_in != -1) {
31.50 - arc.id = arcs[arc.id].next_in;
31.51 + if (arcs[arc.id].next_out != -1) {
31.52 + arc.id = arcs[arc.id].next_out;
31.53 } else {
31.54 int n;
31.55 - for(n = nodes[arcs[arc.id].target].next;
31.56 - n!=-1 && nodes[n].first_in == -1;
31.57 + for(n = nodes[arcs[arc.id].source].next;
31.58 + n != -1 && nodes[n].first_out == -1;
31.59 n = nodes[n].next) {}
31.60 - arc.id = (n == -1) ? -1 : nodes[n].first_in;
31.61 + arc.id = (n == -1) ? -1 : nodes[n].first_out;
31.62 }
31.63 }
31.64
31.65 @@ -311,31 +315,25 @@
31.66
31.67 ///A general directed graph structure.
31.68
31.69 - ///\ref ListDigraph is a simple and fast <em>directed graph</em>
31.70 - ///implementation based on static linked lists that are stored in
31.71 + ///\ref ListDigraph is a versatile and fast directed graph
31.72 + ///implementation based on linked lists that are stored in
31.73 ///\c std::vector structures.
31.74 ///
31.75 - ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
31.76 - ///also provides several useful additional functionalities.
31.77 - ///Most of the member functions and nested classes are documented
31.78 + ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
31.79 + ///and it also provides several useful additional functionalities.
31.80 + ///Most of its member functions and nested classes are documented
31.81 ///only in the concept class.
31.82 ///
31.83 ///\sa concepts::Digraph
31.84 -
31.85 + ///\sa ListGraph
31.86 class ListDigraph : public ExtendedListDigraphBase {
31.87 typedef ExtendedListDigraphBase Parent;
31.88
31.89 private:
31.90 - ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
31.91 -
31.92 - ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
31.93 - ///
31.94 + /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
31.95 ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
31.96 - ///\brief Assignment of ListDigraph to another one is \e not allowed.
31.97 - ///Use copyDigraph() instead.
31.98 -
31.99 - ///Assignment of ListDigraph to another one is \e not allowed.
31.100 - ///Use copyDigraph() instead.
31.101 + /// \brief Assignment of a digraph to another one is \e not allowed.
31.102 + /// Use DigraphCopy instead.
31.103 void operator=(const ListDigraph &) {}
31.104 public:
31.105
31.106 @@ -347,71 +345,65 @@
31.107
31.108 ///Add a new node to the digraph.
31.109
31.110 - ///Add a new node to the digraph.
31.111 + ///This function adds a new node to the digraph.
31.112 ///\return The new node.
31.113 Node addNode() { return Parent::addNode(); }
31.114
31.115 ///Add a new arc to the digraph.
31.116
31.117 - ///Add a new arc to the digraph with source node \c s
31.118 + ///This function adds a new arc to the digraph with source node \c s
31.119 ///and target node \c t.
31.120 ///\return The new arc.
31.121 - Arc addArc(const Node& s, const Node& t) {
31.122 + Arc addArc(Node s, Node t) {
31.123 return Parent::addArc(s, t);
31.124 }
31.125
31.126 ///\brief Erase a node from the digraph.
31.127 ///
31.128 - ///Erase a node from the digraph.
31.129 - ///
31.130 - void erase(const Node& n) { Parent::erase(n); }
31.131 + ///This function erases the given node from the digraph.
31.132 + void erase(Node n) { Parent::erase(n); }
31.133
31.134 ///\brief Erase an arc from the digraph.
31.135 ///
31.136 - ///Erase an arc from the digraph.
31.137 - ///
31.138 - void erase(const Arc& a) { Parent::erase(a); }
31.139 + ///This function erases the given arc from the digraph.
31.140 + void erase(Arc a) { Parent::erase(a); }
31.141
31.142 /// Node validity check
31.143
31.144 - /// This function gives back true if the given node is valid,
31.145 - /// ie. it is a real node of the graph.
31.146 + /// This function gives back \c true if the given node is valid,
31.147 + /// i.e. it is a real node of the digraph.
31.148 ///
31.149 - /// \warning A Node pointing to a removed item
31.150 - /// could become valid again later if new nodes are
31.151 - /// added to the graph.
31.152 + /// \warning A removed node could become valid again if new nodes are
31.153 + /// added to the digraph.
31.154 bool valid(Node n) const { return Parent::valid(n); }
31.155
31.156 /// Arc validity check
31.157
31.158 - /// This function gives back true if the given arc is valid,
31.159 - /// ie. it is a real arc of the graph.
31.160 + /// This function gives back \c true if the given arc is valid,
31.161 + /// i.e. it is a real arc of the digraph.
31.162 ///
31.163 - /// \warning An Arc pointing to a removed item
31.164 - /// could become valid again later if new nodes are
31.165 - /// added to the graph.
31.166 + /// \warning A removed arc could become valid again if new arcs are
31.167 + /// added to the digraph.
31.168 bool valid(Arc a) const { return Parent::valid(a); }
31.169
31.170 - /// Change the target of \c a to \c n
31.171 + /// Change the target node of an arc
31.172
31.173 - /// Change the target of \c a to \c n
31.174 + /// This function changes the target node of the given arc \c a to \c n.
31.175 ///
31.176 - ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
31.177 - ///the changed arc remain valid. However <tt>InArcIt</tt>s are
31.178 - ///invalidated.
31.179 + ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
31.180 + ///arc remain valid, however \c InArcIt iterators are invalidated.
31.181 ///
31.182 ///\warning This functionality cannot be used together with the Snapshot
31.183 ///feature.
31.184 void changeTarget(Arc a, Node n) {
31.185 Parent::changeTarget(a,n);
31.186 }
31.187 - /// Change the source of \c a to \c n
31.188 + /// Change the source node of an arc
31.189
31.190 - /// Change the source of \c a to \c n
31.191 + /// This function changes the source node of the given arc \c a to \c n.
31.192 ///
31.193 - ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
31.194 - ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
31.195 - ///invalidated.
31.196 + ///\note \c InArcIt iterators referencing the changed arc remain
31.197 + ///valid, however \c ArcIt and \c OutArcIt iterators are invalidated.
31.198 ///
31.199 ///\warning This functionality cannot be used together with the Snapshot
31.200 ///feature.
31.201 @@ -419,94 +411,76 @@
31.202 Parent::changeSource(a,n);
31.203 }
31.204
31.205 - /// Invert the direction of an arc.
31.206 + /// Reverse the direction of an arc.
31.207
31.208 - ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
31.209 - ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
31.210 - ///invalidated.
31.211 + /// This function reverses the direction of the given arc.
31.212 + ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
31.213 + ///the changed arc are invalidated.
31.214 ///
31.215 ///\warning This functionality cannot be used together with the Snapshot
31.216 ///feature.
31.217 - void reverseArc(Arc e) {
31.218 - Node t=target(e);
31.219 - changeTarget(e,source(e));
31.220 - changeSource(e,t);
31.221 + void reverseArc(Arc a) {
31.222 + Node t=target(a);
31.223 + changeTarget(a,source(a));
31.224 + changeSource(a,t);
31.225 }
31.226
31.227 - /// Reserve memory for nodes.
31.228 -
31.229 - /// Using this function it is possible to avoid the superfluous memory
31.230 - /// allocation: if you know that the digraph you want to build will
31.231 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
31.232 - /// then it is worth reserving space for this amount before starting
31.233 - /// to build the digraph.
31.234 - /// \sa reserveArc
31.235 - void reserveNode(int n) { nodes.reserve(n); };
31.236 -
31.237 - /// Reserve memory for arcs.
31.238 -
31.239 - /// Using this function it is possible to avoid the superfluous memory
31.240 - /// allocation: if you know that the digraph you want to build will
31.241 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
31.242 - /// then it is worth reserving space for this amount before starting
31.243 - /// to build the digraph.
31.244 - /// \sa reserveNode
31.245 - void reserveArc(int m) { arcs.reserve(m); };
31.246 -
31.247 ///Contract two nodes.
31.248
31.249 - ///This function contracts two nodes.
31.250 - ///Node \p b will be removed but instead of deleting
31.251 - ///incident arcs, they will be joined to \p a.
31.252 - ///The last parameter \p r controls whether to remove loops. \c true
31.253 - ///means that loops will be removed.
31.254 + ///This function contracts the given two nodes.
31.255 + ///Node \c v is removed, but instead of deleting its
31.256 + ///incident arcs, they are joined to node \c u.
31.257 + ///If the last parameter \c r is \c true (this is the default value),
31.258 + ///then the newly created loops are removed.
31.259 ///
31.260 - ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
31.261 - ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
31.262 - ///may be invalidated.
31.263 + ///\note The moved arcs are joined to node \c u using changeSource()
31.264 + ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
31.265 + ///invalidated for the outgoing arcs of node \c v and \c InArcIt
31.266 + ///iterators are invalidated for the incomming arcs of \c v.
31.267 + ///Moreover all iterators referencing node \c v or the removed
31.268 + ///loops are also invalidated. Other iterators remain valid.
31.269 ///
31.270 ///\warning This functionality cannot be used together with the Snapshot
31.271 ///feature.
31.272 - void contract(Node a, Node b, bool r = true)
31.273 + void contract(Node u, Node v, bool r = true)
31.274 {
31.275 - for(OutArcIt e(*this,b);e!=INVALID;) {
31.276 + for(OutArcIt e(*this,v);e!=INVALID;) {
31.277 OutArcIt f=e;
31.278 ++f;
31.279 - if(r && target(e)==a) erase(e);
31.280 - else changeSource(e,a);
31.281 + if(r && target(e)==u) erase(e);
31.282 + else changeSource(e,u);
31.283 e=f;
31.284 }
31.285 - for(InArcIt e(*this,b);e!=INVALID;) {
31.286 + for(InArcIt e(*this,v);e!=INVALID;) {
31.287 InArcIt f=e;
31.288 ++f;
31.289 - if(r && source(e)==a) erase(e);
31.290 - else changeTarget(e,a);
31.291 + if(r && source(e)==u) erase(e);
31.292 + else changeTarget(e,u);
31.293 e=f;
31.294 }
31.295 - erase(b);
31.296 + erase(v);
31.297 }
31.298
31.299 ///Split a node.
31.300
31.301 - ///This function splits a node. First a new node is added to the digraph,
31.302 - ///then the source of each outgoing arc of \c n is moved to this new node.
31.303 - ///If \c connect is \c true (this is the default value), then a new arc
31.304 - ///from \c n to the newly created node is also added.
31.305 + ///This function splits the given node. First, a new node is added
31.306 + ///to the digraph, then the source of each outgoing arc of node \c n
31.307 + ///is moved to this new node.
31.308 + ///If the second parameter \c connect is \c true (this is the default
31.309 + ///value), then a new arc from node \c n to the newly created node
31.310 + ///is also added.
31.311 ///\return The newly created node.
31.312 ///
31.313 - ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
31.314 - ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
31.315 - ///be invalidated.
31.316 + ///\note All iterators remain valid.
31.317 ///
31.318 - ///\warning This functionality cannot be used in conjunction with the
31.319 + ///\warning This functionality cannot be used together with the
31.320 ///Snapshot feature.
31.321 Node split(Node n, bool connect = true) {
31.322 Node b = addNode();
31.323 - for(OutArcIt e(*this,n);e!=INVALID;) {
31.324 - OutArcIt f=e;
31.325 - ++f;
31.326 - changeSource(e,b);
31.327 - e=f;
31.328 + nodes[b.id].first_out=nodes[n.id].first_out;
31.329 + nodes[n.id].first_out=-1;
31.330 + for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
31.331 + arcs[i].source=b.id;
31.332 }
31.333 if (connect) addArc(n,b);
31.334 return b;
31.335 @@ -514,21 +488,52 @@
31.336
31.337 ///Split an arc.
31.338
31.339 - ///This function splits an arc. First a new node \c b is added to
31.340 - ///the digraph, then the original arc is re-targeted to \c
31.341 - ///b. Finally an arc from \c b to the original target is added.
31.342 + ///This function splits the given arc. First, a new node \c v is
31.343 + ///added to the digraph, then the target node of the original arc
31.344 + ///is set to \c v. Finally, an arc from \c v to the original target
31.345 + ///is added.
31.346 + ///\return The newly created node.
31.347 ///
31.348 - ///\return The newly created node.
31.349 + ///\note \c InArcIt iterators referencing the original arc are
31.350 + ///invalidated. Other iterators remain valid.
31.351 ///
31.352 ///\warning This functionality cannot be used together with the
31.353 ///Snapshot feature.
31.354 - Node split(Arc e) {
31.355 - Node b = addNode();
31.356 - addArc(b,target(e));
31.357 - changeTarget(e,b);
31.358 - return b;
31.359 + Node split(Arc a) {
31.360 + Node v = addNode();
31.361 + addArc(v,target(a));
31.362 + changeTarget(a,v);
31.363 + return v;
31.364 }
31.365
31.366 + ///Clear the digraph.
31.367 +
31.368 + ///This function erases all nodes and arcs from the digraph.
31.369 + ///
31.370 + void clear() {
31.371 + Parent::clear();
31.372 + }
31.373 +
31.374 + /// Reserve memory for nodes.
31.375 +
31.376 + /// Using this function, it is possible to avoid superfluous memory
31.377 + /// allocation: if you know that the digraph you want to build will
31.378 + /// be large (e.g. it will contain millions of nodes and/or arcs),
31.379 + /// then it is worth reserving space for this amount before starting
31.380 + /// to build the digraph.
31.381 + /// \sa reserveArc()
31.382 + void reserveNode(int n) { nodes.reserve(n); };
31.383 +
31.384 + /// Reserve memory for arcs.
31.385 +
31.386 + /// Using this function, it is possible to avoid superfluous memory
31.387 + /// allocation: if you know that the digraph you want to build will
31.388 + /// be large (e.g. it will contain millions of nodes and/or arcs),
31.389 + /// then it is worth reserving space for this amount before starting
31.390 + /// to build the digraph.
31.391 + /// \sa reserveNode()
31.392 + void reserveArc(int m) { arcs.reserve(m); };
31.393 +
31.394 /// \brief Class to make a snapshot of the digraph and restore
31.395 /// it later.
31.396 ///
31.397 @@ -537,9 +542,15 @@
31.398 /// The newly added nodes and arcs can be removed using the
31.399 /// restore() function.
31.400 ///
31.401 - /// \warning Arc and node deletions and other modifications (e.g.
31.402 - /// contracting, splitting, reversing arcs or nodes) cannot be
31.403 + /// \note After a state is restored, you cannot restore a later state,
31.404 + /// i.e. you cannot add the removed nodes and arcs again using
31.405 + /// another Snapshot instance.
31.406 + ///
31.407 + /// \warning Node and arc deletions and other modifications (e.g.
31.408 + /// reversing, contracting, splitting arcs or nodes) cannot be
31.409 /// restored. These events invalidate the snapshot.
31.410 + /// However the arcs and nodes that were added to the digraph after
31.411 + /// making the current snapshot can be removed without invalidating it.
31.412 class Snapshot {
31.413 protected:
31.414
31.415 @@ -709,39 +720,40 @@
31.416 /// \brief Default constructor.
31.417 ///
31.418 /// Default constructor.
31.419 - /// To actually make a snapshot you must call save().
31.420 + /// You have to call save() to actually make a snapshot.
31.421 Snapshot()
31.422 : digraph(0), node_observer_proxy(*this),
31.423 arc_observer_proxy(*this) {}
31.424
31.425 /// \brief Constructor that immediately makes a snapshot.
31.426 ///
31.427 - /// This constructor immediately makes a snapshot of the digraph.
31.428 - /// \param _digraph The digraph we make a snapshot of.
31.429 - Snapshot(ListDigraph &_digraph)
31.430 + /// This constructor immediately makes a snapshot of the given digraph.
31.431 + Snapshot(ListDigraph &gr)
31.432 : node_observer_proxy(*this),
31.433 arc_observer_proxy(*this) {
31.434 - attach(_digraph);
31.435 + attach(gr);
31.436 }
31.437
31.438 /// \brief Make a snapshot.
31.439 ///
31.440 - /// Make a snapshot of the digraph.
31.441 - ///
31.442 - /// This function can be called more than once. In case of a repeated
31.443 + /// This function makes a snapshot of the given digraph.
31.444 + /// It can be called more than once. In case of a repeated
31.445 /// call, the previous snapshot gets lost.
31.446 - /// \param _digraph The digraph we make the snapshot of.
31.447 - void save(ListDigraph &_digraph) {
31.448 + void save(ListDigraph &gr) {
31.449 if (attached()) {
31.450 detach();
31.451 clear();
31.452 }
31.453 - attach(_digraph);
31.454 + attach(gr);
31.455 }
31.456
31.457 /// \brief Undo the changes until the last snapshot.
31.458 - //
31.459 - /// Undo the changes until the last snapshot created by save().
31.460 + ///
31.461 + /// This function undos the changes until the last snapshot
31.462 + /// created by save() or Snapshot(ListDigraph&).
31.463 + ///
31.464 + /// \warning This method invalidates the snapshot, i.e. repeated
31.465 + /// restoring is not supported unless you call save() again.
31.466 void restore() {
31.467 detach();
31.468 for(std::list<Arc>::iterator it = added_arcs.begin();
31.469 @@ -755,9 +767,9 @@
31.470 clear();
31.471 }
31.472
31.473 - /// \brief Gives back true when the snapshot is valid.
31.474 + /// \brief Returns \c true if the snapshot is valid.
31.475 ///
31.476 - /// Gives back true when the snapshot is valid.
31.477 + /// This function returns \c true if the snapshot is valid.
31.478 bool valid() const {
31.479 return attached();
31.480 }
31.481 @@ -795,10 +807,6 @@
31.482
31.483 typedef ListGraphBase Graph;
31.484
31.485 - class Node;
31.486 - class Arc;
31.487 - class Edge;
31.488 -
31.489 class Node {
31.490 friend class ListGraphBase;
31.491 protected:
31.492 @@ -848,8 +856,6 @@
31.493 bool operator<(const Arc& arc) const {return id < arc.id;}
31.494 };
31.495
31.496 -
31.497 -
31.498 ListGraphBase()
31.499 : nodes(), first_node(-1),
31.500 first_free_node(-1), arcs(), first_free_arc(-1) {}
31.501 @@ -1164,31 +1170,25 @@
31.502
31.503 ///A general undirected graph structure.
31.504
31.505 - ///\ref ListGraph is a simple and fast <em>undirected graph</em>
31.506 - ///implementation based on static linked lists that are stored in
31.507 + ///\ref ListGraph is a versatile and fast undirected graph
31.508 + ///implementation based on linked lists that are stored in
31.509 ///\c std::vector structures.
31.510 ///
31.511 - ///It conforms to the \ref concepts::Graph "Graph concept" and it
31.512 - ///also provides several useful additional functionalities.
31.513 - ///Most of the member functions and nested classes are documented
31.514 + ///This type fully conforms to the \ref concepts::Graph "Graph concept"
31.515 + ///and it also provides several useful additional functionalities.
31.516 + ///Most of its member functions and nested classes are documented
31.517 ///only in the concept class.
31.518 ///
31.519 ///\sa concepts::Graph
31.520 -
31.521 + ///\sa ListDigraph
31.522 class ListGraph : public ExtendedListGraphBase {
31.523 typedef ExtendedListGraphBase Parent;
31.524
31.525 private:
31.526 - ///ListGraph is \e not copy constructible. Use copyGraph() instead.
31.527 -
31.528 - ///ListGraph is \e not copy constructible. Use copyGraph() instead.
31.529 - ///
31.530 + /// Graphs are \e not copy constructible. Use GraphCopy instead.
31.531 ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
31.532 - ///\brief Assignment of ListGraph to another one is \e not allowed.
31.533 - ///Use copyGraph() instead.
31.534 -
31.535 - ///Assignment of ListGraph to another one is \e not allowed.
31.536 - ///Use copyGraph() instead.
31.537 + /// \brief Assignment of a graph to another one is \e not allowed.
31.538 + /// Use GraphCopy instead.
31.539 void operator=(const ListGraph &) {}
31.540 public:
31.541 /// Constructor
31.542 @@ -1201,94 +1201,95 @@
31.543
31.544 /// \brief Add a new node to the graph.
31.545 ///
31.546 - /// Add a new node to the graph.
31.547 + /// This function adds a new node to the graph.
31.548 /// \return The new node.
31.549 Node addNode() { return Parent::addNode(); }
31.550
31.551 /// \brief Add a new edge to the graph.
31.552 ///
31.553 - /// Add a new edge to the graph with source node \c s
31.554 - /// and target node \c t.
31.555 + /// This function adds a new edge to the graph between nodes
31.556 + /// \c u and \c v with inherent orientation from node \c u to
31.557 + /// node \c v.
31.558 /// \return The new edge.
31.559 - Edge addEdge(const Node& s, const Node& t) {
31.560 - return Parent::addEdge(s, t);
31.561 + Edge addEdge(Node u, Node v) {
31.562 + return Parent::addEdge(u, v);
31.563 }
31.564
31.565 - /// \brief Erase a node from the graph.
31.566 + ///\brief Erase a node from the graph.
31.567 ///
31.568 - /// Erase a node from the graph.
31.569 + /// This function erases the given node from the graph.
31.570 + void erase(Node n) { Parent::erase(n); }
31.571 +
31.572 + ///\brief Erase an edge from the graph.
31.573 ///
31.574 - void erase(const Node& n) { Parent::erase(n); }
31.575 -
31.576 - /// \brief Erase an edge from the graph.
31.577 - ///
31.578 - /// Erase an edge from the graph.
31.579 - ///
31.580 - void erase(const Edge& e) { Parent::erase(e); }
31.581 + /// This function erases the given edge from the graph.
31.582 + void erase(Edge e) { Parent::erase(e); }
31.583 /// Node validity check
31.584
31.585 - /// This function gives back true if the given node is valid,
31.586 - /// ie. it is a real node of the graph.
31.587 + /// This function gives back \c true if the given node is valid,
31.588 + /// i.e. it is a real node of the graph.
31.589 ///
31.590 - /// \warning A Node pointing to a removed item
31.591 - /// could become valid again later if new nodes are
31.592 + /// \warning A removed node could become valid again if new nodes are
31.593 /// added to the graph.
31.594 bool valid(Node n) const { return Parent::valid(n); }
31.595 + /// Edge validity check
31.596 +
31.597 + /// This function gives back \c true if the given edge is valid,
31.598 + /// i.e. it is a real edge of the graph.
31.599 + ///
31.600 + /// \warning A removed edge could become valid again if new edges are
31.601 + /// added to the graph.
31.602 + bool valid(Edge e) const { return Parent::valid(e); }
31.603 /// Arc validity check
31.604
31.605 - /// This function gives back true if the given arc is valid,
31.606 - /// ie. it is a real arc of the graph.
31.607 + /// This function gives back \c true if the given arc is valid,
31.608 + /// i.e. it is a real arc of the graph.
31.609 ///
31.610 - /// \warning An Arc pointing to a removed item
31.611 - /// could become valid again later if new edges are
31.612 + /// \warning A removed arc could become valid again if new edges are
31.613 /// added to the graph.
31.614 bool valid(Arc a) const { return Parent::valid(a); }
31.615 - /// Edge validity check
31.616
31.617 - /// This function gives back true if the given edge is valid,
31.618 - /// ie. it is a real arc of the graph.
31.619 + /// \brief Change the first node of an edge.
31.620 ///
31.621 - /// \warning A Edge pointing to a removed item
31.622 - /// could become valid again later if new edges are
31.623 - /// added to the graph.
31.624 - bool valid(Edge e) const { return Parent::valid(e); }
31.625 - /// \brief Change the end \c u of \c e to \c n
31.626 + /// This function changes the first node of the given edge \c e to \c n.
31.627 ///
31.628 - /// This function changes the end \c u of \c e to node \c n.
31.629 - ///
31.630 - ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
31.631 - ///changed edge are invalidated and if the changed node is the
31.632 - ///base node of an iterator then this iterator is also
31.633 - ///invalidated.
31.634 + ///\note \c EdgeIt and \c ArcIt iterators referencing the
31.635 + ///changed edge are invalidated and all other iterators whose
31.636 + ///base node is the changed node are also invalidated.
31.637 ///
31.638 ///\warning This functionality cannot be used together with the
31.639 ///Snapshot feature.
31.640 void changeU(Edge e, Node n) {
31.641 Parent::changeU(e,n);
31.642 }
31.643 - /// \brief Change the end \c v of \c e to \c n
31.644 + /// \brief Change the second node of an edge.
31.645 ///
31.646 - /// This function changes the end \c v of \c e to \c n.
31.647 + /// This function changes the second node of the given edge \c e to \c n.
31.648 ///
31.649 - ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
31.650 - ///valid, however <tt>ArcIt</tt>s and if the changed node is the
31.651 - ///base node of an iterator then this iterator is invalidated.
31.652 + ///\note \c EdgeIt iterators referencing the changed edge remain
31.653 + ///valid, however \c ArcIt iterators referencing the changed edge and
31.654 + ///all other iterators whose base node is the changed node are also
31.655 + ///invalidated.
31.656 ///
31.657 ///\warning This functionality cannot be used together with the
31.658 ///Snapshot feature.
31.659 void changeV(Edge e, Node n) {
31.660 Parent::changeV(e,n);
31.661 }
31.662 +
31.663 /// \brief Contract two nodes.
31.664 ///
31.665 - /// This function contracts two nodes.
31.666 - /// Node \p b will be removed but instead of deleting
31.667 - /// its neighboring arcs, they will be joined to \p a.
31.668 - /// The last parameter \p r controls whether to remove loops. \c true
31.669 - /// means that loops will be removed.
31.670 + /// This function contracts the given two nodes.
31.671 + /// Node \c b is removed, but instead of deleting
31.672 + /// its incident edges, they are joined to node \c a.
31.673 + /// If the last parameter \c r is \c true (this is the default value),
31.674 + /// then the newly created loops are removed.
31.675 ///
31.676 - /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
31.677 - /// valid.
31.678 + /// \note The moved edges are joined to node \c a using changeU()
31.679 + /// or changeV(), thus all edge and arc iterators whose base node is
31.680 + /// \c b are invalidated.
31.681 + /// Moreover all iterators referencing node \c b or the removed
31.682 + /// loops are also invalidated. Other iterators remain valid.
31.683 ///
31.684 ///\warning This functionality cannot be used together with the
31.685 ///Snapshot feature.
31.686 @@ -1307,6 +1308,33 @@
31.687 erase(b);
31.688 }
31.689
31.690 + ///Clear the graph.
31.691 +
31.692 + ///This function erases all nodes and arcs from the graph.
31.693 + ///
31.694 + void clear() {
31.695 + Parent::clear();
31.696 + }
31.697 +
31.698 + /// Reserve memory for nodes.
31.699 +
31.700 + /// Using this function, it is possible to avoid superfluous memory
31.701 + /// allocation: if you know that the graph you want to build will
31.702 + /// be large (e.g. it will contain millions of nodes and/or edges),
31.703 + /// then it is worth reserving space for this amount before starting
31.704 + /// to build the graph.
31.705 + /// \sa reserveEdge()
31.706 + void reserveNode(int n) { nodes.reserve(n); };
31.707 +
31.708 + /// Reserve memory for edges.
31.709 +
31.710 + /// Using this function, it is possible to avoid superfluous memory
31.711 + /// allocation: if you know that the graph you want to build will
31.712 + /// be large (e.g. it will contain millions of nodes and/or edges),
31.713 + /// then it is worth reserving space for this amount before starting
31.714 + /// to build the graph.
31.715 + /// \sa reserveNode()
31.716 + void reserveEdge(int m) { arcs.reserve(2 * m); };
31.717
31.718 /// \brief Class to make a snapshot of the graph and restore
31.719 /// it later.
31.720 @@ -1316,9 +1344,15 @@
31.721 /// The newly added nodes and edges can be removed
31.722 /// using the restore() function.
31.723 ///
31.724 - /// \warning Edge and node deletions and other modifications
31.725 - /// (e.g. changing nodes of edges, contracting nodes) cannot be
31.726 - /// restored. These events invalidate the snapshot.
31.727 + /// \note After a state is restored, you cannot restore a later state,
31.728 + /// i.e. you cannot add the removed nodes and edges again using
31.729 + /// another Snapshot instance.
31.730 + ///
31.731 + /// \warning Node and edge deletions and other modifications
31.732 + /// (e.g. changing the end-nodes of edges or contracting nodes)
31.733 + /// cannot be restored. These events invalidate the snapshot.
31.734 + /// However the edges and nodes that were added to the graph after
31.735 + /// making the current snapshot can be removed without invalidating it.
31.736 class Snapshot {
31.737 protected:
31.738
31.739 @@ -1488,39 +1522,40 @@
31.740 /// \brief Default constructor.
31.741 ///
31.742 /// Default constructor.
31.743 - /// To actually make a snapshot you must call save().
31.744 + /// You have to call save() to actually make a snapshot.
31.745 Snapshot()
31.746 : graph(0), node_observer_proxy(*this),
31.747 edge_observer_proxy(*this) {}
31.748
31.749 /// \brief Constructor that immediately makes a snapshot.
31.750 ///
31.751 - /// This constructor immediately makes a snapshot of the graph.
31.752 - /// \param _graph The graph we make a snapshot of.
31.753 - Snapshot(ListGraph &_graph)
31.754 + /// This constructor immediately makes a snapshot of the given graph.
31.755 + Snapshot(ListGraph &gr)
31.756 : node_observer_proxy(*this),
31.757 edge_observer_proxy(*this) {
31.758 - attach(_graph);
31.759 + attach(gr);
31.760 }
31.761
31.762 /// \brief Make a snapshot.
31.763 ///
31.764 - /// Make a snapshot of the graph.
31.765 - ///
31.766 - /// This function can be called more than once. In case of a repeated
31.767 + /// This function makes a snapshot of the given graph.
31.768 + /// It can be called more than once. In case of a repeated
31.769 /// call, the previous snapshot gets lost.
31.770 - /// \param _graph The graph we make the snapshot of.
31.771 - void save(ListGraph &_graph) {
31.772 + void save(ListGraph &gr) {
31.773 if (attached()) {
31.774 detach();
31.775 clear();
31.776 }
31.777 - attach(_graph);
31.778 + attach(gr);
31.779 }
31.780
31.781 /// \brief Undo the changes until the last snapshot.
31.782 - //
31.783 - /// Undo the changes until the last snapshot created by save().
31.784 + ///
31.785 + /// This function undos the changes until the last snapshot
31.786 + /// created by save() or Snapshot(ListGraph&).
31.787 + ///
31.788 + /// \warning This method invalidates the snapshot, i.e. repeated
31.789 + /// restoring is not supported unless you call save() again.
31.790 void restore() {
31.791 detach();
31.792 for(std::list<Edge>::iterator it = added_edges.begin();
31.793 @@ -1534,9 +1569,9 @@
31.794 clear();
31.795 }
31.796
31.797 - /// \brief Gives back true when the snapshot is valid.
31.798 + /// \brief Returns \c true if the snapshot is valid.
31.799 ///
31.800 - /// Gives back true when the snapshot is valid.
31.801 + /// This function returns \c true if the snapshot is valid.
31.802 bool valid() const {
31.803 return attached();
31.804 }
32.1 --- a/lemon/lp_base.h Mon Sep 28 15:53:20 2009 +0200
32.2 +++ b/lemon/lp_base.h Thu Nov 05 10:27:17 2009 +0100
32.3 @@ -943,6 +943,14 @@
32.4 virtual int _addCol() = 0;
32.5 virtual int _addRow() = 0;
32.6
32.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
32.8 + int row = _addRow();
32.9 + _setRowCoeffs(row, b, e);
32.10 + _setRowLowerBound(row, l);
32.11 + _setRowUpperBound(row, u);
32.12 + return row;
32.13 + }
32.14 +
32.15 virtual void _eraseCol(int col) = 0;
32.16 virtual void _eraseRow(int row) = 0;
32.17
32.18 @@ -1207,8 +1215,10 @@
32.19 ///\param u is the upper bound (\ref INF means no bound)
32.20 ///\return The created row.
32.21 Row addRow(Value l,const Expr &e, Value u) {
32.22 - Row r=addRow();
32.23 - row(r,l,e,u);
32.24 + Row r;
32.25 + e.simplify();
32.26 + r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
32.27 + ExprIterator(e.comps.end(), cols), u - *e));
32.28 return r;
32.29 }
32.30
32.31 @@ -1217,8 +1227,12 @@
32.32 ///\param c is a linear expression (see \ref Constr)
32.33 ///\return The created row.
32.34 Row addRow(const Constr &c) {
32.35 - Row r=addRow();
32.36 - row(r,c);
32.37 + Row r;
32.38 + c.expr().simplify();
32.39 + r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound():-INF,
32.40 + ExprIterator(c.expr().comps.begin(), cols),
32.41 + ExprIterator(c.expr().comps.end(), cols),
32.42 + c.upperBounded()?c.upperBound():INF));
32.43 return r;
32.44 }
32.45 ///Erase a column (i.e a variable) from the LP
33.1 --- a/lemon/lp_skeleton.cc Mon Sep 28 15:53:20 2009 +0200
33.2 +++ b/lemon/lp_skeleton.cc Thu Nov 05 10:27:17 2009 +0100
33.3 @@ -32,6 +32,11 @@
33.4 return ++row_num;
33.5 }
33.6
33.7 + int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
33.8 + {
33.9 + return ++row_num;
33.10 + }
33.11 +
33.12 void SkeletonSolverBase::_eraseCol(int) {}
33.13 void SkeletonSolverBase::_eraseRow(int) {}
33.14
34.1 --- a/lemon/lp_skeleton.h Mon Sep 28 15:53:20 2009 +0200
34.2 +++ b/lemon/lp_skeleton.h Thu Nov 05 10:27:17 2009 +0100
34.3 @@ -45,6 +45,8 @@
34.4 /// \e
34.5 virtual int _addRow();
34.6 /// \e
34.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
34.8 + /// \e
34.9 virtual void _eraseCol(int i);
34.10 /// \e
34.11 virtual void _eraseRow(int i);
35.1 --- a/lemon/network_simplex.h Mon Sep 28 15:53:20 2009 +0200
35.2 +++ b/lemon/network_simplex.h Thu Nov 05 10:27:17 2009 +0100
35.3 @@ -40,7 +40,9 @@
35.4 /// for finding a \ref min_cost_flow "minimum cost flow".
35.5 ///
35.6 /// \ref NetworkSimplex implements the primal Network Simplex algorithm
35.7 - /// for finding a \ref min_cost_flow "minimum cost flow".
35.8 + /// for finding a \ref min_cost_flow "minimum cost flow"
35.9 + /// \ref amo93networkflows, \ref dantzig63linearprog,
35.10 + /// \ref kellyoneill91netsimplex.
35.11 /// This algorithm is a specialized version of the linear programming
35.12 /// simplex method directly for the minimum cost flow problem.
35.13 /// It is one of the most efficient solution methods.
36.1 --- a/lemon/path.h Mon Sep 28 15:53:20 2009 +0200
36.2 +++ b/lemon/path.h Thu Nov 05 10:27:17 2009 +0100
36.3 @@ -1015,18 +1015,20 @@
36.4
36.5 /// \brief The source of a path
36.6 ///
36.7 - /// This function returns the source of the given path.
36.8 + /// This function returns the source node of the given path.
36.9 + /// If the path is empty, then it returns \c INVALID.
36.10 template <typename Digraph, typename Path>
36.11 typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
36.12 - return digraph.source(path.front());
36.13 + return path.empty() ? INVALID : digraph.source(path.front());
36.14 }
36.15
36.16 /// \brief The target of a path
36.17 ///
36.18 - /// This function returns the target of the given path.
36.19 + /// This function returns the target node of the given path.
36.20 + /// If the path is empty, then it returns \c INVALID.
36.21 template <typename Digraph, typename Path>
36.22 typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
36.23 - return digraph.target(path.back());
36.24 + return path.empty() ? INVALID : digraph.target(path.back());
36.25 }
36.26
36.27 /// \brief Class which helps to iterate through the nodes of a path
37.1 --- a/lemon/preflow.h Mon Sep 28 15:53:20 2009 +0200
37.2 +++ b/lemon/preflow.h Thu Nov 05 10:27:17 2009 +0100
37.3 @@ -102,7 +102,8 @@
37.4 ///
37.5 /// This class provides an implementation of Goldberg-Tarjan's \e preflow
37.6 /// \e push-relabel algorithm producing a \ref max_flow
37.7 - /// "flow of maximum value" in a digraph.
37.8 + /// "flow of maximum value" in a digraph \ref clrs01algorithms,
37.9 + /// \ref amo93networkflows, \ref goldberg88newapproach.
37.10 /// The preflow algorithms are the fastest known maximum
37.11 /// flow algorithms. The current implementation uses a mixture of the
37.12 /// \e "highest label" and the \e "bound decrease" heuristics.
38.1 --- a/lemon/smart_graph.h Mon Sep 28 15:53:20 2009 +0200
38.2 +++ b/lemon/smart_graph.h Thu Nov 05 10:27:17 2009 +0100
38.3 @@ -32,10 +32,7 @@
38.4 namespace lemon {
38.5
38.6 class SmartDigraph;
38.7 - ///Base of SmartDigraph
38.8
38.9 - ///Base of SmartDigraph
38.10 - ///
38.11 class SmartDigraphBase {
38.12 protected:
38.13
38.14 @@ -187,28 +184,26 @@
38.15 ///
38.16 ///\brief A smart directed graph class.
38.17 ///
38.18 - ///This is a simple and fast digraph implementation.
38.19 - ///It is also quite memory efficient, but at the price
38.20 - ///that <b> it does support only limited (only stack-like)
38.21 - ///node and arc deletions</b>.
38.22 - ///It fully conforms to the \ref concepts::Digraph "Digraph concept".
38.23 + ///\ref SmartDigraph is a simple and fast digraph implementation.
38.24 + ///It is also quite memory efficient but at the price
38.25 + ///that it does not support node and arc deletion
38.26 + ///(except for the Snapshot feature).
38.27 ///
38.28 - ///\sa concepts::Digraph.
38.29 + ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
38.30 + ///and it also provides some additional functionalities.
38.31 + ///Most of its member functions and nested classes are documented
38.32 + ///only in the concept class.
38.33 + ///
38.34 + ///\sa concepts::Digraph
38.35 + ///\sa SmartGraph
38.36 class SmartDigraph : public ExtendedSmartDigraphBase {
38.37 typedef ExtendedSmartDigraphBase Parent;
38.38
38.39 private:
38.40 -
38.41 - ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
38.42 -
38.43 - ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
38.44 - ///
38.45 + /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
38.46 SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
38.47 - ///\brief Assignment of SmartDigraph to another one is \e not allowed.
38.48 - ///Use DigraphCopy() instead.
38.49 -
38.50 - ///Assignment of SmartDigraph to another one is \e not allowed.
38.51 - ///Use DigraphCopy() instead.
38.52 + /// \brief Assignment of a digraph to another one is \e not allowed.
38.53 + /// Use DigraphCopy instead.
38.54 void operator=(const SmartDigraph &) {}
38.55
38.56 public:
38.57 @@ -221,79 +216,49 @@
38.58
38.59 ///Add a new node to the digraph.
38.60
38.61 - /// Add a new node to the digraph.
38.62 - /// \return The new node.
38.63 + ///This function adds a new node to the digraph.
38.64 + ///\return The new node.
38.65 Node addNode() { return Parent::addNode(); }
38.66
38.67 ///Add a new arc to the digraph.
38.68
38.69 - ///Add a new arc to the digraph with source node \c s
38.70 + ///This function adds a new arc to the digraph with source node \c s
38.71 ///and target node \c t.
38.72 ///\return The new arc.
38.73 - Arc addArc(const Node& s, const Node& t) {
38.74 + Arc addArc(Node s, Node t) {
38.75 return Parent::addArc(s, t);
38.76 }
38.77
38.78 - /// \brief Using this it is possible to avoid the superfluous memory
38.79 - /// allocation.
38.80 -
38.81 - /// Using this it is possible to avoid the superfluous memory
38.82 - /// allocation: if you know that the digraph you want to build will
38.83 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
38.84 - /// then it is worth reserving space for this amount before starting
38.85 - /// to build the digraph.
38.86 - /// \sa reserveArc
38.87 - void reserveNode(int n) { nodes.reserve(n); };
38.88 -
38.89 - /// \brief Using this it is possible to avoid the superfluous memory
38.90 - /// allocation.
38.91 -
38.92 - /// Using this it is possible to avoid the superfluous memory
38.93 - /// allocation: if you know that the digraph you want to build will
38.94 - /// be very large (e.g. it will contain millions of nodes and/or arcs)
38.95 - /// then it is worth reserving space for this amount before starting
38.96 - /// to build the digraph.
38.97 - /// \sa reserveNode
38.98 - void reserveArc(int m) { arcs.reserve(m); };
38.99 -
38.100 /// \brief Node validity check
38.101 ///
38.102 - /// This function gives back true if the given node is valid,
38.103 - /// ie. it is a real node of the graph.
38.104 + /// This function gives back \c true if the given node is valid,
38.105 + /// i.e. it is a real node of the digraph.
38.106 ///
38.107 /// \warning A removed node (using Snapshot) could become valid again
38.108 - /// when new nodes are added to the graph.
38.109 + /// if new nodes are added to the digraph.
38.110 bool valid(Node n) const { return Parent::valid(n); }
38.111
38.112 /// \brief Arc validity check
38.113 ///
38.114 - /// This function gives back true if the given arc is valid,
38.115 - /// ie. it is a real arc of the graph.
38.116 + /// This function gives back \c true if the given arc is valid,
38.117 + /// i.e. it is a real arc of the digraph.
38.118 ///
38.119 /// \warning A removed arc (using Snapshot) could become valid again
38.120 - /// when new arcs are added to the graph.
38.121 + /// if new arcs are added to the graph.
38.122 bool valid(Arc a) const { return Parent::valid(a); }
38.123
38.124 - ///Clear the digraph.
38.125 -
38.126 - ///Erase all the nodes and arcs from the digraph.
38.127 - ///
38.128 - void clear() {
38.129 - Parent::clear();
38.130 - }
38.131 -
38.132 ///Split a node.
38.133
38.134 - ///This function splits a node. First a new node is added to the digraph,
38.135 - ///then the source of each outgoing arc of \c n is moved to this new node.
38.136 - ///If \c connect is \c true (this is the default value), then a new arc
38.137 - ///from \c n to the newly created node is also added.
38.138 + ///This function splits the given node. First, a new node is added
38.139 + ///to the digraph, then the source of each outgoing arc of node \c n
38.140 + ///is moved to this new node.
38.141 + ///If the second parameter \c connect is \c true (this is the default
38.142 + ///value), then a new arc from node \c n to the newly created node
38.143 + ///is also added.
38.144 ///\return The newly created node.
38.145 ///
38.146 - ///\note The <tt>Arc</tt>s
38.147 - ///referencing a moved arc remain
38.148 - ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
38.149 - ///may be invalidated.
38.150 + ///\note All iterators remain valid.
38.151 + ///
38.152 ///\warning This functionality cannot be used together with the Snapshot
38.153 ///feature.
38.154 Node split(Node n, bool connect = true)
38.155 @@ -308,6 +273,34 @@
38.156 return b;
38.157 }
38.158
38.159 + ///Clear the digraph.
38.160 +
38.161 + ///This function erases all nodes and arcs from the digraph.
38.162 + ///
38.163 + void clear() {
38.164 + Parent::clear();
38.165 + }
38.166 +
38.167 + /// Reserve memory for nodes.
38.168 +
38.169 + /// Using this function, it is possible to avoid superfluous memory
38.170 + /// allocation: if you know that the digraph you want to build will
38.171 + /// be large (e.g. it will contain millions of nodes and/or arcs),
38.172 + /// then it is worth reserving space for this amount before starting
38.173 + /// to build the digraph.
38.174 + /// \sa reserveArc()
38.175 + void reserveNode(int n) { nodes.reserve(n); };
38.176 +
38.177 + /// Reserve memory for arcs.
38.178 +
38.179 + /// Using this function, it is possible to avoid superfluous memory
38.180 + /// allocation: if you know that the digraph you want to build will
38.181 + /// be large (e.g. it will contain millions of nodes and/or arcs),
38.182 + /// then it is worth reserving space for this amount before starting
38.183 + /// to build the digraph.
38.184 + /// \sa reserveNode()
38.185 + void reserveArc(int m) { arcs.reserve(m); };
38.186 +
38.187 public:
38.188
38.189 class Snapshot;
38.190 @@ -332,20 +325,23 @@
38.191
38.192 public:
38.193
38.194 - ///Class to make a snapshot of the digraph and to restrore to it later.
38.195 + ///Class to make a snapshot of the digraph and to restore it later.
38.196
38.197 - ///Class to make a snapshot of the digraph and to restrore to it later.
38.198 + ///Class to make a snapshot of the digraph and to restore it later.
38.199 ///
38.200 ///The newly added nodes and arcs can be removed using the
38.201 - ///restore() function.
38.202 - ///\note After you restore a state, you cannot restore
38.203 - ///a later state, in other word you cannot add again the arcs deleted
38.204 - ///by restore() using another one Snapshot instance.
38.205 + ///restore() function. This is the only way for deleting nodes and/or
38.206 + ///arcs from a SmartDigraph structure.
38.207 ///
38.208 - ///\warning If you do not use correctly the snapshot that can cause
38.209 - ///either broken program, invalid state of the digraph, valid but
38.210 - ///not the restored digraph or no change. Because the runtime performance
38.211 - ///the validity of the snapshot is not stored.
38.212 + ///\note After a state is restored, you cannot restore a later state,
38.213 + ///i.e. you cannot add the removed nodes and arcs again using
38.214 + ///another Snapshot instance.
38.215 + ///
38.216 + ///\warning Node splitting cannot be restored.
38.217 + ///\warning The validity of the snapshot is not stored due to
38.218 + ///performance reasons. If you do not use the snapshot correctly,
38.219 + ///it can cause broken program, invalid or not restored state of
38.220 + ///the digraph or no change.
38.221 class Snapshot
38.222 {
38.223 SmartDigraph *_graph;
38.224 @@ -357,39 +353,32 @@
38.225 ///Default constructor.
38.226
38.227 ///Default constructor.
38.228 - ///To actually make a snapshot you must call save().
38.229 - ///
38.230 + ///You have to call save() to actually make a snapshot.
38.231 Snapshot() : _graph(0) {}
38.232 ///Constructor that immediately makes a snapshot
38.233
38.234 - ///This constructor immediately makes a snapshot of the digraph.
38.235 - ///\param graph The digraph we make a snapshot of.
38.236 - Snapshot(SmartDigraph &graph) : _graph(&graph) {
38.237 + ///This constructor immediately makes a snapshot of the given digraph.
38.238 + ///
38.239 + Snapshot(SmartDigraph &gr) : _graph(&gr) {
38.240 node_num=_graph->nodes.size();
38.241 arc_num=_graph->arcs.size();
38.242 }
38.243
38.244 ///Make a snapshot.
38.245
38.246 - ///Make a snapshot of the digraph.
38.247 - ///
38.248 - ///This function can be called more than once. In case of a repeated
38.249 + ///This function makes a snapshot of the given digraph.
38.250 + ///It can be called more than once. In case of a repeated
38.251 ///call, the previous snapshot gets lost.
38.252 - ///\param graph The digraph we make the snapshot of.
38.253 - void save(SmartDigraph &graph)
38.254 - {
38.255 - _graph=&graph;
38.256 + void save(SmartDigraph &gr) {
38.257 + _graph=&gr;
38.258 node_num=_graph->nodes.size();
38.259 arc_num=_graph->arcs.size();
38.260 }
38.261
38.262 ///Undo the changes until a snapshot.
38.263
38.264 - ///Undo the changes until a snapshot created by save().
38.265 - ///
38.266 - ///\note After you restored a state, you cannot restore
38.267 - ///a later state, in other word you cannot add again the arcs deleted
38.268 - ///by restore().
38.269 + ///This function undos the changes until the last snapshot
38.270 + ///created by save() or Snapshot(SmartDigraph&).
38.271 void restore()
38.272 {
38.273 _graph->restoreSnapshot(*this);
38.274 @@ -508,7 +497,7 @@
38.275 node._id = nodes.size() - 1;
38.276 }
38.277
38.278 - void next(Node& node) const {
38.279 + static void next(Node& node) {
38.280 --node._id;
38.281 }
38.282
38.283 @@ -516,7 +505,7 @@
38.284 arc._id = arcs.size() - 1;
38.285 }
38.286
38.287 - void next(Arc& arc) const {
38.288 + static void next(Arc& arc) {
38.289 --arc._id;
38.290 }
38.291
38.292 @@ -524,7 +513,7 @@
38.293 arc._id = arcs.size() / 2 - 1;
38.294 }
38.295
38.296 - void next(Edge& arc) const {
38.297 + static void next(Edge& arc) {
38.298 --arc._id;
38.299 }
38.300
38.301 @@ -621,29 +610,26 @@
38.302 ///
38.303 /// \brief A smart undirected graph class.
38.304 ///
38.305 - /// This is a simple and fast graph implementation.
38.306 - /// It is also quite memory efficient, but at the price
38.307 - /// that <b> it does support only limited (only stack-like)
38.308 - /// node and arc deletions</b>.
38.309 - /// It fully conforms to the \ref concepts::Graph "Graph concept".
38.310 + /// \ref SmartGraph is a simple and fast graph implementation.
38.311 + /// It is also quite memory efficient but at the price
38.312 + /// that it does not support node and edge deletion
38.313 + /// (except for the Snapshot feature).
38.314 ///
38.315 - /// \sa concepts::Graph.
38.316 + /// This type fully conforms to the \ref concepts::Graph "Graph concept"
38.317 + /// and it also provides some additional functionalities.
38.318 + /// Most of its member functions and nested classes are documented
38.319 + /// only in the concept class.
38.320 + ///
38.321 + /// \sa concepts::Graph
38.322 + /// \sa SmartDigraph
38.323 class SmartGraph : public ExtendedSmartGraphBase {
38.324 typedef ExtendedSmartGraphBase Parent;
38.325
38.326 private:
38.327 -
38.328 - ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
38.329 -
38.330 - ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
38.331 - ///
38.332 + /// Graphs are \e not copy constructible. Use GraphCopy instead.
38.333 SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
38.334 -
38.335 - ///\brief Assignment of SmartGraph to another one is \e not allowed.
38.336 - ///Use GraphCopy() instead.
38.337 -
38.338 - ///Assignment of SmartGraph to another one is \e not allowed.
38.339 - ///Use GraphCopy() instead.
38.340 + /// \brief Assignment of a graph to another one is \e not allowed.
38.341 + /// Use GraphCopy instead.
38.342 void operator=(const SmartGraph &) {}
38.343
38.344 public:
38.345 @@ -654,56 +640,77 @@
38.346 ///
38.347 SmartGraph() {}
38.348
38.349 - ///Add a new node to the graph.
38.350 -
38.351 - /// Add a new node to the graph.
38.352 + /// \brief Add a new node to the graph.
38.353 + ///
38.354 + /// This function adds a new node to the graph.
38.355 /// \return The new node.
38.356 Node addNode() { return Parent::addNode(); }
38.357
38.358 - ///Add a new edge to the graph.
38.359 -
38.360 - ///Add a new edge to the graph with node \c s
38.361 - ///and \c t.
38.362 - ///\return The new edge.
38.363 - Edge addEdge(const Node& s, const Node& t) {
38.364 - return Parent::addEdge(s, t);
38.365 + /// \brief Add a new edge to the graph.
38.366 + ///
38.367 + /// This function adds a new edge to the graph between nodes
38.368 + /// \c u and \c v with inherent orientation from node \c u to
38.369 + /// node \c v.
38.370 + /// \return The new edge.
38.371 + Edge addEdge(Node u, Node v) {
38.372 + return Parent::addEdge(u, v);
38.373 }
38.374
38.375 /// \brief Node validity check
38.376 ///
38.377 - /// This function gives back true if the given node is valid,
38.378 - /// ie. it is a real node of the graph.
38.379 + /// This function gives back \c true if the given node is valid,
38.380 + /// i.e. it is a real node of the graph.
38.381 ///
38.382 /// \warning A removed node (using Snapshot) could become valid again
38.383 - /// when new nodes are added to the graph.
38.384 + /// if new nodes are added to the graph.
38.385 bool valid(Node n) const { return Parent::valid(n); }
38.386
38.387 + /// \brief Edge validity check
38.388 + ///
38.389 + /// This function gives back \c true if the given edge is valid,
38.390 + /// i.e. it is a real edge of the graph.
38.391 + ///
38.392 + /// \warning A removed edge (using Snapshot) could become valid again
38.393 + /// if new edges are added to the graph.
38.394 + bool valid(Edge e) const { return Parent::valid(e); }
38.395 +
38.396 /// \brief Arc validity check
38.397 ///
38.398 - /// This function gives back true if the given arc is valid,
38.399 - /// ie. it is a real arc of the graph.
38.400 + /// This function gives back \c true if the given arc is valid,
38.401 + /// i.e. it is a real arc of the graph.
38.402 ///
38.403 /// \warning A removed arc (using Snapshot) could become valid again
38.404 - /// when new edges are added to the graph.
38.405 + /// if new edges are added to the graph.
38.406 bool valid(Arc a) const { return Parent::valid(a); }
38.407
38.408 - /// \brief Edge validity check
38.409 - ///
38.410 - /// This function gives back true if the given edge is valid,
38.411 - /// ie. it is a real edge of the graph.
38.412 - ///
38.413 - /// \warning A removed edge (using Snapshot) could become valid again
38.414 - /// when new edges are added to the graph.
38.415 - bool valid(Edge e) const { return Parent::valid(e); }
38.416 -
38.417 ///Clear the graph.
38.418
38.419 - ///Erase all the nodes and edges from the graph.
38.420 + ///This function erases all nodes and arcs from the graph.
38.421 ///
38.422 void clear() {
38.423 Parent::clear();
38.424 }
38.425
38.426 + /// Reserve memory for nodes.
38.427 +
38.428 + /// Using this function, it is possible to avoid superfluous memory
38.429 + /// allocation: if you know that the graph you want to build will
38.430 + /// be large (e.g. it will contain millions of nodes and/or edges),
38.431 + /// then it is worth reserving space for this amount before starting
38.432 + /// to build the graph.
38.433 + /// \sa reserveEdge()
38.434 + void reserveNode(int n) { nodes.reserve(n); };
38.435 +
38.436 + /// Reserve memory for edges.
38.437 +
38.438 + /// Using this function, it is possible to avoid superfluous memory
38.439 + /// allocation: if you know that the graph you want to build will
38.440 + /// be large (e.g. it will contain millions of nodes and/or edges),
38.441 + /// then it is worth reserving space for this amount before starting
38.442 + /// to build the graph.
38.443 + /// \sa reserveNode()
38.444 + void reserveEdge(int m) { arcs.reserve(2 * m); };
38.445 +
38.446 public:
38.447
38.448 class Snapshot;
38.449 @@ -742,21 +749,22 @@
38.450
38.451 public:
38.452
38.453 - ///Class to make a snapshot of the digraph and to restrore to it later.
38.454 + ///Class to make a snapshot of the graph and to restore it later.
38.455
38.456 - ///Class to make a snapshot of the digraph and to restrore to it later.
38.457 + ///Class to make a snapshot of the graph and to restore it later.
38.458 ///
38.459 - ///The newly added nodes and arcs can be removed using the
38.460 - ///restore() function.
38.461 + ///The newly added nodes and edges can be removed using the
38.462 + ///restore() function. This is the only way for deleting nodes and/or
38.463 + ///edges from a SmartGraph structure.
38.464 ///
38.465 - ///\note After you restore a state, you cannot restore
38.466 - ///a later state, in other word you cannot add again the arcs deleted
38.467 - ///by restore() using another one Snapshot instance.
38.468 + ///\note After a state is restored, you cannot restore a later state,
38.469 + ///i.e. you cannot add the removed nodes and edges again using
38.470 + ///another Snapshot instance.
38.471 ///
38.472 - ///\warning If you do not use correctly the snapshot that can cause
38.473 - ///either broken program, invalid state of the digraph, valid but
38.474 - ///not the restored digraph or no change. Because the runtime performance
38.475 - ///the validity of the snapshot is not stored.
38.476 + ///\warning The validity of the snapshot is not stored due to
38.477 + ///performance reasons. If you do not use the snapshot correctly,
38.478 + ///it can cause broken program, invalid or not restored state of
38.479 + ///the graph or no change.
38.480 class Snapshot
38.481 {
38.482 SmartGraph *_graph;
38.483 @@ -768,36 +776,30 @@
38.484 ///Default constructor.
38.485
38.486 ///Default constructor.
38.487 - ///To actually make a snapshot you must call save().
38.488 - ///
38.489 + ///You have to call save() to actually make a snapshot.
38.490 Snapshot() : _graph(0) {}
38.491 ///Constructor that immediately makes a snapshot
38.492
38.493 - ///This constructor immediately makes a snapshot of the digraph.
38.494 - ///\param graph The digraph we make a snapshot of.
38.495 - Snapshot(SmartGraph &graph) {
38.496 - graph.saveSnapshot(*this);
38.497 + /// This constructor immediately makes a snapshot of the given graph.
38.498 + ///
38.499 + Snapshot(SmartGraph &gr) {
38.500 + gr.saveSnapshot(*this);
38.501 }
38.502
38.503 ///Make a snapshot.
38.504
38.505 - ///Make a snapshot of the graph.
38.506 - ///
38.507 - ///This function can be called more than once. In case of a repeated
38.508 + ///This function makes a snapshot of the given graph.
38.509 + ///It can be called more than once. In case of a repeated
38.510 ///call, the previous snapshot gets lost.
38.511 - ///\param graph The digraph we make the snapshot of.
38.512 - void save(SmartGraph &graph)
38.513 + void save(SmartGraph &gr)
38.514 {
38.515 - graph.saveSnapshot(*this);
38.516 + gr.saveSnapshot(*this);
38.517 }
38.518
38.519 - ///Undo the changes until a snapshot.
38.520 + ///Undo the changes until the last snapshot.
38.521
38.522 - ///Undo the changes until a snapshot created by save().
38.523 - ///
38.524 - ///\note After you restored a state, you cannot restore
38.525 - ///a later state, in other word you cannot add again the arcs deleted
38.526 - ///by restore().
38.527 + ///This function undos the changes until the last snapshot
38.528 + ///created by save() or Snapshot(SmartGraph&).
38.529 void restore()
38.530 {
38.531 _graph->restoreSnapshot(*this);
39.1 --- a/lemon/soplex.cc Mon Sep 28 15:53:20 2009 +0200
39.2 +++ b/lemon/soplex.cc Thu Nov 05 10:27:17 2009 +0100
39.3 @@ -91,6 +91,19 @@
39.4 return soplex->nRows() - 1;
39.5 }
39.6
39.7 + int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
39.8 + soplex::DSVector v;
39.9 + for (ExprIterator it = b; it != e; ++it) {
39.10 + v.add(it->first, it->second);
39.11 + }
39.12 + soplex::LPRow r(l, v, u);
39.13 + soplex->addRow(r);
39.14 +
39.15 + _row_names.push_back(std::string());
39.16 +
39.17 + return soplex->nRows() - 1;
39.18 + }
39.19 +
39.20
39.21 void SoplexLp::_eraseCol(int i) {
39.22 soplex->removeCol(i);
40.1 --- a/lemon/soplex.h Mon Sep 28 15:53:20 2009 +0200
40.2 +++ b/lemon/soplex.h Thu Nov 05 10:27:17 2009 +0100
40.3 @@ -84,6 +84,7 @@
40.4
40.5 virtual int _addCol();
40.6 virtual int _addRow();
40.7 + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
40.8
40.9 virtual void _eraseCol(int i);
40.10 virtual void _eraseRow(int i);
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/lemon/static_graph.h Thu Nov 05 10:27:17 2009 +0100
41.3 @@ -0,0 +1,474 @@
41.4 +/* -*- C++ -*-
41.5 + *
41.6 + * This file is a part of LEMON, a generic C++ optimization library
41.7 + *
41.8 + * Copyright (C) 2003-2008
41.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
41.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
41.11 + *
41.12 + * Permission to use, modify and distribute this software is granted
41.13 + * provided that this copyright notice appears in all copies. For
41.14 + * precise terms see the accompanying LICENSE file.
41.15 + *
41.16 + * This software is provided "AS IS" with no warranty of any kind,
41.17 + * express or implied, and with no claim as to its suitability for any
41.18 + * purpose.
41.19 + *
41.20 + */
41.21 +
41.22 +#ifndef LEMON_STATIC_GRAPH_H
41.23 +#define LEMON_STATIC_GRAPH_H
41.24 +
41.25 +///\ingroup graphs
41.26 +///\file
41.27 +///\brief StaticDigraph class.
41.28 +
41.29 +#include <lemon/core.h>
41.30 +#include <lemon/bits/graph_extender.h>
41.31 +
41.32 +namespace lemon {
41.33 +
41.34 + class StaticDigraphBase {
41.35 + public:
41.36 +
41.37 + StaticDigraphBase()
41.38 + : built(false), node_num(0), arc_num(0),
41.39 + node_first_out(NULL), node_first_in(NULL),
41.40 + arc_source(NULL), arc_target(NULL),
41.41 + arc_next_in(NULL), arc_next_out(NULL) {}
41.42 +
41.43 + ~StaticDigraphBase() {
41.44 + if (built) {
41.45 + delete[] node_first_out;
41.46 + delete[] node_first_in;
41.47 + delete[] arc_source;
41.48 + delete[] arc_target;
41.49 + delete[] arc_next_out;
41.50 + delete[] arc_next_in;
41.51 + }
41.52 + }
41.53 +
41.54 + class Node {
41.55 + friend class StaticDigraphBase;
41.56 + protected:
41.57 + int id;
41.58 + Node(int _id) : id(_id) {}
41.59 + public:
41.60 + Node() {}
41.61 + Node (Invalid) : id(-1) {}
41.62 + bool operator==(const Node& node) const { return id == node.id; }
41.63 + bool operator!=(const Node& node) const { return id != node.id; }
41.64 + bool operator<(const Node& node) const { return id < node.id; }
41.65 + };
41.66 +
41.67 + class Arc {
41.68 + friend class StaticDigraphBase;
41.69 + protected:
41.70 + int id;
41.71 + Arc(int _id) : id(_id) {}
41.72 + public:
41.73 + Arc() { }
41.74 + Arc (Invalid) : id(-1) {}
41.75 + bool operator==(const Arc& arc) const { return id == arc.id; }
41.76 + bool operator!=(const Arc& arc) const { return id != arc.id; }
41.77 + bool operator<(const Arc& arc) const { return id < arc.id; }
41.78 + };
41.79 +
41.80 + Node source(const Arc& e) const { return Node(arc_source[e.id]); }
41.81 + Node target(const Arc& e) const { return Node(arc_target[e.id]); }
41.82 +
41.83 + void first(Node& n) const { n.id = node_num - 1; }
41.84 + static void next(Node& n) { --n.id; }
41.85 +
41.86 + void first(Arc& e) const { e.id = arc_num - 1; }
41.87 + static void next(Arc& e) { --e.id; }
41.88 +
41.89 + void firstOut(Arc& e, const Node& n) const {
41.90 + e.id = node_first_out[n.id] != node_first_out[n.id + 1] ?
41.91 + node_first_out[n.id] : -1;
41.92 + }
41.93 + void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
41.94 +
41.95 + void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
41.96 + void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
41.97 +
41.98 + static int id(const Node& n) { return n.id; }
41.99 + static Node nodeFromId(int id) { return Node(id); }
41.100 + int maxNodeId() const { return node_num - 1; }
41.101 +
41.102 + static int id(const Arc& e) { return e.id; }
41.103 + static Arc arcFromId(int id) { return Arc(id); }
41.104 + int maxArcId() const { return arc_num - 1; }
41.105 +
41.106 + typedef True NodeNumTag;
41.107 + typedef True ArcNumTag;
41.108 +
41.109 + int nodeNum() const { return node_num; }
41.110 + int arcNum() const { return arc_num; }
41.111 +
41.112 + private:
41.113 +
41.114 + template <typename Digraph, typename NodeRefMap>
41.115 + class ArcLess {
41.116 + public:
41.117 + typedef typename Digraph::Arc Arc;
41.118 +
41.119 + ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef)
41.120 + : digraph(_graph), nodeRef(_nodeRef) {}
41.121 +
41.122 + bool operator()(const Arc& left, const Arc& right) const {
41.123 + return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
41.124 + }
41.125 + private:
41.126 + const Digraph& digraph;
41.127 + const NodeRefMap& nodeRef;
41.128 + };
41.129 +
41.130 + public:
41.131 +
41.132 + typedef True BuildTag;
41.133 +
41.134 + void clear() {
41.135 + if (built) {
41.136 + delete[] node_first_out;
41.137 + delete[] node_first_in;
41.138 + delete[] arc_source;
41.139 + delete[] arc_target;
41.140 + delete[] arc_next_out;
41.141 + delete[] arc_next_in;
41.142 + }
41.143 + built = false;
41.144 + node_num = 0;
41.145 + arc_num = 0;
41.146 + }
41.147 +
41.148 + template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
41.149 + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
41.150 + typedef typename Digraph::Node GNode;
41.151 + typedef typename Digraph::Arc GArc;
41.152 +
41.153 + built = true;
41.154 +
41.155 + node_num = countNodes(digraph);
41.156 + arc_num = countArcs(digraph);
41.157 +
41.158 + node_first_out = new int[node_num + 1];
41.159 + node_first_in = new int[node_num];
41.160 +
41.161 + arc_source = new int[arc_num];
41.162 + arc_target = new int[arc_num];
41.163 + arc_next_out = new int[arc_num];
41.164 + arc_next_in = new int[arc_num];
41.165 +
41.166 + int node_index = 0;
41.167 + for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
41.168 + nodeRef[n] = Node(node_index);
41.169 + node_first_in[node_index] = -1;
41.170 + ++node_index;
41.171 + }
41.172 +
41.173 + ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
41.174 +
41.175 + int arc_index = 0;
41.176 + for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
41.177 + int source = nodeRef[n].id;
41.178 + std::vector<GArc> arcs;
41.179 + for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
41.180 + arcs.push_back(e);
41.181 + }
41.182 + if (!arcs.empty()) {
41.183 + node_first_out[source] = arc_index;
41.184 + std::sort(arcs.begin(), arcs.end(), arcLess);
41.185 + for (typename std::vector<GArc>::iterator it = arcs.begin();
41.186 + it != arcs.end(); ++it) {
41.187 + int target = nodeRef[digraph.target(*it)].id;
41.188 + arcRef[*it] = Arc(arc_index);
41.189 + arc_source[arc_index] = source;
41.190 + arc_target[arc_index] = target;
41.191 + arc_next_in[arc_index] = node_first_in[target];
41.192 + node_first_in[target] = arc_index;
41.193 + arc_next_out[arc_index] = arc_index + 1;
41.194 + ++arc_index;
41.195 + }
41.196 + arc_next_out[arc_index - 1] = -1;
41.197 + } else {
41.198 + node_first_out[source] = arc_index;
41.199 + }
41.200 + }
41.201 + node_first_out[node_num] = arc_num;
41.202 + }
41.203 +
41.204 + template <typename ArcListIterator>
41.205 + void build(int n, ArcListIterator first, ArcListIterator last) {
41.206 + built = true;
41.207 +
41.208 + node_num = n;
41.209 + arc_num = std::distance(first, last);
41.210 +
41.211 + node_first_out = new int[node_num + 1];
41.212 + node_first_in = new int[node_num];
41.213 +
41.214 + arc_source = new int[arc_num];
41.215 + arc_target = new int[arc_num];
41.216 + arc_next_out = new int[arc_num];
41.217 + arc_next_in = new int[arc_num];
41.218 +
41.219 + for (int i = 0; i != node_num; ++i) {
41.220 + node_first_in[i] = -1;
41.221 + }
41.222 +
41.223 + int arc_index = 0;
41.224 + for (int i = 0; i != node_num; ++i) {
41.225 + node_first_out[i] = arc_index;
41.226 + for ( ; first != last && (*first).first == i; ++first) {
41.227 + int j = (*first).second;
41.228 + LEMON_ASSERT(j >= 0 && j < node_num,
41.229 + "Wrong arc list for StaticDigraph::build()");
41.230 + arc_source[arc_index] = i;
41.231 + arc_target[arc_index] = j;
41.232 + arc_next_in[arc_index] = node_first_in[j];
41.233 + node_first_in[j] = arc_index;
41.234 + arc_next_out[arc_index] = arc_index + 1;
41.235 + ++arc_index;
41.236 + }
41.237 + if (arc_index > node_first_out[i])
41.238 + arc_next_out[arc_index - 1] = -1;
41.239 + }
41.240 + LEMON_ASSERT(first == last,
41.241 + "Wrong arc list for StaticDigraph::build()");
41.242 + node_first_out[node_num] = arc_num;
41.243 + }
41.244 +
41.245 + protected:
41.246 +
41.247 + void fastFirstOut(Arc& e, const Node& n) const {
41.248 + e.id = node_first_out[n.id];
41.249 + }
41.250 +
41.251 + static void fastNextOut(Arc& e) {
41.252 + ++e.id;
41.253 + }
41.254 + void fastLastOut(Arc& e, const Node& n) const {
41.255 + e.id = node_first_out[n.id + 1];
41.256 + }
41.257 +
41.258 + protected:
41.259 + bool built;
41.260 + int node_num;
41.261 + int arc_num;
41.262 + int *node_first_out;
41.263 + int *node_first_in;
41.264 + int *arc_source;
41.265 + int *arc_target;
41.266 + int *arc_next_in;
41.267 + int *arc_next_out;
41.268 + };
41.269 +
41.270 + typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
41.271 +
41.272 +
41.273 + /// \ingroup graphs
41.274 + ///
41.275 + /// \brief A static directed graph class.
41.276 + ///
41.277 + /// \ref StaticDigraph is a highly efficient digraph implementation,
41.278 + /// but it is fully static.
41.279 + /// It stores only two \c int values for each node and only four \c int
41.280 + /// values for each arc. Moreover it provides faster item iteration than
41.281 + /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
41.282 + /// iterators, since its arcs are stored in an appropriate order.
41.283 + /// However it only provides build() and clear() functions and does not
41.284 + /// support any other modification of the digraph.
41.285 + ///
41.286 + /// Since this digraph structure is completely static, its nodes and arcs
41.287 + /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
41.288 + /// and <tt>[0..arcNum()-1]</tt>, respectively.
41.289 + /// The index of an item is the same as its ID, it can be obtained
41.290 + /// using the corresponding \ref index() or \ref concepts::Digraph::id()
41.291 + /// "id()" function. A node or arc with a certain index can be obtained
41.292 + /// using node() or arc().
41.293 + ///
41.294 + /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
41.295 + /// Most of its member functions and nested classes are documented
41.296 + /// only in the concept class.
41.297 + ///
41.298 + /// \sa concepts::Digraph
41.299 + class StaticDigraph : public ExtendedStaticDigraphBase {
41.300 + public:
41.301 +
41.302 + typedef ExtendedStaticDigraphBase Parent;
41.303 +
41.304 + public:
41.305 +
41.306 + /// \brief Constructor
41.307 + ///
41.308 + /// Default constructor.
41.309 + StaticDigraph() : Parent() {}
41.310 +
41.311 + /// \brief The node with the given index.
41.312 + ///
41.313 + /// This function returns the node with the given index.
41.314 + /// \sa index()
41.315 + static Node node(int ix) { return Parent::nodeFromId(ix); }
41.316 +
41.317 + /// \brief The arc with the given index.
41.318 + ///
41.319 + /// This function returns the arc with the given index.
41.320 + /// \sa index()
41.321 + static Arc arc(int ix) { return Parent::arcFromId(ix); }
41.322 +
41.323 + /// \brief The index of the given node.
41.324 + ///
41.325 + /// This function returns the index of the the given node.
41.326 + /// \sa node()
41.327 + static int index(Node node) { return Parent::id(node); }
41.328 +
41.329 + /// \brief The index of the given arc.
41.330 + ///
41.331 + /// This function returns the index of the the given arc.
41.332 + /// \sa arc()
41.333 + static int index(Arc arc) { return Parent::id(arc); }
41.334 +
41.335 + /// \brief Number of nodes.
41.336 + ///
41.337 + /// This function returns the number of nodes.
41.338 + int nodeNum() const { return node_num; }
41.339 +
41.340 + /// \brief Number of arcs.
41.341 + ///
41.342 + /// This function returns the number of arcs.
41.343 + int arcNum() const { return arc_num; }
41.344 +
41.345 + /// \brief Build the digraph copying another digraph.
41.346 + ///
41.347 + /// This function builds the digraph copying another digraph of any
41.348 + /// kind. It can be called more than once, but in such case, the whole
41.349 + /// structure and all maps will be cleared and rebuilt.
41.350 + ///
41.351 + /// This method also makes possible to copy a digraph to a StaticDigraph
41.352 + /// structure using \ref DigraphCopy.
41.353 + ///
41.354 + /// \param digraph An existing digraph to be copied.
41.355 + /// \param nodeRef The node references will be copied into this map.
41.356 + /// Its key type must be \c Digraph::Node and its value type must be
41.357 + /// \c StaticDigraph::Node.
41.358 + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
41.359 + /// concept.
41.360 + /// \param arcRef The arc references will be copied into this map.
41.361 + /// Its key type must be \c Digraph::Arc and its value type must be
41.362 + /// \c StaticDigraph::Arc.
41.363 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
41.364 + ///
41.365 + /// \note If you do not need the arc references, then you could use
41.366 + /// \ref NullMap for the last parameter. However the node references
41.367 + /// are required by the function itself, thus they must be readable
41.368 + /// from the map.
41.369 + template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
41.370 + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
41.371 + if (built) Parent::clear();
41.372 + Parent::build(digraph, nodeRef, arcRef);
41.373 + }
41.374 +
41.375 + /// \brief Build the digraph from an arc list.
41.376 + ///
41.377 + /// This function builds the digraph from the given arc list.
41.378 + /// It can be called more than once, but in such case, the whole
41.379 + /// structure and all maps will be cleared and rebuilt.
41.380 + ///
41.381 + /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
41.382 + /// specified by STL compatible itartors whose \c value_type must be
41.383 + /// <tt>std::pair<int,int></tt>.
41.384 + /// Each arc must be specified by a pair of integer indices
41.385 + /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
41.386 + /// non-decreasing order with respect to their first values.</i>
41.387 + /// If the k-th pair in the list is <tt>(i,j)</tt>, then
41.388 + /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
41.389 + ///
41.390 + /// \param n The number of nodes.
41.391 + /// \param begin An iterator pointing to the beginning of the arc list.
41.392 + /// \param end An iterator pointing to the end of the arc list.
41.393 + ///
41.394 + /// For example, a simple digraph can be constructed like this.
41.395 + /// \code
41.396 + /// std::vector<std::pair<int,int> > arcs;
41.397 + /// arcs.push_back(std::make_pair(0,1));
41.398 + /// arcs.push_back(std::make_pair(0,2));
41.399 + /// arcs.push_back(std::make_pair(1,3));
41.400 + /// arcs.push_back(std::make_pair(1,2));
41.401 + /// arcs.push_back(std::make_pair(3,0));
41.402 + /// StaticDigraph gr;
41.403 + /// gr.build(4, arcs.begin(), arcs.end());
41.404 + /// \endcode
41.405 + template <typename ArcListIterator>
41.406 + void build(int n, ArcListIterator begin, ArcListIterator end) {
41.407 + if (built) Parent::clear();
41.408 + StaticDigraphBase::build(n, begin, end);
41.409 + notifier(Node()).build();
41.410 + notifier(Arc()).build();
41.411 + }
41.412 +
41.413 + /// \brief Clear the digraph.
41.414 + ///
41.415 + /// This function erases all nodes and arcs from the digraph.
41.416 + void clear() {
41.417 + Parent::clear();
41.418 + }
41.419 +
41.420 + protected:
41.421 +
41.422 + using Parent::fastFirstOut;
41.423 + using Parent::fastNextOut;
41.424 + using Parent::fastLastOut;
41.425 +
41.426 + public:
41.427 +
41.428 + class OutArcIt : public Arc {
41.429 + public:
41.430 +
41.431 + OutArcIt() { }
41.432 +
41.433 + OutArcIt(Invalid i) : Arc(i) { }
41.434 +
41.435 + OutArcIt(const StaticDigraph& digraph, const Node& node) {
41.436 + digraph.fastFirstOut(*this, node);
41.437 + digraph.fastLastOut(last, node);
41.438 + if (last == *this) *this = INVALID;
41.439 + }
41.440 +
41.441 + OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
41.442 + if (arc != INVALID) {
41.443 + digraph.fastLastOut(last, digraph.source(arc));
41.444 + }
41.445 + }
41.446 +
41.447 + OutArcIt& operator++() {
41.448 + StaticDigraph::fastNextOut(*this);
41.449 + if (last == *this) *this = INVALID;
41.450 + return *this;
41.451 + }
41.452 +
41.453 + private:
41.454 + Arc last;
41.455 + };
41.456 +
41.457 + Node baseNode(const OutArcIt &arc) const {
41.458 + return Parent::source(static_cast<const Arc&>(arc));
41.459 + }
41.460 +
41.461 + Node runningNode(const OutArcIt &arc) const {
41.462 + return Parent::target(static_cast<const Arc&>(arc));
41.463 + }
41.464 +
41.465 + Node baseNode(const InArcIt &arc) const {
41.466 + return Parent::target(static_cast<const Arc&>(arc));
41.467 + }
41.468 +
41.469 + Node runningNode(const InArcIt &arc) const {
41.470 + return Parent::source(static_cast<const Arc&>(arc));
41.471 + }
41.472 +
41.473 + };
41.474 +
41.475 +}
41.476 +
41.477 +#endif
42.1 --- a/m4/lx_check_coin.m4 Mon Sep 28 15:53:20 2009 +0200
42.2 +++ b/m4/lx_check_coin.m4 Thu Nov 05 10:27:17 2009 +0100
42.3 @@ -88,7 +88,7 @@
42.4 elif test x"$with_coin" != x"yes"; then
42.5 CBC_LDFLAGS="-L$with_coin/lib"
42.6 fi
42.7 - CBC_LIBS="-lOsi -lCbc -lOsiCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
42.8 + CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
42.9
42.10 lx_save_cxxflags="$CXXFLAGS"
42.11 lx_save_ldflags="$LDFLAGS"
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/scripts/bib2dox.py Thu Nov 05 10:27:17 2009 +0100
43.3 @@ -0,0 +1,811 @@
43.4 +#!/usr/bin/env /usr/local/Python/bin/python2.1
43.5 +"""
43.6 + BibTeX to Doxygen converter
43.7 + Usage: python bib2dox.py bibfile.bib > bibfile.dox
43.8 +
43.9 + This code is the modification of the BibTeX to XML converter
43.10 + by Vidar Bronken Gundersen et al. See the original copyright notices below.
43.11 +
43.12 + **********************************************************************
43.13 +
43.14 + Decoder for bibliographic data, BibTeX
43.15 + Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
43.16 +
43.17 + v.8
43.18 + (c)2002-06-23 Vidar Bronken Gundersen
43.19 + http://bibtexml.sf.net/
43.20 + Reuse approved as long as this notification is kept.
43.21 + Licence: GPL.
43.22 +
43.23 + Contributions/thanks to:
43.24 + Egon Willighagen, http://sf.net/projects/jreferences/
43.25 + Richard Mahoney (for providing a test case)
43.26 +
43.27 + Editted by Sara Sprenkle to be more robust and handle more bibtex features.
43.28 + (c) 2003-01-15
43.29 +
43.30 + 1. Changed bibtex: tags to bibxml: tags.
43.31 + 2. Use xmlns:bibxml="http://bibtexml.sf.net/"
43.32 + 3. Allow spaces between @type and first {
43.33 + 4. "author" fields with multiple authors split by " and "
43.34 + are put in separate xml "bibxml:author" tags.
43.35 + 5. Option for Titles: words are capitalized
43.36 + only if first letter in title or capitalized inside braces
43.37 + 6. Removes braces from within field values
43.38 + 7. Ignores comments in bibtex file (including @comment{ or % )
43.39 + 8. Replaces some special latex tags, e.g., replaces ~ with ' '
43.40 + 9. Handles bibtex @string abbreviations
43.41 + --> includes bibtex's default abbreviations for months
43.42 + --> does concatenation of abbr # " more " and " more " # abbr
43.43 + 10. Handles @type( ... ) or @type{ ... }
43.44 + 11. The keywords field is split on , or ; and put into separate xml
43.45 + "bibxml:keywords" tags
43.46 + 12. Ignores @preamble
43.47 +
43.48 + Known Limitations
43.49 + 1. Does not transform Latex encoding like math mode and special
43.50 + latex symbols.
43.51 + 2. Does not parse author fields into first and last names.
43.52 + E.g., It does not do anything special to an author whose name is
43.53 + in the form LAST_NAME, FIRST_NAME
43.54 + In "author" tag, will show up as
43.55 + <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
43.56 + 3. Does not handle "crossref" fields other than to print
43.57 + <bibxml:crossref>...</bibxml:crossref>
43.58 + 4. Does not inform user of the input's format errors. You just won't
43.59 + be able to transform the file later with XSL
43.60 +
43.61 + You will have to manually edit the XML output if you need to handle
43.62 + these (and unknown) limitations.
43.63 +
43.64 +"""
43.65 +
43.66 +import string, re
43.67 +
43.68 +# set of valid name characters
43.69 +valid_name_chars = '[\w\-:]'
43.70 +
43.71 +#
43.72 +# define global regular expression variables
43.73 +#
43.74 +author_rex = re.compile('\s+and\s+')
43.75 +rembraces_rex = re.compile('[{}]')
43.76 +capitalize_rex = re.compile('({[^}]*})')
43.77 +
43.78 +# used by bibtexkeywords(data)
43.79 +keywords_rex = re.compile('[,;]')
43.80 +
43.81 +# used by concat_line(line)
43.82 +concatsplit_rex = re.compile('\s*#\s*')
43.83 +
43.84 +# split on {, }, or " in verify_out_of_braces
43.85 +delimiter_rex = re.compile('([{}"])',re.I)
43.86 +
43.87 +field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
43.88 +data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
43.89 +
43.90 +url_rex = re.compile('\\\url\{([^}]*)\}')
43.91 +
43.92 +#
43.93 +# styles for html formatting
43.94 +#
43.95 +divstyle = 'margin-top: -4ex; margin-left: 8em;'
43.96 +
43.97 +#
43.98 +# return the string parameter without braces
43.99 +#
43.100 +def transformurls(str):
43.101 + return url_rex.sub(r'<a href="\1">\1</a>', str)
43.102 +
43.103 +#
43.104 +# return the string parameter without braces
43.105 +#
43.106 +def removebraces(str):
43.107 + return rembraces_rex.sub('', str)
43.108 +
43.109 +#
43.110 +# latex-specific replacements
43.111 +# (do this after braces were removed)
43.112 +#
43.113 +def latexreplacements(line):
43.114 + line = string.replace(line, '~', ' ')
43.115 + line = string.replace(line, '\\\'a', 'á')
43.116 + line = string.replace(line, '\\"a', 'ä')
43.117 + line = string.replace(line, '\\\'e', 'é')
43.118 + line = string.replace(line, '\\"e', 'ë')
43.119 + line = string.replace(line, '\\\'i', 'í')
43.120 + line = string.replace(line, '\\"i', 'ï')
43.121 + line = string.replace(line, '\\\'o', 'ó')
43.122 + line = string.replace(line, '\\"o', 'ö')
43.123 + line = string.replace(line, '\\\'u', 'ú')
43.124 + line = string.replace(line, '\\"u', 'ü')
43.125 + line = string.replace(line, '\\H o', 'õ')
43.126 + line = string.replace(line, '\\H u', 'ü') # ũ does not exist
43.127 + line = string.replace(line, '\\\'A', 'Á')
43.128 + line = string.replace(line, '\\"A', 'Ä')
43.129 + line = string.replace(line, '\\\'E', 'É')
43.130 + line = string.replace(line, '\\"E', 'Ë')
43.131 + line = string.replace(line, '\\\'I', 'Í')
43.132 + line = string.replace(line, '\\"I', 'Ï')
43.133 + line = string.replace(line, '\\\'O', 'Ó')
43.134 + line = string.replace(line, '\\"O', 'Ö')
43.135 + line = string.replace(line, '\\\'U', 'Ú')
43.136 + line = string.replace(line, '\\"U', 'Ü')
43.137 + line = string.replace(line, '\\H O', 'Õ')
43.138 + line = string.replace(line, '\\H U', 'Ü') # Ũ does not exist
43.139 +
43.140 + return line
43.141 +
43.142 +#
43.143 +# copy characters form a string decoding html expressions (&xyz;)
43.144 +#
43.145 +def copychars(str, ifrom, count):
43.146 + result = ''
43.147 + i = ifrom
43.148 + c = 0
43.149 + html_spec = False
43.150 + while (i < len(str)) and (c < count):
43.151 + if str[i] == '&':
43.152 + html_spec = True;
43.153 + if i+1 < len(str):
43.154 + result += str[i+1]
43.155 + c += 1
43.156 + i += 2
43.157 + else:
43.158 + if not html_spec:
43.159 + if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
43.160 + ((str[i] >= 'a') and (str[i] <= 'z')):
43.161 + result += str[i]
43.162 + c += 1
43.163 + elif str[i] == ';':
43.164 + html_spec = False;
43.165 + i += 1
43.166 +
43.167 + return result
43.168 +
43.169 +
43.170 +#
43.171 +# Handle a list of authors (separated by 'and').
43.172 +# It gives back an array of the follwing values:
43.173 +# - num: the number of authors,
43.174 +# - list: the list of the author names,
43.175 +# - text: the bibtex text (separated by commas and/or 'and')
43.176 +# - abbrev: abbreviation that can be used for indicate the
43.177 +# bibliography entries
43.178 +#
43.179 +def bibtexauthor(data):
43.180 + result = {}
43.181 + bibtex = ''
43.182 + result['list'] = author_rex.split(data)
43.183 + result['num'] = len(result['list'])
43.184 + for i, author in enumerate(result['list']):
43.185 + # general transformations
43.186 + author = latexreplacements(removebraces(author.strip()))
43.187 + # transform "Xyz, A. B." to "A. B. Xyz"
43.188 + pos = author.find(',')
43.189 + if pos != -1:
43.190 + author = author[pos+1:].strip() + ' ' + author[:pos].strip()
43.191 + result['list'][i] = author
43.192 + bibtex += author + '#'
43.193 + bibtex = bibtex[:-1]
43.194 + if result['num'] > 1:
43.195 + ix = bibtex.rfind('#')
43.196 + if result['num'] == 2:
43.197 + bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
43.198 + else:
43.199 + bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
43.200 + bibtex = bibtex.replace('#', ', ')
43.201 + result['text'] = bibtex
43.202 +
43.203 + result['abbrev'] = ''
43.204 + for author in result['list']:
43.205 + pos = author.rfind(' ') + 1
43.206 + count = 1
43.207 + if result['num'] == 1:
43.208 + count = 3
43.209 + result['abbrev'] += copychars(author, pos, count)
43.210 +
43.211 + return result
43.212 +
43.213 +
43.214 +#
43.215 +# data = title string
43.216 +# @return the capitalized title (first letter is capitalized), rest are capitalized
43.217 +# only if capitalized inside braces
43.218 +#
43.219 +def capitalizetitle(data):
43.220 + title_list = capitalize_rex.split(data)
43.221 + title = ''
43.222 + count = 0
43.223 + for phrase in title_list:
43.224 + check = string.lstrip(phrase)
43.225 +
43.226 + # keep phrase's capitalization the same
43.227 + if check.find('{') == 0:
43.228 + title += removebraces(phrase)
43.229 + else:
43.230 + # first word --> capitalize first letter (after spaces)
43.231 + if count == 0:
43.232 + title += check.capitalize()
43.233 + else:
43.234 + title += phrase.lower()
43.235 + count = count + 1
43.236 +
43.237 + return title
43.238 +
43.239 +
43.240 +#
43.241 +# @return the bibtex for the title
43.242 +# @param data --> title string
43.243 +# braces are removed from title
43.244 +#
43.245 +def bibtextitle(data, entrytype):
43.246 + if entrytype in ('book', 'inbook'):
43.247 + title = removebraces(data.strip())
43.248 + else:
43.249 + title = removebraces(capitalizetitle(data.strip()))
43.250 + bibtex = title
43.251 + return bibtex
43.252 +
43.253 +
43.254 +#
43.255 +# function to compare entry lists
43.256 +#
43.257 +def entry_cmp(x, y):
43.258 + return cmp(x[0], y[0])
43.259 +
43.260 +
43.261 +#
43.262 +# print the XML for the transformed "filecont_source"
43.263 +#
43.264 +def bibtexdecoder(filecont_source):
43.265 + filecont = []
43.266 + file = []
43.267 +
43.268 + # want @<alphanumeric chars><spaces>{<spaces><any chars>,
43.269 + pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
43.270 + endtype_rex = re.compile('}\s*$')
43.271 + endtag_rex = re.compile('^\s*}\s*$')
43.272 +
43.273 + bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
43.274 + bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
43.275 +
43.276 + quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
43.277 + quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
43.278 +
43.279 + for line in filecont_source:
43.280 + line = line[:-1]
43.281 +
43.282 + # encode character entities
43.283 + line = string.replace(line, '&', '&')
43.284 + line = string.replace(line, '<', '<')
43.285 + line = string.replace(line, '>', '>')
43.286 +
43.287 + # start entry: publication type (store for later use)
43.288 + if pubtype_rex.match(line):
43.289 + # want @<alphanumeric chars><spaces>{<spaces><any chars>,
43.290 + entrycont = {}
43.291 + entry = []
43.292 + entrytype = pubtype_rex.sub('\g<1>',line)
43.293 + entrytype = string.lower(entrytype)
43.294 + entryid = pubtype_rex.sub('\g<2>', line)
43.295 +
43.296 + # end entry if just a }
43.297 + elif endtype_rex.match(line):
43.298 + # generate doxygen code for the entry
43.299 +
43.300 + # enty type related formattings
43.301 + if entrytype in ('book', 'inbook'):
43.302 + entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
43.303 + if not entrycont.has_key('author'):
43.304 + entrycont['author'] = entrycont['editor']
43.305 + entrycont['author']['text'] += ', editors'
43.306 + elif entrytype == 'article':
43.307 + entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
43.308 + elif entrytype in ('inproceedings', 'incollection', 'conference'):
43.309 + entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
43.310 + elif entrytype == 'techreport':
43.311 + if not entrycont.has_key('type'):
43.312 + entrycont['type'] = 'Technical report'
43.313 + elif entrytype == 'mastersthesis':
43.314 + entrycont['type'] = 'Master\'s thesis'
43.315 + elif entrytype == 'phdthesis':
43.316 + entrycont['type'] = 'PhD thesis'
43.317 +
43.318 + for eline in entrycont:
43.319 + if eline != '':
43.320 + eline = latexreplacements(eline)
43.321 +
43.322 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
43.323 + entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
43.324 +
43.325 + if entrycont.has_key('author') and (entrycont['author'] != ''):
43.326 + entry.append(entrycont['author']['text'] + '.')
43.327 + if entrycont.has_key('title') and (entrycont['title'] != ''):
43.328 + entry.append(entrycont['title'] + '.')
43.329 + if entrycont.has_key('journal') and (entrycont['journal'] != ''):
43.330 + entry.append(entrycont['journal'] + ',')
43.331 + if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
43.332 + entry.append('In ' + entrycont['booktitle'] + ',')
43.333 + if entrycont.has_key('type') and (entrycont['type'] != ''):
43.334 + eline = entrycont['type']
43.335 + if entrycont.has_key('number') and (entrycont['number'] != ''):
43.336 + eline += ' ' + entrycont['number']
43.337 + eline += ','
43.338 + entry.append(eline)
43.339 + if entrycont.has_key('institution') and (entrycont['institution'] != ''):
43.340 + entry.append(entrycont['institution'] + ',')
43.341 + if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
43.342 + entry.append(entrycont['publisher'] + ',')
43.343 + if entrycont.has_key('school') and (entrycont['school'] != ''):
43.344 + entry.append(entrycont['school'] + ',')
43.345 + if entrycont.has_key('address') and (entrycont['address'] != ''):
43.346 + entry.append(entrycont['address'] + ',')
43.347 + if entrycont.has_key('edition') and (entrycont['edition'] != ''):
43.348 + entry.append(entrycont['edition'] + ' edition,')
43.349 + if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
43.350 + entry.append(entrycont['howpublished'] + ',')
43.351 + if entrycont.has_key('volume') and (entrycont['volume'] != ''):
43.352 + eline = entrycont['volume'];
43.353 + if entrycont.has_key('number') and (entrycont['number'] != ''):
43.354 + eline += '(' + entrycont['number'] + ')'
43.355 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
43.356 + eline += ':' + entrycont['pages']
43.357 + eline += ','
43.358 + entry.append(eline)
43.359 + else:
43.360 + if entrycont.has_key('pages') and (entrycont['pages'] != ''):
43.361 + entry.append('pages ' + entrycont['pages'] + ',')
43.362 + if entrycont.has_key('year') and (entrycont['year'] != ''):
43.363 + if entrycont.has_key('month') and (entrycont['month'] != ''):
43.364 + entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
43.365 + else:
43.366 + entry.append(entrycont['year'] + '.')
43.367 + if entrycont.has_key('note') and (entrycont['note'] != ''):
43.368 + entry.append(entrycont['note'] + '.')
43.369 + if entrycont.has_key('url') and (entrycont['url'] != ''):
43.370 + entry.append(entrycont['url'] + '.')
43.371 +
43.372 + # generate keys for sorting and for the output
43.373 + sortkey = ''
43.374 + bibkey = ''
43.375 + if entrycont.has_key('author'):
43.376 + for author in entrycont['author']['list']:
43.377 + sortkey += copychars(author, author.rfind(' ')+1, len(author))
43.378 + bibkey = entrycont['author']['abbrev']
43.379 + else:
43.380 + bibkey = 'x'
43.381 + if entrycont.has_key('year'):
43.382 + sortkey += entrycont['year']
43.383 + bibkey += entrycont['year'][-2:]
43.384 + if entrycont.has_key('title'):
43.385 + sortkey += entrycont['title']
43.386 + if entrycont.has_key('key'):
43.387 + sortkey = entrycont['key'] + sortkey
43.388 + bibkey = entrycont['key']
43.389 + entry.insert(0, sortkey)
43.390 + entry.insert(1, bibkey)
43.391 + entry.insert(2, entryid)
43.392 +
43.393 + # add the entry to the file contents
43.394 + filecont.append(entry)
43.395 +
43.396 + else:
43.397 + # field, publication info
43.398 + field = ''
43.399 + data = ''
43.400 +
43.401 + # field = {data} entries
43.402 + if bracedata_rex.match(line):
43.403 + field = bracefield_rex.sub('\g<1>', line)
43.404 + field = string.lower(field)
43.405 + data = bracedata_rex.sub('\g<2>', line)
43.406 +
43.407 + # field = "data" entries
43.408 + elif quotedata_rex.match(line):
43.409 + field = quotefield_rex.sub('\g<1>', line)
43.410 + field = string.lower(field)
43.411 + data = quotedata_rex.sub('\g<2>', line)
43.412 +
43.413 + # field = data entries
43.414 + elif data_rex.match(line):
43.415 + field = field_rex.sub('\g<1>', line)
43.416 + field = string.lower(field)
43.417 + data = data_rex.sub('\g<2>', line)
43.418 +
43.419 + if field == 'url':
43.420 + data = '\\url{' + data.strip() + '}'
43.421 +
43.422 + if field in ('author', 'editor'):
43.423 + entrycont[field] = bibtexauthor(data)
43.424 + line = ''
43.425 + elif field == 'title':
43.426 + line = bibtextitle(data, entrytype)
43.427 + elif field != '':
43.428 + line = removebraces(transformurls(data.strip()))
43.429 +
43.430 + if line != '':
43.431 + line = latexreplacements(line)
43.432 + entrycont[field] = line
43.433 +
43.434 +
43.435 + # sort entries
43.436 + filecont.sort(entry_cmp)
43.437 +
43.438 + # count the bibtex keys
43.439 + keytable = {}
43.440 + counttable = {}
43.441 + for entry in filecont:
43.442 + bibkey = entry[1]
43.443 + if not keytable.has_key(bibkey):
43.444 + keytable[bibkey] = 1
43.445 + else:
43.446 + keytable[bibkey] += 1
43.447 +
43.448 + for bibkey in keytable.keys():
43.449 + counttable[bibkey] = 0
43.450 +
43.451 + # generate output
43.452 + for entry in filecont:
43.453 + # generate output key form the bibtex key
43.454 + bibkey = entry[1]
43.455 + entryid = entry[2]
43.456 + if keytable[bibkey] == 1:
43.457 + outkey = bibkey
43.458 + else:
43.459 + outkey = bibkey + chr(97 + counttable[bibkey])
43.460 + counttable[bibkey] += 1
43.461 +
43.462 + # append the entry code to the output
43.463 + file.append('\\section ' + entryid + ' [' + outkey + ']')
43.464 + file.append('<div style="' + divstyle + '">')
43.465 + for line in entry[3:]:
43.466 + file.append(line)
43.467 + file.append('</div>')
43.468 + file.append('')
43.469 +
43.470 + return file
43.471 +
43.472 +
43.473 +#
43.474 +# return 1 iff abbr is in line but not inside braces or quotes
43.475 +# assumes that abbr appears only once on the line (out of braces and quotes)
43.476 +#
43.477 +def verify_out_of_braces(line, abbr):
43.478 +
43.479 + phrase_split = delimiter_rex.split(line)
43.480 +
43.481 + abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
43.482 +
43.483 + open_brace = 0
43.484 + open_quote = 0
43.485 +
43.486 + for phrase in phrase_split:
43.487 + if phrase == "{":
43.488 + open_brace = open_brace + 1
43.489 + elif phrase == "}":
43.490 + open_brace = open_brace - 1
43.491 + elif phrase == '"':
43.492 + if open_quote == 1:
43.493 + open_quote = 0
43.494 + else:
43.495 + open_quote = 1
43.496 + elif abbr_rex.search(phrase):
43.497 + if open_brace == 0 and open_quote == 0:
43.498 + return 1
43.499 +
43.500 + return 0
43.501 +
43.502 +
43.503 +#
43.504 +# a line in the form phrase1 # phrase2 # ... # phrasen
43.505 +# is returned as phrase1 phrase2 ... phrasen
43.506 +# with the correct punctuation
43.507 +# Bug: Doesn't always work with multiple abbreviations plugged in
43.508 +#
43.509 +def concat_line(line):
43.510 + # only look at part after equals
43.511 + field = field_rex.sub('\g<1>',line)
43.512 + rest = field_rex.sub('\g<2>',line)
43.513 +
43.514 + concat_line = field + ' ='
43.515 +
43.516 + pound_split = concatsplit_rex.split(rest)
43.517 +
43.518 + phrase_count = 0
43.519 + length = len(pound_split)
43.520 +
43.521 + for phrase in pound_split:
43.522 + phrase = phrase.strip()
43.523 + if phrase_count != 0:
43.524 + if phrase.startswith('"') or phrase.startswith('{'):
43.525 + phrase = phrase[1:]
43.526 + elif phrase.startswith('"'):
43.527 + phrase = phrase.replace('"','{',1)
43.528 +
43.529 + if phrase_count != length-1:
43.530 + if phrase.endswith('"') or phrase.endswith('}'):
43.531 + phrase = phrase[:-1]
43.532 + else:
43.533 + if phrase.endswith('"'):
43.534 + phrase = phrase[:-1]
43.535 + phrase = phrase + "}"
43.536 + elif phrase.endswith('",'):
43.537 + phrase = phrase[:-2]
43.538 + phrase = phrase + "},"
43.539 +
43.540 + # if phrase did have \#, add the \# back
43.541 + if phrase.endswith('\\'):
43.542 + phrase = phrase + "#"
43.543 + concat_line = concat_line + ' ' + phrase
43.544 +
43.545 + phrase_count = phrase_count + 1
43.546 +
43.547 + return concat_line
43.548 +
43.549 +
43.550 +#
43.551 +# substitute abbreviations into filecont
43.552 +# @param filecont_source - string of data from file
43.553 +#
43.554 +def bibtex_replace_abbreviations(filecont_source):
43.555 + filecont = filecont_source.splitlines()
43.556 +
43.557 + # These are defined in bibtex, so we'll define them too
43.558 + abbr_list = ['jan','feb','mar','apr','may','jun',
43.559 + 'jul','aug','sep','oct','nov','dec']
43.560 + value_list = ['January','February','March','April',
43.561 + 'May','June','July','August','September',
43.562 + 'October','November','December']
43.563 +
43.564 + abbr_rex = []
43.565 + total_abbr_count = 0
43.566 +
43.567 + front = '\\b'
43.568 + back = '(,?)\\b'
43.569 +
43.570 + for x in abbr_list:
43.571 + abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
43.572 + total_abbr_count = total_abbr_count + 1
43.573 +
43.574 +
43.575 + abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
43.576 + re.I)
43.577 +
43.578 + comment_rex = re.compile('@comment\s*{',re.I)
43.579 + preamble_rex = re.compile('@preamble\s*{',re.I)
43.580 +
43.581 + waiting_for_end_string = 0
43.582 + i = 0
43.583 + filecont2 = ''
43.584 +
43.585 + for line in filecont:
43.586 + if line == ' ' or line == '':
43.587 + continue
43.588 +
43.589 + if waiting_for_end_string:
43.590 + if re.search('}',line):
43.591 + waiting_for_end_string = 0
43.592 + continue
43.593 +
43.594 + if abbrdef_rex.search(line):
43.595 + abbr = abbrdef_rex.sub('\g<1>', line)
43.596 +
43.597 + if abbr_list.count(abbr) == 0:
43.598 + val = abbrdef_rex.sub('\g<2>', line)
43.599 + abbr_list.append(abbr)
43.600 + value_list.append(string.strip(val))
43.601 + abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
43.602 + total_abbr_count = total_abbr_count + 1
43.603 + waiting_for_end_string = 1
43.604 + continue
43.605 +
43.606 + if comment_rex.search(line):
43.607 + waiting_for_end_string = 1
43.608 + continue
43.609 +
43.610 + if preamble_rex.search(line):
43.611 + waiting_for_end_string = 1
43.612 + continue
43.613 +
43.614 +
43.615 + # replace subsequent abbreviations with the value
43.616 + abbr_count = 0
43.617 +
43.618 + for x in abbr_list:
43.619 +
43.620 + if abbr_rex[abbr_count].search(line):
43.621 + if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
43.622 + line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
43.623 + # Check for # concatenations
43.624 + if concatsplit_rex.search(line):
43.625 + line = concat_line(line)
43.626 + abbr_count = abbr_count + 1
43.627 +
43.628 +
43.629 + filecont2 = filecont2 + line + '\n'
43.630 + i = i+1
43.631 +
43.632 +
43.633 + # Do one final pass over file
43.634 +
43.635 + # make sure that didn't end up with {" or }" after the substitution
43.636 + filecont2 = filecont2.replace('{"','{{')
43.637 + filecont2 = filecont2.replace('"}','}}')
43.638 +
43.639 + afterquotevalue_rex = re.compile('"\s*,\s*')
43.640 + afterbrace_rex = re.compile('"\s*}')
43.641 + afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
43.642 +
43.643 + # add new lines to data that changed because of abbreviation substitutions
43.644 + filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
43.645 + filecont2 = afterbrace_rex.sub('"\n}', filecont2)
43.646 + filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
43.647 +
43.648 + return filecont2
43.649 +
43.650 +#
43.651 +# convert @type( ... ) to @type{ ... }
43.652 +#
43.653 +def no_outer_parens(filecont):
43.654 +
43.655 + # do checking for open parens
43.656 + # will convert to braces
43.657 + paren_split = re.split('([(){}])',filecont)
43.658 +
43.659 + open_paren_count = 0
43.660 + open_type = 0
43.661 + look_next = 0
43.662 +
43.663 + # rebuild filecont
43.664 + filecont = ''
43.665 +
43.666 + at_rex = re.compile('@\w*')
43.667 +
43.668 + for phrase in paren_split:
43.669 + if look_next == 1:
43.670 + if phrase == '(':
43.671 + phrase = '{'
43.672 + open_paren_count = open_paren_count + 1
43.673 + else:
43.674 + open_type = 0
43.675 + look_next = 0
43.676 +
43.677 + if phrase == '(':
43.678 + open_paren_count = open_paren_count + 1
43.679 +
43.680 + elif phrase == ')':
43.681 + open_paren_count = open_paren_count - 1
43.682 + if open_type == 1 and open_paren_count == 0:
43.683 + phrase = '}'
43.684 + open_type = 0
43.685 +
43.686 + elif at_rex.search( phrase ):
43.687 + open_type = 1
43.688 + look_next = 1
43.689 +
43.690 + filecont = filecont + phrase
43.691 +
43.692 + return filecont
43.693 +
43.694 +
43.695 +#
43.696 +# make all whitespace into just one space
43.697 +# format the bibtex file into a usable form.
43.698 +#
43.699 +def bibtexwasher(filecont_source):
43.700 +
43.701 + space_rex = re.compile('\s+')
43.702 + comment_rex = re.compile('\s*%')
43.703 +
43.704 + filecont = []
43.705 +
43.706 + # remove trailing and excessive whitespace
43.707 + # ignore comments
43.708 + for line in filecont_source:
43.709 + line = string.strip(line)
43.710 + line = space_rex.sub(' ', line)
43.711 + # ignore comments
43.712 + if not comment_rex.match(line) and line != '':
43.713 + filecont.append(' '+ line)
43.714 +
43.715 + filecont = string.join(filecont, '')
43.716 +
43.717 + # the file is in one long string
43.718 +
43.719 + filecont = no_outer_parens(filecont)
43.720 +
43.721 + #
43.722 + # split lines according to preferred syntax scheme
43.723 + #
43.724 + filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
43.725 +
43.726 + # add new lines after commas that are after values
43.727 + filecont = re.sub('"\s*,', '",\n', filecont)
43.728 + filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
43.729 + filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
43.730 + '\n\n\g<1>\g<2>,\n', filecont)
43.731 +
43.732 + # add new lines after }
43.733 + filecont = re.sub('"\s*}','"\n}\n', filecont)
43.734 + filecont = re.sub('}\s*,','},\n', filecont)
43.735 +
43.736 +
43.737 + filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
43.738 +
43.739 + # character encoding, reserved latex characters
43.740 + filecont = re.sub('{\\\&}', '&', filecont)
43.741 + filecont = re.sub('\\\&', '&', filecont)
43.742 +
43.743 + # do checking for open braces to get format correct
43.744 + open_brace_count = 0
43.745 + brace_split = re.split('([{}])',filecont)
43.746 +
43.747 + # rebuild filecont
43.748 + filecont = ''
43.749 +
43.750 + for phrase in brace_split:
43.751 + if phrase == '{':
43.752 + open_brace_count = open_brace_count + 1
43.753 + elif phrase == '}':
43.754 + open_brace_count = open_brace_count - 1
43.755 + if open_brace_count == 0:
43.756 + filecont = filecont + '\n'
43.757 +
43.758 + filecont = filecont + phrase
43.759 +
43.760 + filecont2 = bibtex_replace_abbreviations(filecont)
43.761 +
43.762 + # gather
43.763 + filecont = filecont2.splitlines()
43.764 + i=0
43.765 + j=0 # count the number of blank lines
43.766 + for line in filecont:
43.767 + # ignore blank lines
43.768 + if line == '' or line == ' ':
43.769 + j = j+1
43.770 + continue
43.771 + filecont[i] = line + '\n'
43.772 + i = i+1
43.773 +
43.774 + # get rid of the extra stuff at the end of the array
43.775 + # (The extra stuff are duplicates that are in the array because
43.776 + # blank lines were removed.)
43.777 + length = len( filecont)
43.778 + filecont[length-j:length] = []
43.779 +
43.780 + return filecont
43.781 +
43.782 +
43.783 +def filehandler(filepath):
43.784 + try:
43.785 + fd = open(filepath, 'r')
43.786 + filecont_source = fd.readlines()
43.787 + fd.close()
43.788 + except:
43.789 + print 'Could not open file:', filepath
43.790 + washeddata = bibtexwasher(filecont_source)
43.791 + outdata = bibtexdecoder(washeddata)
43.792 + print '/**'
43.793 + print '\page references References'
43.794 + print
43.795 + for line in outdata:
43.796 + print line
43.797 + print '*/'
43.798 +
43.799 +
43.800 +# main program
43.801 +
43.802 +def main():
43.803 + import sys
43.804 + if sys.argv[1:]:
43.805 + filepath = sys.argv[1]
43.806 + else:
43.807 + print "No input file"
43.808 + sys.exit()
43.809 + filehandler(filepath)
43.810 +
43.811 +if __name__ == "__main__": main()
43.812 +
43.813 +
43.814 +# end python script
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/scripts/bootstrap.sh Thu Nov 05 10:27:17 2009 +0100
44.3 @@ -0,0 +1,134 @@
44.4 +#!/bin/bash
44.5 +#
44.6 +# This file is a part of LEMON, a generic C++ optimization library.
44.7 +#
44.8 +# Copyright (C) 2003-2009
44.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
44.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
44.11 +#
44.12 +# Permission to use, modify and distribute this software is granted
44.13 +# provided that this copyright notice appears in all copies. For
44.14 +# precise terms see the accompanying LICENSE file.
44.15 +#
44.16 +# This software is provided "AS IS" with no warranty of any kind,
44.17 +# express or implied, and with no claim as to its suitability for any
44.18 +# purpose.
44.19 +
44.20 +
44.21 +if [ ! -f ~/.lemon-bootstrap ]; then
44.22 + echo 'Create ~/.lemon-bootstrap'.
44.23 + cat >~/.lemon-bootstrap <<EOF
44.24 +#
44.25 +# Default settings for bootstraping the LEMON source code repository
44.26 +#
44.27 +EOF
44.28 +fi
44.29 +
44.30 +source ~/.lemon-bootstrap
44.31 +if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
44.32 +if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
44.33 +if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
44.34 +if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
44.35 +
44.36 +
44.37 +function augment_config() {
44.38 + if [ "x${!1}" == "x" ]; then
44.39 + eval $1=$2
44.40 + echo Add "'$1'" to '~/.lemon-bootstrap'.
44.41 + echo >>~/.lemon-bootstrap
44.42 + echo $3 >>~/.lemon-bootstrap
44.43 + echo $1=$2 >>~/.lemon-bootstrap
44.44 + fi
44.45 +}
44.46 +
44.47 +augment_config LEMON_INSTALL_PREFIX /usr/local \
44.48 + "# LEMON installation prefix"
44.49 +
44.50 +augment_config COIN_OR_PREFIX /usr/local/coin-or \
44.51 + "# COIN-OR installation root prefix (used for CLP/CBC)"
44.52 +
44.53 +augment_config SOPLEX_PREFIX /usr/local/soplex \
44.54 + "# Soplex build prefix"
44.55 +
44.56 +
44.57 +function ask() {
44.58 +echo -n "$1 [$2]? "
44.59 +read _an
44.60 +if [ "x$_an" == "x" ]; then
44.61 + ret="$2"
44.62 +else
44.63 + ret=$_an
44.64 +fi
44.65 +}
44.66 +
44.67 +function yesorno() {
44.68 + ret='rossz'
44.69 + while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
44.70 + ask "$1" "$2"
44.71 + done
44.72 + if [ "$ret" != "y" -a "$ret" != "yes" ]; then
44.73 + return 1
44.74 + else
44.75 + return 0
44.76 + fi
44.77 +}
44.78 +
44.79 +if yesorno "External build" "n"
44.80 +then
44.81 + CONFIGURE_PATH=".."
44.82 +else
44.83 + CONFIGURE_PATH="."
44.84 + if yesorno "Autoreconf" "y"
44.85 + then
44.86 + AUTORE=yes
44.87 + else
44.88 + AUTORE=no
44.89 + fi
44.90 +fi
44.91 +
44.92 +if yesorno "Optimize" "n"
44.93 +then
44.94 + opt_flags=' -O2'
44.95 +else
44.96 + opt_flags=''
44.97 +fi
44.98 +
44.99 +if yesorno "Stop on warning" "y"
44.100 +then
44.101 + werror_flags=' -Werror'
44.102 +else
44.103 + werror_flags=''
44.104 +fi
44.105 +
44.106 +cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
44.107 +
44.108 +if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
44.109 + if yesorno "Use COIN-OR (CBC/CLP)" "n"
44.110 + then
44.111 + coin_flag="--with-coin=$COIN_OR_PREFIX"
44.112 + else
44.113 + coin_flag=""
44.114 + fi
44.115 +else
44.116 + coin_flag=""
44.117 +fi
44.118 +
44.119 +if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
44.120 + if yesorno "Use Soplex" "n"
44.121 + then
44.122 + soplex_flag="--with-soplex=$SOPLEX_PREFIX"
44.123 + else
44.124 + soplex_flag=""
44.125 + fi
44.126 +else
44.127 + soplex_flag=""
44.128 +fi
44.129 +
44.130 +if [ "x$AUTORE" == "xyes" ]; then
44.131 + autoreconf -vif;
44.132 +fi
44.133 +${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
44.134 +"$cxx_flags" \
44.135 +$coin_flag \
44.136 +$soplex_flag \
44.137 +$*
45.1 --- a/scripts/chg-len.py Mon Sep 28 15:53:20 2009 +0200
45.2 +++ b/scripts/chg-len.py Thu Nov 05 10:27:17 2009 +0100
45.3 @@ -1,4 +1,18 @@
45.4 #! /usr/bin/env python
45.5 +#
45.6 +# This file is a part of LEMON, a generic C++ optimization library.
45.7 +#
45.8 +# Copyright (C) 2003-2009
45.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
45.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
45.11 +#
45.12 +# Permission to use, modify and distribute this software is granted
45.13 +# provided that this copyright notice appears in all copies. For
45.14 +# precise terms see the accompanying LICENSE file.
45.15 +#
45.16 +# This software is provided "AS IS" with no warranty of any kind,
45.17 +# express or implied, and with no claim as to its suitability for any
45.18 +# purpose.
45.19
45.20 import sys
45.21
46.1 --- a/scripts/mk-release.sh Mon Sep 28 15:53:20 2009 +0200
46.2 +++ b/scripts/mk-release.sh Thu Nov 05 10:27:17 2009 +0100
46.3 @@ -1,4 +1,18 @@
46.4 #!/bin/bash
46.5 +#
46.6 +# This file is a part of LEMON, a generic C++ optimization library.
46.7 +#
46.8 +# Copyright (C) 2003-2009
46.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
46.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
46.11 +#
46.12 +# Permission to use, modify and distribute this software is granted
46.13 +# provided that this copyright notice appears in all copies. For
46.14 +# precise terms see the accompanying LICENSE file.
46.15 +#
46.16 +# This software is provided "AS IS" with no warranty of any kind,
46.17 +# express or implied, and with no claim as to its suitability for any
46.18 +# purpose.
46.19
46.20 set -e
46.21
47.1 --- a/scripts/unify-sources.sh Mon Sep 28 15:53:20 2009 +0200
47.2 +++ b/scripts/unify-sources.sh Thu Nov 05 10:27:17 2009 +0100
47.3 @@ -1,4 +1,18 @@
47.4 #!/bin/bash
47.5 +#
47.6 +# This file is a part of LEMON, a generic C++ optimization library.
47.7 +#
47.8 +# Copyright (C) 2003-2009
47.9 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
47.10 +# (Egervary Research Group on Combinatorial Optimization, EGRES).
47.11 +#
47.12 +# Permission to use, modify and distribute this software is granted
47.13 +# provided that this copyright notice appears in all copies. For
47.14 +# precise terms see the accompanying LICENSE file.
47.15 +#
47.16 +# This software is provided "AS IS" with no warranty of any kind,
47.17 +# express or implied, and with no claim as to its suitability for any
47.18 +# purpose.
47.19
47.20 YEAR=`date +%Y`
47.21 HGROOT=`hg root`
48.1 --- a/test/CMakeLists.txt Mon Sep 28 15:53:20 2009 +0200
48.2 +++ b/test/CMakeLists.txt Thu Nov 05 10:27:17 2009 +0100
48.3 @@ -32,6 +32,7 @@
48.4 matching_test
48.5 min_cost_arborescence_test
48.6 min_cost_flow_test
48.7 + min_mean_cycle_test
48.8 path_test
48.9 preflow_test
48.10 radix_sort_test
49.1 --- a/test/Makefile.am Mon Sep 28 15:53:20 2009 +0200
49.2 +++ b/test/Makefile.am Thu Nov 05 10:27:17 2009 +0100
49.3 @@ -30,6 +30,7 @@
49.4 test/matching_test \
49.5 test/min_cost_arborescence_test \
49.6 test/min_cost_flow_test \
49.7 + test/min_mean_cycle_test \
49.8 test/path_test \
49.9 test/preflow_test \
49.10 test/radix_sort_test \
49.11 @@ -78,6 +79,7 @@
49.12 test_matching_test_SOURCES = test/matching_test.cc
49.13 test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
49.14 test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
49.15 +test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
49.16 test_path_test_SOURCES = test/path_test.cc
49.17 test_preflow_test_SOURCES = test/preflow_test.cc
49.18 test_radix_sort_test_SOURCES = test/radix_sort_test.cc
50.1 --- a/test/digraph_test.cc Mon Sep 28 15:53:20 2009 +0200
50.2 +++ b/test/digraph_test.cc Thu Nov 05 10:27:17 2009 +0100
50.3 @@ -19,6 +19,7 @@
50.4 #include <lemon/concepts/digraph.h>
50.5 #include <lemon/list_graph.h>
50.6 #include <lemon/smart_graph.h>
50.7 +#include <lemon/static_graph.h>
50.8 #include <lemon/full_graph.h>
50.9
50.10 #include "test_tools.h"
50.11 @@ -35,6 +36,9 @@
50.12 checkGraphNodeList(G, 0);
50.13 checkGraphArcList(G, 0);
50.14
50.15 + G.reserveNode(3);
50.16 + G.reserveArc(4);
50.17 +
50.18 Node
50.19 n1 = G.addNode(),
50.20 n2 = G.addNode(),
50.21 @@ -283,6 +287,14 @@
50.22 G.addArc(G.addNode(), G.addNode());
50.23
50.24 snapshot.restore();
50.25 + snapshot.save(G);
50.26 +
50.27 + checkGraphNodeList(G, 4);
50.28 + checkGraphArcList(G, 4);
50.29 +
50.30 + G.addArc(G.addNode(), G.addNode());
50.31 +
50.32 + snapshot.restore();
50.33
50.34 checkGraphNodeList(G, 4);
50.35 checkGraphArcList(G, 4);
50.36 @@ -317,6 +329,10 @@
50.37 checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
50.38 checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
50.39 }
50.40 + { // Checking StaticDigraph
50.41 + checkConcept<Digraph, StaticDigraph>();
50.42 + checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
50.43 + }
50.44 { // Checking FullDigraph
50.45 checkConcept<Digraph, FullDigraph>();
50.46 }
50.47 @@ -372,10 +388,122 @@
50.48 check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
50.49 }
50.50
50.51 +void checkStaticDigraph() {
50.52 + SmartDigraph g;
50.53 + SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
50.54 + SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
50.55 +
50.56 + StaticDigraph G;
50.57 +
50.58 + checkGraphNodeList(G, 0);
50.59 + checkGraphArcList(G, 0);
50.60 +
50.61 + G.build(g, nref, aref);
50.62 +
50.63 + checkGraphNodeList(G, 0);
50.64 + checkGraphArcList(G, 0);
50.65 +
50.66 + SmartDigraph::Node
50.67 + n1 = g.addNode(),
50.68 + n2 = g.addNode(),
50.69 + n3 = g.addNode();
50.70 +
50.71 + G.build(g, nref, aref);
50.72 +
50.73 + checkGraphNodeList(G, 3);
50.74 + checkGraphArcList(G, 0);
50.75 +
50.76 + SmartDigraph::Arc a1 = g.addArc(n1, n2);
50.77 +
50.78 + G.build(g, nref, aref);
50.79 +
50.80 + check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
50.81 + "Wrong arc or wrong references");
50.82 + checkGraphNodeList(G, 3);
50.83 + checkGraphArcList(G, 1);
50.84 +
50.85 + checkGraphOutArcList(G, nref[n1], 1);
50.86 + checkGraphOutArcList(G, nref[n2], 0);
50.87 + checkGraphOutArcList(G, nref[n3], 0);
50.88 +
50.89 + checkGraphInArcList(G, nref[n1], 0);
50.90 + checkGraphInArcList(G, nref[n2], 1);
50.91 + checkGraphInArcList(G, nref[n3], 0);
50.92 +
50.93 + checkGraphConArcList(G, 1);
50.94 +
50.95 + SmartDigraph::Arc
50.96 + a2 = g.addArc(n2, n1),
50.97 + a3 = g.addArc(n2, n3),
50.98 + a4 = g.addArc(n2, n3);
50.99 +
50.100 + digraphCopy(g, G).nodeRef(nref).run();
50.101 +
50.102 + checkGraphNodeList(G, 3);
50.103 + checkGraphArcList(G, 4);
50.104 +
50.105 + checkGraphOutArcList(G, nref[n1], 1);
50.106 + checkGraphOutArcList(G, nref[n2], 3);
50.107 + checkGraphOutArcList(G, nref[n3], 0);
50.108 +
50.109 + checkGraphInArcList(G, nref[n1], 1);
50.110 + checkGraphInArcList(G, nref[n2], 1);
50.111 + checkGraphInArcList(G, nref[n3], 2);
50.112 +
50.113 + checkGraphConArcList(G, 4);
50.114 +
50.115 + std::vector<std::pair<int,int> > arcs;
50.116 + arcs.push_back(std::make_pair(0,1));
50.117 + arcs.push_back(std::make_pair(0,2));
50.118 + arcs.push_back(std::make_pair(1,3));
50.119 + arcs.push_back(std::make_pair(1,2));
50.120 + arcs.push_back(std::make_pair(3,0));
50.121 + arcs.push_back(std::make_pair(3,3));
50.122 + arcs.push_back(std::make_pair(4,2));
50.123 + arcs.push_back(std::make_pair(4,3));
50.124 + arcs.push_back(std::make_pair(4,1));
50.125 +
50.126 + G.build(6, arcs.begin(), arcs.end());
50.127 +
50.128 + checkGraphNodeList(G, 6);
50.129 + checkGraphArcList(G, 9);
50.130 +
50.131 + checkGraphOutArcList(G, G.node(0), 2);
50.132 + checkGraphOutArcList(G, G.node(1), 2);
50.133 + checkGraphOutArcList(G, G.node(2), 0);
50.134 + checkGraphOutArcList(G, G.node(3), 2);
50.135 + checkGraphOutArcList(G, G.node(4), 3);
50.136 + checkGraphOutArcList(G, G.node(5), 0);
50.137 +
50.138 + checkGraphInArcList(G, G.node(0), 1);
50.139 + checkGraphInArcList(G, G.node(1), 2);
50.140 + checkGraphInArcList(G, G.node(2), 3);
50.141 + checkGraphInArcList(G, G.node(3), 3);
50.142 + checkGraphInArcList(G, G.node(4), 0);
50.143 + checkGraphInArcList(G, G.node(5), 0);
50.144 +
50.145 + checkGraphConArcList(G, 9);
50.146 +
50.147 + checkNodeIds(G);
50.148 + checkArcIds(G);
50.149 + checkGraphNodeMap(G);
50.150 + checkGraphArcMap(G);
50.151 +
50.152 + int n = G.nodeNum();
50.153 + int m = G.arcNum();
50.154 + check(G.index(G.node(n-1)) == n-1, "Wrong index.");
50.155 + check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
50.156 +}
50.157 +
50.158 void checkFullDigraph(int num) {
50.159 typedef FullDigraph Digraph;
50.160 DIGRAPH_TYPEDEFS(Digraph);
50.161 +
50.162 Digraph G(num);
50.163 + check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
50.164 +
50.165 + G.resize(num);
50.166 + check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
50.167
50.168 checkGraphNodeList(G, num);
50.169 checkGraphArcList(G, num * num);
50.170 @@ -419,6 +547,9 @@
50.171 checkDigraphSnapshot<SmartDigraph>();
50.172 checkDigraphValidity<SmartDigraph>();
50.173 }
50.174 + { // Checking StaticDigraph
50.175 + checkStaticDigraph();
50.176 + }
50.177 { // Checking FullDigraph
50.178 checkFullDigraph(8);
50.179 }
51.1 --- a/test/graph_test.cc Mon Sep 28 15:53:20 2009 +0200
51.2 +++ b/test/graph_test.cc Thu Nov 05 10:27:17 2009 +0100
51.3 @@ -38,6 +38,9 @@
51.4 checkGraphEdgeList(G, 0);
51.5 checkGraphArcList(G, 0);
51.6
51.7 + G.reserveNode(3);
51.8 + G.reserveEdge(3);
51.9 +
51.10 Node
51.11 n1 = G.addNode(),
51.12 n2 = G.addNode(),
51.13 @@ -256,6 +259,15 @@
51.14 G.addEdge(G.addNode(), G.addNode());
51.15
51.16 snapshot.restore();
51.17 + snapshot.save(G);
51.18 +
51.19 + checkGraphNodeList(G, 4);
51.20 + checkGraphEdgeList(G, 3);
51.21 + checkGraphArcList(G, 6);
51.22 +
51.23 + G.addEdge(G.addNode(), G.addNode());
51.24 +
51.25 + snapshot.restore();
51.26
51.27 checkGraphNodeList(G, 4);
51.28 checkGraphEdgeList(G, 3);
51.29 @@ -267,6 +279,13 @@
51.30 GRAPH_TYPEDEFS(Graph);
51.31
51.32 Graph G(num);
51.33 + check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
51.34 + "Wrong size");
51.35 +
51.36 + G.resize(num);
51.37 + check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
51.38 + "Wrong size");
51.39 +
51.40 checkGraphNodeList(G, num);
51.41 checkGraphEdgeList(G, num * (num - 1) / 2);
51.42
51.43 @@ -411,6 +430,10 @@
51.44 check(G.width() == width, "Wrong column number");
51.45 check(G.height() == height, "Wrong row number");
51.46
51.47 + G.resize(width, height);
51.48 + check(G.width() == width, "Wrong column number");
51.49 + check(G.height() == height, "Wrong row number");
51.50 +
51.51 for (int i = 0; i < width; ++i) {
51.52 for (int j = 0; j < height; ++j) {
51.53 check(G.col(G(i, j)) == i, "Wrong column");
51.54 @@ -486,6 +509,11 @@
51.55 GRAPH_TYPEDEFS(HypercubeGraph);
51.56
51.57 HypercubeGraph G(dim);
51.58 + check(G.dimension() == dim, "Wrong dimension");
51.59 +
51.60 + G.resize(dim);
51.61 + check(G.dimension() == dim, "Wrong dimension");
51.62 +
51.63 checkGraphNodeList(G, 1 << dim);
51.64 checkGraphEdgeList(G, dim * (1 << (dim-1)));
51.65 checkGraphArcList(G, dim * (1 << dim));
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52.2 +++ b/test/min_mean_cycle_test.cc Thu Nov 05 10:27:17 2009 +0100
52.3 @@ -0,0 +1,216 @@
52.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
52.5 + *
52.6 + * This file is a part of LEMON, a generic C++ optimization library.
52.7 + *
52.8 + * Copyright (C) 2003-2009
52.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
52.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
52.11 + *
52.12 + * Permission to use, modify and distribute this software is granted
52.13 + * provided that this copyright notice appears in all copies. For
52.14 + * precise terms see the accompanying LICENSE file.
52.15 + *
52.16 + * This software is provided "AS IS" with no warranty of any kind,
52.17 + * express or implied, and with no claim as to its suitability for any
52.18 + * purpose.
52.19 + *
52.20 + */
52.21 +
52.22 +#include <iostream>
52.23 +#include <sstream>
52.24 +
52.25 +#include <lemon/smart_graph.h>
52.26 +#include <lemon/lgf_reader.h>
52.27 +#include <lemon/path.h>
52.28 +#include <lemon/concepts/digraph.h>
52.29 +#include <lemon/concept_check.h>
52.30 +
52.31 +#include <lemon/karp.h>
52.32 +#include <lemon/hartmann_orlin.h>
52.33 +#include <lemon/howard.h>
52.34 +
52.35 +#include "test_tools.h"
52.36 +
52.37 +using namespace lemon;
52.38 +
52.39 +char test_lgf[] =
52.40 + "@nodes\n"
52.41 + "label\n"
52.42 + "1\n"
52.43 + "2\n"
52.44 + "3\n"
52.45 + "4\n"
52.46 + "5\n"
52.47 + "6\n"
52.48 + "7\n"
52.49 + "@arcs\n"
52.50 + " len1 len2 len3 len4 c1 c2 c3 c4\n"
52.51 + "1 2 1 1 1 1 0 0 0 0\n"
52.52 + "2 4 5 5 5 5 1 0 0 0\n"
52.53 + "2 3 8 8 8 8 0 0 0 0\n"
52.54 + "3 2 -2 0 0 0 1 0 0 0\n"
52.55 + "3 4 4 4 4 4 0 0 0 0\n"
52.56 + "3 7 -4 -4 -4 -4 0 0 0 0\n"
52.57 + "4 1 2 2 2 2 0 0 0 0\n"
52.58 + "4 3 3 3 3 3 1 0 0 0\n"
52.59 + "4 4 3 3 0 0 0 0 1 0\n"
52.60 + "5 2 4 4 4 4 0 0 0 0\n"
52.61 + "5 6 3 3 3 3 0 1 0 0\n"
52.62 + "6 5 2 2 2 2 0 1 0 0\n"
52.63 + "6 4 -1 -1 -1 -1 0 0 0 0\n"
52.64 + "6 7 1 1 1 1 0 0 0 0\n"
52.65 + "7 7 4 4 4 -1 0 0 0 1\n";
52.66 +
52.67 +
52.68 +// Check the interface of an MMC algorithm
52.69 +template <typename GR, typename Value>
52.70 +struct MmcClassConcept
52.71 +{
52.72 + template <typename MMC>
52.73 + struct Constraints {
52.74 + void constraints() {
52.75 + const Constraints& me = *this;
52.76 +
52.77 + typedef typename MMC
52.78 + ::template SetPath<ListPath<GR> >
52.79 + ::template SetLargeValue<Value>
52.80 + ::Create MmcAlg;
52.81 + MmcAlg mmc(me.g, me.length);
52.82 + const MmcAlg& const_mmc = mmc;
52.83 +
52.84 + typename MmcAlg::Tolerance tol = const_mmc.tolerance();
52.85 + mmc.tolerance(tol);
52.86 +
52.87 + b = mmc.cycle(p).run();
52.88 + b = mmc.findMinMean();
52.89 + b = mmc.findCycle();
52.90 +
52.91 + v = const_mmc.cycleLength();
52.92 + i = const_mmc.cycleArcNum();
52.93 + d = const_mmc.cycleMean();
52.94 + p = const_mmc.cycle();
52.95 + }
52.96 +
52.97 + typedef concepts::ReadMap<typename GR::Arc, Value> LM;
52.98 +
52.99 + GR g;
52.100 + LM length;
52.101 + ListPath<GR> p;
52.102 + Value v;
52.103 + int i;
52.104 + double d;
52.105 + bool b;
52.106 + };
52.107 +};
52.108 +
52.109 +// Perform a test with the given parameters
52.110 +template <typename MMC>
52.111 +void checkMmcAlg(const SmartDigraph& gr,
52.112 + const SmartDigraph::ArcMap<int>& lm,
52.113 + const SmartDigraph::ArcMap<int>& cm,
52.114 + int length, int size) {
52.115 + MMC alg(gr, lm);
52.116 + alg.findMinMean();
52.117 + check(alg.cycleMean() == static_cast<double>(length) / size,
52.118 + "Wrong cycle mean");
52.119 + alg.findCycle();
52.120 + check(alg.cycleLength() == length && alg.cycleArcNum() == size,
52.121 + "Wrong path");
52.122 + SmartDigraph::ArcMap<int> cycle(gr, 0);
52.123 + for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
52.124 + ++cycle[a];
52.125 + }
52.126 + for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
52.127 + check(cm[a] == cycle[a], "Wrong path");
52.128 + }
52.129 +}
52.130 +
52.131 +// Class for comparing types
52.132 +template <typename T1, typename T2>
52.133 +struct IsSameType {
52.134 + static const int result = 0;
52.135 +};
52.136 +
52.137 +template <typename T>
52.138 +struct IsSameType<T,T> {
52.139 + static const int result = 1;
52.140 +};
52.141 +
52.142 +
52.143 +int main() {
52.144 + #ifdef LEMON_HAVE_LONG_LONG
52.145 + typedef long long long_int;
52.146 + #else
52.147 + typedef long long_int;
52.148 + #endif
52.149 +
52.150 + // Check the interface
52.151 + {
52.152 + typedef concepts::Digraph GR;
52.153 +
52.154 + // Karp
52.155 + checkConcept< MmcClassConcept<GR, int>,
52.156 + Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
52.157 + checkConcept< MmcClassConcept<GR, float>,
52.158 + Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
52.159 +
52.160 + // HartmannOrlin
52.161 + checkConcept< MmcClassConcept<GR, int>,
52.162 + HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
52.163 + checkConcept< MmcClassConcept<GR, float>,
52.164 + HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
52.165 +
52.166 + // Howard
52.167 + checkConcept< MmcClassConcept<GR, int>,
52.168 + Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
52.169 + checkConcept< MmcClassConcept<GR, float>,
52.170 + Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
52.171 +
52.172 + if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
52.173 + long_int>::result == 0) check(false, "Wrong LargeValue type");
52.174 + if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
52.175 + double>::result == 0) check(false, "Wrong LargeValue type");
52.176 + }
52.177 +
52.178 + // Run various tests
52.179 + {
52.180 + typedef SmartDigraph GR;
52.181 + DIGRAPH_TYPEDEFS(GR);
52.182 +
52.183 + GR gr;
52.184 + IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
52.185 + IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
52.186 +
52.187 + std::istringstream input(test_lgf);
52.188 + digraphReader(gr, input).
52.189 + arcMap("len1", l1).
52.190 + arcMap("len2", l2).
52.191 + arcMap("len3", l3).
52.192 + arcMap("len4", l4).
52.193 + arcMap("c1", c1).
52.194 + arcMap("c2", c2).
52.195 + arcMap("c3", c3).
52.196 + arcMap("c4", c4).
52.197 + run();
52.198 +
52.199 + // Karp
52.200 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1, 6, 3);
52.201 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2, 5, 2);
52.202 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3, 0, 1);
52.203 + checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
52.204 +
52.205 + // HartmannOrlin
52.206 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1, 6, 3);
52.207 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2, 5, 2);
52.208 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3, 0, 1);
52.209 + checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
52.210 +
52.211 + // Howard
52.212 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1, 6, 3);
52.213 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2, 5, 2);
52.214 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3, 0, 1);
52.215 + checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
52.216 + }
52.217 +
52.218 + return 0;
52.219 +}
53.1 --- a/test/mip_test.cc Mon Sep 28 15:53:20 2009 +0200
53.2 +++ b/test/mip_test.cc Thu Nov 05 10:27:17 2009 +0100
53.3 @@ -50,7 +50,8 @@
53.4
53.5 if (stat == MipSolver::OPTIMAL) {
53.6 std::ostringstream sbuf;
53.7 - buf << "Wrong optimal value: the right optimum is " << exp_opt;
53.8 + sbuf << "Wrong optimal value ("<< mip.solValue()
53.9 + <<" instead of " << exp_opt << ")";
53.10 check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
53.11 //+ecvt(exp_opt,2)
53.12 }
54.1 --- a/test/test_tools.h Mon Sep 28 15:53:20 2009 +0200
54.2 +++ b/test/test_tools.h Thu Nov 05 10:27:17 2009 +0100
54.3 @@ -37,10 +37,14 @@
54.4 ///\code check(0==1,"This is obviously false.");\endcode will
54.5 ///print something like this (and then exits).
54.6 ///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
54.7 -#define check(rc, msg) \
54.8 - if(!(rc)) { \
54.9 - std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
54.10 - abort(); \
54.11 - } else { } \
54.12 +#define check(rc, msg) \
54.13 + { \
54.14 + if(!(rc)) { \
54.15 + std::cerr << __FILE__ ":" << __LINE__ << ": error: " \
54.16 + << msg << std::endl; \
54.17 + abort(); \
54.18 + } else { } \
54.19 + } \
54.20 +
54.21
54.22 #endif