Changes in / [1166:d59484d5fc1f:1165:16f55008c863] in lemon
- Files:
-
- 17 added
- 1 deleted
- 43 edited
Legend:
- Unmodified
- Added
- Removed
-
AUTHORS
r1148 r1072 1 The main developers of release series 1.xare1 The authors of the 1.x series are 2 2 3 3 * Balazs Dezso <deba@inf.elte.hu> … … 6 6 * Akos Ladanyi <ladanyi@tmit.bme.hu> 7 7 8 For more complete list of contributors, please visit the history of9 the LEMON source code repository: http://lemon.cs.elte.hu/hg/lemon8 For more details on the actual contribution, please visit the history 9 of the main LEMON source repository: http://lemon.cs.elte.hu/hg/lemon 10 10 11 Moreover, this version is heavily based on version 0.x of LEMON. Here12 is the list of people who contributed to those versions.11 Moreover, this version is heavily based on the 0.x series of 12 LEMON. Here is the list of people who contributed to those versions. 13 13 14 14 * Mihaly Barasz <klao@cs.elte.hu> -
CMakeLists.txt
r1162 r1132 13 13 ELSE() 14 14 EXECUTE_PROCESS( 15 COMMAND 16 hg log -r. --template "{latesttag}" 15 COMMAND ${PYTHON_EXECUTABLE} ./scripts/chg-len.py 17 16 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 18 OUTPUT_VARIABLE HG_REVISION_ TAG17 OUTPUT_VARIABLE HG_REVISION_PATH 19 18 ERROR_QUIET 20 19 OUTPUT_STRIP_TRAILING_WHITESPACE 21 20 ) 22 21 EXECUTE_PROCESS( 23 COMMAND 24 hg log -r. --template "{latesttagdistance}" 22 COMMAND hg id -i 25 23 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 26 OUTPUT_VARIABLE HG_REVISION _DIST24 OUTPUT_VARIABLE HG_REVISION 27 25 ERROR_QUIET 28 26 OUTPUT_STRIP_TRAILING_WHITESPACE 29 27 ) 30 EXECUTE_PROCESS( 31 COMMAND 32 hg log -r. --template "{node|short}" 33 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 34 OUTPUT_VARIABLE HG_REVISION_ID 35 ERROR_QUIET 36 OUTPUT_STRIP_TRAILING_WHITESPACE 37 ) 38 39 IF(HG_REVISION_TAG STREQUAL "") 28 IF(HG_REVISION STREQUAL "") 40 29 SET(HG_REVISION_ID "hg-tip") 41 30 ELSE() 42 IF(HG_REVISION_TAG STREQUAL "null") 43 SET(HG_REVISION_TAG "trunk") 44 ELSEIF(HG_REVISION_TAG MATCHES "^r") 45 STRING(SUBSTRING ${HG_REVISION_TAG} 1 -1 HG_REVISION_TAG) 46 ENDIF() 47 IF(HG_REVISION_DIST STREQUAL "0") 48 SET(HG_REVISION ${HG_REVISION_TAG}) 31 IF(HG_REVISION_PATH STREQUAL "") 32 SET(HG_REVISION_ID ${HG_REVISION}) 49 33 ELSE() 50 SET(HG_REVISION 51 "${HG_REVISION_TAG}+${HG_REVISION_DIST}-${HG_REVISION_ID}") 34 SET(HG_REVISION_ID ${HG_REVISION_PATH}.${HG_REVISION}) 52 35 ENDIF() 53 36 ENDIF() 54 55 SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.") 37 SET(LEMON_VERSION ${HG_REVISION_ID} CACHE STRING "LEMON version string.") 56 38 ENDIF() 57 39 … … 189 171 ENDIF() 190 172 191 CONFIGURE_FILE(192 ${PROJECT_SOURCE_DIR}/cmake/version.cmake.in193 ${PROJECT_BINARY_DIR}/cmake/version.cmake194 @ONLY195 )196 197 SET(ARCHIVE_BASE_NAME ${CMAKE_PROJECT_NAME})198 STRING(TOLOWER ${ARCHIVE_BASE_NAME} ARCHIVE_BASE_NAME)199 SET(ARCHIVE_NAME ${ARCHIVE_BASE_NAME}-${PROJECT_VERSION})200 ADD_CUSTOM_TARGET(dist201 COMMAND cmake -E remove_directory ${ARCHIVE_NAME}202 COMMAND hg archive ${ARCHIVE_NAME}203 COMMAND cmake -E copy cmake/version.cmake ${ARCHIVE_NAME}/cmake/version.cmake204 COMMAND tar -czf ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_NAME}205 COMMAND zip -r ${ARCHIVE_BASE_NAME}-nodoc-${PROJECT_VERSION}.zip ${ARCHIVE_NAME}206 COMMAND cmake -E copy_directory doc/html ${ARCHIVE_NAME}/doc/html207 COMMAND tar -czf ${ARCHIVE_NAME}.tar.gz ${ARCHIVE_NAME}208 COMMAND zip -r ${ARCHIVE_NAME}.zip ${ARCHIVE_NAME}209 COMMAND cmake -E copy_directory doc/html ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}210 COMMAND tar -czf ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.tar.gz ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}211 COMMAND zip -r ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}.zip ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}212 COMMAND cmake -E remove_directory ${ARCHIVE_NAME}213 COMMAND cmake -E remove_directory ${ARCHIVE_BASE_NAME}-doc-${PROJECT_VERSION}214 DEPENDS html215 WORKING_DIRECTORY ${PROJECT_BINARY_DIR})216 217 # CPACK config (Basically for NSIS)218 173 IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR}) 219 174 SET(CPACK_PACKAGE_NAME ${PROJECT_NAME}) -
INSTALL
r1148 r890 2 2 ========================= 3 3 4 This file contains instructions for building and installing LEMON from 5 source on Linux. The process on Windows is similar. 4 Since you are reading this I assume you already obtained one of the release 5 tarballs and successfully extracted it. The latest version of LEMON is 6 available at our web page (http://lemon.cs.elte.hu/). 6 7 7 Note that it is not necessary to install LEMON in order to use 8 it. Instead, you can easily integrate it with your own code 9 directly. For instructions, see 10 https://lemon.cs.elte.hu/trac/lemon/wiki/HowToCompile 11 8 LEMON provides two different build environments, one is based on "autotool", 9 while the other is based on "cmake". This file contains instructions only for 10 the former one, which is the recommended build environment on Linux, Mac OSX 11 and other unices or if you use Cygwin on Windows. For cmake installation 12 instructions visit http://lemon.cs.elte.hu. 12 13 13 14 In order to install LEMON from the extracted source tarball you have to 14 15 issue the following commands: 15 16 16 1. Step into the root of the source directory.17 1. `cd lemon-x.y.z' 17 18 18 $ cd lemon-x.y.z 19 This command changes to the directory which was created when you 20 extracted the sources. The x.y.z part is a version number. 19 21 20 2. Create a build subdirectory and step into it.22 2. `./configure' 21 23 22 $ mkdir build23 $ cd build24 This command runs the configure shell script, which does some checks and 25 creates the makefiles. 24 26 25 3. Perform system checks and create the makefiles.27 3. `make' 26 28 27 $ cmake .. 29 This command compiles the non-template part of LEMON into libemon.a 30 file. It also compiles the programs in the tools subdirectory by 31 default. 28 32 29 4. Build LEMON.33 4. `make check' 30 34 31 $ make 35 This step is optional, but recommended. It runs the test programs that 36 we developed for LEMON to check whether the library works properly on 37 your platform. 32 38 33 This command compiles the non-template part of LEMON into 34 libemon.a file. It also compiles the programs in the 'tools' and 35 'demo' subdirectories. 36 37 5. [Optional] Compile and run the self-tests. 38 39 $ make check 40 41 5. [Optional] Generate the user documentation. 42 43 $ make html 44 45 The release tarballs already include the documentation. 46 47 Note that for this step you need to have the following tools 48 installed: Python, Doxygen, Graphviz, Ghostscript, LaTeX. 49 50 6. [Optional] Install LEMON 51 52 $ make install 39 5. `make install' 53 40 54 41 This command installs LEMON under /usr/local (you will need root 55 privileges to be able to do that). If you want to install it to 56 some other location, then pass the 57 -DCMAKE_INSTALL_PREFIX=DIRECTORY flag to cmake in Step 3. 58 For example: 59 60 $ cmake -DCMAKE_INSTALL_PREFIX=/home/username/lemon' 42 privileges to be able to do that). If you want to install it to some 43 other location, then pass the --prefix=DIRECTORY flag to configure in 44 step 2. For example: `./configure --prefix=/home/username/lemon'. 45 46 6. `make install-html' 47 48 This command installs the documentation under share/doc/lemon/docs. The 49 generated documentation is included in the tarball. If you want to 50 generate it yourself, then run `make html'. Note that for this you need 51 to have the following programs installed: Doxygen, Graphviz, Ghostscript, 52 Latex. 53 61 54 62 55 Configure Options and Variables 63 56 =============================== 64 57 65 In Step 3, you can customize the build process by passing options to CMAKE. 58 In step 2 you can customize the actions of configure by setting variables 59 and passing options to it. This can be done like this: 60 `./configure [OPTION]... [VARIABLE=VALUE]...' 66 61 67 $ cmake [OPTIONS] .. 62 Below you will find some useful variables and options (see `./configure --help' 63 for more): 68 64 69 You find a list of the most useful options below. 65 CXX='comp' 70 66 71 -DCMAKE_INSTALL_PREFIX=PREFIX 67 Change the C++ compiler to 'comp'. 68 69 CXXFLAGS='flags' 70 71 Pass the 'flags' to the compiler. For example CXXFLAGS='-O3 -march=pentium-m' 72 turns on generation of aggressively optimized Pentium-M specific code. 73 74 --prefix=PREFIX 72 75 73 76 Set the installation prefix to PREFIX. By default it is /usr/local. 74 77 75 - DCMAKE_BUILD_TYPE=[Release|Debug|Maintainer|...]78 --enable-tools 76 79 77 This sets the compiler options. The choices are the following80 Build the programs in the tools subdirectory (default). 78 81 79 'Release': A strong optimization is turned on (-O3 with gcc). This 80 is the default setting and we strongly recommend using this for 81 the final compilation. 82 --disable-tools 82 83 83 'Debug': Optimization is turned off and debug info is added (-O0 84 -ggdb with gcc). If is recommended during the development. 84 Do not build the programs in the tools subdirectory. 85 85 86 'Maintainer': The same as 'Debug' but the compiler warnings are 87 converted to errors (-Werror with gcc). In addition, 'make' will 88 also automatically compile and execute the test codes. It is the 89 best way of ensuring that LEMON codebase is clean and safe. 86 --with-glpk[=PREFIX] 90 87 91 'RelWithDebInfo': Optimized build with debug info. 88 Enable GLPK support (default). You should specify the prefix too if 89 you installed GLPK to some non-standard location (e.g. your home 90 directory). If it is not found, GLPK support will be disabled. 92 91 93 'MinSizeRel': Size optimized build (-Os with gcc) 92 --with-glpk-includedir=DIR 94 93 95 -DTEST_WITH_VALGRIND=YES 94 The directory where the GLPK header files are located. This is only 95 useful when the GLPK headers and libraries are not under the same 96 prefix (which is unlikely). 96 97 97 Using this, the test codes will be executed using valgrind. It is a 98 very effective way of identifying indexing problems and memory leaks. 98 --with-glpk-libdir=DIR 99 99 100 -DCMAKE_CXX_COMPILER=path-to-compiler 100 The directory where the GLPK libraries are located. This is only 101 useful when the GLPK headers and libraries are not under the same 102 prefix (which is unlikely). 101 103 102 Change the compiler to be used. 104 --without-glpk 103 105 104 -DBUILD_SHARED_LIBS=TRUE 106 Disable GLPK support. 105 107 106 Build shared library instead of static one. Think twice if you 107 really want to use this option. 108 --with-cplex[=PREFIX] 108 109 109 -DGLPK_ROOT_DIR=DIRECTORY 110 -DCOIN_ROOT_DIR=DIRECTORY 111 -DCPLEX_ROOT_DIR=DIRECTORY 110 Enable CPLEX support (default). You should specify the prefix too 111 if you installed CPLEX to some non-standard location 112 (e.g. /opt/ilog/cplex75). If it is not found, CPLEX support will be 113 disabled. 112 114 113 Install root directory prefixes of optional third party libraries. 115 --with-cplex-includedir=DIR 116 117 The directory where the CPLEX header files are located. This is 118 only useful when the CPLEX headers and libraries are not under the 119 same prefix (e.g. /usr/local/cplex/cplex75/include). 120 121 --with-cplex-libdir=DIR 122 123 The directory where the CPLEX libraries are located. This is only 124 useful when the CPLEX headers and libraries are not under the same 125 prefix (e.g. 126 /usr/local/cplex/cplex75/lib/i86_linux2_glibc2.2_gcc3.0/static_pic_mt). 127 128 --without-cplex 129 130 Disable CPLEX support. 131 132 --with-soplex[=PREFIX] 133 134 Enable SoPlex support (default). You should specify the prefix too if 135 you installed SoPlex to some non-standard location (e.g. your home 136 directory). If it is not found, SoPlex support will be disabled. 137 138 --with-soplex-includedir=DIR 139 140 The directory where the SoPlex header files are located. This is only 141 useful when the SoPlex headers and libraries are not under the same 142 prefix (which is unlikely). 143 144 --with-soplex-libdir=DIR 145 146 The directory where the SoPlex libraries are located. This is only 147 useful when the SoPlex headers and libraries are not under the same 148 prefix (which is unlikely). 149 150 --without-soplex 151 152 Disable SoPlex support. 153 154 --with-coin[=PREFIX] 155 156 Enable support for COIN-OR solvers (CLP and CBC). You should 157 specify the prefix too. (by default, COIN-OR tools install 158 themselves to the source code directory). This command enables the 159 solvers that are actually found. 160 161 --with-coin-includedir=DIR 162 163 The directory where the COIN-OR header files are located. This is 164 only useful when the COIN-OR headers and libraries are not under 165 the same prefix (which is unlikely). 166 167 --with-coin-libdir=DIR 168 169 The directory where the COIN-OR libraries are located. This is only 170 useful when the COIN-OR headers and libraries are not under the 171 same prefix (which is unlikely). 172 173 --without-coin 174 175 Disable COIN-OR support. 176 114 177 115 178 Makefile Variables 116 179 ================== 117 180 118 make VERBOSE=1 181 Some Makefile variables are reserved by the GNU Coding Standards for 182 the use of the "user" - the person building the package. For instance, 183 CXX and CXXFLAGS are such variables, and have the same meaning as 184 explained in the previous section. These variables can be set on the 185 command line when invoking `make' like this: 186 `make [VARIABLE=VALUE]...' 119 187 120 This results in a more verbose output by showing the full 121 compiler and linker commands. 188 WARNINGCXXFLAGS is a non-standard Makefile variable introduced by us 189 to hold several compiler flags related to warnings. Its default value 190 can be overridden when invoking `make'. For example to disable all 191 warning flags use `make WARNINGCXXFLAGS='. 192 193 In order to turn off a single flag from the default set of warning 194 flags, you can use the CXXFLAGS variable, since this is passed after 195 WARNINGCXXFLAGS. For example to turn off `-Wold-style-cast' (which is 196 used by default when g++ is detected) you can use 197 `make CXXFLAGS="-g -O2 -Wno-old-style-cast"'. -
LICENSE
r1148 r959 2 2 copyright/license. 3 3 4 Copyright (C) 2003-201 2Egervary Jeno Kombinatorikus Optimalizalasi4 Copyright (C) 2003-2010 Egervary Jeno Kombinatorikus Optimalizalasi 5 5 Kutatocsoport (Egervary Combinatorial Optimization Research Group, 6 6 EGRES). -
cmake/version.cmake.in
r1135 r725 1 SET(LEMON_VERSION "@ LEMON_VERSION@" CACHE STRING "LEMON version string.")1 SET(LEMON_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.") -
doc/CMakeLists.txt
r1135 r1111 17 17 @ONLY 18 18 ) 19 20 # Copy doc from source (if exists)21 IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/html AND22 NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html/index.html)23 MESSAGE(STATUS "Copy doc from source tree")24 EXECUTE_PROCESS(25 COMMAND cmake -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/html ${CMAKE_CURRENT_BINARY_DIR}/html26 )27 ENDIF()28 19 29 20 IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE) -
lemon/CMakeLists.txt
r1133 r1113 5 5 6 6 CONFIGURE_FILE( 7 ${CMAKE_CURRENT_SOURCE_DIR}/config.h. in7 ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake 8 8 ${CMAKE_CURRENT_BINARY_DIR}/config.h 9 9 ) 10 10 11 11 CONFIGURE_FILE( 12 ${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc. in12 ${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc.cmake 13 13 ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc 14 14 @ONLY -
lemon/adaptors.h
r1159 r956 1372 1372 /// and edge filter maps. 1373 1373 SubGraph(GR& graph, NF& node_filter, EF& edge_filter) { 1374 this->initialize(graph, node_filter, edge_filter);1374 initialize(graph, node_filter, edge_filter); 1375 1375 } 1376 1376 … … 2278 2278 /// Creates an undirected graph from the given digraph. 2279 2279 Undirector(DGR& digraph) { 2280 this->initialize(digraph);2280 initialize(digraph); 2281 2281 } 2282 2282 -
lemon/bits/bezier.h
r1157 r463 160 160 const Point d=(a+b)/2; 161 161 const Point e=(b+c)/2; 162 //const Point f=(d+e)/2;162 const Point f=(d+e)/2; 163 163 R f1=_f(Bezier3(p1,a,d,e),_d); 164 164 R f2=_f(Bezier3(e,d,c,p4),_d); -
lemon/bits/edge_set_extender.h
r1161 r1110 524 524 // Returns the base node of the iterator 525 525 Node baseNode(const IncEdgeIt &e) const { 526 return e.direction ? this->u(e) : this->v(e);526 return e.direction ? u(e) : v(e); 527 527 } 528 528 // Running node of the iterator … … 530 530 // Returns the running node of the iterator 531 531 Node runningNode(const IncEdgeIt &e) const { 532 return e.direction ? this->v(e) : this->u(e);532 return e.direction ? v(e) : u(e); 533 533 } 534 534 -
lemon/bits/graph_extender.h
r1159 r825 588 588 // Returns the base node of the iterator 589 589 Node baseNode(const IncEdgeIt &edge) const { 590 return edge._direction ? this->u(edge) : this->v(edge);590 return edge._direction ? u(edge) : v(edge); 591 591 } 592 592 // Running node of the iterator … … 594 594 // Returns the running node of the iterator 595 595 Node runningNode(const IncEdgeIt &edge) const { 596 return edge._direction ? this->v(edge) : this->u(edge);596 return edge._direction ? v(edge) : u(edge); 597 597 } 598 598 -
lemon/bits/solver_bits.h
r1142 r956 45 45 void clear() { 46 46 first_item = -1; 47 last_item = -1;48 47 first_free_item = -1; 49 48 items.clear(); -
lemon/bits/windows.cc
r1163 r1131 137 137 InitializeCriticalSection(lock); 138 138 _repr = lock; 139 #else140 _repr = 0; //Just to avoid 'unused variable' warning with clang141 139 #endif 142 140 } -
lemon/capacity_scaling.h
r1166 r1165 93 93 /// 94 94 /// \warning Both \c V and \c C must be signed number types. 95 /// \warning Capacity bounds and supply values must be integer, but96 /// arc costs can be arbitrary real numbers.95 /// \warning All input data (capacities, supply values, and costs) must 96 /// be integer. 97 97 /// \warning This algorithm does not support negative costs for 98 98 /// arcs having infinite upper bound. -
lemon/cbc.cc
r1161 r1122 436 436 437 437 _prob = new CoinModel(); 438 rows.clear(); 439 cols.clear(); 438 440 } 439 441 -
lemon/circulation.h
r1159 r956 573 573 574 574 Node act; 575 Node bact=INVALID; 576 Node last_activated=INVALID; 575 577 while((act=_level->highestActive())!=INVALID) { 576 578 int actlevel=(*_level)[act]; -
lemon/clp.cc
r1142 r956 438 438 delete _prob; 439 439 _prob = new ClpSimplex(); 440 rows.clear(); 441 cols.clear(); 440 442 _col_names_ref.clear(); 441 443 _clear_temporals(); -
lemon/concept_check.h
r1157 r463 36 36 37 37 template <class T> inline void ignore_unused_variable_warning(const T&) { } 38 template <class T1, class T2>39 inline void ignore_unused_variable_warning(const T1&, const T2&) { }40 template <class T1, class T2, class T3>41 inline void ignore_unused_variable_warning(const T1&, const T2&,42 const T3&) { }43 template <class T1, class T2, class T3, class T4>44 inline void ignore_unused_variable_warning(const T1&, const T2&,45 const T3&, const T4&) { }46 template <class T1, class T2, class T3, class T4, class T5>47 inline void ignore_unused_variable_warning(const T1&, const T2&,48 const T3&, const T4&,49 const T5&) { }50 template <class T1, class T2, class T3, class T4, class T5, class T6>51 inline void ignore_unused_variable_warning(const T1&, const T2&,52 const T3&, const T4&,53 const T5&, const T6&) { }54 38 55 39 ///\e -
lemon/concepts/graph_components.h
r1161 r1127 495 495 _GraphItemIt it3 = it1; 496 496 _GraphItemIt it4 = INVALID; 497 ignore_unused_variable_warning(it3);498 ignore_unused_variable_warning(it4);499 497 500 498 it2 = ++it1; … … 586 584 _GraphIncIt it3 = it1; 587 585 _GraphIncIt it4 = INVALID; 588 ignore_unused_variable_warning(it3);589 ignore_unused_variable_warning(it4);590 586 591 587 it2 = ++it1; -
lemon/concepts/maps.h
r1157 r1125 50 50 /// Returns the value associated with the given key. 51 51 Value operator[](const Key &) const { 52 return * (static_cast<Value *>(0)+1);52 return *static_cast<Value *>(0); 53 53 } 54 54 -
lemon/config.h.in
r1133 r1131 1 #define LEMON_VERSION "@PROJECT_VERSION@" 2 #cmakedefine LEMON_HAVE_LONG_LONG 1 3 #cmakedefine LEMON_HAVE_LP 1 4 #cmakedefine LEMON_HAVE_MIP 1 5 #cmakedefine LEMON_HAVE_GLPK 1 6 #cmakedefine LEMON_HAVE_CPLEX 1 7 #cmakedefine LEMON_HAVE_CLP 1 8 #cmakedefine LEMON_HAVE_CBC 1 9 #cmakedefine LEMON_USE_PTHREAD 1 10 #cmakedefine LEMON_USE_WIN32_THREADS 1 1 /* The version string */ 2 #undef LEMON_VERSION 3 4 /* Define to 1 if you have long long */ 5 #undef LEMON_HAVE_LONG_LONG 6 7 /* Define to 1 if you have any LP solver. */ 8 #undef LEMON_HAVE_LP 9 10 /* Define to 1 if you have any MIP solver. */ 11 #undef LEMON_HAVE_MIP 12 13 /* Define to 1 if you have CPLEX. */ 14 #undef LEMON_HAVE_CPLEX 15 16 /* Define to 1 if you have GLPK. */ 17 #undef LEMON_HAVE_GLPK 18 19 /* Define to 1 if you have SOPLEX */ 20 #undef LEMON_HAVE_SOPLEX 21 22 /* Define to 1 if you have CLP */ 23 #undef LEMON_HAVE_CLP 24 25 /* Define to 1 if you have CBC */ 26 #undef LEMON_HAVE_CBC 27 28 /* Define to 1 if you have pthread */ 29 #undef LEMON_USE_PTHREAD 30 31 /* Define to 1 if you have win32 threads */ 32 #undef LEMON_USE_WIN32_THREADS -
lemon/core.h
r1162 r1111 1869 1869 ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough. 1870 1870 /// 1871 Arc operator()(Node s, Node t, Arc prev=INVALID) const 1871 #ifdef DOXYGEN 1872 Arc operator()(Node s, Node t, Arc prev=INVALID) const {} 1873 #else 1874 using ArcLookUp<GR>::operator() ; 1875 Arc operator()(Node s, Node t, Arc prev) const 1872 1876 { 1873 if(prev==INVALID) 1874 { 1875 Arc f=INVALID; 1876 Arc e; 1877 for(e=_head[s]; 1878 e!=INVALID&&_g.target(e)!=t; 1879 e = t < _g.target(e)?_left[e]:_right[e]) ; 1880 while(e!=INVALID) 1881 if(_g.target(e)==t) 1882 { 1883 f = e; 1884 e = _left[e]; 1885 } 1886 else e = _right[e]; 1887 return f; 1888 } 1889 else return _next[prev]; 1890 } 1877 return prev==INVALID?(*this)(s,t):_next[prev]; 1878 } 1879 #endif 1891 1880 1892 1881 }; -
lemon/cplex.cc
r1142 r956 471 471 int status; 472 472 _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem"); 473 rows.clear(); 474 cols.clear(); 473 475 } 474 476 -
lemon/glpk.cc
r1142 r956 557 557 void GlpkBase::_clear() { 558 558 glp_erase_prob(lp); 559 rows.clear(); 560 cols.clear(); 559 561 } 560 562 -
lemon/graph_to_eps.h
r1159 r1107 223 223 using T::_copyright; 224 224 225 using typenameT::NodeTextColorType;225 using T::NodeTextColorType; 226 226 using T::CUST_COL; 227 227 using T::DIST_COL; -
lemon/lemon.pc.in
r1133 r705 1 prefix=@ CMAKE_INSTALL_PREFIX@2 exec_prefix=@ CMAKE_INSTALL_PREFIX@/bin3 libdir=@ CMAKE_INSTALL_PREFIX@/lib4 includedir=@ CMAKE_INSTALL_PREFIX@/include1 prefix=@prefix@ 2 exec_prefix=@exec_prefix@ 3 libdir=@libdir@ 4 includedir=@includedir@ 5 5 6 Name: @P ROJECT_NAME@6 Name: @PACKAGE_NAME@ 7 7 Description: Library for Efficient Modeling and Optimization in Networks 8 Version: @P ROJECT_VERSION@8 Version: @PACKAGE_VERSION@ 9 9 Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@ 10 10 Cflags: -I${includedir} -
lemon/lp_base.h
r1143 r1094 1557 1557 1558 1558 ///Clears the problem 1559 void clear() { _clear(); rows.clear(); cols.clear();}1559 void clear() { _clear(); } 1560 1560 1561 1561 /// Sets the message level of the solver -
lemon/network_simplex.h
r1166 r1165 124 124 /// the \ref run() function. 125 125 /// 126 /// \ref NetworkSimplex provides five different implementations for127 /// the pivot strategy that significantly affectsthe running time126 /// \ref NetworkSimplex provides five different pivot rule 127 /// implementations that significantly affect the running time 128 128 /// of the algorithm. 129 /// According to experimental tests conducted on various problem 130 /// instances, \ref BLOCK_SEARCH "Block Search" and 131 /// \ref ALTERING_LIST "Altering Candidate List" rules turned out 132 /// to be the most efficient. 133 /// Since \ref BLOCK_SEARCH "Block Search" is a simpler strategy that 134 /// seemed to be slightly more robust, it is used by default. 135 /// However, another pivot rule can easily be selected using the 136 /// \ref run() function with the proper parameter. 129 /// By default, \ref BLOCK_SEARCH "Block Search" is used, which 130 /// turend out to be the most efficient and the most robust on various 131 /// test inputs. 132 /// However, another pivot rule can be selected using the \ref run() 133 /// function with the proper parameter. 137 134 enum PivotRule { 138 135 … … 160 157 /// The \e Altering \e Candidate \e List pivot rule. 161 158 /// It is a modified version of the Candidate List method. 162 /// It keeps only a few of thebest eligible arcs from the former159 /// It keeps only the several best eligible arcs from the former 163 160 /// candidate list and extends this list in every iteration. 164 161 ALTERING_LIST … … 543 540 SortFunc(const CostVector &map) : _map(map) {} 544 541 bool operator()(int left, int right) { 545 return _map[left] <_map[right];542 return _map[left] > _map[right]; 546 543 } 547 544 }; … … 561 558 const double BLOCK_SIZE_FACTOR = 1.0; 562 559 const int MIN_BLOCK_SIZE = 10; 563 const double HEAD_LENGTH_FACTOR = 0. 01;560 const double HEAD_LENGTH_FACTOR = 0.1; 564 561 const int MIN_HEAD_LENGTH = 3; 565 562 … … 605 602 } 606 603 for (e = 0; e != _next_arc; ++e) { 607 c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);608 if (c < 0) {609 _cand_cost[e] = c;604 _cand_cost[e] = _state[e] * 605 (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); 606 if (_cand_cost[e] < 0) { 610 607 _candidates[_curr_length++] = e; 611 608 } … … 620 617 search_end: 621 618 622 // Perform partial sort operation on the candidate list 623 int new_length = std::min(_head_length + 1, _curr_length); 624 std::partial_sort(_candidates.begin(), _candidates.begin() + new_length, 625 _candidates.begin() + _curr_length, _sort_func); 626 627 // Select the entering arc and remove it from the list 619 // Make heap of the candidate list (approximating a partial sort) 620 make_heap( _candidates.begin(), _candidates.begin() + _curr_length, 621 _sort_func ); 622 623 // Pop the first element of the heap 628 624 _in_arc = _candidates[0]; 629 625 _next_arc = e; 630 _candidates[0] = _candidates[new_length - 1]; 631 _curr_length = new_length - 1; 626 pop_heap( _candidates.begin(), _candidates.begin() + _curr_length, 627 _sort_func ); 628 _curr_length = std::min(_head_length, _curr_length - 1); 632 629 return true; 633 630 } -
lemon/path.h
r1162 r1024 65 65 Path() {} 66 66 67 /// \brief Copy constructor68 ///69 Path(const Path& cpath) {70 pathCopy(cpath, *this);71 }72 73 67 /// \brief Template copy constructor 74 68 /// … … 78 72 Path(const CPath& cpath) { 79 73 pathCopy(cpath, *this); 80 }81 82 /// \brief Copy assignment83 ///84 Path& operator=(const Path& cpath) {85 pathCopy(cpath, *this);86 return *this;87 74 } 88 75 … … 266 253 SimplePath() {} 267 254 268 /// \brief Copy constructor269 ///270 SimplePath(const SimplePath& cpath) {271 pathCopy(cpath, *this);272 }273 274 255 /// \brief Template copy constructor 275 256 /// … … 279 260 SimplePath(const CPath& cpath) { 280 261 pathCopy(cpath, *this); 281 }282 283 /// \brief Copy assignment284 ///285 SimplePath& operator=(const SimplePath& cpath) {286 pathCopy(cpath, *this);287 return *this;288 262 } 289 263 … … 458 432 ListPath() : first(0), last(0) {} 459 433 460 /// \brief Copy constructor461 ///462 ListPath(const ListPath& cpath) : first(0), last(0) {463 pathCopy(cpath, *this);464 }465 466 434 /// \brief Template copy constructor 467 435 /// … … 478 446 ~ListPath() { 479 447 clear(); 480 }481 482 /// \brief Copy assignment483 ///484 ListPath& operator=(const ListPath& cpath) {485 pathCopy(cpath, *this);486 return *this;487 448 } 488 449 … … 798 759 StaticPath() : len(0), arcs(0) {} 799 760 800 /// \brief Copy constructor801 ///802 StaticPath(const StaticPath& cpath) : arcs(0) {803 pathCopy(cpath, *this);804 }805 806 761 /// \brief Template copy constructor 807 762 /// … … 817 772 ~StaticPath() { 818 773 if (arcs) delete[] arcs; 819 }820 821 /// \brief Copy assignment822 ///823 StaticPath& operator=(const StaticPath& cpath) {824 pathCopy(cpath, *this);825 return *this;826 774 } 827 775 -
lemon/planarity.h
r1160 r956 73 73 74 74 void discover(const Arc& arc) { 75 Node source = _graph.source(arc); 75 76 Node target = _graph.target(arc); 76 77 -
test/CMakeLists.txt
r1162 r1124 14 14 SET(TESTS 15 15 adaptors_test 16 arc_look_up_test17 16 bellman_ford_test 18 17 bfs_test -
test/adaptors_test.cc
r1159 r550 66 66 Digraph::Arc a2 = digraph.addArc(n1, n3); 67 67 Digraph::Arc a3 = digraph.addArc(n2, n3); 68 ignore_unused_variable_warning(a3);69 68 70 69 // Check the adaptor … … 101 100 Adaptor::Arc a7 = adaptor.addArc(n1, n4); 102 101 Adaptor::Arc a8 = adaptor.addArc(n1, n2); 103 ignore_unused_variable_warning(a6,a7,a8);104 102 105 103 adaptor.erase(a1); … … 761 759 Digraph::Arc a2 = digraph.addArc(n1, n3); 762 760 Digraph::Arc a3 = digraph.addArc(n2, n3); 763 ignore_unused_variable_warning(a1,a2,a3);764 761 765 762 checkGraphNodeList(adaptor, 6); … … 1381 1378 1382 1379 // Apply several adaptors on the grid graph 1383 typedef Orienter< const GridGraph, GridGraph::EdgeMap<bool> > 1384 OrientedGridGraph; 1385 typedef SplitNodes<OrientedGridGraph> SplitGridGraph; 1380 typedef SplitNodes<Orienter< const GridGraph, GridGraph::EdgeMap<bool> > > 1381 SplitGridGraph; 1386 1382 typedef Undirector<const SplitGridGraph> USplitGridGraph; 1387 1383 checkConcept<concepts::Digraph, SplitGridGraph>(); 1388 1384 checkConcept<concepts::Graph, USplitGridGraph>(); 1389 1385 1390 OrientedGridGraph oadaptor = orienter(graph, dir_map); 1391 SplitGridGraph adaptor = splitNodes(oadaptor); 1386 SplitGridGraph adaptor = splitNodes(orienter(graph, dir_map)); 1392 1387 USplitGridGraph uadaptor = undirector(adaptor); 1393 1388 -
test/bellman_ford_test.cc
r1160 r960 191 191 192 192 ListPath<Digraph> path; 193 Value dist = 0;193 Value dist; 194 194 bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t); 195 195 -
test/connectivity_test.cc
r1159 r956 69 69 Graph g(d); 70 70 Digraph::Node n = d.addNode(); 71 ignore_unused_variable_warning(n);72 71 73 72 check(stronglyConnected(d), "This digraph is strongly connected"); … … 247 246 Digraph::Node watch = d.addNode(); 248 247 Digraph::Node pants = d.addNode(); 249 ignore_unused_variable_warning(watch);250 248 251 249 d.addArc(socks, shoe); -
test/digraph_test.cc
r1160 r956 65 65 a3 = G.addArc(n2, n3), 66 66 a4 = G.addArc(n2, n3); 67 ignore_unused_variable_warning(a2,a3,a4);68 67 69 68 checkGraphNodeList(G, 3); … … 94 93 Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1), 95 94 a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3); 96 ignore_unused_variable_warning(a1,a2,a3,a4);97 95 98 96 Node n4 = G.split(n2); … … 128 126 a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3), 129 127 a5 = G.addArc(n2, n4); 130 ignore_unused_variable_warning(a1,a2,a3,a5);131 128 132 129 checkGraphNodeList(G, 4); … … 208 205 a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1), 209 206 a5 = G.addArc(n2, n4); 210 ignore_unused_variable_warning(a2,a3,a4,a5);211 207 212 208 // Check arc deletion … … 256 252 Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1), 257 253 a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3); 258 ignore_unused_variable_warning(a1,a2,a3,a4);259 254 260 255 typename Digraph::Snapshot snapshot(G); … … 357 352 e1 = g.addArc(n1, n2), 358 353 e2 = g.addArc(n2, n3); 359 ignore_unused_variable_warning(e2);360 354 361 355 check(g.valid(n1), "Wrong validity check"); … … 443 437 a3 = g.addArc(n2, n3), 444 438 a4 = g.addArc(n2, n3); 445 ignore_unused_variable_warning(a2,a3,a4);446 439 447 440 digraphCopy(g, G).nodeRef(nref).run(); -
test/edge_set_test.cc
r1159 r956 45 45 46 46 Digraph::Arc ga1 = digraph.addArc(n1, n2); 47 ignore_unused_variable_warning(ga1);48 47 49 48 ArcSet arc_set(digraph); 50 49 51 50 Digraph::Arc ga2 = digraph.addArc(n2, n1); 52 ignore_unused_variable_warning(ga2);53 51 54 52 checkGraphNodeList(arc_set, 2); … … 78 76 a3 = arc_set.addArc(n2, n3), 79 77 a4 = arc_set.addArc(n2, n3); 80 ignore_unused_variable_warning(a2,a3,a4);81 82 78 checkGraphNodeList(arc_set, 3); 83 79 checkGraphArcList(arc_set, 4); … … 115 111 116 112 Digraph::Arc ga1 = digraph.addArc(n1, n2); 117 ignore_unused_variable_warning(ga1);118 113 119 114 ArcSet arc_set(digraph); 120 115 121 116 Digraph::Arc ga2 = digraph.addArc(n2, n1); 122 ignore_unused_variable_warning(ga2);123 117 124 118 checkGraphNodeList(arc_set, 2); … … 148 142 a3 = arc_set.addArc(n2, n3), 149 143 a4 = arc_set.addArc(n2, n3); 150 ignore_unused_variable_warning(a2,a3,a4);151 152 144 checkGraphNodeList(arc_set, 3); 153 145 checkGraphArcList(arc_set, 4); … … 199 191 200 192 Digraph::Arc ga1 = digraph.addArc(n1, n2); 201 ignore_unused_variable_warning(ga1);202 193 203 194 EdgeSet edge_set(digraph); 204 195 205 196 Digraph::Arc ga2 = digraph.addArc(n2, n1); 206 ignore_unused_variable_warning(ga2);207 197 208 198 checkGraphNodeList(edge_set, 2); … … 241 231 e3 = edge_set.addEdge(n2, n3), 242 232 e4 = edge_set.addEdge(n2, n3); 243 ignore_unused_variable_warning(e2,e3,e4);244 245 233 checkGraphNodeList(edge_set, 3); 246 234 checkGraphEdgeList(edge_set, 4); … … 287 275 288 276 Digraph::Arc ga1 = digraph.addArc(n1, n2); 289 ignore_unused_variable_warning(ga1);290 277 291 278 EdgeSet edge_set(digraph); 292 279 293 280 Digraph::Arc ga2 = digraph.addArc(n2, n1); 294 ignore_unused_variable_warning(ga2);295 281 296 282 checkGraphNodeList(edge_set, 2); … … 329 315 e3 = edge_set.addEdge(n2, n3), 330 316 e4 = edge_set.addEdge(n2, n3); 331 ignore_unused_variable_warning(e2,e3,e4);332 333 317 checkGraphNodeList(edge_set, 3); 334 318 checkGraphEdgeList(edge_set, 4); -
test/euler_test.cc
r1159 r956 102 102 Graph g(d); 103 103 Digraph::Node n = d.addNode(); 104 ignore_unused_variable_warning(n); 105 104 106 105 checkDiEulerIt(d); 107 106 checkDiEulerIt(g); … … 191 190 Digraph::Node n4 = d.addNode(); 192 191 Digraph::Node n5 = d.addNode(); 193 ignore_unused_variable_warning(n0,n4,n5);194 192 195 193 d.addArc(n1, n2); -
test/fractional_matching_test.cc
r1160 r956 343 343 pv += weight[mwfm.matching(n)]; 344 344 SmartGraph::Node o = graph.target(mwfm.matching(n)); 345 ignore_unused_variable_warning(o);346 345 } else { 347 346 check(mwfm.nodeValue(n) == 0, "Invalid matching"); … … 408 407 pv += weight[mwpfm.matching(n)]; 409 408 SmartGraph::Node o = graph.target(mwpfm.matching(n)); 410 ignore_unused_variable_warning(o);411 409 } 412 410 -
test/graph_test.cc
r1159 r956 67 67 Edge e2 = G.addEdge(n2, n1), 68 68 e3 = G.addEdge(n2, n3); 69 ignore_unused_variable_warning(e2,e3);70 69 71 70 checkGraphNodeList(G, 3); … … 100 99 e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4), 101 100 e5 = G.addEdge(n4, n3); 102 ignore_unused_variable_warning(e1,e3,e4,e5);103 101 104 102 checkGraphNodeList(G, 4); … … 180 178 e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4), 181 179 e5 = G.addEdge(n4, n3); 182 ignore_unused_variable_warning(e1,e3,e4,e5);183 180 184 181 // Check edge deletion … … 221 218 Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1), 222 219 e3 = G.addEdge(n2, n3); 223 ignore_unused_variable_warning(e1,e2,e3);224 220 225 221 checkGraphNodeList(G, 3); … … 386 382 e1 = g.addEdge(n1, n2), 387 383 e2 = g.addEdge(n2, n3); 388 ignore_unused_variable_warning(e2);389 384 390 385 check(g.valid(n1), "Wrong validity check"); … … 525 520 526 521 Node n = G.nodeFromId(dim); 527 ignore_unused_variable_warning(n);528 522 529 523 for (NodeIt n(G); n != INVALID; ++n) { -
test/lp_test.cc
r1140 r1092 42 42 using namespace lemon; 43 43 44 int countCols(LpBase & lp) {45 int count=0;46 for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;47 return count;48 }49 50 int countRows(LpBase & lp) {51 int count=0;52 for (LpBase::RowIt r(lp); r!=INVALID; ++r) ++count;53 return count;54 }55 56 57 44 void lpTest(LpSolver& lp) 58 45 { 59 46 60 47 typedef LpSolver LP; 61 62 // Test LpBase::clear()63 check(countRows(lp)==0, "Wrong number of rows");64 check(countCols(lp)==0, "Wrong number of cols");65 lp.addCol(); lp.addRow(); lp.addRow();66 check(countRows(lp)==2, "Wrong number of rows");67 check(countCols(lp)==1, "Wrong number of cols");68 lp.clear();69 check(countRows(lp)==0, "Wrong number of rows");70 check(countCols(lp)==0, "Wrong number of cols");71 lp.addCol(); lp.addCol(); lp.addCol(); lp.addRow();72 check(countRows(lp)==1, "Wrong number of rows");73 check(countCols(lp)==3, "Wrong number of cols");74 lp.clear();75 48 76 49 std::vector<LP::Col> x(10); -
test/maps_test.cc
r1159 r1057 104 104 NullMap<A,B> map1; 105 105 NullMap<A,B> map2 = map1; 106 ignore_unused_variable_warning(map2);107 106 map1 = nullMap<A,B>(); 108 107 } … … 115 114 ConstMap<A,B> map2 = B(); 116 115 ConstMap<A,B> map3 = map1; 117 ignore_unused_variable_warning(map2,map3);118 119 116 map1 = constMap<A>(B()); 120 117 map1 = constMap<A,B>(); … … 122 119 ConstMap<A,C> map4(C(1)); 123 120 ConstMap<A,C> map5 = map4; 124 ignore_unused_variable_warning(map5);125 126 121 map4 = constMap<A>(C(2)); 127 122 map4.setAll(C(3)); … … 144 139 IdentityMap<A> map1; 145 140 IdentityMap<A> map2 = map1; 146 ignore_unused_variable_warning(map2);147 148 141 map1 = identityMap<A>(); 149 142 … … 205 198 checkConcept<ReadMap<B,double>, CompMap>(); 206 199 CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>()); 207 ignore_unused_variable_warning(map1);208 200 CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>()); 209 ignore_unused_variable_warning(map2);210 201 211 202 SparseMap<double, bool> m1(false); m1[3.14] = true; … … 220 211 checkConcept<ReadMap<A,double>, CombMap>(); 221 212 CombMap map1 = CombMap(DoubleMap(), DoubleMap()); 222 ignore_unused_variable_warning(map1);223 213 CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>()); 224 ignore_unused_variable_warning(map2);225 214 226 215 check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3, … … 234 223 FunctorToMap<F> map1; 235 224 FunctorToMap<F> map2 = FunctorToMap<F>(F()); 236 ignore_unused_variable_warning(map2);237 238 225 B b = functorToMap(F())[A()]; 239 ignore_unused_variable_warning(b);240 226 241 227 checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >(); 242 228 MapToFunctor<ReadMap<A,B> > map = 243 229 MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>()); 244 ignore_unused_variable_warning(map);245 230 246 231 check(functorToMap(&func)[A()] == 3, … … 260 245 ConvertMap<ReadMap<double, int>, double> >(); 261 246 ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true)); 262 ignore_unused_variable_warning(map1);263 247 ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false)); 264 ignore_unused_variable_warning(map2);265 266 248 } 267 249 -
test/path_test.cc
r1144 r463 39 39 } 40 40 41 // Check if proper copy consructor is called (use valgrind for testing)42 template<class _Path>43 void checkCopy()44 {45 ListDigraph g;46 ListDigraph::Arc a = g.addArc(g.addNode(), g.addNode());47 48 _Path p,q;49 p.addBack(a);50 q=p;51 _Path r(p);52 StaticPath<ListDigraph> s(r);53 }54 55 41 int main() { 56 42 check_concepts(); 57 58 checkCopy<Path<ListDigraph> >();59 checkCopy<SimplePath<ListDigraph> >();60 checkCopy<ListPath<ListDigraph> >();61 62 ListDigraph g;63 ListDigraph::Arc a = g.addArc(g.addNode(), g.addNode());64 65 Path<ListDigraph> p;66 StaticPath<ListDigraph> q,r;67 p.addBack(a);68 q=p;69 r=q;70 StaticPath<ListDigraph> s(q);71 72 43 return 0; 73 44 } -
test/time_measure_test.cc
r1157 r605 18 18 19 19 #include <lemon/time_measure.h> 20 #include <lemon/concept_check.h>21 20 22 21 using namespace lemon; … … 34 33 35 34 for(int i=0;i<1000;i++) 36 { 37 TimeStamp x(T); 38 ignore_unused_variable_warning(x); 39 } 35 TimeStamp x(T); 40 36 } 41 37
Note: See TracChangeset
for help on using the changeset viewer.