diff -Nru coinor-cbc-2.8.12/configure coinor-cbc-2.9.9+repack1/configure --- coinor-cbc-2.8.12/configure 2014-08-28 03:30:12.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/configure 2017-06-12 10:55:45.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for Cbc 2.8.12. +# Generated by GNU Autoconf 2.59 for Cbc 2.9.9. # # Report bugs to . # @@ -429,8 +429,8 @@ # Identity of this package. PACKAGE_NAME='Cbc' PACKAGE_TARNAME='cbc' -PACKAGE_VERSION='2.8.12' -PACKAGE_STRING='Cbc 2.8.12' +PACKAGE_VERSION='2.9.9' +PACKAGE_STRING='Cbc 2.9.9' PACKAGE_BUGREPORT='cbc@lists.coin-or.org' ac_unique_file="src/CbcTree.hpp" @@ -472,7 +472,7 @@ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os ALWAYS_FALSE_TRUE ALWAYS_FALSE_FALSE have_svnversion CBC_SVN_REV CDEFS ADD_CFLAGS DBG_CFLAGS OPT_CFLAGS sol_cc_compiler CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT COIN_CC_IS_CL_TRUE COIN_CC_IS_CL_FALSE MPICC CXXDEFS ADD_CXXFLAGS DBG_CXXFLAGS OPT_CXXFLAGS CXX CXXFLAGS ac_ct_CXX COIN_CXX_IS_CL_TRUE COIN_CXX_IS_CL_FALSE MPICXX EGREP LN_S INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBTOOLM4 have_autoconf have_automake have_svn BUILDTOOLSDIR AUX_DIR abs_source_dir abs_lib_dir abs_include_dir abs_bin_dir HAVE_EXTERNALS_TRUE HAVE_EXTERNALS_FALSE host host_cpu host_vendor host_os ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL ac_c_preproc_warn_flag ac_cxx_preproc_warn_flag RPATH_FLAGS DEPENDENCY_LINKING_TRUE DEPENDENCY_LINKING_FALSE LT_LDFLAGS PKG_CONFIG ac_ct_PKG_CONFIG COIN_HAS_PKGCONFIG_TRUE COIN_HAS_PKGCONFIG_FALSE COIN_PKG_CONFIG_PATH COIN_PKG_CONFIG_PATH_UNINSTALLED COINDEPEND_LIBS COINDEPEND_CFLAGS COINDEPEND_DATA COINDEPEND_DEPENDENCIES COINDEPEND_LIBS_INSTALLED COINDEPEND_CFLAGS_INSTALLED COINDEPEND_DATA_INSTALLED CBCLIB_CFLAGS CBCLIB_LIBS CBCLIB_PCLIBS CBCLIB_PCREQUIRES CBCLIB_DEPENDENCIES CBCLIB_CFLAGS_INSTALLED CBCLIB_LIBS_INSTALLED CBCGENERIC_CFLAGS CBCGENERIC_LIBS CBCGENERIC_PCLIBS CBCGENERIC_PCREQUIRES CBCGENERIC_DEPENDENCIES CBCGENERIC_CFLAGS_INSTALLED CBCGENERIC_LIBS_INSTALLED COIN_HAS_COINDEPEND_TRUE COIN_HAS_COINDEPEND_FALSE CLP_LIBS CLP_CFLAGS CLP_DATA CLP_DEPENDENCIES CLP_LIBS_INSTALLED CLP_CFLAGS_INSTALLED CLP_DATA_INSTALLED COIN_HAS_CLP_TRUE COIN_HAS_CLP_FALSE OSITESTS_LIBS OSITESTS_CFLAGS OSITESTS_DATA OSITESTS_DEPENDENCIES OSITESTS_LIBS_INSTALLED OSITESTS_CFLAGS_INSTALLED OSITESTS_DATA_INSTALLED COIN_HAS_OSITESTS_TRUE COIN_HAS_OSITESTS_FALSE SAMPLE_LIBS SAMPLE_CFLAGS SAMPLE_DATA SAMPLE_DEPENDENCIES SAMPLE_LIBS_INSTALLED SAMPLE_CFLAGS_INSTALLED SAMPLE_DATA_INSTALLED COIN_HAS_SAMPLE_TRUE COIN_HAS_SAMPLE_FALSE NETLIB_LIBS NETLIB_CFLAGS NETLIB_DATA NETLIB_DEPENDENCIES NETLIB_LIBS_INSTALLED NETLIB_CFLAGS_INSTALLED NETLIB_DATA_INSTALLED COIN_HAS_NETLIB_TRUE COIN_HAS_NETLIB_FALSE MIPLIB3_LIBS MIPLIB3_CFLAGS MIPLIB3_DATA MIPLIB3_DEPENDENCIES MIPLIB3_LIBS_INSTALLED MIPLIB3_CFLAGS_INSTALLED MIPLIB3_DATA_INSTALLED COIN_HAS_MIPLIB3_TRUE COIN_HAS_MIPLIB3_FALSE DYLP_LIBS DYLP_CFLAGS DYLP_DATA DYLP_DEPENDENCIES DYLP_LIBS_INSTALLED DYLP_CFLAGS_INSTALLED DYLP_DATA_INSTALLED COIN_HAS_DYLP_TRUE COIN_HAS_DYLP_FALSE VOL_LIBS VOL_CFLAGS VOL_DATA VOL_DEPENDENCIES VOL_LIBS_INSTALLED VOL_CFLAGS_INSTALLED VOL_DATA_INSTALLED COIN_HAS_VOL_TRUE COIN_HAS_VOL_FALSE CPX_LIBS CPX_CFLAGS CPX_DATA CPX_DEPENDENCIES CPX_LIBS_INSTALLED CPX_CFLAGS_INSTALLED CPX_DATA_INSTALLED COIN_HAS_CPX_TRUE COIN_HAS_CPX_FALSE GLPK_LIBS GLPK_CFLAGS GLPK_DATA GLPK_DEPENDENCIES GLPK_LIBS_INSTALLED GLPK_CFLAGS_INSTALLED GLPK_DATA_INSTALLED COIN_HAS_GLPK_TRUE COIN_HAS_GLPK_FALSE GRB_LIBS GRB_CFLAGS GRB_DATA GRB_DEPENDENCIES GRB_LIBS_INSTALLED GRB_CFLAGS_INSTALLED GRB_DATA_INSTALLED COIN_HAS_GRB_TRUE COIN_HAS_GRB_FALSE MSK_LIBS MSK_CFLAGS MSK_DATA MSK_DEPENDENCIES MSK_LIBS_INSTALLED MSK_CFLAGS_INSTALLED MSK_DATA_INSTALLED COIN_HAS_MSK_TRUE COIN_HAS_MSK_FALSE SPX_LIBS SPX_CFLAGS SPX_DATA SPX_DEPENDENCIES SPX_LIBS_INSTALLED SPX_CFLAGS_INSTALLED SPX_DATA_INSTALLED COIN_HAS_SPX_TRUE COIN_HAS_SPX_FALSE XPR_LIBS XPR_CFLAGS XPR_DATA XPR_DEPENDENCIES XPR_LIBS_INSTALLED XPR_CFLAGS_INSTALLED XPR_DATA_INSTALLED COIN_HAS_XPR_TRUE COIN_HAS_XPR_FALSE ASL_LIBS ASL_CFLAGS ASL_DATA ASL_DEPENDENCIES ASL_LIBS_INSTALLED ASL_CFLAGS_INSTALLED ASL_DATA_INSTALLED COIN_HAS_ASL_TRUE COIN_HAS_ASL_FALSE CBC_BUILD_CBC_GENERIC_TRUE CBC_BUILD_CBC_GENERIC_FALSE OSICBC_DFLT_SOLVER_CLP_TRUE OSICBC_DFLT_SOLVER_CLP_FALSE OSICBC_DFLT_SOLVER_CPX_TRUE OSICBC_DFLT_SOLVER_CPX_FALSE OSICBC_DFLT_SOLVER_DYLP_TRUE OSICBC_DFLT_SOLVER_DYLP_FALSE OSICBC_DFLT_SOLVER_GLPK_TRUE OSICBC_DFLT_SOLVER_GLPK_FALSE OSICBC_DFLT_SOLVER_GRB_TRUE OSICBC_DFLT_SOLVER_GRB_FALSE OSICBC_DFLT_SOLVER_MSK_TRUE OSICBC_DFLT_SOLVER_MSK_FALSE OSICBC_DFLT_SOLVER_SPX_TRUE OSICBC_DFLT_SOLVER_SPX_FALSE OSICBC_DFLT_SOLVER_SYM_TRUE OSICBC_DFLT_SOLVER_SYM_FALSE OSICBC_DFLT_SOLVER_VOL_TRUE OSICBC_DFLT_SOLVER_VOL_FALSE OSICBC_DFLT_SOLVER_XPR_TRUE OSICBC_DFLT_SOLVER_XPR_FALSE coin_have_doxygen coin_doxy_usedot coin_doxy_tagname coin_doxy_logname coin_doxy_tagfiles coin_doxy_excludes LIBEXT VPATH_DISTCLEANFILES ABSBUILDDIR LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os ALWAYS_FALSE_TRUE ALWAYS_FALSE_FALSE have_svnversion CBC_SVN_REV CDEFS ADD_CFLAGS DBG_CFLAGS OPT_CFLAGS sol_cc_compiler CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT COIN_CC_IS_CL_TRUE COIN_CC_IS_CL_FALSE MPICC CXXDEFS ADD_CXXFLAGS DBG_CXXFLAGS OPT_CXXFLAGS CXX CXXFLAGS ac_ct_CXX COIN_CXX_IS_CL_TRUE COIN_CXX_IS_CL_FALSE MPICXX EGREP LN_S INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LIBTOOLM4 have_autoconf have_automake have_svn BUILDTOOLSDIR AUX_DIR abs_source_dir abs_lib_dir abs_include_dir abs_bin_dir HAVE_EXTERNALS_TRUE HAVE_EXTERNALS_FALSE host host_cpu host_vendor host_os ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL ac_c_preproc_warn_flag ac_cxx_preproc_warn_flag RPATH_FLAGS DEPENDENCY_LINKING_TRUE DEPENDENCY_LINKING_FALSE LT_LDFLAGS PKG_CONFIG ac_ct_PKG_CONFIG COIN_HAS_PKGCONFIG_TRUE COIN_HAS_PKGCONFIG_FALSE COIN_PKG_CONFIG_PATH COIN_PKG_CONFIG_PATH_UNINSTALLED COINDEPEND_LIBS COINDEPEND_CFLAGS COINDEPEND_DATA COINDEPEND_DEPENDENCIES COINDEPEND_LIBS_INSTALLED COINDEPEND_CFLAGS_INSTALLED COINDEPEND_DATA_INSTALLED CBCLIB_CFLAGS CBCLIB_LIBS CBCLIB_PCLIBS CBCLIB_PCREQUIRES CBCLIB_DEPENDENCIES CBCLIB_CFLAGS_INSTALLED CBCLIB_LIBS_INSTALLED CBCGENERIC_CFLAGS CBCGENERIC_LIBS CBCGENERIC_PCLIBS CBCGENERIC_PCREQUIRES CBCGENERIC_DEPENDENCIES CBCGENERIC_CFLAGS_INSTALLED CBCGENERIC_LIBS_INSTALLED COIN_HAS_COINDEPEND_TRUE COIN_HAS_COINDEPEND_FALSE CLP_LIBS CLP_CFLAGS CLP_DATA CLP_DEPENDENCIES CLP_LIBS_INSTALLED CLP_CFLAGS_INSTALLED CLP_DATA_INSTALLED COIN_HAS_CLP_TRUE COIN_HAS_CLP_FALSE OSITESTS_LIBS OSITESTS_CFLAGS OSITESTS_DATA OSITESTS_DEPENDENCIES OSITESTS_LIBS_INSTALLED OSITESTS_CFLAGS_INSTALLED OSITESTS_DATA_INSTALLED COIN_HAS_OSITESTS_TRUE COIN_HAS_OSITESTS_FALSE SAMPLE_LIBS SAMPLE_CFLAGS SAMPLE_DATA SAMPLE_DEPENDENCIES SAMPLE_LIBS_INSTALLED SAMPLE_CFLAGS_INSTALLED SAMPLE_DATA_INSTALLED COIN_HAS_SAMPLE_TRUE COIN_HAS_SAMPLE_FALSE NETLIB_LIBS NETLIB_CFLAGS NETLIB_DATA NETLIB_DEPENDENCIES NETLIB_LIBS_INSTALLED NETLIB_CFLAGS_INSTALLED NETLIB_DATA_INSTALLED COIN_HAS_NETLIB_TRUE COIN_HAS_NETLIB_FALSE MIPLIB3_LIBS MIPLIB3_CFLAGS MIPLIB3_DATA MIPLIB3_DEPENDENCIES MIPLIB3_LIBS_INSTALLED MIPLIB3_CFLAGS_INSTALLED MIPLIB3_DATA_INSTALLED COIN_HAS_MIPLIB3_TRUE COIN_HAS_MIPLIB3_FALSE DYLP_LIBS DYLP_CFLAGS DYLP_DATA DYLP_DEPENDENCIES DYLP_LIBS_INSTALLED DYLP_CFLAGS_INSTALLED DYLP_DATA_INSTALLED COIN_HAS_DYLP_TRUE COIN_HAS_DYLP_FALSE VOL_LIBS VOL_CFLAGS VOL_DATA VOL_DEPENDENCIES VOL_LIBS_INSTALLED VOL_CFLAGS_INSTALLED VOL_DATA_INSTALLED COIN_HAS_VOL_TRUE COIN_HAS_VOL_FALSE CPX_LIBS CPX_CFLAGS CPX_DATA CPX_DEPENDENCIES CPX_LIBS_INSTALLED CPX_CFLAGS_INSTALLED CPX_DATA_INSTALLED COIN_HAS_CPX_TRUE COIN_HAS_CPX_FALSE GLPK_LIBS GLPK_CFLAGS GLPK_DATA GLPK_DEPENDENCIES GLPK_LIBS_INSTALLED GLPK_CFLAGS_INSTALLED GLPK_DATA_INSTALLED COIN_HAS_GLPK_TRUE COIN_HAS_GLPK_FALSE GRB_LIBS GRB_CFLAGS GRB_DATA GRB_DEPENDENCIES GRB_LIBS_INSTALLED GRB_CFLAGS_INSTALLED GRB_DATA_INSTALLED COIN_HAS_GRB_TRUE COIN_HAS_GRB_FALSE MSK_LIBS MSK_CFLAGS MSK_DATA MSK_DEPENDENCIES MSK_LIBS_INSTALLED MSK_CFLAGS_INSTALLED MSK_DATA_INSTALLED COIN_HAS_MSK_TRUE COIN_HAS_MSK_FALSE SPX_LIBS SPX_CFLAGS SPX_DATA SPX_DEPENDENCIES SPX_LIBS_INSTALLED SPX_CFLAGS_INSTALLED SPX_DATA_INSTALLED COIN_HAS_SPX_TRUE COIN_HAS_SPX_FALSE XPR_LIBS XPR_CFLAGS XPR_DATA XPR_DEPENDENCIES XPR_LIBS_INSTALLED XPR_CFLAGS_INSTALLED XPR_DATA_INSTALLED COIN_HAS_XPR_TRUE COIN_HAS_XPR_FALSE ASL_LIBS ASL_CFLAGS ASL_DATA ASL_DEPENDENCIES ASL_LIBS_INSTALLED ASL_CFLAGS_INSTALLED ASL_DATA_INSTALLED COIN_HAS_ASL_TRUE COIN_HAS_ASL_FALSE NTYINCDIR NTYLIB COIN_HAS_NTY_TRUE COIN_HAS_NTY_FALSE CBC_BUILD_CBC_GENERIC_TRUE CBC_BUILD_CBC_GENERIC_FALSE OSICBC_DFLT_SOLVER_CLP_TRUE OSICBC_DFLT_SOLVER_CLP_FALSE OSICBC_DFLT_SOLVER_CPX_TRUE OSICBC_DFLT_SOLVER_CPX_FALSE OSICBC_DFLT_SOLVER_DYLP_TRUE OSICBC_DFLT_SOLVER_DYLP_FALSE OSICBC_DFLT_SOLVER_GLPK_TRUE OSICBC_DFLT_SOLVER_GLPK_FALSE OSICBC_DFLT_SOLVER_GRB_TRUE OSICBC_DFLT_SOLVER_GRB_FALSE OSICBC_DFLT_SOLVER_MSK_TRUE OSICBC_DFLT_SOLVER_MSK_FALSE OSICBC_DFLT_SOLVER_SPX_TRUE OSICBC_DFLT_SOLVER_SPX_FALSE OSICBC_DFLT_SOLVER_SYM_TRUE OSICBC_DFLT_SOLVER_SYM_FALSE OSICBC_DFLT_SOLVER_VOL_TRUE OSICBC_DFLT_SOLVER_VOL_FALSE OSICBC_DFLT_SOLVER_XPR_TRUE OSICBC_DFLT_SOLVER_XPR_FALSE coin_have_doxygen coin_have_latex coin_doxy_usedot coin_doxy_tagname coin_doxy_logname COIN_HAS_DOXYGEN_TRUE COIN_HAS_DOXYGEN_FALSE COIN_HAS_LATEX_TRUE COIN_HAS_LATEX_FALSE coin_doxy_tagfiles coin_doxy_excludes LIBEXT VPATH_DISTCLEANFILES ABSBUILDDIR LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -1005,7 +1005,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Cbc 2.8.12 to adapt to many kinds of systems. +\`configure' configures Cbc 2.9.9 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1071,7 +1071,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Cbc 2.8.12:";; + short | recursive ) echo "Configuration of Cbc 2.9.9:";; esac cat <<\_ACEOF @@ -1094,11 +1094,16 @@ --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) + --disable-dependency-linking + disable linking library dependencies into shared + libraries --disable-pkg-config disable use of pkg-config (if available) --disable-interpackage-dependencies disables deduction of Makefile dependencies from package linker flags --enable-gnu-packages compile with GNU packages (disabled by default) + --disable-nauty-libcheck + skip the link check at configuration time --enable-cbc-parallel enables compilation of the SMP version of Cbc Optional Packages: @@ -1164,6 +1169,8 @@ --with-asl-lib linker flags for using package ASL --with-asl-incdir directory with header files for using package ASL --with-asl-datadir directory with data files for using package ASL + --with-nauty-incdir specify the header file directory for library Nauty + --with-nauty-lib specify the flags used to link with the library Nauty --with-cbc-generic specify whether to build cbc-generic (default: no) --with-cbc-generic-solver specify default solver for cbc-generic in lower case @@ -1305,7 +1312,7 @@ test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -Cbc configure 2.8.12 +Cbc configure 2.9.9 generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -1325,7 +1332,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Cbc $as_me 2.8.12, which was +It was created by Cbc $as_me 2.9.9, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1851,7 +1858,7 @@ # Capture libtool library version, if given. - coin_libversion=11:12:8 + coin_libversion=12:9:9 @@ -2092,7 +2099,7 @@ comps="xlc gcc pgcc icc cc" fi ;; - *-*-darwin*) comps="clang gcc" ;; + *-*-darwin*) comps="clang gcc cc" ;; *-linux-gnu*) comps="gcc cc pgcc icc xlc" ;; *-linux-*) comps="xlc gcc cc pgcc icc" ;; *) comps="xlc_r xlc cc gcc pgcc icc" ;; @@ -2880,13 +2887,6 @@ coin_add_cflags="-pipe" coin_dbg_cflags="-g -O0" coin_warn_cflags="-Wimplicit -Wparentheses -Wsequence-point -Wreturn-type -Wcast-qual -Wall -Wno-unknown-pragmas -Wno-long-long" - case $build in - *-darwin*) - ;; - *) - coin_warn_cflags="-pedantic-errors $coin_warn_cflags" - ;; - esac esac fi if test -z "$coin_opt_cflags"; then @@ -3249,7 +3249,7 @@ fi ;; *-*-solaris*) comps="CC xlC_r aCC g++ c++ pgCC icpc gpp cxx cc++ cl FCC KCC RCC" ;; - *-darwin*) comps="g++ c++ CC" ;; + *-darwin*) comps="clang++ g++ c++ CC" ;; *-linux-gnu*) comps="g++ c++ pgCC icpc gpp cxx cc++ cl FCC KCC RCC xlC_r aCC CC" ;; *) comps="xlC_r aCC CC g++ c++ pgCC icpc gpp cxx cc++ cl FCC KCC RCC" ;; @@ -3686,7 +3686,7 @@ coin_cxx_is_cl=false # It seems that we need to cleanup something here for the Windows case "$CXX" in - clang* ) ;; + clang* | */clang*) ;; cl* | */cl* | CL* | */CL* | icl* | */icl* | ICL* | */ICL*) sed -e 's/^void exit (int);//' confdefs.h >> confdefs.hh mv confdefs.hh confdefs.h @@ -3749,13 +3749,6 @@ coin_add_cxxflags="-pipe" coin_dbg_cxxflags="-g -O0" coin_warn_cxxflags="-Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion -Wno-unknown-pragmas -Wno-long-long" - case $build in - *-darwin*) - ;; - *) - coin_warn_cxxflags="-pedantic-errors $coin_warn_cxxflags" - ;; - esac esac fi @@ -4086,7 +4079,7 @@ CXX="$MPICXX" fi -# correct the LD variable in a build with MS or intel compiler +# correct the LD variable in a build with MS or Intel-windows compiler case "$CXX" in clang* ) ;; cl* | */cl* | CL* | */CL* | icl* | */icl* | ICL* | */ICL*) @@ -4119,31 +4112,30 @@ fi enable_shared=yes; else - # On Cygwin and AIX, building DLLs doesn't work case $build in *-cygwin* | *-mingw*) coin_disable_shared=yes if test x"$enable_shared" = xyes; then case "$CC" in clang* ) - { echo "$as_me:$LINENO: WARNING: DLL building not supported. I'm disabling your choice." >&5 -echo "$as_me: WARNING: DLL building not supported. I'm disabling your choice." >&2;} + { echo "$as_me:$LINENO: WARNING: Building of DLLs not supported in this configuration." >&5 +echo "$as_me: WARNING: Building of DLLs not supported in this configuration." >&2;} ;; cl* | */cl* | CL* | */CL* | icl* | */icl* | ICL* | */ICL*) - { echo "$as_me:$LINENO: DLL building not supported, but will build with -MD(d) instead of -MT(d)." >&5 -echo "$as_me: DLL building not supported, but will build with -MD(d) instead of -MT(d)." >&6;} + { echo "$as_me:$LINENO: Building of DLLs not supported in this configuration." >&5 +echo "$as_me: Building of DLLs not supported in this configuration." >&6;} ;; *gcc*) - if test x"$enable_dependency_linking" = xyes; then + if test x"$enable_dependency_linking" = xyes; then coin_disable_shared=no else - { echo "$as_me:$LINENO: WARNING: To build shared libraries with gcc on CYGWIN or MSys, use --enable-dependency-linking" >&5 -echo "$as_me: WARNING: To build shared libraries with gcc on CYGWIN or MSys, use --enable-dependency-linking" >&2;} + { echo "$as_me:$LINENO: WARNING: Dependency linking seems to be disabled, so shared libraries (DLLs) will not be built" >&5 +echo "$as_me: WARNING: Dependency linking seems to be disabled, so shared libraries (DLLs) will not be built" >&2;} fi ;; *) - { echo "$as_me:$LINENO: WARNING: DLL building not supported. I'm disabling your choice." >&5 -echo "$as_me: WARNING: DLL building not supported. I'm disabling your choice." >&2;} + { echo "$as_me:$LINENO: WARNING: Building of DLLs not supported in this configuration." >&5 +echo "$as_me: WARNING: Building of DLLs not supported in this configuration." >&2;} ;; esac fi @@ -4152,8 +4144,8 @@ coin_disable_shared=yes platform=AIX if test x"$enable_shared" = xyes; then - { echo "$as_me:$LINENO: WARNING: Shared objects are not supported. I'm disabling your choice." >&5 -echo "$as_me: WARNING: Shared objects are not supported. I'm disabling your choice." >&2;} + { echo "$as_me:$LINENO: WARNING: Shared objects are not supported." >&5 +echo "$as_me: WARNING: Shared objects are not supported." >&2;} fi ;; esac @@ -4574,7 +4566,7 @@ # Define the identity of the package. PACKAGE='cbc' - VERSION='2.8.12' + VERSION='2.9.9' cat >>confdefs.h <<_ACEOF @@ -5870,7 +5862,7 @@ ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5873 "configure"' > conftest.$ac_ext + echo '#line 5865 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7004,7 +6996,7 @@ # Provide some information about the compiler. -echo "$as_me:7007:" \ +echo "$as_me:6999:" \ "checking for Fortran 77 compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 @@ -8071,11 +8063,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8074: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8066: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8078: \$? = $ac_status" >&5 + echo "$as_me:8070: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -8339,11 +8331,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8342: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8334: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8346: \$? = $ac_status" >&5 + echo "$as_me:8338: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -8443,11 +8435,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8446: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8438: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8450: \$? = $ac_status" >&5 + echo "$as_me:8442: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10788,7 +10780,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:13227: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:13239: \$? = $ac_status" >&5 + echo "$as_me:13231: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -13336,11 +13328,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:13339: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13331: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:13343: \$? = $ac_status" >&5 + echo "$as_me:13335: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14906,11 +14898,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14909: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14901: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14913: \$? = $ac_status" >&5 + echo "$as_me:14905: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -15010,11 +15002,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15013: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15005: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:15017: \$? = $ac_status" >&5 + echo "$as_me:15009: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -17217,11 +17209,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17220: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17212: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:17224: \$? = $ac_status" >&5 + echo "$as_me:17216: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -17485,11 +17477,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17488: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17480: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:17492: \$? = $ac_status" >&5 + echo "$as_me:17484: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -17589,11 +17581,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17592: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17584: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:17596: \$? = $ac_status" >&5 + echo "$as_me:17588: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -20281,7 +20273,6 @@ case $build in *-mingw*) CYGPATH_W=echo - mydos2unix= ;; esac @@ -20479,13 +20470,37 @@ enableval="$enable_dependency_linking" dependency_linking="$enableval" else - dependency_linking=no + dependency_linking=auto fi; -# ToDo -# For now, don't use the -no-undefined flag, since the Makefiles are -# not yet set up that way. But we need to fix this, when we want -# to comile DLLs under Windows. +if test "$dependency_linking" = auto; then + # On Cygwin and AIX, building DLLs doesn't work + dependency_linking=no + if test x"$coin_disable_shared" = xno; then + case $build in + *-cygwin* | *-mingw*) + case "$CC" in + clang* ) + dependency_linking=yes + ;; + cl* | */cl* | CL* | */CL* | icl* | */icl* | ICL* | */ICL*) + dependency_linking=no + ;; + *gcc*) + dependency_linking=yes + ;; + *) + dependency_linking=yes + ;; + esac + ;; + *) + dependency_linking=yes + ;; + esac + fi +fi + if test "$dependency_linking" = yes ; then LT_LDFLAGS="-no-undefined" @@ -29616,6 +29631,211 @@ +# Nauty library (for symmetry detection) +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + echo "$as_me:$LINENO: checking if user provides library for Nauty" >&5 +echo $ECHO_N "checking if user provides library for Nauty... $ECHO_C" >&6 + +# Check for header file directory + + +# Check whether --with-nauty-incdir or --without-nauty-incdir was given. +if test "${with_nauty_incdir+set}" = set; then + withval="$with_nauty_incdir" + NTYINCDIR=`cd $withval; pwd` +fi; + +# Check for library directory + + +# Check whether --with-nauty-lib or --without-nauty-lib was given. +if test "${with_nauty_lib+set}" = set; then + withval="$with_nauty_lib" + NTYLIB=$withval +fi; + +# Switch to disable library check if requested + + # Check whether --enable-nauty-libcheck or --disable-nauty-libcheck was given. +if test "${enable_nauty_libcheck+set}" = set; then + enableval="$enable_nauty_libcheck" + nauty_libcheck=$enableval +else + nauty_libcheck=yes +fi; + +# At this point, if we're going to use the library, both LBRYINCDIR and +# LBRYLIB must be defined and not empty. + + if test x"$NTYINCDIR" != x || test x"$NTYLIB" != x; then + if test x"$NTYINCDIR" = x || test x"$NTYLIB" = x; then + { { echo "$as_me:$LINENO: error: You need to specify both an include directory and link flags to use library Nauty. Use --with-nauty-incdir of environment variable $NTYINCDIR to specify the include directory. Use --with-nauty-lib or environment variable $NTYLIB to specify link flags." >&5 +echo "$as_me: error: You need to specify both an include directory and link flags to use library Nauty. Use --with-nauty-incdir of environment variable $NTYINCDIR to specify the include directory. Use --with-nauty-lib or environment variable $NTYLIB to specify link flags." >&2;} + { (exit 1); exit 1; }; } + fi + coin_has_nty=true + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + coin_has_nty=false + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + +# If we have instructions for use, consider header and link checks. + + if test $coin_has_nty = true; then + +# If argument 3 (file) is given, check for the file. Typically this will be a +# header file, but that's not assumed. + + if test -r $NTYINCDIR/nauty.h; then + + : +else + { { echo "$as_me:$LINENO: error: Cannot find file nauty.h in $NTYINCDIR" >&5 +echo "$as_me: error: Cannot find file nauty.h in $NTYINCDIR" >&2;} + { (exit 1); exit 1; }; } + : +fi + + +# Now see if we can link the function. There are arguments for and against +# assuming argument 3 is a header file declaring the function. A correct +# function declaration is the main argument in favour. Having to cope with +# possible dependencies or other oddities are the main arguments against. +# Force the use of C as the best single choice amongst C++, C, and Fortran. +# Obviously, this has limits. + + if test x"$nauty_libcheck" != xno; then + coin_save_LIBS="$LIBS" + LIBS="$NTYLIB " + coin_NTY_link=no + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + for fnm in nauty ; do + echo "$as_me:$LINENO: checking whether symbol $fnm is available with NTY" >&5 +echo $ECHO_N "checking whether symbol $fnm is available with NTY... $ECHO_C" >&6 + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +$fnm() + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + coin_NTY_link=yes + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + LIBS="$coin_save_LIBS" + if test x"$coin_NTY_link" != xyes ; then + { { echo "$as_me:$LINENO: error: Cannot find symbol(s) nauty with NTY" >&5 +echo "$as_me: error: Cannot find symbol(s) nauty with NTY" >&2;} + { (exit 1); exit 1; }; } + fi + fi + + +# If we make it this far, we've verified the file and linked the function. Add +# the necessary link flags to CbcLib CbcGeneric_{PC}LIBS and define the preprocessor symbol +# COIN_HAS_LBRY. + + + CBCLIB_LIBS="$NTYLIB $CBCLIB_LIBS" + CBCLIB_PCLIBS="$NTYLIB $CBCLIB_PCLIBS" + CBCLIB_LIBS_INSTALLED="$NTYLIB $CBCLIB_LIBS_INSTALLED" + + CBCGENERIC_LIBS="$NTYLIB $CBCGENERIC_LIBS" + CBCGENERIC_PCLIBS="$NTYLIB $CBCGENERIC_PCLIBS" + CBCGENERIC_LIBS_INSTALLED="$NTYLIB $CBCGENERIC_LIBS_INSTALLED" + + + +cat >>confdefs.h <<\_ACEOF +#define COIN_HAS_NTY 1 +_ACEOF + + fi + +# Arrange for configure to substitute LBRYINCDIR and LBRYLIB and create the +# automake conditional. These actions must occur unconditionally. + + + + + +if test $coin_has_nty = true; then + COIN_HAS_NTY_TRUE= + COIN_HAS_NTY_FALSE='#' +else + COIN_HAS_NTY_TRUE='#' + COIN_HAS_NTY_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ############################################################################# # CbcGeneric configuration # ############################################################################# @@ -30223,6 +30443,42 @@ echo "${ECHO_T}no" >&6 fi +# Extract the first word of "latex", so it can be a program name with args. +set dummy latex; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_coin_have_latex+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$coin_have_latex"; then + ac_cv_prog_coin_have_latex="$coin_have_latex" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_coin_have_latex="yes" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_coin_have_latex" && ac_cv_prog_coin_have_latex="no" +fi +fi +coin_have_latex=$ac_cv_prog_coin_have_latex +if test -n "$coin_have_latex"; then + echo "$as_me:$LINENO: result: $coin_have_latex" >&5 +echo "${ECHO_T}$coin_have_latex" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + # Look for the dot tool from the graphviz package, unless the user has # disabled it. @@ -30287,6 +30543,26 @@ coin_doxy_logname=doxydoc/${PACKAGE}_doxy.log + +if test $coin_have_doxygen = yes; then + COIN_HAS_DOXYGEN_TRUE= + COIN_HAS_DOXYGEN_FALSE='#' +else + COIN_HAS_DOXYGEN_TRUE='#' + COIN_HAS_DOXYGEN_FALSE= +fi + + + +if test $coin_have_latex = yes; then + COIN_HAS_LATEX_TRUE= + COIN_HAS_LATEX_FALSE='#' +else + COIN_HAS_LATEX_TRUE='#' + COIN_HAS_LATEX_FALSE= +fi + + # Process the list of project names and massage them into possible doxygen # doc'n directories. Prefer 1) classic external, source processed using # a project-specific doxygen.conf, we use the tag file; 2) classic @@ -30306,32 +30582,28 @@ echo $ECHO_N "checking for doxygen doc'n for $proj ... $ECHO_C" >&6 doxytag=${lc_proj}_doxy.tag doxyfound=no - for chkProj in $coin_subdirs ; do - if test "$chkProj" = "$proj" ; then - # proj will be configured, hence doxydoc present in build tree - doxysrcdir="${srcdir}/${proj}" - # AC_MSG_NOTICE([Considering $doxysrcdir (base)]) - if test -d "$doxysrcdir" ; then - # with a doxydoc directory? - doxydir="$doxysrcdir/doxydoc" - # AC_MSG_NOTICE([Considering $doxydir (base)]) - # AC_MSG_NOTICE([Subdirs: $coin_subdirs)]) - if test -d "$doxydir" ; then - # use tag file; don't process source - eval doxydir="`pwd`/${proj}/doxydoc" - coin_doxy_tagfiles="$coin_doxy_tagfiles $doxydir/$doxytag=$doxydir/html" - echo "$as_me:$LINENO: result: $doxydir (tag)" >&5 + # proj will be configured, hence doxydoc present in build tree + doxysrcdir="${srcdir}/../${proj}" + # AC_MSG_NOTICE([Considering $doxysrcdir (base)]) + if test -d "$doxysrcdir" ; then + # with a doxydoc directory? + doxydir="$doxysrcdir/doxydoc" + # AC_MSG_NOTICE([Considering $doxydir (base)]) + # AC_MSG_NOTICE([Subdirs: $coin_subdirs)]) + if test -d "$doxydir" ; then + # use tag file; don't process source + doxydir="../${proj}/doxydoc" + coin_doxy_tagfiles="$coin_doxy_tagfiles $doxydir/$doxytag=../../$doxydir/html" + echo "$as_me:$LINENO: result: $doxydir (tag)" >&5 echo "${ECHO_T}$doxydir (tag)" >&6 - coin_doxy_excludes="$coin_doxy_excludes */${proj}" - else - # will process the source -- nothing further to be done here - echo "$as_me:$LINENO: result: $doxysrcdir (src)" >&5 + coin_doxy_excludes="$coin_doxy_excludes */${proj}" + else + # will process the source -- nothing further to be done here + echo "$as_me:$LINENO: result: $doxysrcdir (src)" >&5 echo "${ECHO_T}$doxysrcdir (src)" >&6 - fi - doxyfound=yes - fi fi - done + doxyfound=yes + fi # Not built, fall back to installed tag file if test $doxyfound = no ; then eval doxydir="${datadir}/coin/doc/${proj}/doxydoc" @@ -30796,6 +31068,13 @@ Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${COIN_HAS_NTY_TRUE}" && test -z "${COIN_HAS_NTY_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"COIN_HAS_NTY\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"COIN_HAS_NTY\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi if test -z "${CBC_BUILD_CBC_GENERIC_TRUE}" && test -z "${CBC_BUILD_CBC_GENERIC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"CBC_BUILD_CBC_GENERIC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 @@ -30873,6 +31152,20 @@ Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${COIN_HAS_DOXYGEN_TRUE}" && test -z "${COIN_HAS_DOXYGEN_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"COIN_HAS_DOXYGEN\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"COIN_HAS_DOXYGEN\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${COIN_HAS_LATEX_TRUE}" && test -z "${COIN_HAS_LATEX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"COIN_HAS_LATEX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"COIN_HAS_LATEX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files @@ -31144,7 +31437,7 @@ } >&5 cat >&5 <<_CSEOF -This file was extended by Cbc $as_me 2.8.12, which was +This file was extended by Cbc $as_me 2.9.9, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -31207,7 +31500,7 @@ cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -Cbc config.status 2.8.12 +Cbc config.status 2.9.9 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -31675,6 +31968,10 @@ s,@ASL_DATA_INSTALLED@,$ASL_DATA_INSTALLED,;t t s,@COIN_HAS_ASL_TRUE@,$COIN_HAS_ASL_TRUE,;t t s,@COIN_HAS_ASL_FALSE@,$COIN_HAS_ASL_FALSE,;t t +s,@NTYINCDIR@,$NTYINCDIR,;t t +s,@NTYLIB@,$NTYLIB,;t t +s,@COIN_HAS_NTY_TRUE@,$COIN_HAS_NTY_TRUE,;t t +s,@COIN_HAS_NTY_FALSE@,$COIN_HAS_NTY_FALSE,;t t s,@CBC_BUILD_CBC_GENERIC_TRUE@,$CBC_BUILD_CBC_GENERIC_TRUE,;t t s,@CBC_BUILD_CBC_GENERIC_FALSE@,$CBC_BUILD_CBC_GENERIC_FALSE,;t t s,@OSICBC_DFLT_SOLVER_CLP_TRUE@,$OSICBC_DFLT_SOLVER_CLP_TRUE,;t t @@ -31698,9 +31995,14 @@ s,@OSICBC_DFLT_SOLVER_XPR_TRUE@,$OSICBC_DFLT_SOLVER_XPR_TRUE,;t t s,@OSICBC_DFLT_SOLVER_XPR_FALSE@,$OSICBC_DFLT_SOLVER_XPR_FALSE,;t t s,@coin_have_doxygen@,$coin_have_doxygen,;t t +s,@coin_have_latex@,$coin_have_latex,;t t s,@coin_doxy_usedot@,$coin_doxy_usedot,;t t s,@coin_doxy_tagname@,$coin_doxy_tagname,;t t s,@coin_doxy_logname@,$coin_doxy_logname,;t t +s,@COIN_HAS_DOXYGEN_TRUE@,$COIN_HAS_DOXYGEN_TRUE,;t t +s,@COIN_HAS_DOXYGEN_FALSE@,$COIN_HAS_DOXYGEN_FALSE,;t t +s,@COIN_HAS_LATEX_TRUE@,$COIN_HAS_LATEX_TRUE,;t t +s,@COIN_HAS_LATEX_FALSE@,$COIN_HAS_LATEX_FALSE,;t t s,@coin_doxy_tagfiles@,$coin_doxy_tagfiles,;t t s,@coin_doxy_excludes@,$coin_doxy_excludes,;t t s,@LIBEXT@,$LIBEXT,;t t diff -Nru coinor-cbc-2.8.12/configure.ac coinor-cbc-2.9.9+repack1/configure.ac --- coinor-cbc-2.8.12/configure.ac 2014-08-28 03:30:12.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/configure.ac 2017-06-12 10:55:45.000000000 +0000 @@ -2,7 +2,7 @@ # All Rights Reserved. # This file is distributed under the Eclipse Public License. -## $Id: configure.ac 2065 2014-08-28 03:30:12Z tkr $ +## $Id: configure.ac 2335 2017-06-12 10:55:45Z stefan $ # Author: Andreas Waechter IBM 2006-04-13 @@ -12,7 +12,7 @@ AC_PREREQ(2.59) -AC_INIT([Cbc],[2.8.12],[cbc@lists.coin-or.org]) +AC_INIT([Cbc],[2.9.9],[cbc@lists.coin-or.org]) AC_COPYRIGHT([ Copyright 2006 International Business Machines and others. @@ -41,7 +41,7 @@ # the source root directory contains definition of where to find those # externals. The following macro ensures that those externals are # retrieved by svn if they are not there yet. -AC_COIN_PROJECTDIR_INIT(Cbc,11:12:8) +AC_COIN_PROJECTDIR_INIT(Cbc,12:9:9) # Check if user wants to produce debugging code AC_COIN_DEBUG_COMPILE(Cbc) @@ -105,6 +105,11 @@ # Ampl Solver library AC_COIN_CHECK_PACKAGE(ASL, [coinasl], [CbcLib CbcGeneric]) +# Nauty library (for symmetry detection) +AC_LANG_PUSH(C) +AC_COIN_CHECK_USER_LIBRARY([Nauty],[NTY],[nauty.h],[nauty],,[CbcLib CbcGeneric]) +AC_LANG_POP(C) + ############################################################################# # CbcGeneric configuration # ############################################################################# diff -Nru coinor-cbc-2.8.12/debian/changelog coinor-cbc-2.9.9+repack1/debian/changelog --- coinor-cbc-2.8.12/debian/changelog 2016-02-22 08:13:07.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/debian/changelog 2017-08-21 19:34:44.000000000 +0000 @@ -1,14 +1,39 @@ -coinor-cbc (2.8.12-1build2) xenial; urgency=medium +coinor-cbc (2.9.9+repack1-1) unstable; urgency=medium - * No-change rebuild for coinor-osi transition. + * Upload into unstable. - -- Matthias Klose Mon, 22 Feb 2016 08:13:07 +0000 + -- Anton Gladky Mon, 21 Aug 2017 21:34:44 +0200 -coinor-cbc (2.8.12-1build1) wily; urgency=medium +coinor-cbc (2.9.9+repack1-1~exp1) experimental; urgency=medium - * No-change rebuild against coinor-libcoinutils3v5 + * [f64a864] Update version numbers + * [4a17490] Set Standards-Version: 4.0.0 + * [129492e] New upstream version 2.9.9+repack1. (Closes: #853350) - -- Steve Langasek Thu, 13 Aug 2015 01:00:11 +0000 + -- Anton Gladky Mon, 21 Aug 2017 10:05:50 +0200 + +coinor-cbc (2.9.8+repack1-1~exp2) experimental; urgency=medium + + * [0b158f8] Rename variable which is causing FTBFSs on mips* archs. + + -- Anton Gladky Tue, 06 Jun 2017 21:14:55 +0200 + +coinor-cbc (2.9.8+repack1-1~exp1) experimental; urgency=medium + + * [4da03d4] Update d/watch + * [f7174cf] Remove unneeded for the build files from the package. + * [b9b9c31] New upstream version 2.9.8+repack1 + * [b3244ac] Set compat level 10. + * [4ab9c53] Remove dbg-package. + * [661a425] Use maximal hardening. + * [e75adb0] Remove applied by upstream patch. + * [7397876] Apply cme fix dpkg. + * [427b409] Update version numbers and entries in dependencies. + (Closes: #780049) + * [8e596a6] Remove Miles Lubin from uploaders. (Closes: #862817) + * [0e96c8d] Add myself to uploaders. + + -- Anton Gladky Mon, 05 Jun 2017 19:55:59 +0200 coinor-cbc (2.8.12-1) unstable; urgency=low diff -Nru coinor-cbc-2.8.12/debian/compat coinor-cbc-2.9.9+repack1/debian/compat --- coinor-cbc-2.8.12/debian/compat 2013-11-05 19:01:38.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/debian/compat 2017-08-21 19:31:47.000000000 +0000 @@ -1 +1 @@ -9 +10 diff -Nru coinor-cbc-2.8.12/debian/control coinor-cbc-2.9.9+repack1/debian/control --- coinor-cbc-2.8.12/debian/control 2015-08-13 01:00:11.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/debian/control 2017-08-21 19:31:47.000000000 +0000 @@ -1,14 +1,13 @@ Source: coinor-cbc +Maintainer: Debian Science Team +Uploaders: Anton Gladky Section: science Priority: extra -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian Science Team -Uploaders: Miles Lubin -Build-Depends: coinor-libcgl-dev (>= 0.58.9), - coinor-libclp-dev (>= 1.15.10), - coinor-libcoinutils-dev (>= 2.9.15), - coinor-libosi-dev (>= 0.106.9), - debhelper (>= 9), +Build-Depends: coinor-libcgl-dev (>= 0.59.10), + coinor-libclp-dev (>= 1.16.11), + coinor-libcoinutils-dev (>= 2.10.14), + coinor-libosi-dev (>= 0.107.9), + debhelper (>= 10), doxygen, graphviz, libblas-dev, @@ -16,16 +15,17 @@ pkg-config, zlib1g-dev, autotools-dev -Standards-Version: 3.9.5 +Standards-Version: 4.0.0 +Vcs-Browser: https://anonscm.debian.org/cgit/debian-science/packages/coinor-cbc.git +Vcs-Git: https://anonscm.debian.org/git/debian-science/packages/coinor-cbc.git Homepage: https://projects.coin-or.org/Cbc -Vcs-Git: git://anonscm.debian.org/debian-science/packages/coinor-cbc.git -Vcs-Browser: http://anonscm.debian.org/gitweb/?p=debian-science/packages/coinor-cbc.git Package: coinor-cbc Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Replaces: coinor-libcbc0 +Depends: ${misc:Depends}, + ${shlibs:Depends} Breaks: coinor-libcbc0 +Replaces: coinor-libcbc0 Description: Coin-or branch-and-cut mixed integer programming solver Cbc (Coin-or branch and cut) is an open-source mixed integer programming solver written in C++. It can be used as a callable library or as a @@ -35,7 +35,8 @@ Package: coinor-libcbc3 Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} +Depends: ${misc:Depends}, + ${shlibs:Depends} Description: Coin-or branch-and-cut mixed integer programming solver (shared libraries) Cbc (Coin-or branch and cut) is an open-source mixed integer programming solver written in C++. It can be used as a callable library or as a @@ -44,9 +45,13 @@ This package contains the shared libraries. Package: coinor-libcbc-dev -Section: libdevel Architecture: any +Section: libdevel Depends: coinor-libcbc3 (= ${binary:Version}), + coinor-libcgl-dev (>= 0.59.9), + coinor-libclp-dev (>= 1.16.10), + coinor-libcoinutils-dev (>= 2.10.13), + coinor-libosi-dev (>= 0.107.8), ${misc:Depends}, ${shlibs:Depends} Description: Coin-or branch-and-cut mixed integer programming solver (developer files) @@ -57,9 +62,10 @@ This package contains the header files for developers. Package: coinor-libcbc-doc -Section: doc Architecture: all -Depends: libjs-jquery, ${misc:Depends} +Section: doc +Depends: libjs-jquery, + ${misc:Depends} Recommends: coinor-libcbc-dev Description: Coin-or branch-and-cut mixed integer programming solver (documentation) Cbc (Coin-or branch and cut) is an open-source mixed integer programming @@ -67,16 +73,3 @@ stand-alone executable. . This package contains the documentation and examples. - -Package: coinor-libcbc3-dbg -Section: debug -Architecture: any -Depends: coinor-libcbc3 (= ${binary:Version}), - ${misc:Depends}, - ${shlibs:Depends} -Description: Coin-or branch-and-cut mixed integer programming solver (debug symbols) - Cbc (Coin-or branch and cut) is an open-source mixed integer programming - solver written in C++. It can be used as a callable library or as a - stand-alone executable. - . - This package contains the debug symbols. diff -Nru coinor-cbc-2.8.12/debian/copyright coinor-cbc-2.9.9+repack1/debian/copyright --- coinor-cbc-2.8.12/debian/copyright 2013-11-30 21:47:08.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/debian/copyright 2017-08-21 19:31:47.000000000 +0000 @@ -1,6 +1,8 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Cbc Source: https://projects.coin-or.org/Cbc +Files-Excluded: + MSVisualStudio Files: * Copyright: 2000-2013, IBM Corporation and others @@ -24,43 +26,6 @@ 2006 IBM Corportation and others License: LUCENT -License: LUCENT - Permission to use, copy, modify, and distribute this software and - its documentation for any purpose and without fee is hereby - granted, provided that the above copyright notice appear in all - copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of Lucent or any of its entities - not be used in advertising or publicity pertaining to - distribution of the software without specific, written prior - permission. - . - LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY - SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - THIS SOFTWARE. - -License: GPL-3 - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License version 3 as - published by the Free Software Foundation. - . - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see . - . - On Debian systems, the complete text of the GNU General Public - License, version 3, can be found in the file - `/usr/share/common-licenses/GPL-3'. - License: EPL-1 Eclipse Public License - v 1.0 . @@ -77,9 +42,9 @@ . b) in the case of each subsequent Contributor: . - i) changes to the Program, and + i) changes to the Program, and . - ii) additions to the Program; + ii) additions to the Program; . where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A @@ -153,24 +118,24 @@ . b) its license agreement: . - i) effectively disclaims on behalf of all Contributors all - warranties and conditions, express and implied, including - warranties or conditions of title and non-infringement, and - implied warranties or conditions of merchantability and - fitness for a particular purpose; - . - ii) effectively excludes on behalf of all Contributors all - liability for damages, including direct, indirect, special, - incidental and consequential damages, such as lost profits; - . - iii) states that any provisions which differ from this - Agreement are offered by that Contributor alone and not by - any other party; and - . - iv) states that source code for the Program is available - from such Contributor, and informs licensees how to obtain - it in a reasonable manner on or through a medium customarily - used for software exchange. + i) effectively disclaims on behalf of all Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and + fitness for a particular purpose; + . + ii) effectively excludes on behalf of all Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + . + iii) states that any provisions which differ from this + Agreement are offered by that Contributor alone and not by + any other party; and + . + iv) states that source code for the Program is available + from such Contributor, and informs licensees how to obtain + it in a reasonable manner on or through a medium customarily + used for software exchange. . When the Program is made available in source code form: . @@ -301,3 +266,40 @@ party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. + +License: GPL-3 + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3 as + published by the Free Software Foundation. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . + . + On Debian systems, the complete text of the GNU General Public + License, version 3, can be found in the file + `/usr/share/common-licenses/GPL-3'. + +License: LUCENT + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby + granted, provided that the above copyright notice appear in all + copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of Lucent or any of its entities + not be used in advertising or publicity pertaining to + distribution of the software without specific, written prior + permission. + . + LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. + IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. diff -Nru coinor-cbc-2.8.12/debian/patches/10_rename_mips_variable.patch coinor-cbc-2.9.9+repack1/debian/patches/10_rename_mips_variable.patch --- coinor-cbc-2.8.12/debian/patches/10_rename_mips_variable.patch 1970-01-01 00:00:00.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/debian/patches/10_rename_mips_variable.patch 2017-08-21 19:31:47.000000000 +0000 @@ -0,0 +1,17 @@ +Description: Rename variable which is causing FTBFSs in mips* archs. +Author: Anton Gladky +Last-Update: 2017-06-06 + +--- coinor-cbc-2.9.8+repack1.orig/src/CbcModel.hpp ++++ coinor-cbc-2.9.8+repack1/src/CbcModel.hpp +@@ -2394,8 +2394,8 @@ public: + void redoWalkBack(); + //@} + +- void setMIPStart( const std::vector< std::pair< std::string, double > > &mips ) { +- this->mipStart_ = mips; ++ void setMIPStart( const std::vector< std::pair< std::string, double > > &MIPS ) { ++ this->mipStart_ = MIPS; + } + + const std::vector< std::pair< std::string, double > > &getMIPStart() { diff -Nru coinor-cbc-2.8.12/debian/patches/fix-addlibs-file.patch coinor-cbc-2.9.9+repack1/debian/patches/fix-addlibs-file.patch --- coinor-cbc-2.8.12/debian/patches/fix-addlibs-file.patch 2014-09-04 12:04:56.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/debian/patches/fix-addlibs-file.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -Author: Miles Lubin -Description: Fix production of cbc_addlibs.txt file. -Bug: https://projects.coin-or.org/BuildTools/ticket/104 ---- a/Makefile.in -+++ b/Makefile.in -@@ -980,7 +980,7 @@ - - install-data-hook: - @$(mkdir_p) "$(addlibsdir)" --@COIN_HAS_PKGCONFIG_TRUE@ PKG_CONFIG_PATH=@COIN_PKG_CONFIG_PATH@ \ -+@COIN_HAS_PKGCONFIG_TRUE@ PKG_CONFIG_PATH=$(DESTDIR)$(pkgconfiglibdir) \ - @COIN_HAS_PKGCONFIG_TRUE@ $(PKG_CONFIG) --libs cbc > $(addlibsdir)/cbc_addlibs.txt - @COIN_CXX_IS_CL_TRUE@@COIN_HAS_PKGCONFIG_FALSE@ echo "-libpath:`$(CYGPATH_W) @abs_lib_dir@` libCbc.lib @CBCLIB_LIBS_INSTALLED@" > $(addlibsdir)/cbc_addlibs.txt - @COIN_CXX_IS_CL_FALSE@@COIN_HAS_PKGCONFIG_FALSE@ echo -L@abs_lib_dir@ -lCbcSolver -lCbc @CBCLIB_LIBS_INSTALLED@ > $(addlibsdir)/cbc_addlibs.txt diff -Nru coinor-cbc-2.8.12/debian/patches/series coinor-cbc-2.9.9+repack1/debian/patches/series --- coinor-cbc-2.8.12/debian/patches/series 2014-09-04 12:04:56.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/debian/patches/series 2017-08-21 19:31:47.000000000 +0000 @@ -1 +1 @@ -fix-addlibs-file.patch +10_rename_mips_variable.patch diff -Nru coinor-cbc-2.8.12/debian/rules coinor-cbc-2.9.9+repack1/debian/rules --- coinor-cbc-2.8.12/debian/rules 2014-09-04 12:04:56.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/debian/rules 2017-08-21 19:31:47.000000000 +0000 @@ -1,7 +1,9 @@ #!/usr/bin/make -f -override_dh_strip: - dh_strip --dbg-package=coinor-libcbc3-dbg +export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +%: + dh $@ --with autotools_dev --without autoreconf override_dh_auto_build: dh_auto_build -- @@ -18,7 +20,3 @@ override_dh_auto_install: dh_auto_install -- $(RM) debian/tmp/usr/share/coin/doc/Cbc/LICENSE - - -%: - dh $@ --with autotools_dev diff -Nru coinor-cbc-2.8.12/debian/watch coinor-cbc-2.9.9+repack1/debian/watch --- coinor-cbc-2.8.12/debian/watch 2013-11-30 21:47:08.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/debian/watch 2017-08-21 19:31:47.000000000 +0000 @@ -1,3 +1,3 @@ version=3 -http://www.coin-or.org/download/pkgsource/Cbc/Cbc-([\d\.]+).tgz \ - debian +opts=repacksuffix=+repack1,uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha|b|a)\d*)$/$1~$2/,dversionmangle=s/\+(debian|dfsg|ds|deb|-dfsg)\d*$// \ +http://www.coin-or.org/download/pkgsource/Cbc/Cbc-(\d\S*).(?:zip|tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) diff -Nru coinor-cbc-2.8.12/examples/allCuts.cpp coinor-cbc-2.9.9+repack1/examples/allCuts.cpp --- coinor-cbc-2.8.12/examples/allCuts.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/allCuts.cpp 2013-04-09 18:06:04.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: allCuts.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: allCuts.cpp 1898 2013-04-09 18:06:04Z stefan $ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/barrier.cpp coinor-cbc-2.9.9+repack1/examples/barrier.cpp --- coinor-cbc-2.8.12/examples/barrier.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/barrier.cpp 2013-04-09 18:06:04.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: barrier.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: barrier.cpp 1898 2013-04-09 18:06:04Z stefan $ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/CbcBranchFollow2.cpp coinor-cbc-2.9.9+repack1/examples/CbcBranchFollow2.cpp --- coinor-cbc-2.8.12/examples/CbcBranchFollow2.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/CbcBranchFollow2.cpp 2013-04-09 18:06:04.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchFollow2.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchFollow2.cpp 1898 2013-04-09 18:06:04Z stefan $ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/CbcBranchLink.cpp coinor-cbc-2.9.9+repack1/examples/CbcBranchLink.cpp --- coinor-cbc-2.8.12/examples/CbcBranchLink.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/CbcBranchLink.cpp 2013-04-10 13:30:07.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchLink.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchLink.cpp 1900 2013-04-10 13:30:07Z forrest $ // Copyright (C) 2005, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/CbcBranchLink.hpp coinor-cbc-2.9.9+repack1/examples/CbcBranchLink.hpp --- coinor-cbc-2.8.12/examples/CbcBranchLink.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/CbcBranchLink.hpp 2013-04-10 13:30:07.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchLink.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchLink.hpp 1900 2013-04-10 13:30:07Z forrest $ // Copyright (C) 2005, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/CbcBranchUser.cpp coinor-cbc-2.9.9+repack1/examples/CbcBranchUser.cpp --- coinor-cbc-2.8.12/examples/CbcBranchUser.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/CbcBranchUser.cpp 2013-04-09 18:06:04.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchUser.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchUser.cpp 1898 2013-04-09 18:06:04Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/CbcCompareUser.cpp coinor-cbc-2.9.9+repack1/examples/CbcCompareUser.cpp --- coinor-cbc-2.8.12/examples/CbcCompareUser.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/CbcCompareUser.cpp 2013-04-09 18:06:04.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCompareUser.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCompareUser.cpp 1898 2013-04-09 18:06:04Z stefan $ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/cbc_driverC_sos.c coinor-cbc-2.9.9+repack1/examples/cbc_driverC_sos.c --- coinor-cbc-2.8.12/examples/cbc_driverC_sos.c 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/cbc_driverC_sos.c 2013-04-09 18:06:04.000000000 +0000 @@ -3,7 +3,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: cbc_driverC_sos.c 1902 2013-04-10 16:58:16Z stefan $ + $Id: cbc_driverC_sos.c 1898 2013-04-09 18:06:04Z stefan $ */ /* This example shows the use of the "C" interface for CBC. */ diff -Nru coinor-cbc-2.8.12/examples/CbcSolver3.cpp coinor-cbc-2.9.9+repack1/examples/CbcSolver3.cpp --- coinor-cbc-2.8.12/examples/CbcSolver3.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/CbcSolver3.cpp 2013-04-09 18:06:04.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcSolver3.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcSolver3.cpp 1898 2013-04-09 18:06:04Z stefan $ // Copyright (C) 2005, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/CbcSolverLongThin.cpp coinor-cbc-2.9.9+repack1/examples/CbcSolverLongThin.cpp --- coinor-cbc-2.8.12/examples/CbcSolverLongThin.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/CbcSolverLongThin.cpp 2013-04-09 18:06:04.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcSolverLongThin.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcSolverLongThin.cpp 1898 2013-04-09 18:06:04Z stefan $ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/crew.cpp coinor-cbc-2.9.9+repack1/examples/crew.cpp --- coinor-cbc-2.8.12/examples/crew.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/crew.cpp 2013-04-09 18:06:04.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: crew.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: crew.cpp 1898 2013-04-09 18:06:04Z stefan $ // Copyright (C) 2005, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/driver2.cpp coinor-cbc-2.9.9+repack1/examples/driver2.cpp --- coinor-cbc-2.8.12/examples/driver2.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/driver2.cpp 2013-04-09 18:06:04.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: driver2.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: driver2.cpp 1898 2013-04-09 18:06:04Z stefan $ // Copyright (C) 2005, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/driver3.cpp coinor-cbc-2.9.9+repack1/examples/driver3.cpp --- coinor-cbc-2.8.12/examples/driver3.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/driver3.cpp 2013-04-09 18:06:04.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: driver3.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: driver3.cpp 1898 2013-04-09 18:06:04Z stefan $ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/examples/driver4.cpp coinor-cbc-2.9.9+repack1/examples/driver4.cpp --- coinor-cbc-2.8.12/examples/driver4.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/driver4.cpp 2014-12-03 17:43:20.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: driver4.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: driver4.cpp 2101 2014-12-03 17:43:20Z forrest $ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -11,6 +11,12 @@ #include "CbcModel.hpp" #include "OsiClpSolverInterface.hpp" #include "CbcSolver.hpp" +#include "CbcHeuristicDiveCoefficient.hpp" +#include "CbcHeuristicDiveFractional.hpp" +#include "CbcHeuristicDiveGuided.hpp" +#include "CbcHeuristicDiveVectorLength.hpp" +#include "CbcHeuristicDivePseudoCost.hpp" +#include "CbcHeuristicDiveLineSearch.hpp" #include "CoinTime.hpp" @@ -69,13 +75,87 @@ break; case 3: { + // Add in some diving heuristics with different options + CbcHeuristicDiveCoefficient heuristicDC(*model); + heuristicDC.setHeuristicName("DiveCoefficient"); + // do if no solution + heuristicDC.setWhen(3); + // 150 passes and fix general integers + heuristicDC.setMaxIterations(151); + // make sure can do as many simplex iterations as wanted + heuristicDC.setMaxSimplexIterations(COIN_INT_MAX); + heuristicDC.setMaxSimplexIterationsAtRoot(COIN_INT_MAX); + model->addHeuristic(&heuristicDC) ; + CbcHeuristicDiveFractional heuristicDF(*model); + heuristicDF.setHeuristicName("DiveFractional"); + // do if no solution + heuristicDF.setWhen(3); + // 150 passes and don't fix general integers + heuristicDF.setMaxIterations(150); + // make sure can do as many simplex iterations as wanted + heuristicDF.setMaxSimplexIterations(COIN_INT_MAX); + heuristicDF.setMaxSimplexIterationsAtRoot(COIN_INT_MAX); + model->addHeuristic(&heuristicDF) ; + CbcHeuristicDiveGuided heuristicDG(*model); + heuristicDG.setHeuristicName("DiveGuided"); + // do if no solution + heuristicDG.setWhen(3); + // 200 passes and fix general integers + heuristicDG.setMaxIterations(201); + // make sure can do as many simplex iterations as wanted + heuristicDG.setMaxSimplexIterations(COIN_INT_MAX); + heuristicDG.setMaxSimplexIterationsAtRoot(COIN_INT_MAX); + model->addHeuristic(&heuristicDG) ; + CbcHeuristicDiveVectorLength heuristicDV(*model); + heuristicDV.setHeuristicName("DiveVectorLength"); + // do if no solution + heuristicDV.setWhen(3); + // 150 passes and fix general integers + heuristicDV.setMaxIterations(151); + // make sure can do as many simplex iterations as wanted + heuristicDV.setMaxSimplexIterations(COIN_INT_MAX); + heuristicDV.setMaxSimplexIterationsAtRoot(COIN_INT_MAX); + model->addHeuristic(&heuristicDV) ; + // Second version! + CbcHeuristicDiveVectorLength heuristicDV2(*model); + heuristicDV2.setHeuristicName("DiveVectorLength"); + // do if no solution + heuristicDV2.setWhen(3); + // 300 passes and don't fix general integers + heuristicDV2.setMaxIterations(300); + // fix fewer + heuristicDV2.setPercentageToFix(0.05); + // make sure can do as many simplex iterations as wanted + heuristicDV2.setMaxSimplexIterations(COIN_INT_MAX); + heuristicDV2.setMaxSimplexIterationsAtRoot(COIN_INT_MAX); + model->addHeuristic(&heuristicDV2) ; + CbcHeuristicDivePseudoCost heuristicDP(*model); + heuristicDP.setHeuristicName("DivePseudoCost"); + // do if no solution + heuristicDP.setWhen(3); + // 100 passes and don't fix general integers + heuristicDP.setMaxIterations(100); + // make sure can do as many simplex iterations as wanted + heuristicDP.setMaxSimplexIterations(COIN_INT_MAX); + heuristicDP.setMaxSimplexIterationsAtRoot(COIN_INT_MAX); + model->addHeuristic(&heuristicDP) ; + CbcHeuristicDiveLineSearch heuristicDL(*model); + heuristicDL.setHeuristicName("DiveLineSearch"); + // do if no solution + heuristicDL.setWhen(3); + // 150 passes and fix general integers + heuristicDL.setMaxIterations(151); + // make sure can do as many simplex iterations as wanted + heuristicDL.setMaxSimplexIterations(COIN_INT_MAX); + heuristicDL.setMaxSimplexIterationsAtRoot(COIN_INT_MAX); + model->addHeuristic(&heuristicDL) ; //CbcCompareUser compare; //model->setNodeComparison(compare); } break; case 4: // If not good enough could skip postprocessing - break; + break; case 5: break; default: @@ -228,18 +308,6 @@ So we need pointer to model. Old way could use modelA. rather than model-> */ // Messy code below copied from CbcSolver.cpp -#ifdef CLP_FAST_CODE -// force new style solver -#ifndef NEW_STYLE_SOLVER -#define NEW_STYLE_SOLVER 1 -#endif -#else -// Not new style solver -#ifndef NEW_STYLE_SOLVER -#define NEW_STYLE_SOLVER 0 -#endif -#endif -#if NEW_STYLE_SOLVER==0 // Pass to Cbc initialize defaults CbcModel modelA(solver1); CbcModel * model = &modelA; @@ -257,16 +325,6 @@ const char * argv2[]={"driver4","-solve","-quit"}; CbcMain1(3,argv2,modelA,callBack); } -#else - CbcSolver control(solver1); - // initialize - control.fillValuesInSolver(); - // Event handler - MyEventHandler3 eventHandler; - CbcModel * model = control.model(); - model->passInEventHandler(&eventHandler); - control.solve (argc-1, argv+1, 1); -#endif // Solver was cloned so get current copy OsiSolverInterface * solver = model->solver(); // Print solution if finished (could get from model->bestSolution() as well diff -Nru coinor-cbc-2.8.12/examples/driver6.cpp coinor-cbc-2.9.9+repack1/examples/driver6.cpp --- coinor-cbc-2.8.12/examples/driver6.cpp 1970-01-01 00:00:00.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/examples/driver6.cpp 2014-07-19 08:40:23.000000000 +0000 @@ -0,0 +1,312 @@ +// $Id: driver6.cpp 1898 2013-04-09 18:06:04Z stefan $ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#include +#include + + +#include "CoinPragma.hpp" +#include "CbcModel.hpp" +#include "OsiClpSolverInterface.hpp" +#include "CbcSolver.hpp" + +#include "CoinTime.hpp" +#include "CoinSignal.hpp" +/* + This shows how to trap signals. + This just traps ctrl-c and allows user to pause and then hit S or C + In this simple version Stop may not be effective until a heuristic has exited + */ + +static CbcModel * currentBranchModel=NULL; +extern "C" { + static void signal_handler(int whichSignal) { + int gotChar='X'; + while (toupper(gotChar)!='S'&&toupper(gotChar)!='C') { + // See what user wants to do + fprintf(stderr,"Enter S to stop, C to continue:"); + gotChar = getchar(); + } + if (currentBranchModel != NULL&&toupper(gotChar)=='S') { + currentBranchModel->sayEventHappened(); // say why stopped + if (currentBranchModel->heuristicModel()) + currentBranchModel->heuristicModel()->sayEventHappened(); + } + return; + } +} +static CoinSighandler_t saveSignal=signal(SIGINT,signal_handler); +//############################################################################# + + +/************************************************************************ + +This main program shows how to take advantage of the standalone cbc in your program, +while still making major modifications. +First it reads in an integer model from an mps file +Then it initializes the integer model with cbc defaults +Then it calls CbcMain1 passing all parameters apart from first but with callBack to modify stuff +Finally it prints solution + +************************************************************************/ +/* Meaning of whereFrom: + 1 after initial solve by dualsimplex etc + 2 after preprocessing + 3 just before branchAndBound (so user can override) + 4 just after branchAndBound (before postprocessing) + 5 after postprocessing +*/ +/* Meaning of model status is as normal + status + -1 before branchAndBound + 0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found + (or check value of best solution) + 1 stopped - on maxnodes, maxsols, maxtime + 2 difficulties so run was abandoned + (5 event user programmed event occurred) + + cbc secondary status of problem + -1 unset (status_ will also be -1) + 0 search completed with solution + 1 linear relaxation not feasible (or worse than cutoff) + 2 stopped on gap + 3 stopped on nodes + 4 stopped on time + 5 stopped on user event + 6 stopped on solutions + 7 linear relaxation unbounded + + but initially check if status is 0 and secondary status is 1 -> infeasible + or you can check solver status. +*/ +/* Return non-zero to return quickly */ +static int callBack(CbcModel * model, int whereFrom) +{ + int returnCode=0; + switch (whereFrom) { + case 1: + case 2: + if (!model->status()&&model->secondaryStatus()) + returnCode=1; + break; + case 3: + { + // set up signal trapping + saveSignal=signal(SIGINT,signal_handler); + currentBranchModel=model; + } + break; + case 4: + { + // restore + signal(SIGINT,saveSignal); + currentBranchModel=NULL; + } + // If not good enough could skip postprocessing + break; + case 5: + break; + default: + abort(); + } + return returnCode; +} +#include "CbcEventHandler.hpp" +/** This is so user can trap events and do useful stuff. + + CbcModel model_ is available as well as anything else you care + to pass in +*/ + +class MyEventHandler3 : public CbcEventHandler { + +public: + /**@name Overrides */ + //@{ + virtual CbcAction event(CbcEvent whichEvent); + //@} + + /**@name Constructors, destructor etc*/ + //@{ + /** Default constructor. */ + MyEventHandler3(); + /// Constructor with pointer to model (redundant as setEventHandler does) + MyEventHandler3(CbcModel * model); + /** Destructor */ + virtual ~MyEventHandler3(); + /** The copy constructor. */ + MyEventHandler3(const MyEventHandler3 & rhs); + /// Assignment + MyEventHandler3& operator=(const MyEventHandler3 & rhs); + /// Clone + virtual CbcEventHandler * clone() const ; + //@} + + +protected: + // data goes here +}; +//------------------------------------------------------------------- +// Default Constructor +//------------------------------------------------------------------- +MyEventHandler3::MyEventHandler3 () + : CbcEventHandler() +{ +} + +//------------------------------------------------------------------- +// Copy constructor +//------------------------------------------------------------------- +MyEventHandler3::MyEventHandler3 (const MyEventHandler3 & rhs) +: CbcEventHandler(rhs) +{ +} + +// Constructor with pointer to model +MyEventHandler3::MyEventHandler3(CbcModel * model) + : CbcEventHandler(model) +{ +} + +//------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------- +MyEventHandler3::~MyEventHandler3 () +{ +} + +//---------------------------------------------------------------- +// Assignment operator +//------------------------------------------------------------------- +MyEventHandler3 & +MyEventHandler3::operator=(const MyEventHandler3& rhs) +{ + if (this != &rhs) { + CbcEventHandler::operator=(rhs); + } + return *this; +} +//------------------------------------------------------------------- +// Clone +//------------------------------------------------------------------- +CbcEventHandler * MyEventHandler3::clone() const +{ + return new MyEventHandler3(*this); +} + +CbcEventHandler::CbcAction +MyEventHandler3::event(CbcEvent whichEvent) +{ + // If in sub tree carry on + if (!model_->parentModel()) { + if (whichEvent==solution||whichEvent==heuristicSolution) { +#ifdef STOP_EARLY + return stop; // say finished +#else + // If preprocessing was done solution will be to processed model + int numberColumns = model_->getNumCols(); + const double * bestSolution = model_->bestSolution(); + assert (bestSolution); + printf("value of solution is %g\n",model_->getObjValue()); + for (int i=0;i1.0e-8) + printf("%d %g\n",i,bestSolution[i]); + } + return noAction; // carry on +#endif + } else { + return noAction; // carry on + } + } else { + return noAction; // carry on + } +} + +int main (int argc, const char *argv[]) +{ + + OsiClpSolverInterface solver1; + //#define USE_OSI_NAMES +#ifdef USE_OSI_NAMES + // Say we are keeping names (a bit slower this way) + solver1.setIntParam(OsiNameDiscipline,1); +#endif + // Read in model using argv[1] + // and assert that it is a clean model + std::string mpsFileName; +#if defined(SAMPLEDIR) + mpsFileName = SAMPLEDIR "/p0033.mps"; +#else + if (argc < 2) { + fprintf(stderr, "Do not know where to find sample MPS files.\n"); + exit(1); + } +#endif + if (argc>=2) mpsFileName = argv[1]; + int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(),""); + if( numMpsReadErrors != 0 ) + { + printf("%d errors reading MPS file\n", numMpsReadErrors); + return numMpsReadErrors; + } + // Tell solver to return fast if presolve or initial solve infeasible + solver1.getModelPtr()->setMoreSpecialOptions(3); + + // Pass to Cbc initialize defaults + CbcModel modelA(solver1); + CbcModel * model = &modelA; + CbcMain0(modelA); + // Event handler + MyEventHandler3 eventHandler; + model->passInEventHandler(&eventHandler); + /* Now go into code for standalone solver + Could copy arguments and add -quit at end to be safe + but this will do + */ + if (argc>2) { + CbcMain1(argc-1,argv+1,modelA,callBack); + } else { + const char * argv2[]={"driver6","-solve","-quit"}; + CbcMain1(3,argv2,modelA,callBack); + } + // Solver was cloned so get current copy + OsiSolverInterface * solver = model->solver(); + // Print solution if finished (could get from model->bestSolution() as well + + if (model->bestSolution()) { + + const double * solution = solver->getColSolution(); + + int iColumn; + int numberColumns = solver->getNumCols(); + std::cout<1.0e-7&&solver->isInteger(iColumn)) + std::cout<getColName(iColumn) + <1.0e-7&&solver->isInteger(iColumn)) + std::cout<columnName(iColumn) + < -#include - - -#include "CoinPragma.hpp" -#include "CbcModel.hpp" -#include "OsiClpSolverInterface.hpp" -#include "CbcSolver.hpp" - -#include "CoinTime.hpp" - -//############################################################################# -// AS parallel.cpp but just one char * and dummy callBack - -/************************************************************************ - -This main program shows how to take advantage of the standalone cbc in your program, -while still making major modifications. -This is like driver4 but executes in parallel -First it reads in a model from an mps file -Then it initializes three integer models with cbc defaults -Then it calls CbcMain0/1 using threads passing parameters -Finally it prints solution (just for first model) - -All models have same parameters unless "-switch" is found so -- - -miplib/p0033 -solve -switch -heuristic off -solve - -would solve first model with heuristics and subsequent ones without - -This could be used to try different ideas OR on different models - -NOTE - -The minimum has been done to make thread safe so -no interrupts --quit is added to make sure just reads from argv -*/ -/*************************************************************************/ -#define USE_PTHREAD -#ifdef USE_PTHREAD -#include -#endif -// For threads -typedef struct { - CbcModel * model; - char * args; -} threadStuff; -static void * doThread(void * voidInfo) -{ - threadStuff * stuff = reinterpret_cast(voidInfo); - CbcModel * model = stuff->model; - callCbc(stuff->args,*model); - return NULL; -} -int main (int argc, const char *argv[]) -{ - // Number of models to do at once - int numberModels=3; - // Stuff for each model - CbcModel * allModels = new CbcModel[numberModels]; - OsiClpSolverInterface * allSolvers = new OsiClpSolverInterface[numberModels]; - threadStuff * allData = new threadStuff[numberModels]; - // First populate first model - /* in a real application models would be different */ - OsiClpSolverInterface & solver1 = allSolvers[0]; - // Read in model using argv[1] - // and assert that it is a clean model - std::string mpsFileName; -#if defined(SAMPLEDIR) - mpsFileName = SAMPLEDIR "/p0033.mps"; -#else - if (argc < 2) { - fprintf(stderr, "Do not know where to find sample MPS files.\n"); - exit(1); - } -#endif - if (argc>=2) mpsFileName = argv[1]; - int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(),""); - if( numMpsReadErrors != 0 ) - { - printf("%d errors reading MPS file\n", numMpsReadErrors); - return numMpsReadErrors; - } - // Tell solver to return fast if presolve or initial solve infeasible - solver1.getModelPtr()->setMoreSpecialOptions(3); - // create models - for (int iModel=1;iModel0) - lastArgc=thisArgc; - else - thisArgc=lastArgc; - // allow extra for -quit - char * args = new char[256]; - allData[iModel].args=args; - for (int iArgc=lastArgPosition;iArgcsolver(); - // Print solution if finished (could get from model->bestSolution() as well - - if (model->bestSolution()) { - - const double * solution = solver->getColSolution(); - - int iColumn; - int numberColumns = solver->getNumCols(); - std::cout<1.0e-7&&solver->isInteger(iColumn)) - std::cout<getColName(iColumn) - <1.0e-7&&solver->isInteger(iColumn)) - std::cout<columnName(iColumn) - < +#include + + +#include "CoinPragma.hpp" +#include "CbcModel.hpp" +#include "OsiClpSolverInterface.hpp" +#include "CbcSolver.hpp" + +#include "CoinTime.hpp" + +//############################################################################# + + +/************************************************************************ + +This main program shows how to take advantage of the standalone cbc in your program, +while still making major modifications. +First it reads in an integer model from an mps file +Then it initializes the integer model with cbc defaults +Then it calls CbcMain1 passing all parameters apart from first but with callBack to modify stuff +Finally it prints solution +*/ +int main (int argc, const char *argv[]) +{ + + OsiClpSolverInterface solver1; + // Read in model using argv[1] + // and assert that it is a clean model + std::string mpsFileName; +#if defined(SAMPLEDIR) + mpsFileName = SAMPLEDIR "/p0033.mps"; +#else + if (argc < 2) { + fprintf(stderr, "Do not know where to find sample MPS files.\n"); + exit(1); + } +#endif + if (argc>=2) mpsFileName = argv[1]; + int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(),""); + if( numMpsReadErrors != 0 ) + { + printf("%d errors reading MPS file\n", numMpsReadErrors); + return numMpsReadErrors; + } + // Tell solver to return fast if presolve or initial solve infeasible + solver1.getModelPtr()->setMoreSpecialOptions(3); + + // Pass to Cbc initialize defaults + CbcModel modelA(solver1); + CbcModel * model = &modelA; + CbcMain0(modelA); + modelA.setMaximumSavedSolutions(5); + /* Now go into code for standalone solver + Could copy arguments and add -quit at end to be safe + but this will do + */ + if (argc>2) { + CbcMain1(argc-1,argv+1,modelA); + } else { + const char * argv2[]={"driver4","-solve","-quit"}; + CbcMain1(3,argv2,modelA); + } + // Solver was cloned so get current copy + OsiSolverInterface * solver = model->solver(); + // Print solution if finished (could get from model->bestSolution() as well + + if (model->bestSolution()) { + + int numberColumns = solver->getNumCols(); + std::cout<1.0e-7&&solver1.isInteger(iColumn)) + std::cout<columnName(iColumn) + < $(addlibsdir)/cbc_addlibs.txt else if COIN_CXX_IS_CL diff -Nru coinor-cbc-2.8.12/Makefile.in coinor-cbc-2.9.9+repack1/Makefile.in --- coinor-cbc-2.8.12/Makefile.in 2013-12-16 15:43:57.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/Makefile.in 2016-02-21 15:25:08.000000000 +0000 @@ -181,18 +181,24 @@ COIN_HAS_COINDEPEND_TRUE = @COIN_HAS_COINDEPEND_TRUE@ COIN_HAS_CPX_FALSE = @COIN_HAS_CPX_FALSE@ COIN_HAS_CPX_TRUE = @COIN_HAS_CPX_TRUE@ +COIN_HAS_DOXYGEN_FALSE = @COIN_HAS_DOXYGEN_FALSE@ +COIN_HAS_DOXYGEN_TRUE = @COIN_HAS_DOXYGEN_TRUE@ COIN_HAS_DYLP_FALSE = @COIN_HAS_DYLP_FALSE@ COIN_HAS_DYLP_TRUE = @COIN_HAS_DYLP_TRUE@ COIN_HAS_GLPK_FALSE = @COIN_HAS_GLPK_FALSE@ COIN_HAS_GLPK_TRUE = @COIN_HAS_GLPK_TRUE@ COIN_HAS_GRB_FALSE = @COIN_HAS_GRB_FALSE@ COIN_HAS_GRB_TRUE = @COIN_HAS_GRB_TRUE@ +COIN_HAS_LATEX_FALSE = @COIN_HAS_LATEX_FALSE@ +COIN_HAS_LATEX_TRUE = @COIN_HAS_LATEX_TRUE@ COIN_HAS_MIPLIB3_FALSE = @COIN_HAS_MIPLIB3_FALSE@ COIN_HAS_MIPLIB3_TRUE = @COIN_HAS_MIPLIB3_TRUE@ COIN_HAS_MSK_FALSE = @COIN_HAS_MSK_FALSE@ COIN_HAS_MSK_TRUE = @COIN_HAS_MSK_TRUE@ COIN_HAS_NETLIB_FALSE = @COIN_HAS_NETLIB_FALSE@ COIN_HAS_NETLIB_TRUE = @COIN_HAS_NETLIB_TRUE@ +COIN_HAS_NTY_FALSE = @COIN_HAS_NTY_FALSE@ +COIN_HAS_NTY_TRUE = @COIN_HAS_NTY_TRUE@ COIN_HAS_OSITESTS_FALSE = @COIN_HAS_OSITESTS_FALSE@ COIN_HAS_OSITESTS_TRUE = @COIN_HAS_OSITESTS_TRUE@ COIN_HAS_PKGCONFIG_FALSE = @COIN_HAS_PKGCONFIG_FALSE@ @@ -299,6 +305,8 @@ NETLIB_DEPENDENCIES = @NETLIB_DEPENDENCIES@ NETLIB_LIBS = @NETLIB_LIBS@ NETLIB_LIBS_INSTALLED = @NETLIB_LIBS_INSTALLED@ +NTYINCDIR = @NTYINCDIR@ +NTYLIB = @NTYLIB@ OBJEXT = @OBJEXT@ OPT_CFLAGS = @OPT_CFLAGS@ OPT_CXXFLAGS = @OPT_CXXFLAGS@ @@ -406,6 +414,7 @@ coin_doxy_tagname = @coin_doxy_tagname@ coin_doxy_usedot = @coin_doxy_usedot@ coin_have_doxygen = @coin_have_doxygen@ +coin_have_latex = @coin_have_latex@ datadir = @datadir@ exec_prefix = @exec_prefix@ have_autoconf = @have_autoconf@ @@ -487,8 +496,10 @@ # Files that are generated and should be cleaned with make distclean DISTCLEANFILES = $(am__append_3) $(VPATH_DISTCLEANFILES) -DocFiles = README AUTHORS LICENSE +DocFiles = README AUTHORS LICENSE DocInstallDir = $(datadir)/coin/doc/$(PACKAGE_NAME) +COIN_HAS_DOXYGEN = @COIN_HAS_DOXYGEN_TRUE@TRUE +COIN_HAS_LATEX = @COIN_HAS_LATEX_TRUE@TRUE all: all-recursive .SUFFIXES: @@ -980,7 +991,7 @@ install-data-hook: @$(mkdir_p) "$(addlibsdir)" -@COIN_HAS_PKGCONFIG_TRUE@ PKG_CONFIG_PATH=@COIN_PKG_CONFIG_PATH@ \ +@COIN_HAS_PKGCONFIG_TRUE@ PKG_CONFIG_PATH=@COIN_PKG_CONFIG_PATH@:$(DESTDIR)$(pkgconfiglibdir) \ @COIN_HAS_PKGCONFIG_TRUE@ $(PKG_CONFIG) --libs cbc > $(addlibsdir)/cbc_addlibs.txt @COIN_CXX_IS_CL_TRUE@@COIN_HAS_PKGCONFIG_FALSE@ echo "-libpath:`$(CYGPATH_W) @abs_lib_dir@` libCbc.lib @CBCLIB_LIBS_INSTALLED@" > $(addlibsdir)/cbc_addlibs.txt @COIN_CXX_IS_CL_FALSE@@COIN_HAS_PKGCONFIG_FALSE@ echo -L@abs_lib_dir@ -lCbcSolver -lCbc @CBCLIB_LIBS_INSTALLED@ > $(addlibsdir)/cbc_addlibs.txt @@ -988,12 +999,100 @@ uninstall-hook: rm -f $(addlibsdir)/cbc_addlibs.txt -install-doc: $(DocFiles) +doxygen-docs: + if test "$(COIN_HAS_DOXYGEN)" = TRUE; then \ + if test -d "doxydoc/"; then \ + doxygen doxydoc/doxygen.conf;\ + fi;\ + fi + +pdf-doxygen-docs: doxygen-docs + if test "$(COIN_HAS_DOXYGEN)" = TRUE; then \ + if test -d "doxydoc/latex"; then \ + if test "$(COIN_HAS_LATEX)" = TRUE; then \ + cd doxydoc/latex;\ + $(MAKE) pdf;\ + cd -;\ + fi;\ + fi;\ + fi + +clean-doxygen-docs: + if test -d "doxydoc/"; then \ + cd doxydoc ;\ + rm -rf html latex *.log *.tag;\ + fi + +install-doxygen-docs: doxygen-docs + if test "$(COIN_HAS_DOXYGEN)" = TRUE; then \ + if test -d "doxydoc/"; then \ + test -d "$(DESTDIR)$(DocInstallDir)/doxydoc" || $(mkdir_p) "$(DESTDIR)$(DocInstallDir)/doxydoc"; \ + $(INSTALL_DATA) @coin_doxy_tagname@ "$(DESTDIR)$(DocInstallDir)/@coin_doxy_tagname@";\ + if test -f "doxydoc/latex/refman.pdf"; then \ + $(INSTALL_DATA) doxydoc/latex/refman.pdf "$(DESTDIR)$(DocInstallDir)";\ + fi;\ + if test -d "doxydoc/html"; then \ + test -d "$(DESTDIR)$(DocInstallDir)/doxydoc/search/" || $(mkdir_p) "$(DESTDIR)$(DocInstallDir)/doxydoc/search/"; \ + $(INSTALL_DATA) doxydoc/html/*.* "$(DESTDIR)$(DocInstallDir)/doxydoc";\ + $(INSTALL_DATA) doxydoc/html/search/*.* "$(DESTDIR)$(DocInstallDir)/doxydoc/search";\ + fi;\ + fi;\ + fi + +uninstall-doxygen-docs: + if test -d "$(DESTDIR)$(DocInstallDir)/doxydoc/"; then \ + rm -rf "$(DESTDIR)$(DocInstallDir)/doxydoc/"; \ + fi + if test -f "$(DESTDIR)$(DocInstallDir)/refman.pdf"; then \ + rm -f "$(DESTDIR)$(DocInstallDir)/refman.pdf"; \ + fi + +all-doxygen-docs: + for dir in $(subdirs) ; do \ + do_project=true;\ + for proj in $(COIN_SKIP_DOXYGEN); do\ + if test $$dir = $$proj; then\ + do_project=false;\ + fi;\ + done;\ + if test -r $$dir/doxydoc & $$do_project = true; then \ + (cd $$dir ; $(MAKE) doxygen-docs) \ + fi ; \ + done ; + +clean-all-doxygen-docs: + for dir in $(subdirs) ; do \ + if test -r $$dir/doxydoc ; then \ + (cd $$dir ; $(MAKE) clean-doxygen-docs) \ + fi ; \ + done ; + +install-all-doxygen-docs: all-doxygen-docs + for dir in $(subdirs) ; do \ + do_project=true;\ + for proj in $(COIN_SKIP_DOXYGEN); do\ + if test $$dir = $$proj; then\ + do_project=false;\ + fi;\ + done;\ + if test -r $$dir/doxydoc & $$do_project = true; then \ + (cd $$dir ; $(MAKE) install-doxygen-docs) \ + fi ; \ + done ; + +uninstall-all-doxygen-docs: + for dir in $(subdirs) ; do \ + if test -r $$dir/doxydoc ; then \ + (cd $$dir ; $(MAKE) uninstall-doxygen-docs) \ + fi ; \ + done ; + +install-doc: $(DocFiles) test -z "$(DocInstallDir)" || $(mkdir_p) "$(DESTDIR)$(DocInstallDir)" for file in $(DocFiles); do \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ if test -f "$$dir$$file"; then $(INSTALL_DATA) "$$dir$$file" "$(DESTDIR)$(DocInstallDir)/$$file"; fi; \ - done + done uninstall-doc: for file in $(DocFiles); do \ diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/cbc/cbc.vcxproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/cbc/cbc.vcxproj --- coinor-cbc-2.8.12/MSVisualStudio/v10/cbc/cbc.vcxproj 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/cbc/cbc.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,263 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {E2294708-C5BA-460A-B0A7-060A4023684A} - cbc - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - false - false - false - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - .\Debug/cbcSolve.tlb - - - - - ..\..\..\src;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - libCbcSolver.lib;libCbc.lib;libCgl.lib;libOsiClp.lib;libOsi.lib;libClp.lib;libCoinUtils.lib;%(AdditionalDependencies) - true - $(OutDir);%(AdditionalLibraryDirectories) - true - Console - false - - - MachineX86 - - - false - - - - - .\Release/cbcSolve.tlb - - - - - ..\..\..\src;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - true - - - Default - - - NDEBUG;_NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - libCbcSolver.lib;libCbc.lib;libCgl.lib;libOsiClp.lib;libOsi.lib;libClp.lib;libCoinUtils.lib;%(AdditionalDependencies) - true - $(OutDir);%(AdditionalLibraryDirectories) - Console - false - - - MachineX86 - - - false - - - - - X64 - .\Debug/cbcSolve.tlb - - - - - ..\..\..\src;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - ProgramDatabase - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - libCbcSolver.lib;libCbc.lib;libCgl.lib;libOsiClp.lib;libOsi.lib;libClp.lib;libCoinUtils.lib;%(AdditionalDependencies) - true - $(OutDir);%(AdditionalLibraryDirectories) - true - Console - false - - - MachineX64 - - - false - - - - - X64 - .\Release/cbcSolve.tlb - - - - - ..\..\..\src;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - - - NDEBUG;_NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - libCbcSolver.lib;libCbc.lib;libCgl.lib;libOsiClp.lib;libOsi.lib;libClp.lib;libCoinUtils.lib;%(AdditionalDependencies) - true - $(OutDir);%(AdditionalLibraryDirectories) - Console - false - - - MachineX64 - - - false - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - {dbea3904-f0b8-408a-9e1a-6497febe8c42} - false - - - {4f8f7d1c-3a9e-444d-8ee9-77f33fa05994} - false - - - {02d45875-a8cf-41b9-990b-3699c0ecfe10} - false - - - {c4867f15-438d-4ff8-8388-62fbaaa9786c} - false - - - {7d98e2cb-876e-4f75-9f71-77d3fe87e149} - false - - - {71da4595-e8a7-4b21-a00a-d96d29d11e3e} - false - - - {363ba154-fec9-4e1e-bc23-93cec58ab785} - false - - - - - - \ No newline at end of file diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/cbcCInterfaceDll/cbcCInterfaceDll.vcxproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/cbcCInterfaceDll/cbcCInterfaceDll.vcxproj --- coinor-cbc-2.8.12/MSVisualStudio/v10/cbcCInterfaceDll/cbcCInterfaceDll.vcxproj 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/cbcCInterfaceDll/cbcCInterfaceDll.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,231 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB} - cbcCInterfaceDll - Win32Proj - - - - DynamicLibrary - - - DynamicLibrary - - - DynamicLibrary - - - DynamicLibrary - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - true - false - true - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - Disabled - ..\..\..\..\Cbc\src\;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_WINDOWS;_USRDLL;CBCCINTERFACEDLL_EXPORTS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - - - libOsiClp.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir);%(AdditionalLibraryDirectories) - true - $(OutDir)cbcCInterfaceDll.pdb - Windows - false - - - $(OutDir)cbcCInterfaceDll.lib - MachineX86 - - - - - ..\..\..\..\Cbc\src\;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_WINDOWS;_USRDLL;CBCCINTERFACEDLL_EXPORTS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - libOsiClp.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir);%(AdditionalLibraryDirectories) - true - Windows - true - true - false - - - $(OutDir)cbcCInterfaceDll.lib - MachineX86 - - - - - X64 - - - Disabled - ..\..\..\..\Cbc\src\;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_WINDOWS;_USRDLL;CBCCINTERFACEDLL_EXPORTS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - ProgramDatabase - - - libOsiClp.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir);%(AdditionalLibraryDirectories) - true - $(OutDir)cbcCInterfaceDll.pdb - Windows - false - - - $(OutDir)cbcCInterfaceDll.lib - MachineX64 - - - - - X64 - - - ..\..\..\..\Cbc\src\;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_WINDOWS;_USRDLL;CBCCINTERFACEDLL_EXPORTS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - MultiThreadedDLL - - - Level3 - ProgramDatabase - - - libOsiClp.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).dll - $(OutDir);%(AdditionalLibraryDirectories) - true - Windows - true - true - false - - - $(OutDir)cbcCInterfaceDll.lib - MachineX64 - - - - - - - - - - - {dbea3904-f0b8-408a-9e1a-6497febe8c42} - false - - - {4f8f7d1c-3a9e-444d-8ee9-77f33fa05994} - false - - - {02d45875-a8cf-41b9-990b-3699c0ecfe10} - false - - - {c4867f15-438d-4ff8-8388-62fbaaa9786c} - false - - - {7d98e2cb-876e-4f75-9f71-77d3fe87e149} - false - - - {363ba154-fec9-4e1e-bc23-93cec58ab785} - false - - - - - - \ No newline at end of file diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/CbcCSosDllSample/cbcCSosDllSample.vcxproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/CbcCSosDllSample/cbcCSosDllSample.vcxproj --- coinor-cbc-2.8.12/MSVisualStudio/v10/CbcCSosDllSample/cbcCSosDllSample.vcxproj 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/CbcCSosDllSample/cbcCSosDllSample.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E} - cbcCSosDllSample - Win32Proj - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - true - false - true - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - ..\..\..\..\Osi\src\OsiCbc;..\..\..\..\Osi\src;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Osi\src\OsiClp;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cbc\src;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CONSOLE;CBCCINTERFACEDLL_EXPORTS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample\\";%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Cdecl - Default - - - false - - - cbcCInterfaceDll.lib;%(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - %(DelayLoadDLLs) - true - true - true - Console - false - - - MachineX86 - - - - - ..\..\..\..\Osi\src\OsiCbc;..\..\..\..\Osi\src;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Osi\src\OsiClp;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cbc\src;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CONSOLE;CBCCINTERFACEDLL_EXPORTS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample\\\\";%(PreprocessorDefinitions) - MultiThreadedDLL - - - Cdecl - Default - - - false - - - cbcCInterfaceDll.lib;%(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - %(DelayLoadDLLs) - true - true - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - ..\..\..\..\Osi\src\OsiCbc;..\..\..\..\Osi\src;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Osi\src\OsiClp;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cbc\src;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CONSOLE;CBCCINTERFACEDLL_EXPORTS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample\\\\";%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - ProgramDatabase - Cdecl - Default - - - false - - - cbcCInterfaceDll.lib;%(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - %(DelayLoadDLLs) - true - true - true - Console - false - - - MachineX64 - - - - - X64 - - - ..\..\..\..\Osi\src\OsiCbc;..\..\..\..\Osi\src;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Osi\src\OsiClp;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cbc\src;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CONSOLE;CBCCINTERFACEDLL_EXPORTS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample\\\\";%(PreprocessorDefinitions) - MultiThreadedDLL - - - Cdecl - Default - - - false - - - cbcCInterfaceDll.lib;%(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - %(DelayLoadDLLs) - true - true - true - Console - true - true - false - - - MachineX64 - - - - - - - - - - - - {f1e9e3f0-6639-4a84-8e0f-a2d5f11978fb} - false - - - - - - \ No newline at end of file diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/cbcExamplesSample2/cbcExamplesSample2.vcxproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/cbcExamplesSample2/cbcExamplesSample2.vcxproj --- coinor-cbc-2.8.12/MSVisualStudio/v10/cbcExamplesSample2/cbcExamplesSample2.vcxproj 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/cbcExamplesSample2/cbcExamplesSample2.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,326 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {4C0B8243-2876-4C92-B6CB-2472B0571CC3} - cbcExamplesSample2 - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - false - false - false - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - .\Debug/cbcExamplesSample2.tlb - - - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample";%(PreprocessorDefinitions) - - - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - libCbcSolver.lib;libCbc.lib;libCgl.lib;libOsiClp.lib;libOsi.lib;libClp.lib;libCoinUtils.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir);%(AdditionalLibraryDirectories) - true - .\Debug/cbcExamplesSample2.pdb - Console - false - - - MachineX86 - - - false - - - - - X64 - .\Debug/cbcExamplesSample2.tlb - - - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample";%(PreprocessorDefinitions) - - - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - libCbcSolver.lib;libCbc.lib;libCgl.lib;libOsiClp.lib;libOsi.lib;libClp.lib;libCoinUtils.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir);%(AdditionalLibraryDirectories) - true - .\Debug/cbcExamplesSample2.pdb - Console - false - - - MachineX64 - - - false - - - - - .\Release/cbcExamplesSample2.tlb - - - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample";%(PreprocessorDefinitions) - - - - - NDEBUG;_NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - libCbcSolver.lib;libCbc.lib;libCgl.lib;libOsiClp.lib;libOsi.lib;libClp.lib;libCoinUtils.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir);%(AdditionalLibraryDirectories) - .\Release/cbcExamplesSample2.pdb - Console - false - - - MachineX86 - - - false - - - - - X64 - .\Release/cbcExamplesSample2.tlb - - - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample";%(PreprocessorDefinitions) - - - - - NDEBUG;_NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - libCbcSolver.lib;libCbc.lib;libCgl.lib;libOsiClp.lib;libOsi.lib;libClp.lib;libCoinUtils.lib;%(AdditionalDependencies) - $(OutDir)$(ProjectName).exe - true - $(OutDir);%(AdditionalLibraryDirectories) - .\Release/cbcExamplesSample2.pdb - Console - false - - - MachineX64 - - - false - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - $(IntDir) - $(IntDir)vc90.pdb - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - $(IntDir) - $(IntDir)vc90.pdb - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - $(IntDir) - $(IntDir)vc90.pdb - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - $(IntDir) - $(IntDir)vc90.pdb - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - $(IntDir) - $(IntDir)vc90.pdb - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - $(IntDir) - $(IntDir)vc90.pdb - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - $(IntDir) - $(IntDir)vc90.pdb - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - $(IntDir) - $(IntDir)vc90.pdb - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - $(IntDir) - $(IntDir)vc90.pdb - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - $(IntDir) - $(IntDir)vc90.pdb - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - $(IntDir) - $(IntDir)vc90.pdb - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - $(IntDir) - $(IntDir)vc90.pdb - - - - - - - - - - - {dbea3904-f0b8-408a-9e1a-6497febe8c42} - false - - - {4f8f7d1c-3a9e-444d-8ee9-77f33fa05994} - false - - - {02d45875-a8cf-41b9-990b-3699c0ecfe10} - false - - - {c4867f15-438d-4ff8-8388-62fbaaa9786c} - false - - - {7d98e2cb-876e-4f75-9f71-77d3fe87e149} - false - - - {363ba154-fec9-4e1e-bc23-93cec58ab785} - false - - - - - - \ No newline at end of file diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/Cbc.sln coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/Cbc.sln --- coinor-cbc-2.8.12/MSVisualStudio/v10/Cbc.sln 2011-10-11 12:27:13.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/Cbc.sln 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cbcExamplesSample2", "cbcExamplesSample2\cbcExamplesSample2.vcxproj", "{4C0B8243-2876-4C92-B6CB-2472B0571CC3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cbc", "cbc\cbc.vcxproj", "{E2294708-C5BA-460A-B0A7-060A4023684A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCbc", "libCbc\libCbc.vcxproj", "{363BA154-FEC9-4E1E-BC23-93CEC58AB785}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCgl", "..\..\..\Cgl\MSVisualStudio\v10\libCgl\libCgl.vcxproj", "{DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libClp", "..\..\..\Clp\MSVisualStudio\v10\libClp\libClp.vcxproj", "{4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCoinUtils", "..\..\..\CoinUtils\MSVisualStudio\v10\libCoinUtils\libCoinUtils.vcxproj", "{C4867F15-438D-4FF8-8388-62FBAAA9786C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsi", "..\..\..\Osi\MSVisualStudio\v10\libOsi\libOsi.vcxproj", "{7D98E2CB-876E-4F75-9F71-77D3FE87E149}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cbcCInterfaceDll", "cbcCInterfaceDll\cbcCInterfaceDll.vcxproj", "{F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cbcCSosDllSample", "cbcCSosDllSample\cbcCSosDllSample.vcxproj", "{8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCbcSolver", "libCbcSolver\libCbcSolver.vcxproj", "{71DA4595-E8A7-4B21-A00A-D96D29D11E3E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsiClp", "..\..\..\Clp\MSVisualStudio\v10\libOsiClp\libOsiClp.vcxproj", "{02D45875-A8CF-41B9-990B-3699C0ECFE10}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsiCbc", "libOsiCbc\libOsiCbc.vcxproj", "{431ED9C6-FDF6-4836-8B33-BE4EC5378640}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OsiCbcUnitTest", "OsiCbcUnitTest\OsiCbcUnitTest.vcxproj", "{BB058D80-D376-4F0F-87F7-E4760BC2C84D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsiCommonTest", "..\..\..\Osi\MSVisualStudio\v10\libOsiCommonTest\libOsiCommonTest.vcxproj", "{109D6E6F-6D91-460F-86AE-DF27400E09A9}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Debug|Win32.ActiveCfg = Debug|Win32 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Debug|Win32.Build.0 = Debug|Win32 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Debug|x64.ActiveCfg = Debug|x64 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Debug|x64.Build.0 = Debug|x64 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Release|Win32.ActiveCfg = Release|Win32 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Release|Win32.Build.0 = Release|Win32 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Release|x64.ActiveCfg = Release|x64 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Release|x64.Build.0 = Release|x64 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Debug|Win32.ActiveCfg = Debug|Win32 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Debug|Win32.Build.0 = Debug|Win32 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Debug|x64.ActiveCfg = Debug|x64 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Debug|x64.Build.0 = Debug|x64 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Release|Win32.ActiveCfg = Release|Win32 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Release|Win32.Build.0 = Release|Win32 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Release|x64.ActiveCfg = Release|x64 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Release|x64.Build.0 = Release|x64 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Debug|Win32.ActiveCfg = Debug|Win32 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Debug|Win32.Build.0 = Debug|Win32 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Debug|x64.ActiveCfg = Debug|x64 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Debug|x64.Build.0 = Debug|x64 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Release|Win32.ActiveCfg = Release|Win32 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Release|Win32.Build.0 = Release|Win32 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Release|x64.ActiveCfg = Release|x64 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Release|x64.Build.0 = Release|x64 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Debug|Win32.ActiveCfg = Debug|Win32 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Debug|Win32.Build.0 = Debug|Win32 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Debug|x64.ActiveCfg = Debug|x64 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Debug|x64.Build.0 = Debug|x64 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Release|Win32.ActiveCfg = Release|Win32 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Release|Win32.Build.0 = Release|Win32 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Release|x64.ActiveCfg = Release|x64 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Release|x64.Build.0 = Release|x64 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Debug|Win32.ActiveCfg = Debug|Win32 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Debug|Win32.Build.0 = Debug|Win32 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Debug|x64.ActiveCfg = Debug|x64 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Debug|x64.Build.0 = Debug|x64 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Release|Win32.ActiveCfg = Release|Win32 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Release|Win32.Build.0 = Release|Win32 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Release|x64.ActiveCfg = Release|x64 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Release|x64.Build.0 = Release|x64 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Debug|Win32.Build.0 = Debug|Win32 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Debug|x64.ActiveCfg = Debug|x64 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Debug|x64.Build.0 = Debug|x64 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Release|Win32.ActiveCfg = Release|Win32 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Release|Win32.Build.0 = Release|Win32 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Release|x64.ActiveCfg = Release|x64 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Release|x64.Build.0 = Release|x64 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Debug|Win32.ActiveCfg = Debug|Win32 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Debug|Win32.Build.0 = Debug|Win32 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Debug|x64.ActiveCfg = Debug|x64 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Debug|x64.Build.0 = Debug|x64 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Release|Win32.ActiveCfg = Release|Win32 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Release|Win32.Build.0 = Release|Win32 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Release|x64.ActiveCfg = Release|x64 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Release|x64.Build.0 = Release|x64 - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}.Debug|Win32.ActiveCfg = Debug|Win32 - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}.Debug|x64.ActiveCfg = Debug|x64 - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}.Release|Win32.ActiveCfg = Release|Win32 - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}.Release|x64.ActiveCfg = Release|x64 - {8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}.Debug|Win32.ActiveCfg = Debug|Win32 - {8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}.Debug|x64.ActiveCfg = Debug|x64 - {8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}.Release|Win32.ActiveCfg = Release|Win32 - {8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}.Release|x64.ActiveCfg = Release|x64 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Debug|Win32.ActiveCfg = Debug|Win32 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Debug|Win32.Build.0 = Debug|Win32 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Debug|x64.ActiveCfg = Debug|x64 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Debug|x64.Build.0 = Debug|x64 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Release|Win32.ActiveCfg = Release|Win32 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Release|Win32.Build.0 = Release|Win32 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Release|x64.ActiveCfg = Release|x64 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Release|x64.Build.0 = Release|x64 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Debug|Win32.ActiveCfg = Debug|Win32 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Debug|Win32.Build.0 = Debug|Win32 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Debug|x64.ActiveCfg = Debug|x64 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Debug|x64.Build.0 = Debug|x64 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Release|Win32.ActiveCfg = Release|Win32 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Release|Win32.Build.0 = Release|Win32 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Release|x64.ActiveCfg = Release|x64 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Release|x64.Build.0 = Release|x64 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Debug|Win32.ActiveCfg = Debug|Win32 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Debug|Win32.Build.0 = Debug|Win32 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Debug|x64.ActiveCfg = Debug|x64 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Debug|x64.Build.0 = Debug|x64 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Release|Win32.ActiveCfg = Release|Win32 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Release|Win32.Build.0 = Release|Win32 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Release|x64.ActiveCfg = Release|x64 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Release|x64.Build.0 = Release|x64 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Debug|Win32.ActiveCfg = Debug|Win32 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Debug|Win32.Build.0 = Debug|Win32 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Debug|x64.ActiveCfg = Debug|x64 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Debug|x64.Build.0 = Debug|x64 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Release|Win32.ActiveCfg = Release|Win32 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Release|Win32.Build.0 = Release|Win32 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Release|x64.ActiveCfg = Release|x64 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Release|x64.Build.0 = Release|x64 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Debug|Win32.ActiveCfg = Debug|Win32 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Debug|Win32.Build.0 = Debug|Win32 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Debug|x64.ActiveCfg = Debug|x64 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Debug|x64.Build.0 = Debug|x64 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Release|Win32.ActiveCfg = Release|Win32 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Release|Win32.Build.0 = Release|Win32 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Release|x64.ActiveCfg = Release|x64 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/CbcWithInstalledLibraries/BaseCBCProject.sln coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/CbcWithInstalledLibraries/BaseCBCProject.sln --- coinor-cbc-2.8.12/MSVisualStudio/v10/CbcWithInstalledLibraries/BaseCBCProject.sln 2013-12-14 02:17:40.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/CbcWithInstalledLibraries/BaseCBCProject.sln 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BaseCBCProject", "BaseCBCProject.vcxproj", "{58EC5CA5-F696-4DC1-8E73-722E90FCFBCA}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {58EC5CA5-F696-4DC1-8E73-722E90FCFBCA}.Debug|Win32.ActiveCfg = Debug|Win32 - {58EC5CA5-F696-4DC1-8E73-722E90FCFBCA}.Debug|Win32.Build.0 = Debug|Win32 - {58EC5CA5-F696-4DC1-8E73-722E90FCFBCA}.Release|Win32.ActiveCfg = Release|Win32 - {58EC5CA5-F696-4DC1-8E73-722E90FCFBCA}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/CbcWithInstalledLibraries/BaseCBCProject.vcxproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/CbcWithInstalledLibraries/BaseCBCProject.vcxproj --- coinor-cbc-2.8.12/MSVisualStudio/v10/CbcWithInstalledLibraries/BaseCBCProject.vcxproj 2013-12-14 02:17:40.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/CbcWithInstalledLibraries/BaseCBCProject.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {58EC5CA5-F696-4DC1-8E73-722E90FCFBCA} - Win32Proj - BaseCBCProject - - - - Application - true - Unicode - - - Application - false - true - Unicode - - - - - - - - - - - - - true - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - C:\Program Files (x86)\COIN-OR\1.7.3\win32-msvc10\include\coin - - - Console - true - libcoinmetis.lib;libcoinmumps.lib;libcoinglpk.lib;libcoinasl.lib;libcoinlapack.lib;libcoinblas.lib;libCbc.lib;libCgl.lib;libClp.lib;libCoinUtils.lib;libOsi.lib;libOsiClp.lib;%(AdditionalDependencies) - C:\Program Files (x86)\COIN-OR\1.7.3\win32-msvc10\lib;C:\Program Files (x86)\COIN-OR\1.7.3\win32-msvc10\lib\intel - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - C:\Program Files (x86)\COIN-OR\1.7.3\win32-msvc10\include\coin - - - Console - true - true - true - libcoinmetis.lib;libcoinmumps.lib;libcoinglpk.lib;libcoinasl.lib;libcoinlapack.lib;libcoinblas.lib;libCbc.lib;libCgl.lib;libClp.lib;libCoinUtils.lib;libOsi.lib;libOsiClp.lib;%(AdditionalDependencies) - C:\Program Files (x86)\COIN-OR\1.7.3\win32-msvc10\lib;C:\Program Files (x86)\COIN-OR\1.7.3\win32-msvc10\lib\intel - - - - - - - - - \ No newline at end of file diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/CbcWithInstalledLibraries/main.cpp coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/CbcWithInstalledLibraries/main.cpp --- coinor-cbc-2.8.12/MSVisualStudio/v10/CbcWithInstalledLibraries/main.cpp 2013-12-14 02:17:40.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/CbcWithInstalledLibraries/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -#include "OsiClpSolverInterface.hpp" -#include "CbcModel.hpp" -#include "CoinModel.hpp" - -#include - -int main() { - const int numcols = 2; - const int numrows = 1; - double obj[] = { 1.0, 1.0}; // obj: Max x0 + x1 - - // Column-major sparse "A" matrix: x0 + 2 x1 <= 3.9 - int start[] = {0, 1, 2}; // where in index columns start (?) - int index[] = {0, 0}; // row indexs for the columns - double values[] = {1.0, 2.0}; // the values in the sparse matrix - double rowlb[] = {0.0}; - double rowub[] = {3.9}; - - // 0 <= x0 <= 10 and integer - // 0 <= x1 <= 10 - double collb[] = {0.0, 0.0}; - double colub[] = {10.0, 10.0}; - - OsiClpSolverInterface model; - model.loadProblem(numcols, numrows, start, index, values, - collb, colub, obj, rowlb, rowub); - model.setInteger(0); // Sets x0 to integer - model.setObjSense(-1.0); // Maximise - - CbcModel solver(model); - solver.branchAndBound(); - bool optimal = solver.isProvenOptimal(); - const double *val = solver.getColSolution(); - printf("Solution %g %g\n", val[0], val[1]); - - return 0; -} \ No newline at end of file diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/CbcWithInstalledLibraries/README.txt coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/CbcWithInstalledLibraries/README.txt --- coinor-cbc-2.8.12/MSVisualStudio/v10/CbcWithInstalledLibraries/README.txt 2013-12-14 02:17:40.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/CbcWithInstalledLibraries/README.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -BaseCBCProject - -Originated by Iain Dunning: http://www.iaindunning.com -Shamelessly modified by Ted Ralphs from original versions on - -https://github.com/IainNZ/BaseCBCProject - -This is a nearly-empty Visual C++ 2010 project with settings ready for use -with the Cbc libraries that come bundled with the COIN-OR installer. - -See more: https://projects.coin-or.org/Cbc/wiki/VSSetup - diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/libCbc/libCbc.vcxproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/libCbc/libCbc.vcxproj --- coinor-cbc-2.8.12/MSVisualStudio/v10/libCbc/libCbc.vcxproj 2013-04-26 16:21:11.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/libCbc/libCbc.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,687 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {363BA154-FEC9-4E1E-BC23-93CEC58AB785} - libCbc - - - - StaticLibrary - - - StaticLibrary - - - StaticLibrary - - - StaticLibrary - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglRedSplit2;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_LIB;USE_CBCCONFIG;COIN_NO_CLP_MESSAGE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglRedSplit2;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;WIN32;_LIB;USE_CBCCONFIG;COIN_NO_CLP_MESSAGE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - true - true - - - - - NDEBUG;_NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - X64 - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglRedSplit2;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_LIB;USE_CBCCONFIG;COIN_NO_CLP_MESSAGE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - true - EnableFastChecks - - - ProgramDatabase - false - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - X64 - - - Default - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglRedSplit2;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;WIN32;_LIB;USE_CBCCONFIG;COIN_NO_CLP_MESSAGE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) - - - - - NDEBUG;_NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - true - - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - Disabled - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - EnableFastChecks - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - MaxSpeed - %(AdditionalIncludeDirectories) - %(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/libCbcSolver/libCbcSolver.vcxproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/libCbcSolver/libCbcSolver.vcxproj --- coinor-cbc-2.8.12/MSVisualStudio/v10/libCbcSolver/libCbcSolver.vcxproj 2013-04-26 16:21:11.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/libCbcSolver/libCbcSolver.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E} - libCbcSolver - ManagedCProj - - - - StaticLibrary - - - StaticLibrary - - - StaticLibrary - - - StaticLibrary - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglRedSplit2;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglRedSplit2;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - Level3 - ProgramDatabase - - - - - X64 - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglRedSplit2;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - Level3 - ProgramDatabase - - - - - X64 - - - ..\..\..\src\;..\..\..\..\Cgl\src\CglZeroHalf;..\..\..\..\Cgl\src\CglGMI;..\..\..\..\Cgl\src\CglLandP;..\..\..\..\Cgl\src\CglTwomir;..\..\..\..\Cgl\src\CglMixedIntegerRounding;..\..\..\..\Cgl\src\CglMixedIntegerRounding2;..\..\..\..\Cgl\src\CglFlowCover;..\..\..\..\Cgl\src\CglClique;..\..\..\..\Cgl\src\CglOddHole;..\..\..\..\Cgl\src\CglKnapsackCover;..\..\..\..\Cgl\src\CglGomory;..\..\..\..\Cgl\src\CglPreProcess;..\..\..\..\Cgl\src\CglDuplicateRow;..\..\..\..\Cgl\src\CglRedSplit;..\..\..\..\Cgl\src\CglProbing;..\..\..\..\Cgl\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\Osi;..\..\..\..\CoinUtils\src;..\..\..\..\BuildTools\headers;..\..\..\..\Cgl\src\CglResidualCapacity;..\..\..\..\Cgl\src\CglRedSplit2;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - Level3 - ProgramDatabase - Default - - - - - true - true - - - true - true - - - true - true - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/libOsiCbc/libOsiCbc.vcxproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/libOsiCbc/libOsiCbc.vcxproj --- coinor-cbc-2.8.12/MSVisualStudio/v10/libOsiCbc/libOsiCbc.vcxproj 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/libOsiCbc/libOsiCbc.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,146 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {431ED9C6-FDF6-4836-8B33-BE4EC5378640} - libOsiCbc - ManagedCProj - - - - StaticLibrary - - - StaticLibrary - - - StaticLibrary - - - StaticLibrary - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - ..\..\..\..\Osi\src\Osi;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\src;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;%(PreprocessorDefinitions) - - - - - - - ..\..\..\..\Osi\src\Osi;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\src;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;%(PreprocessorDefinitions) - - - Level3 - ProgramDatabase - - - - - X64 - - - ..\..\..\..\Osi\src\Osi;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\src;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;%(PreprocessorDefinitions) - - - Level3 - ProgramDatabase - - - - - X64 - - - ..\..\..\..\Osi\src\Osi;..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\src;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;%(PreprocessorDefinitions) - - - Level3 - ProgramDatabase - Default - - - - - true - true - - - true - true - - - true - true - - - - - - - - - - - - \ No newline at end of file diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v10/OsiCbcUnitTest/OsiCbcUnitTest.vcxproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/OsiCbcUnitTest/OsiCbcUnitTest.vcxproj --- coinor-cbc-2.8.12/MSVisualStudio/v10/OsiCbcUnitTest/OsiCbcUnitTest.vcxproj 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v10/OsiCbcUnitTest/OsiCbcUnitTest.vcxproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {BB058D80-D376-4F0F-87F7-E4760BC2C84D} - OsiCbcUnitTest - Win32Proj - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - true - false - true - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - ..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\src\OsiCbc;..\..\..\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\OsiCommonTest;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_CONSOLE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample";NETLIBDIR="..\\..\\..\\..\\Data\\Netlib";MIPLIBDIR="..\\..\\..\\..\\Data\\miplib3";%(PreprocessorDefinitions) - - - - - libCoinUtils.lib;libOsi.lib;libOsiCommonTest.lib;libClp.lib;libOsiClp.lib;libCgl.lib;libCbc.lib;libOsiCbc.lib;libOsiClp.lib;libClp.lib;libOsi.lib;libOsiCommonTest.lib;libCoinUtils.lib;%(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - true - Console - MachineX86 - - - false - - - - - ..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\src\OsiCbc;..\..\..\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\OsiCommonTest;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CONSOLE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample";NETLIBDIR="..\\..\\..\\..\\Data\\Netlib";MIPLIBDIR="..\\..\\..\\..\\Data\\miplib3";%(PreprocessorDefinitions) - - - - - libCoinUtils.lib;libOsi.lib;libOsiCommonTest.lib;libClp.lib;libOsiClp.lib;libCgl.lib;libCbc.lib;libOsiCbc.lib;libOsiClp.lib;libClp.lib;libOsi.lib;libOsiCommonTest.lib;libCoinUtils.lib;%(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - true - Console - true - true - MachineX86 - - - false - - - - - X64 - - - ..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\src\OsiCbc;..\..\..\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\OsiCommonTest;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;_DEBUG;_CONSOLE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample";NETLIBDIR="..\\..\\..\\..\\Data\\Netlib";MIPLIBDIR="..\\..\\..\\..\\Data\\miplib3";%(PreprocessorDefinitions) - - - - - libCoinUtils.lib;libOsi.lib;libOsiCommonTest.lib;libClp.lib;libOsiClp.lib;libCgl.lib;libCbc.lib;libOsiCbc.lib;libCgl.lib;libOsiClp.lib;libClp.lib;libOsi.lib;libOsiCommonTest.lib;libCoinUtils.lib;%(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - true - Console - MachineX64 - - - false - - - - - X64 - - - ..\..\..\..\BuildTools\headers;..\..\..\..\CoinUtils\src;..\..\..\..\Osi\src\Osi;..\..\..\src\OsiCbc;..\..\..\src;..\..\..\..\Clp\src;..\..\..\..\Clp\src\OsiClp;..\..\..\..\Osi\src\OsiCommonTest;%(AdditionalIncludeDirectories) - CBC_BUILD;WIN32;NDEBUG;_NDEBUG;COIN_FAST_CODE;CLP_FAST_CODE;COIN_NO_TEST_DUPLICATE;_CONSOLE;SAMPLEDIR="..\\..\\..\\..\\Data\\Sample";NETLIBDIR="..\\..\\..\\..\\Data\\Netlib";MIPLIBDIR="..\\..\\..\\..\\Data\\miplib3";%(PreprocessorDefinitions) - - - - - libCoinUtils.lib;libOsi.lib;libOsiCommonTest.lib;libClp.lib;libOsiClp.lib;libCgl.lib;libCbc.lib;libOsiCbc.lib;libCgl.lib;libOsiClp.lib;libClp.lib;libOsi.lib;libOsiCommonTest.lib;libCoinUtils.lib;%(AdditionalDependencies) - $(OutDir);%(AdditionalLibraryDirectories) - true - Console - true - true - MachineX64 - - - false - - - - - - - - - {dbea3904-f0b8-408a-9e1a-6497febe8c42} - false - - - {4f8f7d1c-3a9e-444d-8ee9-77f33fa05994} - false - - - {02d45875-a8cf-41b9-990b-3699c0ecfe10} - false - - - {c4867f15-438d-4ff8-8388-62fbaaa9786c} - false - - - {109d6e6f-6d91-460f-86ae-df27400e09a9} - false - - - {7d98e2cb-876e-4f75-9f71-77d3fe87e149} - false - - - {e2294708-c5ba-460a-b0a7-060a4023684a} - false - - - {363ba154-fec9-4e1e-bc23-93cec58ab785} - false - - - {431ed9c6-fdf6-4836-8b33-be4ec5378640} - false - - - - - - \ No newline at end of file diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v9/cbc/cbc.vcproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/cbc/cbc.vcproj --- coinor-cbc-2.8.12/MSVisualStudio/v9/cbc/cbc.vcproj 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/cbc/cbc.vcproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,431 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v9/cbcCInterfaceDll/cbcCInterfaceDll.vcproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/cbcCInterfaceDll/cbcCInterfaceDll.vcproj --- coinor-cbc-2.8.12/MSVisualStudio/v9/cbcCInterfaceDll/cbcCInterfaceDll.vcproj 2011-01-10 12:58:03.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/cbcCInterfaceDll/cbcCInterfaceDll.vcproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,371 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v9/cbcCSosDllSample/cbcCSosDllSample.vcproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/cbcCSosDllSample/cbcCSosDllSample.vcproj --- coinor-cbc-2.8.12/MSVisualStudio/v9/cbcCSosDllSample/cbcCSosDllSample.vcproj 2011-01-10 12:58:03.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/cbcCSosDllSample/cbcCSosDllSample.vcproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,387 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v9/cbcExamplesSample2/cbcExamplesSample2.vcproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/cbcExamplesSample2/cbcExamplesSample2.vcproj --- coinor-cbc-2.8.12/MSVisualStudio/v9/cbcExamplesSample2/cbcExamplesSample2.vcproj 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/cbcExamplesSample2/cbcExamplesSample2.vcproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,807 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v9/Cbc.sln coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/Cbc.sln --- coinor-cbc-2.8.12/MSVisualStudio/v9/Cbc.sln 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/Cbc.sln 1970-01-01 00:00:00.000000000 +0000 @@ -1,182 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cbcExamplesSample2", "cbcExamplesSample2\cbcExamplesSample2.vcproj", "{4C0B8243-2876-4C92-B6CB-2472B0571CC3}" - ProjectSection(ProjectDependencies) = postProject - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42} = {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42} - {C4867F15-438D-4FF8-8388-62FBAAA9786C} = {C4867F15-438D-4FF8-8388-62FBAAA9786C} - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994} = {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994} - {363BA154-FEC9-4E1E-BC23-93CEC58AB785} = {363BA154-FEC9-4E1E-BC23-93CEC58AB785} - {02D45875-A8CF-41B9-990B-3699C0ECFE10} = {02D45875-A8CF-41B9-990B-3699C0ECFE10} - {7D98E2CB-876E-4F75-9F71-77D3FE87E149} = {7D98E2CB-876E-4F75-9F71-77D3FE87E149} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cbc", "cbc\cbc.vcproj", "{E2294708-C5BA-460A-B0A7-060A4023684A}" - ProjectSection(ProjectDependencies) = postProject - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42} = {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42} - {C4867F15-438D-4FF8-8388-62FBAAA9786C} = {C4867F15-438D-4FF8-8388-62FBAAA9786C} - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994} = {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994} - {363BA154-FEC9-4E1E-BC23-93CEC58AB785} = {363BA154-FEC9-4E1E-BC23-93CEC58AB785} - {02D45875-A8CF-41B9-990B-3699C0ECFE10} = {02D45875-A8CF-41B9-990B-3699C0ECFE10} - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E} = {71DA4595-E8A7-4B21-A00A-D96D29D11E3E} - {7D98E2CB-876E-4F75-9F71-77D3FE87E149} = {7D98E2CB-876E-4F75-9F71-77D3FE87E149} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCbc", "libCbc\libCbc.vcproj", "{363BA154-FEC9-4E1E-BC23-93CEC58AB785}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCgl", "..\..\..\Cgl\MSVisualStudio\v9\libCgl\libCgl.vcproj", "{DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libClp", "..\..\..\Clp\MSVisualStudio\v9\libClp\libClp.vcproj", "{4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCoinUtils", "..\..\..\CoinUtils\MSVisualStudio\v9\libCoinUtils\libCoinUtils.vcproj", "{C4867F15-438D-4FF8-8388-62FBAAA9786C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsi", "..\..\..\Osi\MSVisualStudio\v9\libOsi\libOsi.vcproj", "{7D98E2CB-876E-4F75-9F71-77D3FE87E149}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cbcCInterfaceDll", "cbcCInterfaceDll\cbcCInterfaceDll.vcproj", "{F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}" - ProjectSection(ProjectDependencies) = postProject - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42} = {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42} - {C4867F15-438D-4FF8-8388-62FBAAA9786C} = {C4867F15-438D-4FF8-8388-62FBAAA9786C} - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994} = {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994} - {363BA154-FEC9-4E1E-BC23-93CEC58AB785} = {363BA154-FEC9-4E1E-BC23-93CEC58AB785} - {02D45875-A8CF-41B9-990B-3699C0ECFE10} = {02D45875-A8CF-41B9-990B-3699C0ECFE10} - {7D98E2CB-876E-4F75-9F71-77D3FE87E149} = {7D98E2CB-876E-4F75-9F71-77D3FE87E149} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cbcCSosDllSample", "cbcCSosDllSample\cbcCSosDllSample.vcproj", "{8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}" - ProjectSection(ProjectDependencies) = postProject - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB} = {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libCbcSolver", "libCbcSolver\libCbcSolver.vcproj", "{71DA4595-E8A7-4B21-A00A-D96D29D11E3E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsiClp", "..\..\..\Clp\MSVisualStudio\v9\libOsiClp\libOsiClp.vcproj", "{02D45875-A8CF-41B9-990B-3699C0ECFE10}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsiCbc", "libOsiCbc\libOsiCbc.vcproj", "{431ED9C6-FDF6-4836-8B33-BE4EC5378640}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OsiCbcUnitTest", "OsiCbcUnitTest\OsiCbcUnitTest.vcproj", "{BB058D80-D376-4F0F-87F7-E4760BC2C84D}" - ProjectSection(ProjectDependencies) = postProject - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42} = {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42} - {E2294708-C5BA-460A-B0A7-060A4023684A} = {E2294708-C5BA-460A-B0A7-060A4023684A} - {C4867F15-438D-4FF8-8388-62FBAAA9786C} = {C4867F15-438D-4FF8-8388-62FBAAA9786C} - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994} = {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994} - {363BA154-FEC9-4E1E-BC23-93CEC58AB785} = {363BA154-FEC9-4E1E-BC23-93CEC58AB785} - {109D6E6F-6D91-460F-86AE-DF27400E09A9} = {109D6E6F-6D91-460F-86AE-DF27400E09A9} - {02D45875-A8CF-41B9-990B-3699C0ECFE10} = {02D45875-A8CF-41B9-990B-3699C0ECFE10} - {431ED9C6-FDF6-4836-8B33-BE4EC5378640} = {431ED9C6-FDF6-4836-8B33-BE4EC5378640} - {7D98E2CB-876E-4F75-9F71-77D3FE87E149} = {7D98E2CB-876E-4F75-9F71-77D3FE87E149} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libOsiCommonTest", "..\..\..\Osi\MSVisualStudio\v9\libOsiCommonTest\libOsiCommonTest.vcproj", "{109D6E6F-6D91-460F-86AE-DF27400E09A9}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Debug|Win32.ActiveCfg = Debug|Win32 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Debug|Win32.Build.0 = Debug|Win32 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Debug|x64.ActiveCfg = Debug|Win32 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Release|Win32.ActiveCfg = Release|Win32 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Release|Win32.Build.0 = Release|Win32 - {4C0B8243-2876-4C92-B6CB-2472B0571CC3}.Release|x64.ActiveCfg = Release|Win32 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Debug|Win32.ActiveCfg = Debug|Win32 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Debug|Win32.Build.0 = Debug|Win32 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Debug|x64.ActiveCfg = Debug|Win32 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Release|Win32.ActiveCfg = Release|Win32 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Release|Win32.Build.0 = Release|Win32 - {E2294708-C5BA-460A-B0A7-060A4023684A}.Release|x64.ActiveCfg = Release|Win32 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Debug|Win32.ActiveCfg = Debug|Win32 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Debug|Win32.Build.0 = Debug|Win32 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Debug|x64.ActiveCfg = Debug|x64 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Debug|x64.Build.0 = Debug|x64 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Release|Win32.ActiveCfg = Release|Win32 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Release|Win32.Build.0 = Release|Win32 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Release|x64.ActiveCfg = Release|x64 - {363BA154-FEC9-4E1E-BC23-93CEC58AB785}.Release|x64.Build.0 = Release|x64 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Debug|Win32.ActiveCfg = Debug|Win32 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Debug|Win32.Build.0 = Debug|Win32 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Debug|x64.ActiveCfg = Debug|x64 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Debug|x64.Build.0 = Debug|x64 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Release|Win32.ActiveCfg = Release|Win32 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Release|Win32.Build.0 = Release|Win32 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Release|x64.ActiveCfg = Release|x64 - {DBEA3904-F0B8-408A-9E1A-6497FEBE8C42}.Release|x64.Build.0 = Release|x64 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Debug|Win32.ActiveCfg = Debug|Win32 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Debug|Win32.Build.0 = Debug|Win32 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Debug|x64.ActiveCfg = Debug|x64 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Debug|x64.Build.0 = Debug|x64 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Release|Win32.ActiveCfg = Release|Win32 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Release|Win32.Build.0 = Release|Win32 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Release|x64.ActiveCfg = Release|x64 - {4F8F7D1C-3A9E-444D-8EE9-77F33FA05994}.Release|x64.Build.0 = Release|x64 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Debug|Win32.ActiveCfg = Debug|Win32 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Debug|Win32.Build.0 = Debug|Win32 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Debug|x64.ActiveCfg = Debug|x64 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Debug|x64.Build.0 = Debug|x64 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Release|Win32.ActiveCfg = Release|Win32 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Release|Win32.Build.0 = Release|Win32 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Release|x64.ActiveCfg = Release|x64 - {C4867F15-438D-4FF8-8388-62FBAAA9786C}.Release|x64.Build.0 = Release|x64 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Debug|Win32.ActiveCfg = Debug|Win32 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Debug|Win32.Build.0 = Debug|Win32 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Debug|x64.ActiveCfg = Debug|x64 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Debug|x64.Build.0 = Debug|x64 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Release|Win32.ActiveCfg = Release|Win32 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Release|Win32.Build.0 = Release|Win32 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Release|x64.ActiveCfg = Release|x64 - {7D98E2CB-876E-4F75-9F71-77D3FE87E149}.Release|x64.Build.0 = Release|x64 - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}.Debug|Win32.ActiveCfg = Debug|Win32 - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}.Debug|x64.ActiveCfg = Debug|x64 - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}.Debug|x64.Build.0 = Debug|x64 - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}.Release|Win32.ActiveCfg = Release|Win32 - {F1E9E3F0-6639-4A84-8E0F-A2D5F11978FB}.Release|x64.ActiveCfg = Release|x64 - {8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}.Debug|Win32.ActiveCfg = Debug|Win32 - {8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}.Debug|x64.ActiveCfg = Debug|x64 - {8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}.Debug|x64.Build.0 = Debug|x64 - {8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}.Release|Win32.ActiveCfg = Release|Win32 - {8AFDEA7E-BC40-4F31-80A8-8D05485E0A1E}.Release|x64.ActiveCfg = Release|x64 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Debug|Win32.ActiveCfg = Debug|Win32 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Debug|Win32.Build.0 = Debug|Win32 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Debug|x64.ActiveCfg = Debug|Win32 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Release|Win32.ActiveCfg = Release|Win32 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Release|Win32.Build.0 = Release|Win32 - {71DA4595-E8A7-4B21-A00A-D96D29D11E3E}.Release|x64.ActiveCfg = Release|Win32 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Debug|Win32.ActiveCfg = Debug|Win32 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Debug|Win32.Build.0 = Debug|Win32 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Debug|x64.ActiveCfg = Debug|x64 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Debug|x64.Build.0 = Debug|x64 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Release|Win32.ActiveCfg = Release|Win32 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Release|Win32.Build.0 = Release|Win32 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Release|x64.ActiveCfg = Release|x64 - {02D45875-A8CF-41B9-990B-3699C0ECFE10}.Release|x64.Build.0 = Release|x64 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Debug|Win32.ActiveCfg = Debug|Win32 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Debug|Win32.Build.0 = Debug|Win32 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Debug|x64.ActiveCfg = Debug|x64 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Debug|x64.Build.0 = Debug|x64 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Release|Win32.ActiveCfg = Release|Win32 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Release|Win32.Build.0 = Release|Win32 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Release|x64.ActiveCfg = Release|x64 - {431ED9C6-FDF6-4836-8B33-BE4EC5378640}.Release|x64.Build.0 = Release|x64 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Debug|Win32.ActiveCfg = Debug|Win32 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Debug|Win32.Build.0 = Debug|Win32 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Debug|x64.ActiveCfg = Debug|x64 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Debug|x64.Build.0 = Debug|x64 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Release|Win32.ActiveCfg = Release|Win32 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Release|Win32.Build.0 = Release|Win32 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Release|x64.ActiveCfg = Release|x64 - {BB058D80-D376-4F0F-87F7-E4760BC2C84D}.Release|x64.Build.0 = Release|x64 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Debug|Win32.ActiveCfg = Debug|Win32 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Debug|Win32.Build.0 = Debug|Win32 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Debug|x64.ActiveCfg = Debug|x64 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Debug|x64.Build.0 = Debug|x64 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Release|Win32.ActiveCfg = Release|Win32 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Release|Win32.Build.0 = Release|Win32 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Release|x64.ActiveCfg = Release|x64 - {109D6E6F-6D91-460F-86AE-DF27400E09A9}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v9/libCbc/libCbc.vcproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/libCbc/libCbc.vcproj --- coinor-cbc-2.8.12/MSVisualStudio/v9/libCbc/libCbc.vcproj 2011-11-03 20:15:03.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/libCbc/libCbc.vcproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,1916 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v9/libCbcSolver/libCbcSolver.vcproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/libCbcSolver/libCbcSolver.vcproj --- coinor-cbc-2.8.12/MSVisualStudio/v9/libCbcSolver/libCbcSolver.vcproj 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/libCbcSolver/libCbcSolver.vcproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,369 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v9/libOsiCbc/libOsiCbc.vcproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/libOsiCbc/libOsiCbc.vcproj --- coinor-cbc-2.8.12/MSVisualStudio/v9/libOsiCbc/libOsiCbc.vcproj 2011-06-19 16:57:59.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/libOsiCbc/libOsiCbc.vcproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,316 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru coinor-cbc-2.8.12/MSVisualStudio/v9/OsiCbcUnitTest/OsiCbcUnitTest.vcproj coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/OsiCbcUnitTest/OsiCbcUnitTest.vcproj --- coinor-cbc-2.8.12/MSVisualStudio/v9/OsiCbcUnitTest/OsiCbcUnitTest.vcproj 2011-01-10 12:58:03.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/MSVisualStudio/v9/OsiCbcUnitTest/OsiCbcUnitTest.vcproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,359 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru coinor-cbc-2.8.12/README coinor-cbc-2.9.9+repack1/README --- coinor-cbc-2.8.12/README 2013-07-16 09:10:26.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/README 2016-09-01 23:11:36.000000000 +0000 @@ -1,15 +1,18 @@ -CBC README -========== +# CBC Version 2.9.4 README Welcome to the README for the COIN Branch and Cut Solver (CBC). CBC is distributed under the Eclipse Public License and is freely redistributable. All source code and documentation is Copyright IBM and others. This README may be redistributed freely. -DOCUMENTATION -============= +## DOWNLOAD -For a quick start guide, please see the INSTALL file in this distribution. A (somehwat outdated) user's manual is available here: +Binaries for most platforms are available for download from [Bintray](https://bintray.com/coin-or/download/Cbc) + +## DOCUMENTATION + +For a quick start guide, please see the INSTALL file in this distribution. A +(somehwat outdated) user's manual is available here: http://www.coin-or.org/Cbc @@ -22,196 +25,299 @@ http://projects.coin-or.org/Cbc -WHAT'S NEW -========== +## SUPPORT -Release 2.8.3: +### List Serve -1. Fix for handling SOS. +CBC users should use the Cbc mailing list. To subscribe, go to +http://list.coin-or.org/mailman/listinfo/cbc -Release 2.8.2: +### Bug Reports -1. Fixed recognition of Glpk source in main configure. +Bug reports should be reported on the CBC development web site at -2. Minor bugfixes in CoinUtils, Clp, and Cbc. +https://projects.coin-or.org/Cbc/newticket -Release 2.8.1: +## CHANGELOG - Ted, please fill this in! + * Release 2.9.8 -Release 2.8.0: + * Update to most current releases of dependencies + * Small bug fixes + * Add support for automatic build and test with Travis and Appveyor -1. Introduced new secondaryStatus 8 to indicate that solving stopped due to an iteration limit. +* Release 2.9.7 -2. Solution pool is now accessible via the command line and the CbcMain* interface. + * Small bug fixes + * Option to switch to line buffered output -3. New mipstart option to read an initial feasible solution from a file. Only values for discrete - variables need to be provided. + * Release 2.9.6 -4. Added Proximity Search heuristic by Fischetti and Monaci (off by default): - The simplest way to switch it on using stand-alone version is "-proximity on". + * Small bug fixes - Proximity Search is the new "No-Neighborhood Search" 0-1 MIP refinement heuristic recently proposed by - Fischetti and Monaci (2012). The idea is to define a sub-MIP without additional constraints but with a - modified objective function intended to attract the search in the proximity of the incumbent. The approach - works well for 0-1 MIPs whose solution landscape is not too irregular (meaning the there is reasonable - probability of finding an improved solution by flipping a small number of binary variables), in particular - when it is applied to the first heuristic solutions found at the root node. - -5. An implementation of Zero-Half-Cuts by Alberto Caprara is now available. - By default, these cuts are off. To use add to your command line -zerohalfCuts root (or other options) or just -zero. - So far, they may help only on a small subset of problems and may need some tuning. - - The implementation of these cuts is described in - G. Andreello, A. Caprara, and M. Fischetti - "Embedding Cuts in a Branch and Cut Framework: a Computational Study with {0,1/2}-Cuts" - INFORMS Journal on Computing 19(2), 229-238, 2007 - http://dx.doi.org/10.1287/ijoc.1050.0162 - -6. An alternative implementation of a reduce and split cut generator by Giacomo Nannicini is now available. - By default, these cuts are off. To use add to your command line -reduce2AndSplitCuts root (or other options). - - The implementation of these cuts is described in - G. Cornuejols and G. Nannicini - "Practical strategies for generating rank-1 split cuts in mixed-integer linear programming" - Mathematical Programming Computation 3(4), 281-318, 2011 - http://dx.doi.org/10.1007/s12532-011-0028-6 - -7. An alternative robust implementation of a Gomory cut generator by Giacomo Nannicini is now available. - By default, these cuts are off. To use add to your command line -GMI root (or other options). - - The implementation of these cuts is described in - G. Cornuejols, F. Margot, and G. Nannicini - "On the safety of Gomory cut generators" - http://faculty.sutd.edu.sg/~nannicini/index.php?page=publications - -8. To encourage the use of some of the more exotic/expensive cut generators a parameter -slowcutpasses has been added. - The idea is that the code does these cuts just a few times - less than the more usual cuts. The default is 10. - The cut generators identified by "may be slow" at present are just Lift and project and ReduceAndSplit (both versions). - -9. Allow initialization of random seed by user. Pseudo-random numbers are used in Cbc and Clp. In Clp they - are used to break ties in degenerate problems, while in Cbc heuristics such as the Feasibility Pump use them - to decide whether to round up or down. So if a different pseudo-random seed is given to Clp then you may get - a different continuous optimum and so different cuts and heuristic solutions. This can be switched on by - setting randomSeed for Clp and/or randomCbcSeed for Cbc. The special value of 0 tells code to use time of day - for initial seed. - -10. Building on this idea, Andrea Lodi, Matteo Fischetti, Michele Monaci, Domenico Salvagnin, Yuji Shinano, and Andrea Tramontani - suggest that this idea be improved by running at the root node with multiple copies of solver, each - with its own different seed and then passing in the solutions and cuts so that the main solver has a richer - set of solutions and possibly stronger cuts. This is switched on by setting -multipleRootPasses. These can also - be done in parallel. - -11. Few changes to presolve for special variables and badly scaled problems (in CoinUtils). + * Release 2.9.5 + + * Small bug fixes + + * Release 2.9.4 + + * Small fixes for stability + * Fixes for Doygen documentation generation -12. New option -extraVariables which switches on a trivial re-formulation that introduces extra integer variables - to group together variables with same cost. + * Release 2.9.3 -13. For some problems, cut generators and general branching work better if the problem would be infeasible if the cost is too high. - If the new option -constraintFromCutoff is set, the objective function is added as a constraint which rhs is set to the current - cutoff value (objective value of best known solution). + * Minor bug fixes -Release 2.7.8: - Look at https://projects.coin-or.org/Cbc/changeset?old_path=%2Freleases%2F2.7.7&new_path=%2Freleases%2F2.7.8 to see all changes. + * Release 2.9.2 -1. Change message when LP simplex iteration limit is hit from "Exiting on maximum nodes" - to "Exiting on maximum number of iterations" + * Fix for proper installation with ```DESTDIR``` -2. Fix for using overlapping SOS. + * Release 2.9.1 -3. Fixes in buildsystem. + * Fix for dependency linking + * Minor bug fixes -Release 2.7.7: - Look at https://projects.coin-or.org/Cbc/changeset?old_path=%2Freleases%2F2.7.6&new_path=%2Freleases%2F2.7.7 to see all changes. + * Release 2.9.0 -1. Fix to report interruption on user event if SIGINT is received by CbcSolver. - model->status() should now be 5 if this event happened. - Added method CbcModel::sayEventHappened() to make cbc stop due to an 'user event'. + * Introduced specialized branching methods for dealing with "big Ms". + * Introduced new methods for dealing with symmetry (requires installation of [nauty](http://pallini.di.uniroma1.it/)) + * Introduction of conflict cuts (off by default, turn on with `-constraint conflict`) -2. Other minor fixes. + * Release 2.8.13 -Release 2.7.6: - Look at https://projects.coin-or.org/Cbc/changeset?old_path=%2Freleases%2F2.7.5&new_path=%2Freleases%2F2.7.6 to see all changes. + * Improved message handling + * Miscellaneous bug fixes. -1. Fixes to build system. + * Release 2.8.12 + * Update for dependencies. -2. Other minor fixes. + * Release 5.8.11 -Release 2.7.5: - Look at https://projects.coin-or.org/Cbc/changeset?old_path=%2Freleases%2F2.7.4&new_path=%2Freleases%2F2.7.5 to see all changes. + * Major overhaul of C interface + * Fixes to SOS + * Miscellaneous bug fixes -1. Fixes to get AMPL interface working again. + * Release 2.8.10 -2. More fixes to MSVC++ files. + * More changes related to thread safety. + * Fix bug in build system with Visual Studio compiler. + * Miscellaneous bug fixes. -Release 2.7.4: - Look at https://projects.coin-or.org/Cbc/changeset?old_path=%2Freleases%2F2.7.3&new_path=%2Freleases%2F2.7.4 to see all changes. + * Release 2.8.9 -1. Minor bugfixes. + * Attempt to make Cbc thread safe. + * Add parallel examples. + * Add CbcSolverUsefulInfo. + * Bug fixes. -Release 2.7.3: - Look at https://projects.coin-or.org/Cbc/changeset?old_path=%2Freleases%2F2.7.2&new_path=%2Freleases%2F2.7.3 to see all changes. + * Release 2.8.8 -1. Minor bugfixes. + * Added example to show how to use Cbc with installed libraries in MSVC++ + * Fixed inconsistency in addition of libCbcSolver to dependencies in + {{{cbc_addlibs.txt}}}. -2. Fixes to MSVC++ files. + * Release 2.8.7 -Release 2.7.2: - Look at https://projects.coin-or.org/Cbc/changeset?old_path=%2Freleases%2F2.7.1&new_path=%2Freleases%2F2.7.2 to see all changes. + * Changed so that Doxygen builds LaTex + * Fixes for build system -1. Allow row/column names for GMPL models. + * Release 2.8.6 -2. Added CbcModel::haveMultiThreadSupport() to indicate whether Cbc library has been compiled with multithread support. + * Added option to explicitly link dependencies to comply with packaging + requirements on Fedora and Debian, as well as allow building of MinGW + DLLs. -3. Added CbcModel::waitingForMiniBranchAndBound() to indicate whether sub-MIP heuristic is currently running. + * Release 2.8.5 -4. Cbc shell should work with readline if configured with --enable-gnu-packages. + * Minor fixes to build system -5. Support for compressed input files (.gz, .bz2) is now enabled by default. + * Release 2.8.4 + * Small bug fixes + * Upgrades to build system -6. Fix problems with relative gap tolerance > 100% and further bugs. + * Release 2.8.3: -7. Fixes for MSVC++ Version 9 files. + * Fix for handling SOS. -8. Minor fixes in buildsystem; update to BuildTools 0.7.1. + * Release 2.8.2: -Release 2.7.1: - Look at https://projects.coin-or.org/Cbc/changeset?old_path=%2Freleases%2F2.7.0&new_path=%2Freleases%2F2.7.1 to see all changes. + * Fixed recognition of Glpk source in main configure. + * Minor bug fixes in CoinUtils, Clp, and Cbc. -1. Fixes to MSVC++ files + * Release 2.8.1: -Release 2.7.0: + * Minor bug fixes -1. License has been changed to the EPL. + * Release 2.8.0: -2. Support for MSVC++ version 10 added. + * Introduced new secondaryStatus 8 to indicate that solving stopped due to + an iteration limit. + * Solution pool is now accessible via the command line and the CbcMain* + interface. + * New mipstart option to read an initial feasible solution from a file. + Only values for discrete variables need to be provided. -3. Support for BuildTools version 0.7 to incorporate recent enhancements, -including proper library versioning in Linux, prohibiting installation of -private headers, etc. + * Added Proximity Search heuristic by Fischetti and Monaci (off by + default): The simplest way to switch it on using stand-alone version is + ```-proximity on```. -4. Updated externals to new stable versions of dependent projects. + Proximity Search is the new "No-Neighborhood Search" 0-1 MIP refinement + heuristic recently proposed by Fischetti and Monaci (2012). The idea is + to define a sub-MIP without additional constraints but with a modified + objective function intended to attract the search in the proximity of the + incumbent. The approach works well for 0-1 MIPs whose solution landscape + is not too irregular (meaning the there is reasonable probability of + finding an improved solution by flipping a small number of binary + variables), in particular when it is applied to the first heuristic + solutions found at the root node. + + * An implementation of Zero-Half-Cuts by Alberto Caprara is now available. + By default, these cuts are off. To use add to your command line + -zerohalfCuts root (or other options) or just -zero. So far, they may + help only on a small subset of problems and may need some tuning. + + The implementation of these cuts is described in G. Andreello, A. + Caprara, and M. Fischetti "Embedding Cuts in a Branch and Cut Framework: + a Computational Study with {0,1/2}-Cuts" INFORMS Journal on Computing + 19(2), 229-238, 2007 http://dx.doi.org/10.1287/ijoc.1050.0162 + + * An alternative implementation of a reduce and split cut generator by + Giacomo Nannicini is now available. By default, these cuts are off. To + use add to your command line -reduce2AndSplitCuts root (or other + options). + + The implementation of these cuts is described in G. Cornuejols and G. + Nannicini "Practical strategies for generating rank-1 split cuts in + mixed-integer linear programming" Mathematical Programming Computation + 3(4), 281-318, 2011 http://dx.doi.org/10.1007/s12532-011-0028-6 + + * An alternative robust implementation of a Gomory cut generator by Giacomo + Nannicini is now available. By default, these cuts are off. To use add to + your command line -GMI root (or other options). + + The implementation of these cuts is described in G. Cornuejols, F. + Margot, and G. Nannicini "On the safety of Gomory cut generators" + http://faculty.sutd.edu.sg/~nannicini/index.php?page=publications + + * To encourage the use of some of the more exotic/expensive cut generators + a parameter -slowcutpasses has been added. The idea is that the code does + these cuts just a few times - less than the more usual cuts. The default + is 10. The cut generators identified by "may be slow" at present are just + Lift and project and ReduceAndSplit (both versions). + + * Allow initialization of random seed by user. Pseudo-random numbers are + used in Cbc and Clp. In Clp they are used to break ties in degenerate + problems, while in Cbc heuristics such as the Feasibility Pump use them + to decide whether to round up or down. So if a different pseudo-random + seed is given to Clp then you may get a different continuous optimum and + so different cuts and heuristic solutions. This can be switched on by + setting randomSeed for Clp and/or randomCbcSeed for Cbc. The special + value of 0 tells code to use time of day for initial seed. + + * Building on this idea, Andrea Lodi, Matteo Fischetti, Michele Monaci, + Domenico Salvagnin, Yuji Shinano, and Andrea Tramontani suggest that this + idea be improved by running at the root node with multiple copies of + solver, each with its own different seed and then passing in the + solutions and cuts so that the main solver has a richer set of solutions + and possibly stronger cuts. This is switched on by setting + -multipleRootPasses. These can also be done in parallel. + + * Few changes to presolve for special variables and badly scaled problems + (in CoinUtils). -5. Improvements to heuristics. + * New option -extraVariables which switches on a trivial + re-formulation that introduces extra integer variables to group together + variables with same cost. -6. New options for cut generation. + * For some problems, cut generators and general branching work better if + the problem would be infeasible if the cost is too high. If the new + option -constraintFromCutoff is set, the objective function is added as a + constraint which rhs is set to the current cutoff value (objective value + of best known solution). -7. Improved reporting of results. + * Release 2.7.8: -8. Improvements to documentation. + * Change message when LP simplex iteration limit is hit from "Exiting on + maximum nodes" to "Exiting on maximum number of iterations" + * Fix for using overlapping SOS. + * Fixes in buildsystem. -9. Minor bug fixes. + * Release 2.7.7: -SUPPORT -======= + * Fix to report interruption on user event if SIGINT is received by + CbcSolver. model->status() should now be 5 if this event happened. Added + method CbcModel::sayEventHappened() to make cbc stop due to an 'user + event'. -1. List Serve + * Other minor fixes. -CBC users should use the Cbc mailing list. To subscribe, go to -http://list.coin-or.org/mailman/listinfo/cbc + * Release 2.7.6: -3. Bug Reports + * Fixes to build system. + + * Other minor fixes. + + * Release 2.7.5: + + * Fixes to get AMPL interface working again. + + * More fixes to MSVC++ files. + + * Release 2.7.4: + + * Minor bugfixes. + + * Release 2.7.3: + + * Minor bugfixes. + + * Fixes to MSVC++ files. + + * Release 2.7.2: + + * Allow row/column names for GMPL models. + + * Added CbcModel::haveMultiThreadSupport() to indicate whether Cbc library + has been compiled with multithread support. + + * Added CbcModel::waitingForMiniBranchAndBound() to indicate whether + sub-MIP heuristic is currently running. + + * Cbc shell should work with readline if configured with + ```--enable-gnu-packages```. + + * Support for compressed input files (.gz, .bz2) is now enabled by default. + + * Fix problems with relative gap tolerance > 100% and further bugs. + + * Fixes for MSVC++ Version 9 files. + + * Minor fixes in buildsystem; update to BuildTools 0.7.1. + + * Release 2.7.1: + + * Fixes to MSVC++ files + + * Release 2.7.0: + + * License has been changed to the EPL. + + * Support for MSVC++ version 10 added. + + * Support for BuildTools version 0.7 to incorporate recent enhancements, + including proper library versioning in Linux, prohibiting installation of + private headers, etc. + + * Updated externals to new stable versions of dependent projects. + + * Improvements to heuristics. + + * New options for cut generation. + + * Improved reporting of results. + + * Improvements to documentation. + + * Minor bug fixes. -Bug reports should be reported on the CBC development web site at -https://projects.coin-or.org/Cbc/newticket diff -Nru coinor-cbc-2.8.12/src/Cbc_ampl.cpp coinor-cbc-2.9.9+repack1/src/Cbc_ampl.cpp --- coinor-cbc-2.8.12/src/Cbc_ampl.cpp 2014-05-13 07:25:03.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/Cbc_ampl.cpp 2014-05-13 07:26:07.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: Cbc_ampl.cpp 2034 2014-05-13 07:25:03Z forrest $ */ +/* $Id: Cbc_ampl.cpp 2035 2014-05-13 07:26:07Z forrest $ */ /**************************************************************** Copyright (C) 1997-2000 Lucent Technologies Modifications for Coin - Copyright (C) 2006, International Business Machines Corporation and others. diff -Nru coinor-cbc-2.8.12/src/CbcBranchAllDifferent.cpp coinor-cbc-2.9.9+repack1/src/CbcBranchAllDifferent.cpp --- coinor-cbc-2.8.12/src/CbcBranchAllDifferent.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchAllDifferent.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchAllDifferent.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchAllDifferent.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcBranchAllDifferent.hpp coinor-cbc-2.9.9+repack1/src/CbcBranchAllDifferent.hpp --- coinor-cbc-2.8.12/src/CbcBranchAllDifferent.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchAllDifferent.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchAllDifferent.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchAllDifferent.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcBranchDecision.cpp coinor-cbc-2.9.9+repack1/src/CbcBranchDecision.cpp --- coinor-cbc-2.8.12/src/CbcBranchDecision.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchDecision.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchDecision.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchDecision.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcBranchDecision.hpp coinor-cbc-2.9.9+repack1/src/CbcBranchDecision.hpp --- coinor-cbc-2.8.12/src/CbcBranchDecision.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchDecision.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchDecision.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchDecision.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcBranchDefaultDecision.cpp coinor-cbc-2.9.9+repack1/src/CbcBranchDefaultDecision.cpp --- coinor-cbc-2.8.12/src/CbcBranchDefaultDecision.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchDefaultDecision.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchDefaultDecision.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchDefaultDecision.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcBranchDefaultDecision.hpp coinor-cbc-2.9.9+repack1/src/CbcBranchDefaultDecision.hpp --- coinor-cbc-2.8.12/src/CbcBranchDefaultDecision.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchDefaultDecision.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchDefaultDecision.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchDefaultDecision.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcBranchDynamic.cpp coinor-cbc-2.9.9+repack1/src/CbcBranchDynamic.cpp --- coinor-cbc-2.8.12/src/CbcBranchDynamic.cpp 2011-01-05 01:12:36.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchDynamic.cpp 2014-09-14 07:53:50.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcBranchDynamic.cpp 1573 2011-01-05 01:12:36Z lou $ */ +/* $Id: CbcBranchDynamic.cpp 2073 2014-09-14 07:53:50Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -61,10 +61,10 @@ char where_; char status_; } History; -History * history = NULL; -int numberHistory = 0; -int maxHistory = 0; -bool getHistoryStatistics_ = true; +static History * history = NULL; +static int numberHistory = 0; +static int maxHistory = 0; +static bool getHistoryStatistics_ = true; static void increaseHistory() { if (numberHistory == maxHistory) { diff -Nru coinor-cbc-2.8.12/src/CbcBranchingObject.cpp coinor-cbc-2.9.9+repack1/src/CbcBranchingObject.cpp --- coinor-cbc-2.8.12/src/CbcBranchingObject.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchingObject.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchingObject.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchingObject.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcBranchingObject.hpp coinor-cbc-2.9.9+repack1/src/CbcBranchingObject.hpp --- coinor-cbc-2.8.12/src/CbcBranchingObject.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchingObject.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchingObject.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchingObject.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcBranchLotsize.cpp coinor-cbc-2.9.9+repack1/src/CbcBranchLotsize.cpp --- coinor-cbc-2.8.12/src/CbcBranchLotsize.cpp 2014-08-09 16:05:41.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchLotsize.cpp 2014-07-01 13:03:51.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcBranchLotsize.cpp 2055 2014-08-09 16:05:41Z forrest $ */ +/* $Id: CbcBranchLotsize.cpp 2043 2014-07-01 13:03:51Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcBranchToFixLots.cpp coinor-cbc-2.9.9+repack1/src/CbcBranchToFixLots.cpp --- coinor-cbc-2.8.12/src/CbcBranchToFixLots.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchToFixLots.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchToFixLots.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchToFixLots.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcBranchToFixLots.hpp coinor-cbc-2.9.9+repack1/src/CbcBranchToFixLots.hpp --- coinor-cbc-2.8.12/src/CbcBranchToFixLots.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcBranchToFixLots.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcBranchToFixLots.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcBranchToFixLots.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCbcParam.cpp coinor-cbc-2.9.9+repack1/src/CbcCbcParam.cpp --- coinor-cbc-2.8.12/src/CbcCbcParam.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCbcParam.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcCbcParam.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcCbcParam.cpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/Cbc_C_Interface.cpp coinor-cbc-2.9.9+repack1/src/Cbc_C_Interface.cpp --- coinor-cbc-2.8.12/src/Cbc_C_Interface.cpp 2014-08-23 16:31:35.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/Cbc_C_Interface.cpp 2014-06-20 02:34:45.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: Cbc_C_Interface.cpp 2059 2014-08-23 16:31:35Z tkr $ +// $Id: Cbc_C_Interface.cpp 2039 2014-06-20 02:34:45Z mlubin $ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/Cbc_C_Interface.h coinor-cbc-2.9.9+repack1/src/Cbc_C_Interface.h --- coinor-cbc-2.8.12/src/Cbc_C_Interface.h 2014-08-23 16:31:35.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/Cbc_C_Interface.h 2014-10-03 00:46:49.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: Cbc_C_Interface.h 2059 2014-08-23 16:31:35Z tkr $ */ +/* $Id: Cbc_C_Interface.h 2091 2014-10-03 00:46:49Z mlubin $ */ /* Copyright (C) 2004 International Business Machines Corporation and others. All Rights Reserved. @@ -208,8 +208,7 @@ COINLIBAPI void COINLINKAGE Cbc_setInteger(Cbc_Model * model, int iColumn) ; - /** Add SOS constraints to the model using row-order matrix - * Unable to confirm that this function is working. */ + /** Add SOS constraints to the model using row-order matrix */ COINLIBAPI void COINLINKAGE Cbc_addSOS(Cbc_Model * model, int numRows, const int * rowStarts, const int * colIndices, const double * weights, const int type) diff -Nru coinor-cbc-2.8.12/src/CbcClique.cpp coinor-cbc-2.9.9+repack1/src/CbcClique.cpp --- coinor-cbc-2.8.12/src/CbcClique.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcClique.cpp 2014-11-18 11:15:36.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcClique.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcClique.cpp 2094 2014-11-18 11:15:36Z forrest $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -43,11 +43,35 @@ const int * which, const char * type, int identifier, int slack) : CbcObject(model) { - id_ = identifier; numberMembers_ = numberMembers; + int * backward = NULL; + if (identifier<0) { + // which are variables in model - not in integers + identifier=-identifier; + int numberColumns = model->getNumCols(); + int numberIntegers = model->numberIntegers(); + const int * integerVariable = model->integerVariable(); + backward = new int [numberColumns]; + for (int i=0;i=0); + members_[i]=iColumn; +#ifdef FULL_PRINT + printf("%d column %d member %d\n",i,which[i],iColumn); +#endif + } + } type_ = new char[numberMembers_]; if (type) { memcpy(type_, type, numberMembers_*sizeof(char)); @@ -67,6 +91,8 @@ numberNonSOSMembers_++; cliqueType_ = cliqueType; slack_ = slack; + delete [] backward; + id_ = identifier; } // Copy constructor @@ -282,6 +308,7 @@ int numberFree = numberMembers_; const int * integer = model_->integerVariable(); //OsiSolverInterface * solver = model_->solver(); + CoinWarmStartBasis * basis = dynamic_cast(solver->getWarmStart()) ; const double * solution = model_->testSolution(); const double * lower = solver->getColLower(); const double * upper = solver->getColUpper(); @@ -311,12 +338,18 @@ sort[numberUnsatis++] = value; } else if (upper[iColumn] > lower[iColumn]) { upList[--numberFree] = j; + sort[numberFree] = 0.0; + if (basis && basis->getStructStatus(iColumn) == CoinWarmStartBasis::basic) + sort[numberFree] = -1.0; + } } assert (numberUnsatis); if (!slackValue) { // sort CoinSort_2(sort, sort + numberUnsatis, upList); + // also try and spread out satisfied basic + CoinSort_2(sort+numberFree, sort + numberMembers_, upList+numberFree); // put first in up etc int kWay = 1; for (j = 0; j < numberUnsatis; j++) { @@ -458,10 +491,23 @@ printf("%d ", i + 32*iWord); #endif // fix weak way - if (clique_->type(i + 32*iWord)) + if (clique_->type(i + 32*iWord)) { +#ifdef FULL_PRINT + printf("member %d int %d matcol %d bound %g %g to 0.0\n", + i,iColumn,integerVariables[iColumn], + model_->solver()->getColLower()[integerVariables[iColumn]], + model_->solver()->getColUpper()[integerVariables[iColumn]]); +#endif model_->solver()->setColUpper(integerVariables[iColumn], 0.0); - else + } else { +#ifdef FULL_PRINT + printf("member %d int %d matcol %d bound %g %g to 1.0\n", + i,iColumn,integerVariables[iColumn], + model_->solver()->getColLower()[integerVariables[iColumn]], + model_->solver()->getColUpper()[integerVariables[iColumn]]); +#endif model_->solver()->setColLower(integerVariables[iColumn], 1.0); + } } } } @@ -480,10 +526,23 @@ printf("%d ", i + 32*iWord); #endif // fix weak way - if (clique_->type(i + 32*iWord)) + if (clique_->type(i + 32*iWord)) { +#ifdef FULL_PRINT + printf("member %d int %d matcol %d bound %g %g to 0.0\n", + i,iColumn,integerVariables[iColumn], + model_->solver()->getColLower()[integerVariables[iColumn]], + model_->solver()->getColUpper()[integerVariables[iColumn]]); +#endif model_->solver()->setColUpper(integerVariables[iColumn], 0.0); - else + } else { +#ifdef FULL_PRINT + printf("member %d int %d matcol %d bound %g %g to 1.0\n", + i,iColumn,integerVariables[iColumn], + model_->solver()->getColLower()[integerVariables[iColumn]], + model_->solver()->getColUpper()[integerVariables[iColumn]]); +#endif model_->solver()->setColLower(integerVariables[iColumn], 1.0); + } } } } diff -Nru coinor-cbc-2.8.12/src/CbcClique.hpp coinor-cbc-2.9.9+repack1/src/CbcClique.hpp --- coinor-cbc-2.8.12/src/CbcClique.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcClique.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcClique.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcClique.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCompareDefault.cpp coinor-cbc-2.9.9+repack1/src/CbcCompareDefault.cpp --- coinor-cbc-2.8.12/src/CbcCompareDefault.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCompareDefault.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCompareDefault.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCompareDefault.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCompareDefault.hpp coinor-cbc-2.9.9+repack1/src/CbcCompareDefault.hpp --- coinor-cbc-2.8.12/src/CbcCompareDefault.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCompareDefault.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCompareDefault.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCompareDefault.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCompareDepth.cpp coinor-cbc-2.9.9+repack1/src/CbcCompareDepth.cpp --- coinor-cbc-2.8.12/src/CbcCompareDepth.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCompareDepth.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCompareDepth.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCompareDepth.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCompareDepth.hpp coinor-cbc-2.9.9+repack1/src/CbcCompareDepth.hpp --- coinor-cbc-2.8.12/src/CbcCompareDepth.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCompareDepth.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCompareDepth.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCompareDepth.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCompareEstimate.cpp coinor-cbc-2.9.9+repack1/src/CbcCompareEstimate.cpp --- coinor-cbc-2.8.12/src/CbcCompareEstimate.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCompareEstimate.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCompareEstimate.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCompareEstimate.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCompareEstimate.hpp coinor-cbc-2.9.9+repack1/src/CbcCompareEstimate.hpp --- coinor-cbc-2.8.12/src/CbcCompareEstimate.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCompareEstimate.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCompareEstimate.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCompareEstimate.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCompare.hpp coinor-cbc-2.9.9+repack1/src/CbcCompare.hpp --- coinor-cbc-2.8.12/src/CbcCompare.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCompare.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcCompare.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcCompare.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCompareObjective.cpp coinor-cbc-2.9.9+repack1/src/CbcCompareObjective.cpp --- coinor-cbc-2.8.12/src/CbcCompareObjective.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCompareObjective.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCompareObjective.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCompareObjective.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCompareObjective.hpp coinor-cbc-2.9.9+repack1/src/CbcCompareObjective.hpp --- coinor-cbc-2.8.12/src/CbcCompareObjective.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCompareObjective.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCompareObjective.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCompareObjective.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcConsequence.cpp coinor-cbc-2.9.9+repack1/src/CbcConsequence.cpp --- coinor-cbc-2.8.12/src/CbcConsequence.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcConsequence.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcConsequence.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcConsequence.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcConsequence.hpp coinor-cbc-2.9.9+repack1/src/CbcConsequence.hpp --- coinor-cbc-2.8.12/src/CbcConsequence.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcConsequence.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcConsequence.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcConsequence.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCountRowCut.cpp coinor-cbc-2.9.9+repack1/src/CbcCountRowCut.cpp --- coinor-cbc-2.8.12/src/CbcCountRowCut.cpp 2013-04-06 13:33:15.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCountRowCut.cpp 2015-02-01 09:33:30.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcCountRowCut.cpp 1883 2013-04-06 13:33:15Z stefan $ */ +/* $Id: CbcCountRowCut.cpp 2124 2015-02-01 09:33:30Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -364,16 +364,18 @@ hash_[ipos]=hash_[k]; ipos=k; } - delete cut; + hash_[ipos].index=-1; // move last to found numberCuts_--; - if (numberCuts_) { + assert (found==numberCuts_); // debug when fails + if (numberCuts_&&found=0); } else { // change hash_[ipos].index=found; @@ -383,13 +385,77 @@ } } } - assert (!rowCut_[numberCuts_]); + delete cut; + rowCut_[numberCuts_]=NULL; + //assert (!rowCut_[numberCuts_-1]); +} +// Truncate +void +CbcRowCuts::truncate(int numberAfter) +{ + if (numberAfter<0||numberAfter>=numberCuts_) + return; + for (int i=numberAfter;i= 0 ) { + if ( !same(*temp[i],*temp[j1]) ) { + int k = hash_[ipos].next; + if ( k != -1 ) + ipos = k; + else + break; + } else { + found = j1; + break; + } + } else { + break; + } + } + if (found<0) { + assert (hash_[ipos].next==-1); + if (ipos==jpos) { + // first + hash_[ipos].index=i; + } else { + // find next space + while ( true ) { + ++lastHash_; + assert (lastHash_setLb(newLb); newCutPtr->setUb(newUb); newCutPtr->setRow(vector); + newCutPtr->setGloballyValid(globallyValid); rowCut_[numberCuts_++]=newCutPtr; + //printf("addedGlobalCut of size %d to %x - cuts size %d\n", + // cut.row().getNumElements(),this,numberCuts_); return 0; } else { return 1; @@ -530,6 +600,7 @@ hash_[i].index=-1; hash_[i].next=-1; } + lastHash_=-1; for (int i=0;isetUb(newUb); newCutPtr->setRow(vector); rowCut_[numberCuts_++]=newCutPtr; + //printf("addedGreedyGlobalCut of size %d to %p - cuts size %d\n", + // cut.row().getNumElements(),this,numberCuts_); return 0; } else { return 1; diff -Nru coinor-cbc-2.8.12/src/CbcCountRowCut.hpp coinor-cbc-2.9.9+repack1/src/CbcCountRowCut.hpp --- coinor-cbc-2.8.12/src/CbcCountRowCut.hpp 2013-01-16 18:41:25.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCountRowCut.hpp 2014-11-18 11:15:36.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcCountRowCut.hpp 1839 2013-01-16 18:41:25Z forrest $ */ +/* $Id: CbcCountRowCut.hpp 2094 2014-11-18 11:15:36Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -124,7 +124,7 @@ b) allow half baked cuts The whichRow_ field in OsiRowCut2 is used for a type 0 - normal - 1 - processed cut + 1 - processed cut (conflict) 2 - unprocessed cut i.e. dual ray computation */ // for hashing @@ -153,6 +153,8 @@ int addCutIfNotDuplicateWhenGreedy(const OsiRowCut & cut,int whichType=0); // Add in cuts as normal cuts (and delete) void addCuts(OsiCuts & cs); + // Truncate + void truncate(int numberAfter); private: OsiRowCut2 ** rowCut_; /// Hash table diff -Nru coinor-cbc-2.8.12/src/CbcCutGenerator.cpp coinor-cbc-2.9.9+repack1/src/CbcCutGenerator.cpp --- coinor-cbc-2.8.12/src/CbcCutGenerator.cpp 2013-04-06 13:33:15.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCutGenerator.cpp 2015-05-05 12:53:14.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcCutGenerator.cpp 1883 2013-04-06 13:33:15Z stefan $ */ +/* $Id: CbcCutGenerator.cpp 2186 2015-05-05 12:53:14Z stefan $ */ // Copyright (C) 2003, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -174,7 +174,9 @@ CbcCutGenerator::refreshModel(CbcModel * model) { model_ = model; - generator_->refreshSolver(model_->solver()); + // added test - helps if generator not thread safe + if (whenCutGenerator_!=-100) + generator_->refreshSolver(model_->solver()); } /* Generate cuts for the model data contained in si. The generated cuts are inserted into and returned in the @@ -427,11 +429,12 @@ if (debugger && debugger->onOptimalPath(*solver)) { printf("On optimal path CbcCut\n"); int nCols = solver->getNumCols(); - int i; const double * optimal = debugger->optimalSolution(); const double * objective = solver->getObjCoefficients(); double objval1 = 0.0, objval2 = 0.0; - for (i = 0; i < nCols; i++) { + for (int i = 0; i < nCols; i++) { + if (!solver->isInteger(i)) + continue; #if CGL_DEBUG>1 printf("%d %g %g %g %g\n", i, lower[i], solution[i], upper[i], optimal[i]); #endif @@ -613,11 +616,113 @@ #ifdef CGL_DEBUG const OsiRowCutDebugger * debugger = solver->getRowCutDebugger(); #endif + //#define WEAKEN_CUTS 1 +#ifdef WEAKEN_CUTS + const double * lower = solver->getColLower(); + const double * upper = solver->getColUpper(); + const double * solution = solver->getColSolution(); +#endif for (k = numberRowCutsBefore; k < numberRowCutsAfter; k++) { OsiRowCut * thisCut = cs.rowCutPtr(k) ; +#ifdef WEAKEN_CUTS + // weaken cut if coefficients not integer + double lb=thisCut->lb(); + double ub=thisCut->ub(); + if (lb<-1.0e100||ub>1.0e100) { + // normal cut + CoinPackedVector rpv = thisCut->row(); + const int n = rpv.getNumElements(); + const int * indices = rpv.getIndices(); + const double * elements = rpv.getElements(); + double bound=0.0; + double sum=0.0; + bool integral=true; + int nInteger=0; + for (int k=0; kisInteger(column)) { + nInteger++; + double largerBound = CoinMax(fabs(lower[column]), + fabs(upper[column])); + double solutionBound=fabs(solution[column])+10.0; + bound += CoinMin(largerBound,solutionBound); + } + } +#if WEAKEN_CUTS ==1 + // leave if all 0-1 + if (nInteger==bound) + integral=true; +#elif WEAKEN_CUTS==4||WEAKEN_CUTS==5 + // leave if all 0-1 + if (nInteger==bound && n < 40) + integral=true; +#endif + if (!integral) { + double weakenBy=1.0e-7*(bound+sum); +#if WEAKEN_CUTS==3||WEAKEN_CUTS==5 + weakenBy *= 10.0; +#endif + if (lb<-1.0e100) + thisCut->setUb(ub+weakenBy); + else + thisCut->setLb(lb-weakenBy); + } + } +#endif #ifdef CGL_DEBUG - if (debugger && debugger->onOptimalPath(*solver)) + if (debugger && debugger->onOptimalPath(*solver)) { + if(debugger->invalidCut(*thisCut)) { +#if CGL_DEBUG>1 + const double * optimal = debugger->optimalSolution(); + CoinPackedVector rpv = thisCut->row(); + const int n = rpv.getNumElements(); + const int * indices = rpv.getIndices(); + const double * elements = rpv.getElements(); + + double lb=thisCut->lb(); + double ub=thisCut->ub(); + double sum=0.0; + + for (int k=0; kub - 1.0e-8 ||sum < lb + 1.0e-8) { + double violation=CoinMax(sum-ub,lb-sum); + std::cout<1.0e-9) { + std::cout<<"( "<invalidCut(*thisCut)); + if(debugger->invalidCut(*thisCut)) + abort(); + } + } #endif thisCut->mutableRow().setTestForDuplicateIndex(false); } diff -Nru coinor-cbc-2.8.12/src/CbcCutGenerator.hpp coinor-cbc-2.9.9+repack1/src/CbcCutGenerator.hpp --- coinor-cbc-2.8.12/src/CbcCutGenerator.hpp 2013-04-06 13:33:15.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCutGenerator.hpp 2014-09-25 11:31:17.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcCutGenerator.hpp 1883 2013-04-06 13:33:15Z stefan $ */ +/* $Id: CbcCutGenerator.hpp 2081 2014-09-25 11:31:17Z forrest $ */ // Copyright (C) 2003, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -172,10 +172,14 @@ inline int maximumTries() const { return maximumTries_;} - /// Get switches (for debug) + /// Get switches inline int switches() const { return switches_; } + /// Set switches (for copying from virgin state) + inline void setSwitches(int value) { + switches_ = value; + } /// Get whether the cut generator should be called in the normal place inline bool normal() const { return (switches_&1) != 0; @@ -347,6 +351,15 @@ switches_ &= ~4096; switches_ |= yesNo ? 4096 : 0; } + /// Whether needs refresh on copy + inline bool needsRefresh() const { + return (switches_&8192) != 0; + } + /// Set whether needs refresh on copy + inline void setNeedsRefresh(bool yesNo) { + switches_ &= ~8192; + switches_ |= yesNo ? 8192 : 0; + } /// Number of cuts generated at root inline int numberCutsAtRoot() const { return numberCutsAtRoot_; diff -Nru coinor-cbc-2.8.12/src/CbcCutModifier.cpp coinor-cbc-2.9.9+repack1/src/CbcCutModifier.cpp --- coinor-cbc-2.8.12/src/CbcCutModifier.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCutModifier.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCutModifier.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCutModifier.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2003, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCutModifier.hpp coinor-cbc-2.9.9+repack1/src/CbcCutModifier.hpp --- coinor-cbc-2.8.12/src/CbcCutModifier.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCutModifier.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCutModifier.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCutModifier.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2003, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCutSubsetModifier.cpp coinor-cbc-2.9.9+repack1/src/CbcCutSubsetModifier.cpp --- coinor-cbc-2.8.12/src/CbcCutSubsetModifier.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCutSubsetModifier.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCutSubsetModifier.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCutSubsetModifier.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2003, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcCutSubsetModifier.hpp coinor-cbc-2.9.9+repack1/src/CbcCutSubsetModifier.hpp --- coinor-cbc-2.8.12/src/CbcCutSubsetModifier.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcCutSubsetModifier.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcCutSubsetModifier.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcCutSubsetModifier.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2003, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcDummyBranchingObject.cpp coinor-cbc-2.9.9+repack1/src/CbcDummyBranchingObject.cpp --- coinor-cbc-2.8.12/src/CbcDummyBranchingObject.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcDummyBranchingObject.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcDummyBranchingObject.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcDummyBranchingObject.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcDummyBranchingObject.hpp coinor-cbc-2.9.9+repack1/src/CbcDummyBranchingObject.hpp --- coinor-cbc-2.8.12/src/CbcDummyBranchingObject.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcDummyBranchingObject.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcDummyBranchingObject.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcDummyBranchingObject.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcEventHandler.cpp coinor-cbc-2.9.9+repack1/src/CbcEventHandler.cpp --- coinor-cbc-2.8.12/src/CbcEventHandler.cpp 2011-01-05 01:12:36.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcEventHandler.cpp 2013-07-21 09:05:45.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcEventHandler.cpp 1573 2011-01-05 01:12:36Z lou $ */ +/* $Id: CbcEventHandler.cpp 1943 2013-07-21 09:05:45Z forrest $ */ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -87,6 +87,29 @@ /* If an event/action map exists and contains an entry for the event, return it. Otherwise return the default action. +*/ +{ + if (eaMap_ != 0) { + eaMapPair::iterator entry = eaMap_->find(event) ; + if (entry != eaMap_->end()) { + return (entry->second) ; + } else { + return (dfltAction_) ; + } + } else { + return (dfltAction_) ; + } +} + +//------------------------------------------------------------------- +// event() -- return the action for an event. +//------------------------------------------------------------------- + +CbcEventHandler::CbcAction CbcEventHandler::event(CbcEvent event, + void * /*data*/) +/* + If an event/action map exists and contains an entry for the event, return it. + Otherwise return the default action. */ { if (eaMap_ != 0) { diff -Nru coinor-cbc-2.8.12/src/CbcEventHandler.hpp coinor-cbc-2.9.9+repack1/src/CbcEventHandler.hpp --- coinor-cbc-2.8.12/src/CbcEventHandler.hpp 2013-11-29 17:24:44.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcEventHandler.hpp 2013-11-29 17:27:29.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcEventHandler.hpp 1986 2013-11-29 17:24:44Z forrest $ + $Id: CbcEventHandler.hpp 1987 2013-11-29 17:27:29Z forrest $ */ #ifndef CbcEventHandler_H @@ -45,6 +45,7 @@ clp-specific code. */ + #include #include @@ -53,7 +54,7 @@ class CbcModel ; /* - cvs/svn: $Id: CbcEventHandler.hpp 1986 2013-11-29 17:24:44Z forrest $ + cvs/svn: $Id: CbcEventHandler.hpp 1987 2013-11-29 17:27:29Z forrest $ */ /*! \class CbcEventHandler @@ -98,6 +99,12 @@ beforeSolution2, /*! After failed heuristic. */ afterHeuristic, + /*! On entry to small branch and bound. */ + smallBranchAndBound, + /*! After a pass of heuristic. */ + heuristicPass, + /*! When converting constraints to cuts. */ + convertToCuts, /*! End of search. */ endSearch } ; @@ -120,7 +127,9 @@ /*! Add special cuts. */ addCuts, /*! Pretend solution never happened. */ - killSolution + killSolution, + /*! Take action on modified data. */ + takeAction } ; @@ -140,6 +149,14 @@ */ virtual CbcAction event(CbcEvent whichEvent) ; + /*! \brief Return the action to be taken for an event - and modify data. + + Return the action that should be taken in response to the event passed as + the parameter. The default implementation simply reads a return code + from a map. + */ + virtual CbcAction event(CbcEvent whichEvent, void * data) ; + //@} diff -Nru coinor-cbc-2.8.12/src/CbcFathomDynamicProgramming.cpp coinor-cbc-2.9.9+repack1/src/CbcFathomDynamicProgramming.cpp --- coinor-cbc-2.8.12/src/CbcFathomDynamicProgramming.cpp 2013-04-06 20:52:59.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcFathomDynamicProgramming.cpp 2013-04-06 18:13:35.000000000 +0000 @@ -1,5 +1,5 @@ /* - $Id: CbcFathomDynamicProgramming.cpp 1888 2013-04-06 20:52:59Z stefan $ + $Id: CbcFathomDynamicProgramming.cpp 1886 2013-04-06 18:13:35Z stefan $ */ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. diff -Nru coinor-cbc-2.8.12/src/CbcFathom.hpp coinor-cbc-2.9.9+repack1/src/CbcFathom.hpp --- coinor-cbc-2.8.12/src/CbcFathom.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcFathom.hpp 2013-04-07 13:46:46.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcFathom.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcFathom.hpp 1889 2013-04-07 13:46:46Z stefan $ */ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcFixVariable.cpp coinor-cbc-2.9.9+repack1/src/CbcFixVariable.cpp --- coinor-cbc-2.8.12/src/CbcFixVariable.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcFixVariable.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcFixVariable.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcFixVariable.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcFixVariable.hpp coinor-cbc-2.9.9+repack1/src/CbcFixVariable.hpp --- coinor-cbc-2.8.12/src/CbcFixVariable.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcFixVariable.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcFixVariable.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcFixVariable.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcFollowOn.cpp coinor-cbc-2.9.9+repack1/src/CbcFollowOn.cpp --- coinor-cbc-2.8.12/src/CbcFollowOn.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcFollowOn.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcFollowOn.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcFollowOn.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcFollowOn.hpp coinor-cbc-2.9.9+repack1/src/CbcFollowOn.hpp --- coinor-cbc-2.8.12/src/CbcFollowOn.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcFollowOn.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcFollowOn.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcFollowOn.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcFullNodeInfo.cpp coinor-cbc-2.9.9+repack1/src/CbcFullNodeInfo.cpp --- coinor-cbc-2.8.12/src/CbcFullNodeInfo.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcFullNodeInfo.cpp 2014-07-16 09:29:16.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcFullNodeInfo.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcFullNodeInfo.cpp 2048 2014-07-16 09:29:16Z forrest $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -129,27 +129,31 @@ { OsiSolverInterface *solver = model->solver() ; - + // may be end game + if (!active_) + return; // branch - do bounds - assert (active_ == 7 || active_ == 15); + assert ((active_&~16) == 7 || (active_&~16) == 15); int i; solver->setColLower(lower_); solver->setColUpper(upper_); - int numberColumns = model->getNumCols(); - // move basis - but make sure size stays - // for bon-min - should not be needed int numberRows = model->getNumRows(); - int numberRows = basis->getNumArtificial(); - delete basis ; - if (basis_) { + if (basis) { + int numberColumns = model->getNumCols(); + // move basis - but make sure size stays + // for bon-min - should not be needed int numberRows = model->getNumRows(); + int numberRows = basis->getNumArtificial(); + delete basis ; + if (basis_) { basis = dynamic_cast(basis_->clone()) ; basis->resize(numberRows, numberColumns); #ifdef CBC_CHECK_BASIS std::cout << "Basis (after applying root " << this << ") " << std::endl ; basis->print() ; #endif - } else { + } else { // We have a solver without a basis basis = NULL; + } } for (i = 0; i < numberCuts_; i++) addCuts[currentNumberCuts+i] = cuts_[i]; diff -Nru coinor-cbc-2.8.12/src/CbcFullNodeInfo.hpp coinor-cbc-2.9.9+repack1/src/CbcFullNodeInfo.hpp --- coinor-cbc-2.8.12/src/CbcFullNodeInfo.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcFullNodeInfo.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcFullNodeInfo.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcFullNodeInfo.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcGenBaB.cpp coinor-cbc-2.9.9+repack1/src/CbcGenBaB.cpp --- coinor-cbc-2.8.12/src/CbcGenBaB.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenBaB.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenBaB.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenBaB.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -37,7 +37,7 @@ namespace { -char svnid[] = "$Id: CbcGenBaB.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenBaB.cpp 1899 2013-04-09 18:12:08Z stefan $" ; /* A hack to fix variables based on reduced cost prior to branch-and-cut. Note diff -Nru coinor-cbc-2.8.12/src/CbcGenCbcParam.cpp coinor-cbc-2.9.9+repack1/src/CbcGenCbcParam.cpp --- coinor-cbc-2.8.12/src/CbcGenCbcParam.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenCbcParam.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenCbcParam.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenCbcParam.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -28,7 +28,7 @@ namespace { -char svnid[] = "$Id: CbcGenCbcParam.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenCbcParam.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcGenCbcParam.hpp coinor-cbc-2.9.9+repack1/src/CbcGenCbcParam.hpp --- coinor-cbc-2.8.12/src/CbcGenCbcParam.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenCbcParam.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenCbcParam.hpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenCbcParam.hpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -18,7 +18,7 @@ */ /* - $Id: CbcGenCbcParam.hpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenCbcParam.hpp 1899 2013-04-09 18:12:08Z stefan $ */ /*! \class CbcCbcParam diff -Nru coinor-cbc-2.8.12/src/CbcGenCbcParamUtils.cpp coinor-cbc-2.9.9+repack1/src/CbcGenCbcParamUtils.cpp --- coinor-cbc-2.8.12/src/CbcGenCbcParamUtils.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenCbcParamUtils.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenCbcParamUtils.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenCbcParamUtils.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -33,7 +33,7 @@ namespace { -char svnid[] = "$Id: CbcGenCbcParamUtils.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenCbcParamUtils.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcGenCtlBlk.cpp coinor-cbc-2.9.9+repack1/src/CbcGenCtlBlk.cpp --- coinor-cbc-2.8.12/src/CbcGenCtlBlk.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenCtlBlk.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenCtlBlk.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenCtlBlk.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -19,7 +19,7 @@ namespace { -char svnid[] = "$Id: CbcGenCtlBlk.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenCtlBlk.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcGenCtlBlk.hpp coinor-cbc-2.9.9+repack1/src/CbcGenCtlBlk.hpp --- coinor-cbc-2.8.12/src/CbcGenCtlBlk.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenCtlBlk.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenCtlBlk.hpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenCtlBlk.hpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -47,7 +47,7 @@ */ /* - $Id: CbcGenCtlBlk.hpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenCtlBlk.hpp 1899 2013-04-09 18:12:08Z stefan $ */ #define CBC_GENERIC_VERSION "00.01.00" diff -Nru coinor-cbc-2.8.12/src/CbcGeneral.cpp coinor-cbc-2.9.9+repack1/src/CbcGeneral.cpp --- coinor-cbc-2.8.12/src/CbcGeneral.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGeneral.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcGeneral.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcGeneral.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcGeneralDepth.cpp coinor-cbc-2.9.9+repack1/src/CbcGeneralDepth.cpp --- coinor-cbc-2.8.12/src/CbcGeneralDepth.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGeneralDepth.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcGeneralDepth.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcGeneralDepth.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcGeneralDepth.hpp coinor-cbc-2.9.9+repack1/src/CbcGeneralDepth.hpp --- coinor-cbc-2.8.12/src/CbcGeneralDepth.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGeneralDepth.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcGeneralDepth.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcGeneralDepth.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcGeneral.hpp coinor-cbc-2.9.9+repack1/src/CbcGeneral.hpp --- coinor-cbc-2.8.12/src/CbcGeneral.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGeneral.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcGeneral.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcGeneral.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcGeneric.cpp coinor-cbc-2.9.9+repack1/src/CbcGeneric.cpp --- coinor-cbc-2.8.12/src/CbcGeneric.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGeneric.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGeneric.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGeneric.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -65,7 +65,7 @@ namespace { -char svnid[] = "$Id: CbcGeneric.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGeneric.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcGenMessages.cpp coinor-cbc-2.9.9+repack1/src/CbcGenMessages.cpp --- coinor-cbc-2.8.12/src/CbcGenMessages.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenMessages.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -5,7 +5,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenMessages.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenMessages.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -17,7 +17,7 @@ namespace { -char svnid[] = "$Id: CbcGenMessages.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenMessages.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcGenMessages.hpp coinor-cbc-2.9.9+repack1/src/CbcGenMessages.hpp --- coinor-cbc-2.8.12/src/CbcGenMessages.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenMessages.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -20,7 +20,7 @@ */ /* - $Id: CbcGenMessages.hpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenMessages.hpp 1899 2013-04-09 18:12:08Z stefan $ */ /* diff -Nru coinor-cbc-2.8.12/src/CbcGenOsiParam.cpp coinor-cbc-2.9.9+repack1/src/CbcGenOsiParam.cpp --- coinor-cbc-2.8.12/src/CbcGenOsiParam.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenOsiParam.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenOsiParam.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenOsiParam.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -29,7 +29,7 @@ namespace { -char svnid[] = "$Id: CbcGenOsiParam.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenOsiParam.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcGenOsiParam.hpp coinor-cbc-2.9.9+repack1/src/CbcGenOsiParam.hpp --- coinor-cbc-2.8.12/src/CbcGenOsiParam.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenOsiParam.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenOsiParam.hpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenOsiParam.hpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -18,7 +18,7 @@ */ /* - $Id: CbcGenOsiParam.hpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenOsiParam.hpp 1899 2013-04-09 18:12:08Z stefan $ */ /*! \class CbcOsiParam diff -Nru coinor-cbc-2.8.12/src/CbcGenOsiParamUtils.cpp coinor-cbc-2.9.9+repack1/src/CbcGenOsiParamUtils.cpp --- coinor-cbc-2.8.12/src/CbcGenOsiParamUtils.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenOsiParamUtils.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenOsiParamUtils.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenOsiParamUtils.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -36,7 +36,7 @@ namespace { -char svnid[] = "$Id: CbcGenOsiParamUtils.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenOsiParamUtils.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcGenParam.cpp coinor-cbc-2.9.9+repack1/src/CbcGenParam.cpp --- coinor-cbc-2.8.12/src/CbcGenParam.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenParam.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenParam.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenParam.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -27,7 +27,7 @@ namespace { -char svnid[] = "$Id: CbcGenParam.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenParam.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcGenParam.hpp coinor-cbc-2.9.9+repack1/src/CbcGenParam.hpp --- coinor-cbc-2.8.12/src/CbcGenParam.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenParam.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenParam.hpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenParam.hpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -19,7 +19,7 @@ */ /* - $Id: CbcGenParam.hpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenParam.hpp 1899 2013-04-09 18:12:08Z stefan $ */ class CbcGenCtlBlk ; diff -Nru coinor-cbc-2.8.12/src/CbcGenParamUtils.cpp coinor-cbc-2.9.9+repack1/src/CbcGenParamUtils.cpp --- coinor-cbc-2.8.12/src/CbcGenParamUtils.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenParamUtils.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenParamUtils.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenParamUtils.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -34,7 +34,7 @@ namespace { -char svnid[] = "$Id: CbcGenParamUtils.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenParamUtils.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcGenSolution.cpp coinor-cbc-2.9.9+repack1/src/CbcGenSolution.cpp --- coinor-cbc-2.8.12/src/CbcGenSolution.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenSolution.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenSolution.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenSolution.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -24,7 +24,7 @@ namespace { -char svnid[] = "$Id: CbcGenSolution.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenSolution.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcGenSolvers.cpp coinor-cbc-2.9.9+repack1/src/CbcGenSolvers.cpp --- coinor-cbc-2.8.12/src/CbcGenSolvers.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcGenSolvers.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -4,7 +4,7 @@ This code is licensed under the terms of the Eclipse Public License (EPL). - $Id: CbcGenSolvers.cpp 1902 2013-04-10 16:58:16Z stefan $ + $Id: CbcGenSolvers.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /* This file is part of cbc-generic. @@ -86,7 +86,7 @@ namespace { -char svnid[] = "$Id: CbcGenSolvers.cpp 1902 2013-04-10 16:58:16Z stefan $" ; +char svnid[] = "$Id: CbcGenSolvers.cpp 1899 2013-04-09 18:12:08Z stefan $" ; } diff -Nru coinor-cbc-2.8.12/src/CbcHeuristic.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristic.cpp --- coinor-cbc-2.8.12/src/CbcHeuristic.cpp 2014-08-09 16:05:41.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristic.cpp 2017-01-12 12:52:49.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristic.cpp 2055 2014-08-09 16:05:41Z forrest $ */ +/* $Id: CbcHeuristic.cpp 2324 2017-01-12 12:52:49Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -23,11 +23,14 @@ #include "CbcMessage.hpp" #include "CbcHeuristic.hpp" #include "CbcHeuristicFPump.hpp" +#include "CbcHeuristicRINS.hpp" +#include "CbcEventHandler.hpp" #include "CbcStrategy.hpp" #include "CglPreProcess.hpp" #include "CglGomory.hpp" #include "CglProbing.hpp" #include "OsiAuxInfo.hpp" +#include "OsiRowCutDebugger.hpp" #include "OsiPresolve.hpp" #include "CbcBranchActual.hpp" #include "CbcCutGenerator.hpp" @@ -147,7 +150,8 @@ numberSolutionsFound_(0), numberNodesDone_(0), inputSolution_(NULL) -{} +{ +} void CbcHeuristic::gutsOfCopy(const CbcHeuristic & rhs) @@ -330,7 +334,7 @@ if (numInvocationsInDeep_ - lastRunDeep_ < howOften_) { return false; } - if (model_->getCurrentPassNumber() != 1) { + if (model_->getCurrentPassNumber() > 1) { // Run the heuristic only when first entering the node. // LL: I don't think this is right. It should run just before strong // LL: branching, I believe. @@ -379,8 +383,8 @@ /* JJF adjustments 3 only at root and if no solution 4 only at root and if this heuristic has not got solution - 5 as 3 but decay more - 6 decay + 5 decay (but only if no solution) + 6 if depth <3 or decay 7 run up to 2 times if solution found 4 otherwise */ switch (when) { @@ -406,6 +410,7 @@ if (depth >= 3) { if ((numCouldRun_ % howOften_) == 0 && numberSolutionsFound_*howOften_ < numCouldRun_) { + //#define COIN_DEVELOP #ifdef COIN_DEVELOP int old = howOften_; #endif @@ -418,6 +423,8 @@ probability = 1.0 / howOften_; if (model_->bestSolution()) probability *= 0.5; + } else { + probability = 1.1; } break; case 7: @@ -663,13 +670,56 @@ return 2.0*(valueNow / valueStart); } - +//static int saveModel=0; // Do mini branch and bound (return 1 if solution) int CbcHeuristic::smallBranchAndBound(OsiSolverInterface * solver, int numberNodes, double * newSolution, double & newSolutionValue, double cutoff, std::string name) const { + CbcEventHandler *eventHandler = model_->getEventHandler() ; + // Use this fraction + double fractionSmall = fractionSmall_; + int maximumSolutions = model_->getMaximumSolutions(); + int iterationMultiplier = 100; + if (eventHandler) { + typedef struct { + double fractionSmall; + double spareDouble[3]; + OsiSolverInterface * solver; + void * sparePointer[2]; + int numberNodes; + int maximumSolutions; + int iterationMultiplier; + int howOften; + int spareInt[3]; + } SmallMod; + SmallMod temp; + temp.solver=solver; + temp.fractionSmall=fractionSmall; + temp.numberNodes=numberNodes; + temp.iterationMultiplier=iterationMultiplier; + temp.howOften=howOften_; + temp.maximumSolutions=maximumSolutions; + CbcEventHandler::CbcAction status = + eventHandler->event(CbcEventHandler::smallBranchAndBound, + &temp); + if (status==CbcEventHandler::killSolution) + return -1; + if (status==CbcEventHandler::takeAction) { + fractionSmall=temp.fractionSmall; + numberNodes=temp.numberNodes; + iterationMultiplier=temp.iterationMultiplier; + howOften_=temp.howOften; + maximumSolutions=temp.maximumSolutions; + } + } +#if 0 + if (saveModel || model_->getMaximumSolutions()==100) { + printf("writing model\n"); + solver->writeMpsNative("before.mps", NULL, NULL, 2, 1); + } +#endif // size before int shiftRows = 0; if (numberNodes < 0) @@ -680,8 +730,6 @@ printf("%s has %d rows, %d columns\n", name.c_str(), solver->getNumRows(), solver->getNumCols()); #endif - // Use this fraction - double fractionSmall = fractionSmall_; double before = 2 * numberRowsStart + numberColumnsStart; if (before > 40000.0) { // fairly large - be more conservative @@ -728,7 +776,7 @@ int saveModelOptions = model_->specialOptions(); //assert ((saveModelOptions&2048) == 0); model_->setSpecialOptions(saveModelOptions | 2048); - { + if (fractionSmall<1.0) { int saveLogLevel = solver->messageHandler()->logLevel(); if (saveLogLevel == 1) solver->messageHandler()->setLogLevel(0); @@ -863,10 +911,17 @@ CglPreProcess process; OsiSolverInterface * solver2 = NULL; if ((model_->moreSpecialOptions()&65536)!=0) - process.setOptions(2+4+8); // no cuts + process.setOptions(2+4+8+16); // no cuts + else + process.setOptions(16); // no complicated dupcol stuff /* Do not try and produce equality cliques and do up to 2 passes (normally) 5 if restart */ int numberPasses = 2; + if ((model_->moreSpecialOptions2()&16)!=0) { + // quick + process.setOptions(2+4+8+16); // no cuts + numberPasses = 1; + } if (numberNodes < 0) { numberPasses = 5; // Say some rows cuts @@ -884,6 +939,17 @@ if (!solver->defaultHandler()&& solver->messageHandler()->logLevel(0)!=-1000) process.passInMessageHandler(solver->messageHandler()); +#ifdef CGL_DEBUG + /* + We're debugging. (specialOptions 1) + */ + if ((model_->specialOptions()&1) != 0) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (debugger) { + process.setApplicationData(const_cast(debugger->optimalSolution())); + } + } +#endif solver2 = process.preProcessNonDefault(*solver, false, numberPasses); if (!solver2) { @@ -917,9 +983,19 @@ << generalPrint << CoinMessageEol; } +#ifdef CGL_DEBUG + if ((model_->specialOptions()&1) != 0) { + const OsiRowCutDebugger *debugger = solver2->getRowCutDebugger() ; + if (debugger) { + printf("On optimal path after preprocessing\n"); + } + } +#endif if (returnCode == 1) { solver2->resolve(); CbcModel model(*solver2); + double startTime=model_->getDblParam(CbcModel::CbcStartSeconds); + model.setDblParam(CbcModel::CbcStartSeconds,startTime); // move seed across model.randomNumberGenerator()->setSeed(model_->randomNumberGenerator()->getSeed()); if (numberNodes >= 0) { @@ -955,6 +1031,7 @@ model.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry); if ((saveModelOptions&2048) == 0) model.setMoreSpecialOptions(model_->moreSpecialOptions()); + model.setMoreSpecialOptions2(model_->moreSpecialOptions2()); // off conflict analysis model.setMoreSpecialOptions(model.moreSpecialOptions()&~4194304); @@ -964,6 +1041,23 @@ model.solver()->setIntParam(OsiMaxNumIterationHotStart, 10); model.setMaximumCutPassesAtRoot(CoinMin(20, CoinAbs(model_->getMaximumCutPassesAtRoot()))); model.setMaximumCutPasses(CoinMin(10, model_->getMaximumCutPasses())); + // Set best solution (even if bad for this submodel) + if (model_->bestSolution()) { + const double * bestSolution = model_->bestSolution(); + int numberColumns2 = model.solver()->getNumCols(); + double * bestSolution2 = new double [numberColumns2]; + const int * originalColumns = process.originalColumns(); + for (int iColumn=0;iColumnmessageHandler()->message(CBC_RESTART, model_->messages()) @@ -971,6 +1065,14 @@ << CoinMessageEol; // going for full search and copy across more stuff model.gutsOfCopy(*model_, 2); +#ifdef CGL_DEBUG + if ((model_->specialOptions()&1) != 0) { + const OsiRowCutDebugger *debugger = model.solver()->getRowCutDebugger() ; + if (debugger) { + printf("On optimal path BB\n"); + } + } +#endif assert (!model_->heuristicModel()); model_->setHeuristicModel(&model); for (int i = 0; i < model.numberCutGenerators(); i++) { @@ -1035,7 +1137,7 @@ } #endif model.setParentModel(*model_); - model.setMaximumSolutions(model_->getMaximumSolutions()); + model.setMaximumSolutions(maximumSolutions); model.setOriginalColumns(process.originalColumns()); model.setSearchStrategy(-1); // If no feasibility pump then insert a lightweight one @@ -1123,7 +1225,25 @@ model.addHeuristic(model_->heuristic(i)); } } + // modify heuristics + for (int i = 0; i < model.numberHeuristics(); i++) { + // reset lastNode + CbcHeuristicRINS * rins = + dynamic_cast(model.heuristic(i)); + if (rins) { + rins->setLastNode(-1000); + rins->setSolutionCount(0); + } + } //printf("sol %x\n",inputSolution_); +#ifdef CGL_DEBUG + if ((model_->specialOptions()&1) != 0) { + const OsiRowCutDebugger *debugger = model.solver()->getRowCutDebugger() ; + if (debugger) { + printf("On optimal path CC\n"); + } + } +#endif if (inputSolution_) { // translate and add a serendipity heuristic int numberColumns = solver2->getNumCols(); @@ -1191,6 +1311,11 @@ value = value + 1.0e-7*(1.0 + fabs(value)); value *= solver3->getObjSense(); model.setCutoff(value); + sprintf(generalPrint, "Unable to insert previous solution - using cutoff of %g", + value); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << generalPrint + << CoinMessageEol; #ifdef CLP_INVESTIGATE printf("NOT added seren\n"); solver3->writeMps("bad_seren"); @@ -1207,9 +1332,10 @@ if (numberNodes >= 0) { setCutAndHeuristicOptions(model); // not too many iterations - model.setMaximumNumberIterations(100*(numberNodes + 10)); + model.setMaximumNumberIterations(iterationMultiplier*(numberNodes + 10)); // Not fast stuff model.setFastNodeDepth(-1); + //model.solver()->writeMps("before"); } else if (model.fastNodeDepth() >= 1000000) { // already set model.setFastNodeDepth(model.fastNodeDepth() - 1000000); @@ -1227,6 +1353,26 @@ // say model_ is sitting there int saveOptions = model_->specialOptions(); model_->setSpecialOptions(saveOptions|1048576); + // and switch off debugger + model.setSpecialOptions(model.specialOptions()&(~1)); +#if 0 //def COIN_HAS_CLP + OsiClpSolverInterface * clpSolver + = dynamic_cast (model.solver()); + if (clpSolver) + clpSolver->zapDebugger(); +#endif +#ifdef CONFLICT_CUTS + if ((model_->moreSpecialOptions()&4194304)!=0) + model.zapGlobalCuts(); +#endif +#ifdef CGL_DEBUG + if ((model_->specialOptions()&1) != 0) { + const OsiRowCutDebugger *debugger = model.solver()->getRowCutDebugger() ; + if (debugger) { + printf("On optimal path DD\n"); + } + } +#endif model.branchAndBound(); model_->setHeuristicModel(NULL); model_->setSpecialOptions(saveOptions); @@ -1332,6 +1478,9 @@ } } else { returnCode = 2; // infeasible finished + if (logLevel > 1){ + printf("Infeasible on initial solve\n"); + } } model_->setSpecialOptions(saveModelOptions); model_->setLogLevel(logLevel); @@ -1652,7 +1801,7 @@ down_ = NULL; up_ = NULL; equal_ = NULL; - //whereFrom_ |= 16; // allow more often + //whereFrom_ |= 16*(1+256); // allow more often } // Constructor from model @@ -1670,7 +1819,7 @@ up_ = NULL; equal_ = NULL; seed_ = 7654321; - //whereFrom_ |= 16; // allow more often + //whereFrom_ |= 16*(1+256); // allow more often } // Destructor @@ -1759,6 +1908,24 @@ matrixByRow_ = *model_->solver()->getMatrixByRow(); validate(); } +/* Check whether the heuristic should run at all + 0 - before cuts at root node (or from doHeuristics) + 1 - during cuts at root + 2 - after root node cuts + 3 - after cuts at other nodes + 4 - during cuts at other nodes + 8 added if previous heuristic in loop found solution +*/ +bool +CbcRounding::shouldHeurRun(int whereFrom) +{ + if (whereFrom!=4) { + return CbcHeuristic::shouldHeurRun(whereFrom); + } else { + numCouldRun_++; + return shouldHeurRun_randomChoice(); + } +} // See if rounding will give solution // Sets value of solution // Assumes rhs for original matrix still okay @@ -1776,6 +1943,10 @@ (when() % 10 == 2 && (model_->phase() != 2 && model_->phase() != 3))) return 0; // switched off numRuns_++; +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif OsiSolverInterface * solver = model_->solver(); double direction = solver->getObjSense(); double newSolutionValue = direction * solver->getObjValue(); @@ -1807,9 +1978,13 @@ double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance); double primalTolerance; solver->getDblParam(OsiPrimalTolerance, primalTolerance); + double useTolerance = primalTolerance; int numberRows = matrix_.getNumRows(); assert (numberRows <= solver->getNumRows()); + if (numberRows == 0){ + return 0; + } int numberIntegers = model_->numberIntegers(); const int * integerVariable = model_->integerVariable(); int i; @@ -1865,6 +2040,7 @@ for (i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = newSolution[iColumn]; + //double thisTolerance = integerTolerance; if (fabs(floor(value + 0.5) - value) > integerTolerance) { double below = floor(value); double newValue = newSolution[iColumn]; @@ -1934,9 +2110,9 @@ double distance = absInfeasibility / absElement; double thisCost = -direction * objective[iColumn] * distance; if (integerType[iColumn]) { - distance = ceil(distance - primalTolerance); - if (currentValue - distance >= lowerValue - primalTolerance) { - if (absInfeasibility - distance*absElement < -gap - primalTolerance) + distance = ceil(distance - useTolerance); + if (currentValue - distance >= lowerValue - useTolerance) { + if (absInfeasibility - distance*absElement < -gap - useTolerance) thisCost = 1.0e100; // no good else thisCost = -direction * objective[iColumn] * distance; @@ -1960,8 +2136,8 @@ double thisCost = direction * objective[iColumn] * distance; if (integerType[iColumn]) { distance = ceil(distance - 1.0e-7); - assert (currentValue - distance <= upperValue + primalTolerance); - if (absInfeasibility - distance*absElement < -gap - primalTolerance) + assert (currentValue - distance <= upperValue + useTolerance); + if (absInfeasibility - distance*absElement < -gap - useTolerance) thisCost = 1.0e100; // no good else thisCost = direction * objective[iColumn] * distance; @@ -2138,8 +2314,10 @@ } // and now all if improving double lastChange = penaltyChange ? 1.0 : 0.0; - while (lastChange > 1.0e-2) { + int numberPasses=0; + while (lastChange > 1.0e-2 && numberPasses < 1000) { lastChange = 0; + numberPasses++; for (iColumn = 0; iColumn < numberColumns; iColumn++) { bool isInteger = (integerType[iColumn] != 0); double currentValue = newSolution[iColumn]; @@ -2241,9 +2419,13 @@ if (downImprovement > 0.0 && currentValue > lowerValue) { way = -1.0; improvement = downImprovement; + if (isInteger&¤tValue 0.0 && currentValue < upperValue) { way = 1.0; improvement = upImprovement; + if (isInteger&¤tValue>upperValue-0.99) + continue; // no good } if (way) { // can improve @@ -2343,7 +2525,7 @@ int iColumn = integerVariable[i]; #ifndef NDEBUG double value = newSolution[iColumn]; - assert (fabs(floor(value + 0.5) - value) < integerTolerance); + assert (fabs(floor(value + 0.5) - value) <= integerTolerance); #endif double cost = direction * objective[iColumn]; double move = 0.0; @@ -2354,8 +2536,8 @@ while (move) { bool good = true; double newValue = newSolution[iColumn] + move; - if (newValue < lower[iColumn] - primalTolerance || - newValue > upper[iColumn] + primalTolerance) { + if (newValue < lower[iColumn] - useTolerance || + newValue > upper[iColumn] + useTolerance) { move = 0.0; } else { // see if we can move @@ -2670,6 +2852,10 @@ // Return if already done if (fixPriority_ < 0) return 0; // switched off +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif const double * hotstartSolution = model_->hotstartSolution(); const int * hotstartPriorities = model_->hotstartPriorities(); if (!hotstartSolution) @@ -2809,6 +2995,10 @@ { if (!model_) return 0; +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif if (!inputSolution_) { // get information on solver type OsiAuxInfo * auxInfo = model_->solver()->getAuxiliaryInfo(); diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDINS.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDINS.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicDINS.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDINS.cpp 2014-11-18 11:15:36.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcHeuristicDINS.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcHeuristicDINS.cpp 2094 2014-11-18 11:15:36Z forrest $ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -167,6 +167,10 @@ const double * bestSolution = model_->bestSolution(); if (!bestSolution) return 0; // No solution found yet +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif if (numberSolutions_ < model_->getSolutionCount()) { // new solution - add info numberSolutions_ = model_->getSolutionCount(); @@ -180,7 +184,7 @@ for (int i = 0; i < maximumKeepSolutions_; i++) values_[i] = NULL; } else { - assert (numberIntegers == numberIntegers_); + assert (numberIntegers >= numberIntegers_); } // move solutions (0 will be most recent) { @@ -192,7 +196,7 @@ values_[0] = temp; } int i; - for (i = 0; i < numberIntegers; i++) { + for (i = 0; i < numberIntegers_; i++) { int iColumn = integerVariable[i]; double value = bestSolution[iColumn]; double nearest = floor(value + 0.5); @@ -201,10 +205,10 @@ numberKeptSolutions_ = CoinMin(numberKeptSolutions_ + 1, maximumKeepSolutions_); } int finalReturnCode = 0; - if (((model_->getNodeCount() % howOften_) == howOften_ / 2 || !model_->getNodeCount()) && (model_->getCurrentPassNumber() == 1 || model_->getCurrentPassNumber() == 999999)) { + if (((model_->getNodeCount() % howOften_) == howOften_ / 2 || !model_->getNodeCount()) && (model_->getCurrentPassNumber() <= 1 || model_->getCurrentPassNumber() == 999999)) { OsiSolverInterface * solver = model_->solver(); - int numberIntegers = model_->numberIntegers(); + //int numberIntegers = model_->numberIntegers(); const int * integerVariable = model_->integerVariable(); const double * currentSolution = solver->getColSolution(); @@ -222,8 +226,8 @@ solver->getDblParam(OsiPrimalTolerance, primalTolerance); const double * continuousSolution = newSolver->getColSolution(); // Space for added constraint - double * element = new double [numberIntegers]; - int * column = new int [numberIntegers]; + double * element = new double [numberIntegers_]; + int * column = new int [numberIntegers_]; int i; int nFix = 0; int nCouldFix = 0; @@ -232,7 +236,7 @@ int nEl = 0; double bias = localSpace; int okSame = numberKeptSolutions_ - 1; - for (i = 0; i < numberIntegers; i++) { + for (i = 0; i < numberIntegers_; i++) { int iColumn = integerVariable[i]; const OsiObject * object = model_->object(i); // get original bounds @@ -332,11 +336,11 @@ model_->messageHandler()->message(CBC_FPUMP2, model_->messages()) << generalPrint << CoinMessageEol; - if (nFix > numberIntegers / 10) { + if (nFix > numberIntegers_ / 10) { #ifdef JJF_ZERO newSolver->initialSolve(); printf("obj %g\n", newSolver->getObjValue()); - for (i = 0; i < numberIntegers; i++) { + for (i = 0; i < numberIntegers_; i++) { int iColumn = integerVariable[i]; printf("%d new bounds %g %g - solutions %g %g\n", iColumn, newSolver->getColLower()[iColumn], diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDINS.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDINS.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicDINS.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDINS.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcHeuristicDINS.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcHeuristicDINS.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDiveCoefficient.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveCoefficient.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicDiveCoefficient.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveCoefficient.cpp 2014-11-18 11:15:36.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDiveCoefficient.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDiveCoefficient.cpp 2094 2014-11-18 11:15:36Z forrest $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -17,12 +17,14 @@ CbcHeuristicDiveCoefficient::CbcHeuristicDiveCoefficient() : CbcHeuristicDive() { + whereFrom_ |= 16*(1+256); } // Constructor from model CbcHeuristicDiveCoefficient::CbcHeuristicDiveCoefficient(CbcModel & model) : CbcHeuristicDive(model) { + whereFrom_ |= 16*(1+256); } // Destructor @@ -80,6 +82,7 @@ double bestFraction = COIN_DBL_MAX; int bestLocks = COIN_INT_MAX; bool allTriviallyRoundableSoFar = true; + int bestPriority = COIN_INT_MAX; for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = newSolution[iColumn]; @@ -116,6 +119,18 @@ if (!solver->isBinary(iColumn)) fraction *= 1000.0; + // if priorities then use + if (priority_) { + int thisRound=static_cast(priority_[i].direction); + if ((thisRound&1)!=0) + round = ((thisRound&2)==0) ? -1 : +1; + if (priority_[i].priority>bestPriority) { + nLocks=COIN_INT_MAX; + } else if (priority_[i].priority(priority_[i].priority); + bestLocks=COIN_INT_MAX; + } + } if (nLocks < bestLocks || (nLocks == bestLocks && fraction < bestFraction)) { bestColumn = iColumn; diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDiveCoefficient.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveCoefficient.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicDiveCoefficient.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveCoefficient.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDiveCoefficient.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDiveCoefficient.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDive.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDive.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicDive.cpp 2013-04-26 10:43:35.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDive.cpp 2015-05-05 13:04:34.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDive.cpp 1912 2013-04-26 10:43:35Z stefan $ */ +/* $Id: CbcHeuristicDive.cpp 2187 2015-05-05 13:04:34Z stefan $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -12,6 +12,7 @@ #include "CbcStrategy.hpp" #include "CbcModel.hpp" #include "CbcSubProblem.hpp" +#include "CbcSimpleInteger.hpp" #include "OsiAuxInfo.hpp" #include "CoinTime.hpp" @@ -21,6 +22,9 @@ //#define DIVE_FIX_BINARY_VARIABLES //#define DIVE_DEBUG +#ifdef DIVE_DEBUG +#define DIVE_PRINT=2 +#endif // Default Constructor CbcHeuristicDive::CbcHeuristicDive() @@ -31,6 +35,7 @@ upLocks_ = NULL; downArray_ = NULL; upArray_ = NULL; + priority_ = NULL; percentageToFix_ = 0.2; maxIterations_ = 100; maxSimplexIterations_ = 10000; @@ -38,6 +43,7 @@ maxTime_ = 600; whereFrom_ = 255 - 2 - 16 + 256; decayFactor_ = 1.0; + smallObjective_ = 1.0e-10; } // Constructor from model @@ -48,6 +54,7 @@ upLocks_ = NULL; downArray_ = NULL; upArray_ = NULL; + priority_ = NULL; // Get a copy of original matrix assert(model.solver()); // model may have empty matrix - wait until setModel @@ -58,12 +65,14 @@ validate(); } percentageToFix_ = 0.2; + maxTime_ = 600; + smallObjective_ = 1.0e-10; maxIterations_ = 100; maxSimplexIterations_ = 10000; maxSimplexIterationsAtRoot_ = 1000000; - maxTime_ = 600; whereFrom_ = 255 - 2 - 16 + 256; decayFactor_ = 1.0; + smallObjective_ = 1.0e-10; } // Destructor @@ -71,6 +80,7 @@ { delete [] downLocks_; delete [] upLocks_; + delete [] priority_; assert (!downArray_); } @@ -105,10 +115,11 @@ matrix_(rhs.matrix_), matrixByRow_(rhs.matrixByRow_), percentageToFix_(rhs.percentageToFix_), + maxTime_(rhs.maxTime_), + smallObjective_(rhs.smallObjective_), maxIterations_(rhs.maxIterations_), maxSimplexIterations_(rhs.maxSimplexIterations_), - maxSimplexIterationsAtRoot_(rhs.maxSimplexIterationsAtRoot_), - maxTime_(rhs.maxTime_) + maxSimplexIterationsAtRoot_(rhs.maxSimplexIterationsAtRoot_) { downArray_ = NULL; upArray_ = NULL; @@ -116,9 +127,11 @@ int numberIntegers = model_->numberIntegers(); downLocks_ = CoinCopyOfArray(rhs.downLocks_, numberIntegers); upLocks_ = CoinCopyOfArray(rhs.upLocks_, numberIntegers); + priority_ = CoinCopyOfArray(rhs.priority_, numberIntegers); } else { downLocks_ = NULL; upLocks_ = NULL; + priority_ = NULL; } } @@ -135,15 +148,19 @@ maxSimplexIterations_ = rhs.maxSimplexIterations_; maxSimplexIterationsAtRoot_ = rhs.maxSimplexIterationsAtRoot_; maxTime_ = rhs.maxTime_; + smallObjective_ = rhs.smallObjective_; delete [] downLocks_; delete [] upLocks_; + delete [] priority_; if (rhs.downLocks_) { int numberIntegers = model_->numberIntegers(); downLocks_ = CoinCopyOfArray(rhs.downLocks_, numberIntegers); upLocks_ = CoinCopyOfArray(rhs.upLocks_, numberIntegers); + priority_ = CoinCopyOfArray(rhs.priority_, numberIntegers); } else { downLocks_ = NULL; upLocks_ = NULL; + priority_ = NULL; } } return *this; @@ -163,10 +180,12 @@ matrixByRow_ = *model->solver()->getMatrixByRow(); validate(); } + setPriorities(); } // update model -void CbcHeuristicDive::setModel(CbcModel * model) +void +CbcHeuristicDive::setModel(CbcModel * model) { model_ = model; assert(model_->solver()); @@ -178,10 +197,70 @@ // make sure model okay for heuristic validate(); } + setPriorities(); +} + +// Sets priorities if any +void +CbcHeuristicDive::setPriorities() +{ + delete [] priority_; + assert (model_); + priority_=NULL; + if (!model_->objects()) + return; + bool gotPriorities=false; + int numberIntegers = model_->numberIntegers(); + int priority1=-COIN_INT_MAX; + int priority2=COIN_INT_MAX; + smallObjective_=0.0; + const double * objective = model_->solver()->getObjCoefficients(); + int numberObjects = model_->numberObjects(); + for (int i = 0; i < numberObjects; i++) { + OsiObject * object = model_->modifiableObject(i); + const CbcSimpleInteger * thisOne = dynamic_cast (object); + if (!thisOne) + continue; // Not integer + int iColumn = thisOne->columnNumber(); + smallObjective_ += objective[iColumn]; + int level=thisOne->priority(); + priority1=CoinMax(priority1,level); + priority2=CoinMin(priority2,level); + if (thisOne->preferredWay()!=0) + gotPriorities=true; + } + smallObjective_ = CoinMax(1.0e-10,1.0e-5*(smallObjective_/numberIntegers)); + if (gotPriorities || priority1>priority2) { + priority_ = new PriorityType [numberIntegers]; + int nInteger=0; + for (int i = 0; i < numberObjects; i++) { + OsiObject * object = model_->modifiableObject(i); + const CbcSimpleInteger * thisOne = dynamic_cast (object); + if (!thisOne) + continue; // Not integer + int level=thisOne->priority()-priority2; + assert (level<(1<<29)); + assert (nInteger(level); + int direction=0; + if (thisOne->preferredWay()<0) + direction=1; + else if (thisOne->preferredWay()>0) + direction=1|1; + // at present don't try other way is not used + priority_[nInteger++].direction=static_cast(direction); + } + assert (nInteger==numberIntegers); + } } + bool CbcHeuristicDive::canHeuristicRun() { + if (model_->bestSolution()||model_->getNodeCount()) { + if (when_==3 || (when_==4 && numberSolutionsFound_) ) + return false; + } return shouldHeurRun_randomChoice(); } @@ -198,17 +277,32 @@ CbcSubProblem ** & nodes, double * newSolution) { -#ifdef DIVE_DEBUG +#if DIVE_PRINT int nRoundInfeasible = 0; int nRoundFeasible = 0; + printf("Entering %s - fix %.1f%% maxTime %.2f maxPasses %d - max iterations %d (at root %d) - when to do %d\n", + heuristicName_.c_str(),percentageToFix_*100.0,maxTime_,maxIterations_, + maxSimplexIterations_,maxSimplexIterationsAtRoot_,when()); #endif int reasonToStop = 0; double time1 = CoinCpuTime(); int numberSimplexIterations = 0; int maxSimplexIterations = (model_->getNodeCount()) ? maxSimplexIterations_ : maxSimplexIterationsAtRoot_; + int maxIterationsInOneSolve = (maxSimplexIterations<1000000) ? 1000 : 10000; // but can't be exactly coin_int_max maxSimplexIterations = CoinMin(maxSimplexIterations,COIN_INT_MAX>>3); + bool fixGeneralIntegers=false; + int maxIterations = maxIterations_; + int saveSwitches = switches_; + if ((maxIterations_%10)!=0) { + int digit = maxIterations_%10; + maxIterations -= digit; + switches_ |= 65536; + if ((digit&3)!=0) + fixGeneralIntegers=true; + } + OsiSolverInterface * solver = cloneBut(6); // was model_->solver()->clone(); # ifdef COIN_HAS_CLP OsiClpSolverInterface * clpSolver @@ -217,6 +311,8 @@ ClpSimplex * clpSimplex = clpSolver->getModelPtr(); int oneSolveIts = clpSimplex->maximumIterations(); oneSolveIts = CoinMin(1000+2*(clpSimplex->numberRows()+clpSimplex->numberColumns()),oneSolveIts); + if (maxSimplexIterations>1000000) + maxIterationsInOneSolve=oneSolveIts; clpSimplex->setMaximumIterations(oneSolveIts); if (!nodes) { // say give up easily @@ -270,7 +366,8 @@ memcpy(newSolution, solution, numberColumns*sizeof(double)); // vectors to store the latest variables fixed at their bounds - int* columnFixed = new int [numberIntegers]; + int* columnFixed = new int [numberIntegers+numberColumns]; + int * back = columnFixed + numberIntegers; double* originalBound = new double [numberIntegers+2*numberColumns]; double * lowerBefore = originalBound+numberIntegers; double * upperBefore = lowerBefore+numberColumns; @@ -286,10 +383,17 @@ // count how many fractional variables int numberFractionalVariables = 0; + for (int i=0;i integerTolerance) { numberFractionalVariables++; } @@ -297,10 +401,14 @@ const double* reducedCost = NULL; // See if not NLP - if (model_->solverCharacteristics()->reducedCostsAccurate()) + if (!model_->solverCharacteristics() || + model_->solverCharacteristics()->reducedCostsAccurate()) reducedCost = solver->getReducedCost(); int iteration = 0; + int numberAtBoundFixed = 0; + int numberGeneralFixed = 0; // fixed as satisfied but not at bound + int numberReducedCostFixed = 0; while (numberFractionalVariables) { iteration++; @@ -340,7 +448,7 @@ } } if (direction*(solver->getObjValue() + delta) < solutionValue) { -#ifdef DIVE_DEBUG +#if DIVE_PRINT nRoundFeasible++; #endif if (!nodes||bestColumn<0) { @@ -387,21 +495,21 @@ } } } -#ifdef DIVE_DEBUG +#if DIVE_PRINT else nRoundInfeasible++; #endif } // do reduced cost fixing -#ifdef DIVE_DEBUG - int numberFixed = reducedCostFix(solver); - std::cout << "numberReducedCostFixed = " << numberFixed << std::endl; +#if DIVE_PRINT>1 + numberReducedCostFixed = reducedCostFix(solver); #else reducedCostFix(solver); #endif - int numberAtBoundFixed = 0; + numberAtBoundFixed = 0; + numberGeneralFixed = 0; // fixed as satisfied but not at bound #ifdef DIVE_FIX_BINARY_VARIABLES // fix binary variables based on pseudo reduced cost if (binVarIndex_.size()) { @@ -479,9 +587,19 @@ #ifdef GAP double gap = 1.0e30; #endif + int fixPriority=COIN_INT_MAX; if (reducedCost && true) { #ifndef JJF_ONE cnt = fixOtherVariables(solver, solution, candidate, random); + if (priority_) { + for (int i = 0; i < cnt; i++) { + int iColumn = candidate[i].var; + if (upper[iColumn] > lower[iColumn]) { + int j=back[iColumn]; + fixPriority = CoinMin(fixPriority,static_cast(priority_[j].priority)); + } + } + } #else #ifdef GAP double cutoff = model_->getCutoff() ; @@ -503,6 +621,9 @@ int iColumn = integerVariable[i]; if (upper[iColumn] > lower[iColumn]) { numberFree++; + if (priority_) { + fixPriority = CoinMin(fixPriority,static_cast(priority_[i].priority)); + } double value = newSolution[iColumn]; if (fabs(floor(value + 0.5) - value) <= integerTolerance) { candidate[cnt].var = iColumn; @@ -538,6 +659,9 @@ for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; if (upper[iColumn] > lower[iColumn]) { + if (priority_) { + fixPriority = CoinMin(fixPriority,static_cast(priority_[i].priority)); + } double value = newSolution[iColumn]; if (fabs(floor(value + 0.5) - value) <= integerTolerance) { candidate[cnt].var = iColumn; @@ -547,6 +671,9 @@ } } std::sort(candidate, candidate + cnt, compareBinaryVars); + // If getting on fix all + if (iteration*3>maxIterations_*2) + fixPriority=COIN_INT_MAX; for (int i = 0; i < cnt; i++) { int iColumn = candidate[i].var; if (upper[iColumn] > lower[iColumn]) { @@ -554,17 +681,61 @@ if (fabs(floor(value + 0.5) - value) <= integerTolerance && numberAtBoundFixed < maxNumberAtBoundToFix) { // fix the variable at one of its bounds - if (fabs(lower[iColumn] - value) <= integerTolerance) { - columnFixed[numberAtBoundFixed] = iColumn; - originalBound[numberAtBoundFixed] = upper[iColumn]; - fixedAtLowerBound[numberAtBoundFixed] = true; - solver->setColUpper(iColumn, lower[iColumn]); + if (fabs(lower[iColumn] - value) <= integerTolerance || + fixGeneralIntegers) { + if (priority_) { + int j=back[iColumn]; + if (priority_[j].priority>fixPriority) + continue; // skip - only fix ones at high priority + int thisRound=static_cast(priority_[j].direction); + if ((thisRound&1)!=0) { + // for now force way + if((thisRound&2)!=0) + continue; + } + } + if (fabs(lower[iColumn] - value) <= integerTolerance) { + columnFixed[numberAtBoundFixed] = iColumn; + originalBound[numberAtBoundFixed] = upper[iColumn]; + fixedAtLowerBound[numberAtBoundFixed] = true; + solver->setColUpper(iColumn, lower[iColumn]); + } else { + // fix to interior value + numberGeneralFixed++; + double fixValue = floor(value + 0.5); + columnFixed[numberAtBoundFixed] = iColumn; + originalBound[numberAtBoundFixed] = upper[iColumn]; + fixedAtLowerBound[numberAtBoundFixed] = true; + solver->setColUpper(iColumn, fixValue); + numberAtBoundFixed++; + columnFixed[numberAtBoundFixed] = iColumn; + originalBound[numberAtBoundFixed] = lower[iColumn]; + fixedAtLowerBound[numberAtBoundFixed] = false; + solver->setColLower(iColumn, fixValue); + } + //if (priority_) + //printf("fixing %d (priority %d) to lower bound of %g\n", + // iColumn,priority_[back[iColumn]].priority,lower[iColumn]); numberAtBoundFixed++; } else if (fabs(upper[iColumn] - value) <= integerTolerance) { + if (priority_) { + int j=back[iColumn]; + if (priority_[j].priority>fixPriority) + continue; // skip - only fix ones at high priority + int thisRound=static_cast(priority_[j].direction); + if ((thisRound&1)!=0) { + // for now force way + if((thisRound&2)==0) + continue; + } + } columnFixed[numberAtBoundFixed] = iColumn; originalBound[numberAtBoundFixed] = lower[iColumn]; fixedAtLowerBound[numberAtBoundFixed] = false; solver->setColLower(iColumn, upper[iColumn]); + //if (priority_) + //printf("fixing %d (priority %d) to upper bound of %g\n", + // iColumn,priority_[back[iColumn]].priority,upper[iColumn]); numberAtBoundFixed++; } if (numberAtBoundFixed == maxNumberAtBoundToFix) @@ -572,9 +743,6 @@ } } } -#ifdef DIVE_DEBUG - std::cout << "numberAtBoundFixed = " << numberAtBoundFixed << std::endl; -#endif double originalBoundBestColumn; double bestColumnValue; @@ -584,10 +752,22 @@ if (bestRound < 0) { originalBoundBestColumn = upper[bestColumn]; solver->setColUpper(bestColumn, floor(bestColumnValue)); +#ifdef DIVE_DEBUG + if (priority_) { + printf("setting %d (priority %d) upper bound to %g (%g)\n", + bestColumn,priority_[back[bestColumn]].priority,floor(bestColumnValue),bestColumnValue); + } +#endif whichWay=0; } else { originalBoundBestColumn = lower[bestColumn]; solver->setColLower(bestColumn, ceil(bestColumnValue)); +#ifdef DIVE_DEBUG + if (priority_) { + printf("setting %d (priority %d) lower bound to %g (%g)\n", + bestColumn,priority_[back[bestColumn]].priority,ceil(bestColumnValue),bestColumnValue); + } +#endif whichWay=1; } } else { @@ -595,14 +775,73 @@ } int originalBestRound = bestRound; int saveModelOptions = model_->specialOptions(); - while (1) { model_->setSpecialOptions(saveModelOptions | 2048); solver->resolve(); + numberSimplexIterations += solver->getIterationCount(); +#if DIVE_PRINT>1 + int numberFractionalVariables = 0; + double sumFractionalVariables=0.0; + int numberFixed=0; + for (int i = 0; i < numberIntegers; i++) { + int iColumn = integerVariable[i]; + double value = newSolution[iColumn]; + double away = fabs(floor(value + 0.5) - value); + if (away > integerTolerance) { + numberFractionalVariables++; + sumFractionalVariables += away; + } + if (upper[iColumn]==lower[iColumn]) + numberFixed++; + } + printf("pass %d obj %g %s its %d total %d fixed %d +(%d,%d)",iteration, + solver->getObjValue(),solver->isProvenOptimal() ? "opt" : "infeasible", + solver->getIterationCount(), + solver->getIterationCount()+numberSimplexIterations, + numberFixed, + numberReducedCostFixed, + numberAtBoundFixed-numberGeneralFixed); + if (solver->isProvenOptimal()) { + printf(" - %d at bound, %d away (sum %g)\n", + numberIntegers-numberFixed-numberFractionalVariables, + numberFractionalVariables,sumFractionalVariables); + } else { + printf("\n"); + if (fixGeneralIntegers) { + int digit = maxIterations_%10; + if (digit==1) { + // switch off for now + switches_=saveSwitches; + fixGeneralIntegers=false; + } else if (digit==2) { + // switch off always + switches_=saveSwitches; + fixGeneralIntegers=false; + maxIterations_ -= digit; + } + } + } +#else + if (!solver->isProvenOptimal()) { + if (fixGeneralIntegers) { + int digit = maxIterations_%10; + if (digit==1) { + // switch off for now + switches_=saveSwitches; + fixGeneralIntegers=false; + } else if (digit==2) { + // switch off always + switches_=saveSwitches; + fixGeneralIntegers=false; + maxIterations_ -= digit; + } + } + } +#endif model_->setSpecialOptions(saveModelOptions); if (!solver->isAbandoned()&&!solver->isIterationLimitReached()) { - numberSimplexIterations += solver->getIterationCount(); + //numberSimplexIterations += solver->getIterationCount(); } else { numberSimplexIterations = maxSimplexIterations + 1; reasonToStop += 100; @@ -671,15 +910,15 @@ } else if (numberSimplexIterations > maxSimplexIterations) { reasonToStop += 4; // also switch off -#ifdef CLP_INVESTIGATE +#if DIVE_PRINT printf("switching off diving as too many iterations %d, %d allowed\n", numberSimplexIterations, maxSimplexIterations); #endif when_ = 0; - } else if (solver->getIterationCount() > 1000 && iteration > 3 && !nodes) { + } else if (solver->getIterationCount() > maxIterationsInOneSolve && iteration > 3 && !nodes) { reasonToStop += 5; // also switch off -#ifdef CLP_INVESTIGATE +#if DIVE_PRINT printf("switching off diving one iteration took %d iterations (total %d)\n", solver->getIterationCount(), numberSimplexIterations); #endif @@ -749,6 +988,7 @@ if (!numberNodes) { // was good at start! - create fake clpSolver->resolve(); + numberSimplexIterations += clpSolver->getIterationCount(); ClpSimplex * simplex = clpSolver->getModelPtr(); CbcSubProblem * sub = new CbcSubProblem(clpSolver,lowerBefore,upperBefore, @@ -845,8 +1085,9 @@ delete [] rowActivity; } -#ifdef DIVE_DEBUG - std::cout << "nRoundInfeasible = " << nRoundInfeasible +#if DIVE_PRINT + std::cout << heuristicName_ + << " nRoundInfeasible = " << nRoundInfeasible << ", nRoundFeasible = " << nRoundFeasible << ", returnCode = " << returnCode << ", reasonToStop = " << reasonToStop @@ -864,6 +1105,7 @@ delete [] upArray_; upArray_ = NULL; delete solver; + switches_ = saveSwitches; return returnCode; } // See if diving will give better solution @@ -876,9 +1118,6 @@ int nodeCount = model_->getNodeCount(); if (feasibilityPumpOptions_>0 && (nodeCount % feasibilityPumpOptions_) != 0) return 0; -#ifdef DIVE_DEBUG - std::cout << "solutionValue = " << solutionValue << std::endl; -#endif ++numCouldRun_; // test if the heuristic can run @@ -891,9 +1130,17 @@ (when() % 10 == 2 && (model_->phase() != 2 && model_->phase() != 3))) return 0; // switched off #endif +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif +#ifdef DIVE_DEBUG + std::cout << "solutionValue = " << solutionValue << std::endl; +#endif // Get solution array for heuristic solution int numberColumns = model_->solver()->getNumCols(); - double * newSolution = new double [numberColumns]; + double * newSolution = CoinCopyOfArray(model_->solver()->getColSolution(), + numberColumns); int numberCuts=0; int numberNodes=-1; CbcSubProblem ** nodes=NULL; diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDiveFractional.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveFractional.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicDiveFractional.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveFractional.cpp 2014-11-06 16:17:38.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDiveFractional.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDiveFractional.cpp 2093 2014-11-06 16:17:38Z forrest $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -77,6 +77,7 @@ bestRound = -1; // -1 rounds down, +1 rounds up double bestFraction = COIN_DBL_MAX; bool allTriviallyRoundableSoFar = true; + int bestPriority = COIN_INT_MAX; for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = newSolution[iColumn]; @@ -102,6 +103,18 @@ if (!solver->isBinary(iColumn)) fraction *= 1000.0; + // if priorities then use + if (priority_) { + int thisRound=static_cast(priority_[i].direction); + if ((thisRound&1)!=0) + round = ((thisRound&2)==0) ? -1 : +1; + if (priority_[i].priority>bestPriority) { + fraction=COIN_DBL_MAX; + } else if (priority_[i].priority(priority_[i].priority); + bestFraction=COIN_DBL_MAX; + } + } if (fraction < bestFraction) { bestColumn = iColumn; bestFraction = fraction; diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDiveFractional.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveFractional.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicDiveFractional.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveFractional.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDiveFractional.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDiveFractional.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDiveGuided.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveGuided.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicDiveGuided.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveGuided.cpp 2014-11-06 16:17:38.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDiveGuided.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDiveGuided.cpp 2093 2014-11-06 16:17:38Z forrest $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -89,6 +89,7 @@ bestRound = -1; // -1 rounds down, +1 rounds up double bestFraction = COIN_DBL_MAX; bool allTriviallyRoundableSoFar = true; + int bestPriority = COIN_INT_MAX; for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = newSolution[iColumn]; @@ -113,6 +114,18 @@ if (!solver->isBinary(iColumn)) fraction *= 1000.0; + // if priorities then use + if (priority_) { + int thisRound=static_cast(priority_[i].direction); + if ((thisRound&1)!=0) + round = ((thisRound&2)==0) ? -1 : +1; + if (priority_[i].priority>bestPriority) { + fraction=COIN_DBL_MAX; + } else if (priority_[i].priority(priority_[i].priority); + bestFraction=COIN_DBL_MAX; + } + } if (fraction < bestFraction) { bestColumn = iColumn; bestFraction = fraction; diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDiveGuided.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveGuided.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicDiveGuided.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveGuided.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDiveGuided.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDiveGuided.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDive.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDive.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicDive.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDive.hpp 2014-11-06 16:17:38.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDive.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDive.hpp 2093 2014-11-06 16:17:38Z forrest $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -61,7 +61,7 @@ virtual int solution(double & objectiveValue, double * newSolution); /// inner part of dive - int solution(double & objectiveValue, int & numberNodes, + int solution(double & objectiveValue, int & numberNodes, int & numberCuts, OsiRowCut ** cuts, CbcSubProblem ** & nodes, double * newSolution); @@ -75,6 +75,9 @@ /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) virtual void validate(); + /// Sets priorities if any + void setPriorities(); + /// Select candidate binary variables for fixing void selectBinaryVariables(); @@ -153,6 +156,12 @@ /// Extra up array (number Integers long) double * upArray_; + /// Array of priorities + typedef struct { + unsigned int direction:3; // 0 bit off, 1 bit (0 down first, 1 up first) 2 bit non zero don't try other way + unsigned int priority:29; + } PriorityType; + PriorityType * priority_; // Indexes of binary variables with 0 objective coefficient // and in variable bound constraints std::vector binVarIndex_; @@ -163,6 +172,12 @@ // Percentage of integer variables to fix at bounds double percentageToFix_; + // Maximum time allowed + double maxTime_; + + // Small objective (i.e. treat zero objective as this) + double smallObjective_; + // Maximum number of major iterations int maxIterations_; @@ -172,9 +187,6 @@ // Maximum number of simplex iterations at root node int maxSimplexIterationsAtRoot_; - // Maximum time allowed - double maxTime_; - }; #endif diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDiveLineSearch.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveLineSearch.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicDiveLineSearch.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveLineSearch.cpp 2014-11-06 16:17:38.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDiveLineSearch.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDiveLineSearch.cpp 2093 2014-11-06 16:17:38Z forrest $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -80,6 +80,7 @@ bestRound = -1; // -1 rounds down, +1 rounds up double bestRelDistance = COIN_DBL_MAX; bool allTriviallyRoundableSoFar = true; + int bestPriority = COIN_INT_MAX; for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double rootValue = rootNodeLPSol[iColumn]; @@ -110,6 +111,18 @@ if (!solver->isBinary(iColumn)) relDistance *= 1000.0; + // if priorities then use + if (priority_) { + int thisRound=static_cast(priority_[i].direction); + if ((thisRound&1)!=0) + round = ((thisRound&2)==0) ? -1 : +1; + if (priority_[i].priority>bestPriority) { + relDistance=COIN_DBL_MAX; + } else if (priority_[i].priority(priority_[i].priority); + bestRelDistance=COIN_DBL_MAX; + } + } if (relDistance < bestRelDistance) { bestColumn = iColumn; bestRelDistance = relDistance; diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDiveLineSearch.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveLineSearch.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicDiveLineSearch.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveLineSearch.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDiveLineSearch.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDiveLineSearch.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDivePseudoCost.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDivePseudoCost.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicDivePseudoCost.cpp 2013-05-16 07:35:51.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDivePseudoCost.cpp 2014-11-06 16:17:38.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDivePseudoCost.cpp 1922 2013-05-16 07:35:51Z forrest $ */ +/* $Id: CbcHeuristicDivePseudoCost.cpp 2093 2014-11-06 16:17:38Z forrest $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -85,6 +85,7 @@ bestRound = -1; // -1 rounds down, +1 rounds up double bestScore = -1.0; bool allTriviallyRoundableSoFar = true; + int bestPriority = COIN_INT_MAX; for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double rootValue = rootNodeLPSol[iColumn]; @@ -131,6 +132,18 @@ if (solver->isBinary(iColumn)) score *= 1000.0; + // if priorities then use + if (priority_) { + int thisRound=static_cast(priority_[i].direction); + if ((thisRound&1)!=0) + round = ((thisRound&2)==0) ? -1 : +1; + if (priority_[i].priority>bestPriority) { + score=COIN_DBL_MAX; + } else if (priority_[i].priority(priority_[i].priority); + bestScore=COIN_DBL_MAX; + } + } if (score > bestScore) { bestColumn = iColumn; bestScore = score; @@ -197,6 +210,7 @@ int numberIntegers = model_->numberIntegers(); const int * integerVariable = model_->integerVariable(); const double* reducedCost = solver->getReducedCost(); + bool fixGeneralIntegers = (switches_&65536)!=0; // fix other integer variables that are at their bounds int cnt = 0; int numberFree = 0; @@ -214,6 +228,11 @@ candidate[cnt].var = iColumn; candidate[cnt++].pseudoRedCost = CoinMax(-1.0e-2 * reducedCost[iColumn], downArray_[i]) * random[i]; + } else if (fixGeneralIntegers && + fabs(floor(value + 0.5) - value) <= integerTolerance) { + candidate[cnt].var = iColumn; + candidate[cnt++].pseudoRedCost = CoinMax(-1.0e-6 * reducedCost[iColumn], + 1.0e-4*downArray_[i]) * random[i]; } } else { numberFixedAlready++; diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDivePseudoCost.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDivePseudoCost.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicDivePseudoCost.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDivePseudoCost.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDivePseudoCost.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDivePseudoCost.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDiveVectorLength.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveVectorLength.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicDiveVectorLength.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveVectorLength.cpp 2014-11-06 16:17:38.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDiveVectorLength.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDiveVectorLength.cpp 2093 2014-11-06 16:17:38Z forrest $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -81,6 +81,7 @@ bestRound = -1; // -1 rounds down, +1 rounds up double bestScore = COIN_DBL_MAX; bool allTriviallyRoundableSoFar = true; + int bestPriority = COIN_INT_MAX; for (int i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = newSolution[iColumn]; @@ -96,15 +97,21 @@ // the variable cannot be rounded double obj = direction * objective[iColumn]; - if (obj >= 0.0) + if (obj > smallObjective_) { round = 1; // round up - else + } else if (obj < -smallObjective_) { round = -1; // round down + } else { + if (fraction<0.4) + round = -1; + else + round = 1; + } double objDelta; if (round == 1) - objDelta = (1.0 - fraction) * obj; + objDelta = (1.0 - fraction) * CoinMax(obj,smallObjective_); else - objDelta = - fraction * obj; + objDelta = - fraction * CoinMin(obj,-smallObjective_); // we want the smaller score double score = objDelta / (static_cast (columnLength[iColumn]) + 1.0); @@ -113,6 +120,18 @@ if (!solver->isBinary(iColumn)) score *= 1000.0; + // if priorities then use + if (priority_) { + int thisRound=static_cast(priority_[i].direction); + if ((thisRound&1)!=0) + round = ((thisRound&2)==0) ? -1 : +1; + if (priority_[i].priority>bestPriority) { + score=COIN_DBL_MAX; + } else if (priority_[i].priority(priority_[i].priority); + bestScore=COIN_DBL_MAX; + } + } if (score < bestScore) { bestColumn = iColumn; bestScore = score; diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDiveVectorLength.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveVectorLength.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicDiveVectorLength.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDiveVectorLength.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicDiveVectorLength.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicDiveVectorLength.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDW.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDW.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicDW.cpp 1970-01-01 00:00:00.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDW.cpp 2014-11-18 11:15:36.000000000 +0000 @@ -0,0 +1,2227 @@ +// $Id: CbcHeuristicDW.cpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif +#include +#include +#include +#include + +#include "OsiSolverInterface.hpp" +#include "OsiClpSolverInterface.hpp" +#include "CbcModel.hpp" +#include "CbcMessage.hpp" +#include "CbcHeuristicDW.hpp" +#include "CbcStrategy.hpp" +#include "ClpPresolve.hpp" +#include "CglProbing.hpp" + +static int dummyCallBack(CbcHeuristicDW * /*heuristic*/, + CbcModel * /*thisModel*/ , int /*whereFrom*/) +{ + return 0; +} + +// Default Constructor +CbcHeuristicDW::CbcHeuristicDW() + : CbcHeuristic() +{ + setDefaults(); +} + +// Constructor with model - assumed before cuts + +CbcHeuristicDW::CbcHeuristicDW(CbcModel & model, int keepContinuous) + : CbcHeuristic(model) +{ + setDefaults(); + functionPointer_ = dummyCallBack; + assert(model.solver()); + solver_ = model.solver()->clone(); + findStructure(); +} +/* Constructor with model - assumed before cuts + */ +CbcHeuristicDW::CbcHeuristicDW (CbcModel & model, + int callBack(CbcHeuristicDW * currentHeuristic, + CbcModel * thisModel, + int whereFrom), + int keepContinuous) + : CbcHeuristic(model) +{ + setDefaults(); + functionPointer_ = callBack; + assert(model.solver()); + solver_ = model.solver()->clone(); + findStructure(); +} +// Set default values +void +CbcHeuristicDW::setDefaults() +{ + targetObjective_ = -COIN_DBL_MAX; + bestObjective_ = COIN_DBL_MAX; + lastObjective_ = COIN_DBL_MAX; + fullDWEverySoOften_ = 0; + numberPasses_ = 0; + howOften_ = 100; + decayFactor_ = 0.5; + functionPointer_ = NULL; + solver_=NULL; + dwSolver_=NULL; + bestSolution_=NULL; + continuousSolution_ = NULL; + fixedDj_ = NULL; + saveLower_=NULL; + saveUpper_=NULL; + random_=NULL; + affinity_=NULL; + weights_=NULL; + objectiveDW_=NULL; + numberColumnsDW_=NULL; + whichRowBlock_=NULL; + whichColumnBlock_=NULL; + dwBlock_=NULL; + backwardRow_=NULL; + rowsInBlock_=NULL; + columnsInBlock_=NULL; + startRowBlock_=NULL; + startColumnBlock_=NULL; + intsInBlock_=NULL; + fingerPrint_=NULL; + fullDWEverySoOften_=0; + numberPasses_=0; + numberBadPasses_=COIN_INT_MAX; + maximumDW_=0; + numberDW_=0; + numberDWTimes_=0; + sizeFingerPrint_=0; + numberMasterColumns_=0; + numberMasterRows_=0; + numberBlocks_=0; + keepContinuous_=0; + phase_=0; + pass_ = 0; + nNeededBase_=200; + nNodesBase_=500; + nNeeded_=nNeededBase_; + nNodes_=nNodesBase_; + solveState_=0; +} +// Guts of copy +void +CbcHeuristicDW::gutsOfCopy(const CbcHeuristicDW & rhs) +{ + targetObjective_ = rhs.targetObjective_; + bestObjective_ = rhs.bestObjective_; + lastObjective_ = rhs.lastObjective_; + fullDWEverySoOften_ = rhs.fullDWEverySoOften_; + numberPasses_ = rhs.numberPasses_; + numberBadPasses_= rhs.numberBadPasses_; + howOften_ = rhs.howOften_; + decayFactor_ = rhs.decayFactor_; + fullDWEverySoOften_ = rhs.fullDWEverySoOften_; + numberPasses_ = rhs.numberPasses_; + maximumDW_ = rhs.maximumDW_; + numberDW_ = rhs.numberDW_; + numberDWTimes_ = rhs.numberDWTimes_; + sizeFingerPrint_ = rhs.sizeFingerPrint_; + numberMasterColumns_ = rhs.numberMasterColumns_; + numberMasterRows_ = rhs.numberMasterRows_; + numberBlocks_ = rhs.numberBlocks_; + keepContinuous_ = rhs.keepContinuous_; + phase_ = rhs.phase_; + pass_ = rhs.pass_; + nNeededBase_ = rhs.nNeededBase_; + nNodesBase_ = rhs.nNodesBase_; + nNeeded_ = rhs.nNeeded_; + nNodes_ = rhs.nNodes_; + solveState_ = rhs.solveState_; + functionPointer_ = rhs.functionPointer_; + if (rhs.solver_) + solver_ = rhs.solver_->clone(); + else + solver_ = NULL; + if (rhs.dwSolver_) + dwSolver_ = rhs.dwSolver_->clone(); + else + dwSolver_=NULL; + if (rhs.saveLower_) { + int numberColumns = solver_->getNumCols(); + int numberRows = solver_->getNumRows(); + saveLower_ = CoinCopyOfArray(rhs.saveLower_,numberColumns); + saveUpper_ = CoinCopyOfArray(rhs.saveUpper_,numberColumns); + whichColumnBlock_ = CoinCopyOfArray(rhs.whichColumnBlock_,numberColumns); + columnsInBlock_ = CoinCopyOfArray(rhs.columnsInBlock_,numberColumns); + whichRowBlock_ = CoinCopyOfArray(rhs.whichRowBlock_,numberRows); + rowsInBlock_ = CoinCopyOfArray(rhs.rowsInBlock_,numberRows); + if (rhs.affinity_) + affinity_ = CoinCopyOfArray(rhs.affinity_,numberBlocks_*numberBlocks_); + else + affinity_ = NULL; + backwardRow_ = CoinCopyOfArray(rhs.backwardRow_,numberRows); + startRowBlock_ = CoinCopyOfArray(rhs.startRowBlock_,numberBlocks_+1); + startColumnBlock_ = CoinCopyOfArray(rhs.startColumnBlock_,numberBlocks_+1); + intsInBlock_ = CoinCopyOfArray(rhs.intsInBlock_,numberBlocks_); + } else { + saveLower_=NULL; + saveUpper_=NULL; + affinity_=NULL; + whichRowBlock_=NULL; + whichColumnBlock_=NULL; + backwardRow_=NULL; + rowsInBlock_=NULL; + columnsInBlock_=NULL; + startRowBlock_=NULL; + startColumnBlock_=NULL; + intsInBlock_=NULL; + } + if (rhs.weights_) { + assert (maximumDW_); + weights_ = CoinCopyOfArray(rhs.weights_,maximumDW_); + random_ = CoinCopyOfArray(rhs.random_,numberMasterRows_); + dwBlock_ = CoinCopyOfArray(rhs.dwBlock_,maximumDW_); + fingerPrint_ = CoinCopyOfArray(rhs.fingerPrint_, + sizeFingerPrint_*maximumDW_); + objectiveDW_ = CoinCopyOfArray(rhs.objectiveDW_,numberDWTimes_); + numberColumnsDW_ = CoinCopyOfArray(rhs.numberColumnsDW_,numberDWTimes_); + } else { + random_=NULL; + weights_=NULL; + objectiveDW_=NULL; + numberColumnsDW_=NULL; + dwBlock_=NULL; + fingerPrint_=NULL; + } + if (rhs.bestSolution_) { + int numberColumns = solver_->getNumCols(); + bestSolution_ = CoinCopyOfArray(rhs.bestSolution_,numberColumns); + } else { + bestSolution_=NULL; + } + if (rhs.continuousSolution_) { + int numberColumns = solver_->getNumCols(); + continuousSolution_ = CoinCopyOfArray(rhs.continuousSolution_,numberColumns); + } else { + continuousSolution_=NULL; + } + if (rhs.fixedDj_) { + int numberColumns = solver_->getNumCols(); + fixedDj_ = CoinCopyOfArray(rhs.fixedDj_,numberColumns); + } else { + fixedDj_=NULL; + } +} +// Guts of delete +void +CbcHeuristicDW::gutsOfDelete() +{ + delete solver_; + delete dwSolver_; + delete [] bestSolution_; + delete [] continuousSolution_; + delete [] fixedDj_; + delete [] saveLower_; + delete [] saveUpper_; + delete [] random_; + delete [] affinity_; + delete [] weights_; + delete [] objectiveDW_; + delete [] numberColumnsDW_; + delete [] whichRowBlock_; + delete [] whichColumnBlock_; + delete [] dwBlock_; + delete [] backwardRow_; + delete [] rowsInBlock_; + delete [] columnsInBlock_; + delete [] startRowBlock_; + delete [] startColumnBlock_; + delete [] intsInBlock_; + delete [] fingerPrint_; + //functionPointer_ = NULL; + solver_ = NULL; + dwSolver_=NULL; + bestSolution_=NULL; + continuousSolution_ = NULL; + fixedDj_ = NULL; + saveLower_=NULL; + saveUpper_=NULL; + random_=NULL; + affinity_=NULL; + weights_=NULL; + objectiveDW_=NULL; + numberColumnsDW_ = NULL; + whichRowBlock_=NULL; + whichColumnBlock_=NULL; + dwBlock_=NULL; + backwardRow_=NULL; + rowsInBlock_=NULL; + columnsInBlock_=NULL; + startRowBlock_=NULL; + startColumnBlock_=NULL; + intsInBlock_=NULL; + fingerPrint_=NULL; + numberBlocks_=0; +} + +// Destructor +CbcHeuristicDW::~CbcHeuristicDW () +{ + gutsOfDelete(); +} + +// Clone +CbcHeuristic * +CbcHeuristicDW::clone() const +{ + return new CbcHeuristicDW(*this); +} + +// Assignment operator +CbcHeuristicDW & +CbcHeuristicDW::operator=( const CbcHeuristicDW & rhs) +{ + if (this != &rhs) { + CbcHeuristic::operator=(rhs); + gutsOfDelete(); + gutsOfCopy(rhs); + } + return *this; +} + +// Create C++ lines to get to current state +void +CbcHeuristicDW::generateCpp( FILE * fp) +{ + abort(); +} + +// Copy constructor +CbcHeuristicDW::CbcHeuristicDW(const CbcHeuristicDW & rhs) + : + CbcHeuristic(rhs) +{ + gutsOfCopy(rhs); +} +// Resets stuff if model changes +void +CbcHeuristicDW::resetModel(CbcModel * model) +{ + if (model_&&numberBlocks_&& + model->getNumCols()!=model->getNumCols()) + abort(); + model_=model; +} +/* + First tries setting a variable to better value. If feasible then + tries setting others. If not feasible then tries swaps + Returns 1 if solution, 0 if not */ +int + CbcHeuristicDW::solution(double & solutionValue, + double * betterSolution) +{ + numCouldRun_++; + int returnCode = 0; + const double * bestSolutionIn = model_->bestSolution(); + if (!bestSolutionIn && !bestSolution_) + return 0; // No solution found yet + if (numberBlocks_<3) + return 0; // no point +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif + if (bestSolutionIn&&objectiveValue(bestSolutionIn)messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + double startTime = CoinCpuTime(); + double startTimeElapsed = CoinGetTimeOfDay(); + CoinWarmStart * basis = NULL; + lastObjective_ = COIN_DBL_MAX; + int passesToDW = dwSolver_ ? 0 : -1; + bool goodSolution=true; + int numberColumns = solver_->getNumCols(); + int logLevel = model_->messageHandler()->logLevel(); + // For moment just OsiClp + OsiClpSolverInterface * solver = dynamic_cast + (solver_); + ClpSimplex * simplex = solver->getModelPtr(); + double * columnLower = simplex->columnLower(); + double * columnUpper = simplex->columnUpper(); + const double * cost = solver->getObjCoefficients(); + const double * dj = solver->getReducedCost(); + assert (solver); + if (!continuousSolution_) { + bool takeHint; + OsiHintStrength strength; + solver->getHintParam(OsiDoDualInResolve, takeHint, strength); + solver->setHintParam(OsiDoDualInResolve, false, OsiHintDo); + solver->resolve(); + solver->setHintParam(OsiDoDualInResolve, takeHint, OsiHintDo); + continuousSolution_ = CoinCopyOfArray(solver->getColSolution(), + numberColumns); + } + // data arrays + // Block order for choosing (after sort) + int * whichBlock = new int [8*numberBlocks_]; + memset(whichBlock,0,8*numberBlocks_*sizeof(int)); + // Count of number of times block chosen + int * doneBlock = whichBlock + numberBlocks_; + // Pass at which block last used + int * whenBlock = doneBlock+numberBlocks_; + // Number of Big Djs' (? artificial costs) in block + int * bigDjBlock = whenBlock+numberBlocks_; + // Number of times block has helped improve solution + int * goodBlock = bigDjBlock+numberBlocks_; + int * priorityBlock = goodBlock+numberBlocks_; + int * orderBlock = priorityBlock+numberBlocks_; + // block can be fixed if nothing in master rows, maybe always same as continuous + int * fixedBlock = orderBlock+numberBlocks_; + // Mixture of stuff to sort blocks on + double * blockSort = new double [4*numberBlocks_]; + // Reduced cost (d sub j was old notation) contribution + double * blockDj = blockSort + numberBlocks_; + // Difference between current best and continuous solutions + double * blockDiff = blockDj+numberBlocks_; + // Difference between current best and continuous solutions (just integers) + double * blockDiffInt = blockDiff+numberBlocks_; + delete [] fixedDj_; + fixedDj_ = CoinCopyOfArray(dj,numberColumns); + int numberImproving=0; + int * whenBetter = new int [numberPasses_]; + double * improvement = new double [numberPasses_]; + // First has number + int ** improvingBlocks = new int * [numberPasses_]; + int numberBlocksUsed = numberBlocks_; + // Get basic priority order + for (int i=0;igetMatrixByCol()->getElements(); + const int * row = solver->getMatrixByCol()->getIndices(); + const CoinBigIndex * columnStart = solver->getMatrixByCol()->getVectorStarts(); + const int * columnLength = solver->getMatrixByCol()->getVectorLengths(); + for (int iBlock=0;iBlock=0) + nElInMaster++; + } + if (fabs(bestSolution_[iColumn]-continuousSolution_[iColumn])<1.0e-5) { + numberDifferentContinuous++; + if (solver->isInteger(iColumn)) + numberDifferentContinuousJustInts++; + } + } + if (!nElInMaster) { + fixedBlock[iBlock]=10; + numberNoMaster++; + } else if (!numberDifferentContinuous) { + fixedBlock[iBlock]=2; + numberSameAsContinuous++; + } else if (!numberDifferentContinuousJustInts) { + fixedBlock[iBlock]=1; + numberSameAsContinuousJustInts++; + } + } + if (numberNoMaster) { + sprintf(dwPrint,"*** %d blocks have no elements in master - can be solved seperately", + numberNoMaster); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + } + sprintf(dwPrint,"With initial best solution %d blocks were same as continuous, %d when just looking at integers", + numberSameAsContinuous,numberSameAsContinuousJustInts); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + int lastGoodPass=0; + for (pass_=0;pass_bestObjective_+1.0e-3 ? "improving" : ""); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + } + if ((pass_%10)==9) { + for (int iImp=CoinMax(1,numberImproving-10);iImpmessageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + if (logLevel>1) { + for (int i=0;i1) { + int * count = new int [numberImproving+1]; + memset(count,0,(numberImproving+1)*sizeof(int)); + for (int i=0;inumberBadPasses_) { + sprintf(dwPrint,"Exiting on lack of progress"); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + break; + } + if (model_->getNodeCount()>=model_->getMaximumNodes()|| + model_->maximumSecondsReached()) { + sprintf(dwPrint,"Exiting on time or interrupt"); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + break; + } + if (bestObjective_>=lastObjective_-1.0e-3) { + // what now + // 0 - fine, 1 can't be better, 2 max node + //assert(solveState); + if (solveState_<2) { + // more in + sprintf(dwPrint,"No improvement - think we need more variables "); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + nNeeded_ += nNeeded_/10; + nNeeded_ = CoinMin(nNeeded_,800); + nNodes_=nNodesBase_; + (*(functionPointer_))(this,NULL,6); + } else { + // more nodes fewer in + sprintf(dwPrint,"No improvement - stopped on nodes - think we need more nodes "); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + if (phase_) { + nNodes_ += nNodes_/5; + nNodes_ = CoinMin(nNodes_,1000); + } + nNeeded_ -= nNeeded_/20; + nNeeded_ = CoinMax(nNeeded_,50); + (*(functionPointer_))(this,NULL,7); + } + } else { + // improving + (*(functionPointer_))(this,NULL,4); + solveState_=0; + //lastObjective_=bestObjective_; + if (phase_) { + //nNeededBase_ += nNeededBase_/50; + //nNodesBase_ += nNodesBase_/50; + } + nNeeded_ -= nNeeded_/10; + nNeeded_=CoinMax(nNeededBase_,nNeeded_); + nNodes_=nNodesBase_; + (*(functionPointer_))(this,NULL,8); + } + sprintf(dwPrint,"new needed %d, nodes %d",nNeeded_,nNodes_); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + for ( int i=0 ; iisInteger(i)) { + double value = floor(bestSolution_[i]+0.5); + columnLower[i] = value; + columnUpper[i] = value; + } else { + columnLower[i] = saveLower_[i]; + columnUpper[i] = saveUpper_[i]; + } + } + if (goodSolution) { + lastGoodPass=pass_; + int lastNumberDW=numberDW_; + solver->setColSolution(bestSolution_); + solver->setHintParam(OsiDoReducePrint, false, OsiHintDo, 0) ; + if (basis) { + solver->setWarmStart(basis); + delete basis; + basis=NULL; + } + solver->resolve(); + solver->setHintParam(OsiDoReducePrint, true, OsiHintDo, 0) ; + if (solver->getObjValue()getColSolution(), + numberColumns*sizeof(double)); + bestObjective_ = solver->getObjValue(); + int * blocks = new int [numberBlocksUsed+1]; + blocks[0]=numberBlocksUsed; + memcpy(blocks+1,whichBlock,numberBlocksUsed*sizeof(int)); + improvingBlocks[numberImproving]=blocks; + whenBetter[numberImproving]=pass_; + improvement[numberImproving]=lastObjective_-bestObjective_; + numberImproving++; + lastObjective_=bestObjective_; + if (pass_) { + // update good + for (int i=0;i0) { + addDW(bestSolution_,numberBlocksUsed, + whichBlock); + } + if (passesToDW==0) { + passesToDW = fullDWEverySoOften_; + const double * duals = solver->getRowPrice(); + double * bestSolution2 = CoinCopyOfArray(bestSolution_, + numberColumns); + // Column copy + const double * element = solver->getMatrixByCol()->getElements(); + const int * row = solver->getMatrixByCol()->getIndices(); + const CoinBigIndex * columnStart = solver->getMatrixByCol()->getVectorStarts(); + const int * columnLength = solver->getMatrixByCol()->getVectorLengths(); + int numberUsed=0; + for (int iBlock=0;iBlockgetModelPtr(), + startRowBlock_[iBlock+1]-startRowBlock_[iBlock], + rowsInBlock_+startRowBlock_[iBlock], + end-start, + columnsInBlock_+startColumnBlock_[iBlock]); + tempModel->setLogLevel(0); + tempModel->setDualObjectiveLimit(COIN_DBL_MAX); + double * objectiveX = tempModel->objective(); + double * columnLowerX = tempModel->columnLower(); + double * columnUpperX = tempModel->columnUpper(); + for (int i=start;iisInteger(iColumn)) + tempModel->setInteger(jColumn); + double cost=objectiveX[jColumn]; + for (CoinBigIndex j=columnStart[iColumn]; + j=0) { + cost -= elementValue * duals[iRow]; + } + } + objectiveX[jColumn]=cost; + } + OsiClpSolverInterface solverX(tempModel,true); + CbcModel modelX(solverX); + modelX.setLogLevel(1); + modelX.setMoreSpecialOptions2(57); + // need to stop after solutions and nodes + //modelX.setMaximumNodes(nNodes_); + modelX.setMaximumSolutions(1); + modelX.branchAndBound(); + const double * bestSolutionX = modelX.bestSolution(); + if (bestSolutionX) { + whichBlock[numberUsed++]=iBlock; + for (int i=start;iisInteger(i)) { + double value = floor(bestSolution2[i]+0.5); + columnLower[i] = value; + columnUpper[i] = value; + } else { + columnLower[i] = saveLower_[i]; + columnUpper[i] = saveUpper_[i]; + } + } + solver_->resolve(); + if (solver_->isProvenOptimal()) { + printf ("DW1 sol %g\n",solver->getObjValue()); + } + } + // now try purer DW + bool takeHint; + OsiHintStrength strength; + dwSolver_->getHintParam(OsiDoDualInResolve, takeHint, strength); + dwSolver_->setHintParam(OsiDoDualInResolve, false, OsiHintDo); + dwSolver_->resolve(); + dwSolver_->setHintParam(OsiDoDualInResolve, takeHint, OsiHintDo); + duals = dwSolver_->getRowPrice(); + numberUsed=0; + for (int iBlock=0;iBlockgetModelPtr(), + startRowBlock_[iBlock+1]-startRowBlock_[iBlock], + rowsInBlock_+startRowBlock_[iBlock], + end-start, + columnsInBlock_+startColumnBlock_[iBlock]); + tempModel->setLogLevel(0); + tempModel->setDualObjectiveLimit(COIN_DBL_MAX); + double * objectiveX = tempModel->objective(); + double * columnLowerX = tempModel->columnLower(); + double * columnUpperX = tempModel->columnUpper(); + double convexityDual = duals[numberMasterRows_+iBlock]; + for (int i=start;iisInteger(iColumn)) + tempModel->setInteger(jColumn); + double cost=objectiveX[jColumn]; + for (CoinBigIndex j=columnStart[iColumn]; + j=0) { + // duals are from dw + cost -= elementValue * duals[backwardRow_[iRow]]; + } + } + objectiveX[jColumn]=cost; + } + OsiClpSolverInterface solverX(tempModel,true); + solverX.initialSolve(); + double cObj=solverX.getObjValue(); + CbcModel modelX(solverX); + modelX.setLogLevel(1); + modelX.setMoreSpecialOptions2(57); + modelX.setMaximumSolutions(1); + modelX.branchAndBound(); + sprintf(dwPrint,"Block %d contobj %g intobj %g convdual %g", + iBlock,cObj,modelX.getObjValue(),convexityDual); + model_->messageHandler()->message(CBC_FPUMP2, model_->messages()) + << dwPrint + << CoinMessageEol; + const double * bestSolutionX = modelX.bestSolution(); + if (bestSolutionX) { + whichBlock[numberUsed++]=iBlock; + for (int i=start;iisInteger(i)) { + double value = floor(bestSolution2[i]+0.5); + columnLower[i] = value; + columnUpper[i] = value; + } else { + columnLower[i] = saveLower_[i]; + columnUpper[i] = saveUpper_[i]; + } + } + solver_->resolve(); + if (solver_->isProvenOptimal()) { + printf ("DW sol %g\n",solver->getObjValue()); + } + } + delete [] bestSolution2; + } + passesToDW--; + if (numberDW_>lastNumberDW) { + intArray_=NULL; + doubleArray_=NULL; + (*(functionPointer_))(this,NULL,3); + } + } + for (int i=0;i=0) { + columnLower[i]=bestSolution_[i]; + columnUpper[i]=bestSolution_[i]; + } + } + for (int iBlock=0;iBlockisInteger(iColumn)) + blockDiffInt[iBlock] += + fabs((bestSolution_[iColumn]-continuousSolution_[iColumn])) + *(fabs(cost[iColumn])+1.0e-5); + } + if (solver->isInteger(iColumn)) { + if (bestSolution_[iColumn]saveLower_[iColumn]+1.0e-1) { + if (fixedDj_[iColumn]>1.0e-5) + blockDj[iBlock]-=fixedDj_[iColumn]; + if (fixedDj_[iColumn]>1.0e4) + bigDjBlock[iBlock]++; + } + } + } + } + // Get average dj and difference + int numberInDj=0; + double averageDj=1.0e-12; + int numberInDiff=0; + double averageDiff=1.0e-12; + for (int i=0;i=0.0); + if (blockDiff[i]>0.0) { + numberInDiff++; + averageDiff += blockDiff[i]; + } + } + if (numberInDj) + averageDj /= static_cast(numberInDj); + if (numberInDiff) + averageDiff /= static_cast(numberInDiff); + double ratioDiff = averageDj/averageDiff; + // downplay + ratioDiff *= 1.0e-3; + for (int i=0;i(intsInBlock_[i]); + //blockSort[i] /= sqrt(static_cast(intsInBlock_[i])); + if (doneBlock[i]) { + blockSort[i] /= static_cast(doneBlock[i]+1); + if (whenBlock[i]>pass_-10) + blockSort[i]+= 1.0e2*averageDj; + } + } + CoinSort_2(blockSort,blockSort+numberBlocks_,whichBlock); + // allow user to modify + intArray_=whichBlock; + doubleArray_=blockSort; + (*(functionPointer_))(this,NULL,1); + int numberBlocksIn=0; + for (int iTry=0;iTry<2;iTry++) { + int nFreed=0; + int nBigDjBlock=0; + numberBlocksUsed=0; + for (int i=0;i=0); + if ((doneBlock[iBlock]&&!phase_)||!blockSort[i]) { + //printf("already done block %d - dj %g\n",iBlock,blockDj[i]); + skipBlock=true; + } else if (bigDjBlock[iBlock]) { + nBigDjBlock++; + if (nBigDjBlock>20&&!phase_) { + skipBlock=true; + } + } + int returnCode = (*(functionPointer_))(this,NULL,5); + if (returnCode<0) + skipBlock=true; + else if (returnCode>0) + skipBlock=false; + if (skipBlock) { + whichBlock[i] -= 1000000; + } else { + // free up + sprintf(dwPrint,"freeing block %d (already freed %d times) - dj %g, diff %g, diffint %g - %d columns (%d integer)", + iBlock,doneBlock[iBlock],blockDj[iBlock], + blockDiff[iBlock],blockDiffInt[iBlock], + startColumnBlock_[iBlock+1]-startColumnBlock_[iBlock], + intsInBlock_[iBlock]); + model_->messageHandler()->message(CBC_FPUMP2, model_->messages()) + << dwPrint + << CoinMessageEol; + numberBlocksIn++; + doneBlock[iBlock]++; + whenBlock[iBlock]=pass_; + nFreed += intsInBlock_[iBlock]; + for (int j=startColumnBlock_[iBlock]; + j=nNeeded_ && numberBlocksIn>3) + break; + } + } + sprintf(dwPrint,"%d big dj blocks found",nBigDjBlock); + model_->messageHandler()->message(CBC_FPUMP2, model_->messages()) + << dwPrint + << CoinMessageEol; + if (nFreed) + break; + phase_=1; // round again + sprintf(dwPrint,"Changing phase"); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + for (int i=0;i=0) + whichBlock[n++]=whichBlock[i]; + } + numberBlocksUsed = n; + int nFixedInts=0; + int nFixedContinuous=0; + int nFreeInts=0; + int nFreeContinuous=0; + int nFreeMaster=0; + int nFixedMaster=0; + for ( int i=0 ; icolumnLower[i]) { + if (kBlock>=0) { + if (solver->isInteger(i)) + nFreeInts++; + else + nFreeContinuous++; + } else { + nFreeMaster++; + } + } else { + if (kBlock>=0) { + if (solver->isInteger(i)) + nFixedInts++; + else + nFixedContinuous++; + } else { + nFixedMaster++; + } + } + } + sprintf(dwPrint,"Fixed %d ints, %d c, %d m - free %d, %d, %d", + nFixedInts,nFixedContinuous,nFixedMaster, + nFreeInts,nFreeContinuous,nFreeMaster); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + // But free up and then fix again + for ( int i=0 ; i=0&&solver->isInteger(i)&&whenBlock[kBlock]!=pass_) { + columnLower[i]=bestSolution_[i]; + columnUpper[i]=bestSolution_[i]; + } + } + bool takeHint; + OsiHintStrength strength; + solver->getHintParam(OsiDoDualInResolve, takeHint, strength); + solver->setHintParam(OsiDoDualInResolve, false, OsiHintDo); + solver->messageHandler()->setLogLevel(1) ; + solver->setHintParam(OsiDoReducePrint, false, OsiHintDo, 0) ; + solver->resolve(); + solver->setHintParam(OsiDoReducePrint, true, OsiHintDo, 0) ; + //solver->messageHandler()->setLogLevel(0) ; + solver->setHintParam(OsiDoDualInResolve, takeHint, strength); + if (solver->getObjValue()>bestObjective_+1.0e-5*(1.0+fabs(bestObjective_))) { + // trouble + if (logLevel>1) { + for (int i=0;iwriteMps("bad","mps"); + const double * lower = solver->getColLower(); + const double * upper = solver->getColUpper(); + if (logLevel>1) { + printf("best obj %g\n",objectiveValue(bestSolution_)); + for ( int i=0 ; iupper[i]+1.0e-5) + printf("column %d (block %d) %g %g <= %g <= %g %g\n", + i,whichColumnBlock_[i],saveLower_[i], + lower[i],value,upper[i],saveUpper_[i]); + } + } + //abort(); + sprintf(dwPrint,"**** Continuous below best - bad solution passed in?!"); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + // give up + break; + } + const double * tempSol = solver->getColSolution(); + // But free up and then fix again + for ( int i=0 ; i=0&&!solver->isInteger(i)&&whenBlock[kBlock]!=pass_) { + columnLower[i]=tempSol[i]; + columnUpper[i]=tempSol[i]; + } + } + solver->getHintParam(OsiDoDualInResolve, takeHint, strength); + solver->setHintParam(OsiDoDualInResolve, false, OsiHintDo); + solver->messageHandler()->setLogLevel(1) ; + solver->setHintParam(OsiDoReducePrint, false, OsiHintDo, 0) ; + solver->resolve(); + solver->setHintParam(OsiDoReducePrint, true, OsiHintDo, 0) ; + //solver->messageHandler()->setLogLevel(0) ; + solver->setHintParam(OsiDoDualInResolve, takeHint, strength); + //solver->messageHandler()->setLogLevel(0) ; + //lp->setLogLevel(0); + ClpPresolve pinfo; + // fix small infeasibilities + pinfo.setPresolveActions(pinfo.presolveActions()|0x4000); + int numberPasses = 2; // can change this + ClpSimplex * model2 = pinfo.presolvedModel(*simplex, 1.0e-8, + true, + numberPasses, true); + if (!model2) { + abort(); + } else { + sprintf(dwPrint,"Reduced model has %d rows and %d columns", + model2->numberRows(),model2->numberColumns()); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + //model2->setLogLevel(0); + OsiClpSolverInterface solver2(model2); + solver2.setWarmStart(NULL); + //solver2.messageHandler()->setLogLevel(0) ; + CbcModel model(solver2); + model.setMaximumNodes(nNodes_); + //model.setMaximumSolutions(2); + model.solver()->setHintParam(OsiDoReducePrint, false, OsiHintDo, 0) ; + model.solver()->setHintParam(OsiDoPresolveInInitial, false, OsiHintDo, 0) ; + //model.solver()->setHintParam(OsiDoPresolveInResolve, false, OsiHintDo, 0) ; + model.initialSolve(); + if (bestObjective_ > model.solver()->getObjValue()+1.0e-1) { + const double * dj = model.solver()->getReducedCost(); + int nFix=0; + const double * lower = model.solver()->getColLower(); + const double * upper = model.solver()->getColUpper(); + const double * solution = model.solver()->getColSolution(); + double gap = CoinMax(bestObjective_-model.solver()->getObjValue(), + 1.0e-3); + int numberColumns2=model.solver()->getNumCols(); +#ifdef HOT_START + // Set up hot start + const int * originalColumns = pinfo.originalColumns(); + double * hot = new double[2*numberColumns2]; + int * hotPriorities = new int[numberColumns2*2]; + double * hotWeight = hot+numberColumns2; + memset(hot,0,numberColumns2*sizeof(double)); + int * sort = hotPriorities+numberColumns2; + for (int i=0;i0.0) + hotWeight[i]=fixedDj_[iColumn]; + } else if (bestSolution_[i]>saveUpper_[iColumn]-1.0e-6) { + if (fixedDj_[i]<0.0) + hotWeight[i]=-fixedDj_[iColumn]; + } + if (solution[i]gap) { + solver2.setColUpper(i,saveLower_[iColumn]); + nFix++; + } + } else if (solution[i]>saveUpper_[iColumn]-1.0e-6) { + if (-dj[i]>gap) { + solver2.setColLower(i,saveUpper_[iColumn]); + nFix++; + } + } + } + } + CoinSort_2(hotWeight,hotWeight+numberColumns2,sort); + for (int i=0;i1) { + if (nFix) + printf("Fixed another %d integers\n",nFix); + } + { + // priorities + memset(priorityBlock,0,numberBlocks_*sizeof(int)); + for (int i=0;i=0) + priorityBlock[iBlock]=i+1; + } +#if 1 + assert (numberBlocks_<4000); + // But make sure we do one block before next + for (int i=0;igetNumCols(); + const int * original = pinfo.originalColumns(); + int * priorities = new int [numberColumns2]; + int n=0; + for (int i=0;igetNumberThreads()); + model.solver()->setHintParam(OsiDoReducePrint, true, OsiHintDo, 0) ; + model.setPrintingMode(1); + model.setCutoff(lastObjective_-model_->getCutoffIncrement()); + model.setLogLevel(1); + intArray_=NULL; + doubleArray_=NULL; + (*(functionPointer_))(this,&model,2); + model.branchAndBound(); + if (logLevel>1) { + printf("After B&B status %d objective %g\n",model.status(), + model.getMinimizationObjValue()); + } + int modelStatus = model.status(); + model.solver()->setHintParam(OsiDoReducePrint, false, OsiHintDo, 0) ; + if (model.bestSolution() && + model.getMinimizationObjValue()1.0e-5) { + if (logLevel>1) { + printf("bad %d %g\n",i,bestSolution2[i]); + } + } else { + solver->setColLower(iColumn,value); + solver->setColUpper(iColumn,value); + } + } + } + pinfo.postsolve(true); + delete model2; + bool takeHint; + OsiHintStrength strength; + solver->getHintParam(OsiDoDualInResolve, takeHint, strength); + solver->setHintParam(OsiDoDualInResolve, false, OsiHintDo); + solver->messageHandler()->setLogLevel(1) ; + solver->setHintParam(OsiDoReducePrint, false, OsiHintDo, 0) ; + solver->resolve(); + if (basis) + delete basis; + basis = solver->getWarmStart(); + memcpy(fixedDj_,solver->getReducedCost(), + numberColumns*sizeof(double)); + solver->setHintParam(OsiDoReducePrint, true, OsiHintDo, 0) ; + //solver->messageHandler()->setLogLevel(0) ; + solver->setHintParam(OsiDoDualInResolve, takeHint, strength); + //solver-> + CbcModel model(*solver); + model.setNumberBeforeTrust(-1); + model.setNumberStrong(0); + model.setMoreSpecialOptions2(57); + model.branchAndBound(); + if (model.getMinimizationObjValue()1) { + for (int i=0;iisInteger(i)) { + if (fabs(bestSolution_[i]-floor(bestSolution_[i]+0.5))>1.0e-5) { + printf("bad after %d %g\n",i,bestSolution_[i]); + } + } + } + } + goodSolution=true; + } + } else if (modelStatus!=0) { + // stopped on nodes + // 0 - fine, 1 can't be better, 2 max node + solveState_=2; + pinfo.destroyPresolve(); + delete model2; + } else { + // complete search + solveState_=1; + pinfo.destroyPresolve(); + delete model2; + } + } else { + // can't be better + // 0 - fine, 1 can't be better, 2 max node + solveState_=1; + pinfo.destroyPresolve(); + delete model2; + } + } + } + delete [] whichBlock; + delete [] blockSort; + delete [] whenBetter; + delete [] improvement; + for (int i=0;igetNumCols()*sizeof(double)); + } + return returnCode; +} +// update model +void +CbcHeuristicDW::setModel(CbcModel * model) +{ + if (model!=model_) { + gutsOfDelete(); + model_ = model; + assert(model->solver()); + solver_ = model->solver()->clone(); + findStructure(); + } +} +// Find structure +void +CbcHeuristicDW::findStructure() +{ + int numberRows = solver_->getNumRows(); + int numberColumns = solver_->getNumCols(); + // look for DW + int * blockStart = new int [3*(numberRows+numberColumns)+1]; + int * columnBlock = blockStart+numberRows; + int * nextColumn = columnBlock+numberColumns; + int * blockCount = nextColumn+numberColumns; + int * blockEls = blockCount+numberRows+1; + int * countIntegers = blockEls+numberRows; + memset(countIntegers,0,numberColumns*sizeof(int)); + int direction[2]={-1,1}; + int bestBreak=-1; + double bestValue=0.0; + int iPass=0; + int halfway=(numberRows+1)/2; + int firstMaster=-1; + int lastMaster=-2; + char dwPrint[200]; + // Column copy + const CoinPackedMatrix * columnCopy = solver_->getMatrixByCol(); + //const double * element = columnCopy->getElements(); + const int * row = columnCopy->getIndices(); + const CoinBigIndex * columnStart = columnCopy->getVectorStarts(); + const int * columnLength = columnCopy->getVectorLengths(); + // Row copy + const CoinPackedMatrix * rowCopy = solver_->getMatrixByRow(); + const int * column = rowCopy->getIndices(); + const int * rowLength = rowCopy->getVectorLengths(); + const CoinBigIndex * rowStart = rowCopy->getVectorStarts(); + //const double * elementByRow = rowCopy->getElements(); + while (iPass<2) { + int increment=direction[iPass]; + int start= increment>0 ? 0 : numberRows-1; + int stop=increment>0 ? numberRows : -1; + int numberBlocks=0; + int thisBestBreak=-1; + double thisBestValue=COIN_DBL_MAX; + int numberRowsDone=0; + int numberMarkedColumns=0; + int maximumBlockSize=0; + for (int i=0;i=0) { + // column marked + if (iBlock<0) { + // put row in that block + iBlock=whichColumnBlock; + } else if (iBlock!=whichColumnBlock) { + // merge + blockCount[iBlock]+=blockCount[whichColumnBlock]; + blockCount[whichColumnBlock]=0; + int jColumn=blockStart[whichColumnBlock]; + while (jColumn>=0) { + columnBlock[jColumn]=iBlock; + iColumn=jColumn; + jColumn=nextColumn[jColumn]; + } + nextColumn[iColumn]=blockStart[iBlock]; + blockStart[iBlock]=blockStart[whichColumnBlock]; + blockStart[whichColumnBlock]=-1; + } + } + } + int n=numberMarkedColumns; + if (iBlock<0) { + //new block + if (rowLength[iRow]) { + numberBlocks++; + iBlock=numberBlocks; + int jColumn=column[rowStart[iRow]]; + columnBlock[jColumn]=iBlock; + blockStart[iBlock]=jColumn; + numberMarkedColumns++; + for (CoinBigIndex j=rowStart[iRow]+1;j maximumBlockSize&&numberRowsDone>halfway) { + thisBestBreak=iRow; + thisBestValue=static_cast(maximumBlockSize)/ + static_cast(numberRowsDone); + } + } + if (thisBestBreak==stop) + thisBestValue=COIN_DBL_MAX; + iPass++; + if (iPass==1) { + bestBreak=thisBestBreak; + bestValue=thisBestValue; + } else { + if (bestValuemessageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + for (int i=0;i=0) { + blockCount[iBlock]++; + blockEls[iBlock]+=rowLength[iRow]; + } else { + if (iBlock==-2) + numberMaster++; + else + numberEmpty++; + } + } + int numberEmptyColumns=0; + int numberMasterColumns=0; + int numberMasterIntegers=0; + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + int iBlock=columnBlock[iColumn]; + bool isInteger = (solver_->isInteger(iColumn)); + if (iBlock>=0) { + nextColumn[iBlock]++; + if (isInteger) + countIntegers[iBlock]++; + } else { + if (isInteger) + numberMasterIntegers++; + if (columnLength[iColumn]) + numberMasterColumns++; + else + numberEmptyColumns++; + } + } + int largestRows=0; + int largestColumns=0; + for (int i=0;ilargestRows+largestColumns) { + largestRows=blockCount[i]; + largestColumns=nextColumn[i]; + } + } + bool useful=true; + if (numberMaster>halfway||largestRows*3>numberRows) + useful=false; + sprintf(dwPrint,"%s %d blocks (largest %d,%d), %d master rows (%d empty) out of %d, %d master columns (%d empty, %d integer) out of %d", + useful ? "**Useful" : "NoGood", + numberBlocks,largestRows,largestColumns,numberMaster,numberEmpty,numberRows, + numberMasterColumns,numberEmptyColumns,numberMasterIntegers, + numberColumns); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + // columnBlock is columnBlock and blockStart is rowBlock + // See if we want to compress + if (!keepContinuous_) { + // use blockEls + int newNumber=0; + for (int i=0;imessageHandler()->message(CBC_FPUMP2, model_->messages()) + << dwPrint + << CoinMessageEol; + if (countIntegers[i]) { + blockEls[i]=newNumber; + newNumber++; + } else { + blockEls[i]=-1; + } + } + for (int i=0;i=0) + blockStart[i]=blockEls[iBlock]; + } + for (int i=0;i=0) + columnBlock[i]=blockEls[iBlock]; + } + if (newNumbermessageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + } + numberBlocks=newNumber; + } + // now set up structures + numberBlocks_ = numberBlocks; + // so callBack can modify + whichRowBlock_ = blockStart; + whichColumnBlock_ = columnBlock; + intArray_=NULL; + doubleArray_=NULL; + (*(functionPointer_))(this,NULL,0); + + saveLower_=CoinCopyOfArray(solver_->getColLower(),numberColumns); + saveUpper_=CoinCopyOfArray(solver_->getColUpper(),numberColumns); + startRowBlock_ = new int [numberBlocks_+2]; + backwardRow_ = new int [numberRows]; + rowsInBlock_ = new int [numberRows]; + whichRowBlock_ = new int [numberRows]; + startColumnBlock_ = new int [numberBlocks_+2]; + columnsInBlock_ = new int [numberColumns]; + whichColumnBlock_ = new int [numberColumns]; + intsInBlock_ = new int [numberBlocks_]; + // use for counts + memset(rowsInBlock_,0,numberBlocks_*sizeof(int)); + numberMasterRows_=0; + for (int i=0;i=0) { + rowsInBlock_[iBlock]++; + whichRowBlock_[i]=iBlock; + backwardRow_[i]=-1; + } else { + whichRowBlock_[i]=-1; + backwardRow_[i]=numberMasterRows_; + numberMasterRows_++; + } + } + memset(columnsInBlock_,0,numberBlocks_*sizeof(int)); + memset(intsInBlock_,0,numberBlocks_*sizeof(int)); + numberMasterColumns_=0; + for (int i=0;i=0) { + columnsInBlock_[iBlock]++; + whichColumnBlock_[i]=iBlock; + if (solver_->isInteger(i)) + intsInBlock_[iBlock]++; + } else { + whichColumnBlock_[i]=-1; + numberMasterColumns_++; + } + } + // starts + int nRow=0; + int nColumn=0; + int maxIntsInBlock=0; + for (int i=0;i0;i--) + startRowBlock_[i]=startRowBlock_[i-1]; + startRowBlock_[0]=0; + for ( int i=0 ; i0;i--) + startColumnBlock_[i]=startColumnBlock_[i-1]; + startColumnBlock_[0]=0; + if (numberBlocks_<10000) { + affinity_ = new unsigned short [numberBlocks_*numberBlocks_]; + // compute space needed + int * build = new int [numberMasterRows_]; + memset(build,0,numberMasterRows_*sizeof(int)); + int nSpace=0; + for (int iBlock=0;iBlock=0) + build[iRow] ++; + } + } + for (int i=0;i=0) + build[iRow] ++; + } + } + for (int i=0;irowJ) { + j++; + if (j65535) + sum = 65535; + unsigned short value = static_cast(sum); + affinity_[iBlock*numberBlocks+jBlock]=value; + affinity_[jBlock*numberBlocks+iBlock]=value; + } + } + // statistics + int nTotalZero=0; + int base=0; + for (int iBlock=0;iBlock(nTotalZero) + /(numberBlocks*numberBlocks))); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + + delete [] starts; + delete [] build; + } else { + sprintf(dwPrint,"Too many blocks - no affinity"); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + } + if (fullDWEverySoOften_>0) { + setupDWStructures(); + } + } + delete [] blockStart; +} +// Add DW proposals +int +CbcHeuristicDW::addDW(const double * solution,int numberBlocksUsed, + const int * whichBlocks) +{ + char dwPrint[200]; + if (numberDW_+numberBlocksUsed>maximumDW_) { + // extend + int n = maximumDW_+5*numberBlocks_; + double * weightsT = new double [n]; + int * dwBlockT = new int[n]; + unsigned int * fingerT = new unsigned int [n*sizeFingerPrint_]; + memcpy(weightsT,weights_,numberDW_*sizeof(double)); + memcpy(dwBlockT,dwBlock_,numberDW_*sizeof(int)); + memcpy(fingerT,fingerPrint_, + numberDW_*sizeFingerPrint_*sizeof(unsigned int)); + delete [] weights_; + weights_=weightsT; + delete [] dwBlock_; + dwBlock_=dwBlockT; + delete [] fingerPrint_; + fingerPrint_ = fingerT; + maximumDW_=n; + } + //int numberColumns = solver_->getNumCols(); + //int numberRows = solver_->getNumRows(); + // get space to add elements +#define MAX_ADD 100000 + int * startsDW = new int[numberBlocks_+1+MAX_ADD]; + int * rowDW = startsDW+numberBlocks_+1; + double * elementDW = new double[MAX_ADD+3*numberBlocks_+numberMasterRows_]; + double * newCost = elementDW+MAX_ADD; + double * newLower = newCost+numberBlocks_; + double * newUpper = newLower+numberBlocks_; + double * build = newUpper+numberBlocks_; + memset(build,0,numberMasterRows_*sizeof(double)); + int nAdd=0; + int nTotalAdded=0; + int nEls=0; + startsDW[0]=0; + // Column copy + const double * element = solver_->getMatrixByCol()->getElements(); + const int * row = solver_->getMatrixByCol()->getIndices(); + const CoinBigIndex * columnStart = solver_->getMatrixByCol()->getVectorStarts(); + const int * columnLength = solver_->getMatrixByCol()->getVectorLengths(); + const double * objective = solver_->getObjCoefficients(); + for (int jBlock=0;jBlockisInteger(iColumn); + double value = solution[iColumn]; + if (isInteger) { + if(value>1.0e-6) + finger[0] |= 1<=0) { + nElInMaster++; + double elementValue=element[j]; + build[iRow]+=value*elementValue; + if (isInteger) { + nElIntInMaster++; + if (value) + nElIntInMaster1++; + thisWeight += random_[iRow]*value*elementValue; + } else { + value = 0.0001*floor(value*10000.0+0.5); + } + thisWeightC += random_[iRow]*value*elementValue; + } + } + } + // see if already in + sprintf(dwPrint,"block %d nel %d nelInt %d nelInt1 %d - weight %g (%g)", + iBlock,nElInMaster,nElIntInMaster,nElIntInMaster1, + thisWeight,thisWeightC); + model_->messageHandler()->message(CBC_FPUMP2, model_->messages()) + << dwPrint + << CoinMessageEol; + int iProposal; + for (iProposal=0;iProposalmessageHandler()->message(CBC_FPUMP2, model_->messages()) + << dwPrint + << CoinMessageEol; + memset(build,0,numberMasterRows_*sizeof(double)); + //iProposal=numberDW; + } + if (iProposal==numberDW_) { + // new + // could build in stages + assert (nEls+numberMasterRows_1.0e-10) { + elementDW[nEls]=value; + rowDW[nEls++]=i; + } + } + } + // convexity + elementDW[nEls]=1.0; + rowDW[nEls++]=numberMasterRows_+iBlock; + weights_[nAdd+numberDW_]=thisWeightC; + dwBlock_[nAdd+numberDW_]=iBlock; + newLower[nAdd]=0.0; + newUpper[nAdd]=1.0; + newCost[nAdd++]=thisCost; + startsDW[nAdd]=nEls; + } + if (nEls+numberMasterRows_>MAX_ADD) { + sprintf(dwPrint,"Adding %d proposals with %d elements - out of room", + nAdd,nEls); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + dwSolver_->addCols(nAdd,startsDW,rowDW,elementDW,newLower, + newUpper,newCost); + numberDW_+=nAdd; + nTotalAdded+=nAdd; + nAdd=0; + nEls=0; + } + } + if (nAdd) { + sprintf(dwPrint,"Adding %d proposals with %d elements", + nAdd,nEls); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + dwSolver_->addCols(nAdd,startsDW,rowDW,elementDW,newLower, + newUpper,newCost); + nTotalAdded+=nAdd; + numberDW_+=nAdd; + } + delete [] startsDW; + delete [] elementDW; + if (nTotalAdded) { + double * objs = new double[numberDWTimes_+1]; + memcpy(objs,objectiveDW_,numberDWTimes_*sizeof(double)); + delete [] objectiveDW_; + objectiveDW_=objs; + int * temp = new int[numberDWTimes_+1]; + memcpy(temp,numberColumnsDW_,numberDWTimes_*sizeof(int)); + delete [] numberColumnsDW_; + numberColumnsDW_=temp; + numberColumnsDW_[numberDWTimes_]= dwSolver_->getNumCols(); + objectiveDW_[numberDWTimes_++]= objectiveValue(solution); + } + return nTotalAdded; +} +// Pass in a solution +void +CbcHeuristicDW::passInSolution(const double * solution) +{ + if (fullDWEverySoOften_>0) { + int * which = new int[numberBlocks_]; + for (int i=0;igetNumCols(); + if (!bestSolution_) + bestSolution_ = new double [numberColumns]; + memcpy(bestSolution_,solution,numberColumns*sizeof(double)); + } +} +// Pass in continuous solution +void +CbcHeuristicDW::passInContinuousSolution(const double * solution) +{ + int numberColumns = solver_->getNumCols(); + if (!continuousSolution_) + continuousSolution_ = new double [numberColumns]; + memcpy(continuousSolution_,solution,numberColumns*sizeof(double)); +} +// Objective value (could also check validity) +double +CbcHeuristicDW::objectiveValue(const double * solution) +{ + // compute objective value + double objOffset = 0.0; + solver_->getDblParam(OsiObjOffset, objOffset); + double objectiveValue = -objOffset; + int numberColumns = solver_->getNumCols(); + const double * objective = solver_->getObjCoefficients(); + int logLevel = model_->messageHandler()->logLevel(); + for (int i=0;i1) { + if (solver_->isInteger(i)) { + if (fabs(value-floor(value+0.5))>1.0e-7) + printf("Bad integer value for %d of %g\n",i,value); + } + } + objectiveValue += objective[i]*value; + } + return objectiveValue; +} +// Objective value when whichDw created +double +CbcHeuristicDW::objectiveValueWhen(int whichDW) const +{ + if (whichDW>=numberDWTimes_) + return COIN_DBL_MAX; + else + return objectiveDW_[whichDW]; +} +// Number of columns in DW +int +CbcHeuristicDW::numberColumnsDW(int whichDW) const +{ + if (whichDW>=numberDWTimes_) + return COIN_INT_MAX; + else + return numberColumnsDW_[whichDW]; +} +// DW model (user must delete) +OsiSolverInterface * +CbcHeuristicDW::DWModel(int whichDW) const +{ + if (whichDW>=numberDWTimes_) + return NULL; + OsiSolverInterface * newSolver = dwSolver_->clone(); + int numberColumns2=newSolver->getNumCols(); + int numberColumns=numberColumnsDW_[whichDW]; + if (numberColumnsdeleteCols(numberColumns2-numberColumns,del); + delete [] del; + } + // Set all to integer that need setting + for (int i=numberMasterColumns_;isetContinuous(i); + } + int numberDW=numberColumns-numberMasterColumns_; + for (int iBlock=0;iBlocksetInteger(iColumn); + } + } + } + } + //newSolver->writeMps("dw","mps"); + return newSolver; +} +/* DW Proposal actions + fullDWEverySoOften - + 0 - off + k - every k times solution gets better +*/ +void +CbcHeuristicDW::setProposalActions(int fullDWEverySoOften) +{ + fullDWEverySoOften_=fullDWEverySoOften; + if (fullDWEverySoOften_>0&&!random_) + setupDWStructures(); +} +// Set up DW structure +void +CbcHeuristicDW::setupDWStructures() +{ + char dwPrint[200]; + random_=new double [numberMasterRows_]; + for (int i=0;igetNumCols(); + int numberRows = solver_->getNumRows(); + int * tempRow = new int [numberRows+numberColumns]; + int * tempColumn = tempRow + numberRows; + int numberMasterRows=0; + for (int i=0;i(solver_); + ClpSimplex * tempModel = new ClpSimplex(solver->getModelPtr(), + numberMasterRows,tempRow, + numberMasterColumns,tempColumn); + // add convexity constraints + double * rhs = new double[numberBlocks_]; + for (int i=0;iaddRows(numberBlocks_,rhs,rhs,NULL,NULL,NULL); + delete [] rhs; + OsiClpSolverInterface * clpSolver = new OsiClpSolverInterface(tempModel,true); + clpSolver->getModelPtr()->setDualObjectiveLimit(COIN_DBL_MAX); + dwSolver_ = clpSolver; + sprintf(dwPrint,"DW model has %d master rows, %d master columns and %d convexity rows", + numberMasterRows,numberMasterColumns,numberBlocks_); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << dwPrint + << CoinMessageEol; + // do master integers + for (int i=0;iisInteger(iColumn)) + dwSolver_->setInteger(i); + } + delete [] tempRow; +} + + diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicDW.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicDW.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicDW.hpp 1970-01-01 00:00:00.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicDW.hpp 2013-08-27 15:19:55.000000000 +0000 @@ -0,0 +1,309 @@ +// $Id: CbcHeuristicDW.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +#ifndef CbcHeuristicDW_H +#define CbcHeuristicDW_H + +#include "CbcHeuristic.hpp" + +/** + This is unlike the other heuristics in that it is very very compute intensive. + It tries to find a DW structure and use that + */ + +class CbcHeuristicDW : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicDW (); + + /* Constructor with model - assumed before cuts + */ + CbcHeuristicDW (CbcModel & model, int keepContinuous=0); + + /* Constructor with model - assumed before cuts + */ + CbcHeuristicDW (CbcModel & model, + int callBack(CbcHeuristicDW * currentHeuristic, + CbcModel * thisModel, + int whereFrom), + int keepContinuous=0); + + // Copy constructor + CbcHeuristicDW ( const CbcHeuristicDW &); + + // Destructor + ~CbcHeuristicDW (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicDW & operator=(const CbcHeuristicDW& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Induced Neighborhood Search + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /** Return number of blocks + <=0 - no usable structure */ + inline int numberBlocks() const + { return numberBlocks_;} + /// Pass in a solution + void passInSolution(const double * solution); + /// Pass in continuous solution + void passInContinuousSolution(const double * solution); + /** DW Proposal actions + fullDWEverySoOften - + 0 - off + k - every k times solution gets better + */ + void setProposalActions(int fullDWEverySoOften); + /// Objective value when whichDw created + double objectiveValueWhen(int whichDW) const; + /// Number of columns in DW + int numberColumnsDW(int whichDW) const; + /// Solver + inline OsiSolverInterface * solver() const + { return solver_;} + /// DW model (user must delete) + OsiSolverInterface * DWModel(int whichDW) const; + /// Best objective value + inline double bestObjective() const + { return bestObjective_;} + /// Best solution found so far + inline const double * bestSolution() const + { return bestSolution_;} + /// Continuous solution + inline const double * continuousSolution() const + { return continuousSolution_;} + /// Reduced costs of fixed solution + inline const double * fixedDj() const + { return fixedDj_;} + /// Objective at which DW updated + inline const double * objectiveDW() const + { return objectiveDW_;} + /// Number of times we have added to DW model + inline int numberDWTimes() const + { return numberDWTimes_;} + /// Number of columns in DW + inline const int * numberColumnsDW() const + { return numberColumnsDW_;} + /// Set number of passes + inline void setNumberPasses(int value) + { numberPasses_ = value;} + /// Set number of passes without better solution + inline void setNumberBadPasses(int value) + { numberBadPasses_ = value;} + /// Set number free integers needed (Base value) + inline void setNumberNeeded(int value) + { nNeededBase_ = value;} + /// Get number free integers needed (Base value) + inline int getNumberNeeded() const + {return nNeededBase_;} + /// Set number free integers needed (Current value) + inline void setCurrentNumberNeeded(int value) + { nNeeded_ = value;} + /// Get number free integers needed (Current value) + inline int getCurrentNumberNeeded() const + {return nNeeded_;} + /// Set number nodes (could be done in callback) (Base value) + inline void setNumberNodes(int value) + { nNodesBase_ = value;} + /// Get number nodes (could be done in callback) (Base value) + inline int getNumberNodes() const + {return nNodesBase_;} + /// Set number nodes (could be done in callback) (Current value) + inline void setCurrentNumberNodes(int value) + { nNodes_ = value;} + /// Get number nodes (could be done in callback) (Current value) + inline int getCurrentNumberNodes() const + {return nNodes_;} + /// Set target objective + inline void setTargetObjective(double value) + { targetObjective_ = value;} + /// Sets how often to do it + inline void setHowOften(int value) { + howOften_ = value; + } + /// Block for every row + inline const int * whichRowBlock() const + { return whichRowBlock_;} + /// Block for every column + inline const int * whichColumnBlock() const + { return whichColumnBlock_;} + /// Initial Lower bounds + inline double * initialLower() const + { return saveLower_;} + /// Initial Upper bounds + inline double * initialUpper() const + { return saveUpper_;} + /// Local integer arrays (each numberBlocks_ long) + inline int * intArrays() const + { return intArray_;} + /// Local double arrays (each numberBlocks_ long) + inline double * doubleArrays() const + { return doubleArray_;} + /// Phase of solution + inline int phase() const + { return phase_;} + /// Pass number + inline int pass() const + { return pass_;} + /// Which columns are in block + inline const int * columnsInBlock() const + { return columnsInBlock_;} + /// Starts for columnsInBlock + inline const int * startColumnBlock() const + { return startColumnBlock_;} + /// Number of integer variables in each block + inline const int * intsInBlock() const + { return intsInBlock_;} + /// Objective value (could also check validity) + double objectiveValue(const double * solution); +private: + /// Guts of copy + void gutsOfCopy(const CbcHeuristicDW & rhs); + /// Guts of delete + void gutsOfDelete(); + /// Set default values + void setDefaults(); + /// Find structure + void findStructure(); + /// Set up DW structure + void setupDWStructures(); + /// Add DW proposals + int addDW(const double * solution,int numberBlocksUsed, + const int * whichBlocks); +protected: + typedef int (*heuristicCallBack) (CbcHeuristicDW * ,CbcModel *, int) ; + // Data + /// Target objective + double targetObjective_; + /// Best objective value + double bestObjective_; + /// Objective value last time + double lastObjective_; + /** Call back + whereFrom - + 0 - after blocks found but before data setup + 1 - after blocks sorted but before used + 2 - just before normal branch and bound + 3 - after DW has been updated + 4 - if better solution found + 5 - every time a block might be used + next few for adjustment of nNeeded etc + 6 - complete search done - no solution + 7 - stopped on nodes - no improvement + 8 - improving (same as 4 but after nNeeded changed + Pointers to local data given by following pointers + */ + heuristicCallBack functionPointer_; + /// Local integer arrays (each numberBlocks_ long) + int * intArray_; + /// Local double arrays (each numberBlocks_ long) + double * doubleArray_; + /// Base solver + OsiSolverInterface * solver_; + /// DW solver + OsiSolverInterface * dwSolver_; + /// Best solution found so far + double * bestSolution_; + /// Continuous solution + double * continuousSolution_; + /// Reduced costs of fixed solution + double * fixedDj_; + /// Original lower bounds + double * saveLower_; + /// Original Upper bounds + double * saveUpper_; + /// random numbers for master rows + double * random_; + /// Weights for each proposal + double * weights_; + /// Objective at which DW updated + double * objectiveDW_; + /// Number of columns in each DW + int * numberColumnsDW_; + /// Block for every row + int * whichRowBlock_; + /// Block for every column + int * whichColumnBlock_; + /// Block number for each proposal + int * dwBlock_; + /// Points back to master rows + int * backwardRow_; + /// Which rows are in blocke + int * rowsInBlock_; + /// Which columns are in block + int * columnsInBlock_; + /// Starts for rowsInBlock + int * startRowBlock_; + /// Starts for columnsInBlock + int * startColumnBlock_; + /// Number of integer variables in each block + int * intsInBlock_; + /// Bits set for 1 integers in each block + unsigned int * fingerPrint_; + /// Affinity each block has for other (will be triangular?) + unsigned short * affinity_; + /** DW Proposal actions + fullDWEverySoOften - + 0 - off + k - every k times solution gets better + */ + int fullDWEverySoOften_; + /// Number of passes + int numberPasses_; + /// How often to do (code can change) + int howOften_; + /// Current maximum number of DW proposals + int maximumDW_; + /// Number of DW proposals + int numberDW_; + /// Number of times we have added to DW model + int numberDWTimes_; + /// Number of unsigned ints needed for each block of fingerPrint + int sizeFingerPrint_; + /// Number of columns in master + int numberMasterColumns_; + /// Number of rows in master + int numberMasterRows_; + /// Number of blocks + int numberBlocks_; + /// Action on decomposition - 1 keep continuous, 0 don't + int keepContinuous_; + /// Phase of solution + int phase_; + /// Pass number + int pass_; + /// Base number of integers needed + int nNeededBase_; + /// Base number of nodes needed + int nNodesBase_; + /// Base number of integers needed + int nNeeded_; + /// Base number of nodes needed + int nNodes_; + /// Number of passes without better solution + int numberBadPasses_; + // 0 - fine, 1 can't be better, 2 max node + int solveState_; +}; + +#endif diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicFPump.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicFPump.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicFPump.cpp 2013-04-06 13:33:15.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicFPump.cpp 2015-05-05 12:53:14.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicFPump.cpp 1883 2013-04-06 13:33:15Z stefan $ */ +/* $Id: CbcHeuristicFPump.cpp 2186 2015-05-05 12:53:14Z stefan $ */ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -25,7 +25,9 @@ #include "CoinWarmStartBasis.hpp" #include "CoinTime.hpp" #include "CbcEventHandler.hpp" - +#ifdef SWITCH_VARIABLES +#include "CbcSimpleIntegerDynamicPseudoCost.hpp" +#endif // Default Constructor CbcHeuristicFPump::CbcHeuristicFPump() @@ -237,6 +239,10 @@ */ if (!when() || (when() == 1 && model_->phase() != 1)) return 0; // switched off +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif // See if at root node bool atRoot = model_->getNodeCount() == 0; int passNumber = model_->getCurrentPassNumber(); @@ -270,10 +276,10 @@ //good = (((passNumber-1)%(kOption-2))==0); good = false; } - if (passNumber != 1 && !good) + if (passNumber > 1 && !good) return 0; } else { - if (passNumber != 1) + if (passNumber > 1) return 0; } // loop round doing repeated pumps @@ -308,6 +314,9 @@ const double * lower = model_->solver()->getColLower(); const double * upper = model_->solver()->getColUpper(); bool doGeneral = (accumulate_ & 4) != 0; + int numberUnsatisfied=0; + double sumUnsatisfied=0.0; + const double * initialSolution = model_->solver()->getColSolution(); j = 0; /* Scan the objects, recording the columns and counting general integers. @@ -326,6 +335,11 @@ dynamic_cast (object); assert(integerObject || integerObject2); #endif + double value = initialSolution[iColumn]; + double nearest = floor(value + 0.5); + sumUnsatisfied += fabs(value - nearest); + if (fabs(value - nearest) > 1.0e-6) + numberUnsatisfied++; if (upper[iColumn] - lower[iColumn] > 1.000001) { general++; if (doGeneral) @@ -365,6 +379,11 @@ if (doGeneral) printf("DOing general with %d out of %d\n", general, numberIntegers); #endif + sprintf(pumpPrint, "Initial state - %d integers unsatisfied sum - %g", + numberUnsatisfied, sumUnsatisfied); + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << pumpPrint + << CoinMessageEol; /* This `closest solution' will satisfy integrality, but violate some other constraints? @@ -395,7 +414,12 @@ */ model_->solver()->resolve(); if (!model_->solver()->isProvenOptimal()) { - // presumably max time or some such + + delete[] integerVariable; + delete[] newSolution; + if (closestSolution) + delete[] closestSolution; + return 0; } numRuns_++; @@ -573,11 +597,28 @@ } // if cutoff exists then add constraint bool useCutoff = (fabs(cutoff) < 1.0e20 && (fakeCutoff_ != COIN_DBL_MAX || numberTries > 1)); + bool tryOneClosePass=fakeCutoff_getObjValue(); // but there may be a close one if (firstCutoff < 2.0*solutionValue && numberTries == 1 && CoinMin(cutoff, fakeCutoff_) < 1.0e20) useCutoff = true; - if (useCutoff) { + if (useCutoff || tryOneClosePass) { double rhs = CoinMin(cutoff, fakeCutoff_); + if (tryOneClosePass) { + // If way off then .05 + if (fakeCutoff_<=-1.0e100) { + // use value as percentage - so 100==0.0, 101==1.0 etc + // probably something like pow I could use but ... + double fraction = 0.0; + while (fakeCutoff_<-1.01e100) { + fakeCutoff_ *= 0.1; + fraction += 0.01; + } + rhs = solver->getObjValue()+fraction*fabs(solver->getObjValue()); + } else { + rhs = 2.0*solver->getObjValue()-fakeCutoff_; // flip difference + } + fakeCutoff_=COIN_DBL_MAX; + } const double * objective = solver->getObjCoefficients(); int numberColumns = solver->getNumCols(); int * which = new int[numberColumns]; @@ -828,6 +869,109 @@ newSolutionValue = saveValue; if (returnCode && newSolutionValue < saveValue) numberBandBsolutions++; + } else if (numberColumns>numberIntegersOrig) { + // relax continuous + bool takeHint; + OsiHintStrength strength; + solver->getHintParam(OsiDoDualInResolve, takeHint, strength); + //solver->setHintParam(OsiDoReducePrint, false, OsiHintTry); + solver->setHintParam(OsiDoDualInResolve, false, OsiHintDo); + //solver->setHintParam(OsiDoScale, false, OsiHintDo); + solver->resolve(); + solver->setHintParam(OsiDoDualInResolve, takeHint, strength); + if (solver->isProvenOptimal()) { + memcpy(newSolution,solver->getColSolution(), + numberColumns*sizeof(double)); + newSolutionValue = -saveOffset; + for ( i = 0 ; i < numberColumns ; i++ ) { + newSolutionValue += saveObjective[i] * newSolution[i]; + } + newSolutionValue *= direction; + sprintf(pumpPrint, "Relaxing continuous gives %g", newSolutionValue); + //#define DEBUG_BEST +#ifdef DEBUG_BEST + { + int numberColumns=solver->getNumCols(); + FILE * fp = fopen("solution.data2","wb"); + printf("Solution data on file solution.data2\n"); + size_t numberWritten; + numberWritten=fwrite(&numberColumns,sizeof(int),1,fp); + assert (numberWritten==1); + numberWritten=fwrite(&newSolutionValue,sizeof(double),1,fp); + assert (numberWritten==1); + numberWritten=fwrite(newSolution,sizeof(double),numberColumns,fp); + assert (numberWritten==numberColumns); + fclose(fp); + const double * rowLower = solver->getRowLower(); + const double * rowUpper = solver->getRowUpper(); + const double * columnLower = solver->getColLower(); + const double * columnUpper = solver->getColUpper(); + int numberRows = solver->getNumRows() ; + double *rowActivity = new double[numberRows] ; + memset(rowActivity, 0, numberRows*sizeof(double)) ; + const double * element = solver->getMatrixByCol()->getElements(); + const int * row = solver->getMatrixByCol()->getIndices(); + const CoinBigIndex * columnStart = solver->getMatrixByCol()->getVectorStarts(); + const int * columnLength = solver->getMatrixByCol()->getVectorLengths(); + double largestAway=0.0; + int away=-1; + double saveOffset; + solver->getDblParam(OsiObjOffset, saveOffset); + double newSolutionValue = -saveOffset; + const double * objective = solver->getObjCoefficients(); + for ( int iColumn=0 ; iColumnisInteger(iColumn)) { + double intValue = floor(value+0.5); + if (fabs(value-intValue)>largestAway) { + largestAway=fabs(value-intValue); + away=iColumn; + } + } + } + printf("Largest away from int at column %d was %g - obj %g\n",away, + largestAway,newSolutionValue); + double largestInfeasibility=0.0; + for (int i = 0 ; i < numberRows ; i++) { +#if 0 //def CLP_INVESTIGATE + double inf; + inf = rowLower[i] - rowActivity[i]; + if (inf > primalTolerance) + printf("Row %d inf %g sum %g %g <= %g <= %g\n", + i, inf, rowSum[i], rowLower[i], rowActivity[i], rowUpper[i]); + inf = rowActivity[i] - rowUpper[i]; + if (inf > primalTolerance) + printf("Row %d inf %g %g <= %g <= %g\n", + i, inf, rowLower[i], rowActivity[i], rowUpper[i]); +#endif + double infeasibility = CoinMax(rowActivity[i]-rowUpper[i], + rowLower[i]-rowActivity[i]); + if (infeasibility>largestInfeasibility) { + largestInfeasibility = infeasibility; + printf("Binf of %g on row %d\n", + infeasibility,i); + } + } + delete [] rowActivity ; + printf("Blargest infeasibility is %g - obj %g\n", largestInfeasibility,newSolutionValue); + } +#endif + } else { + sprintf(pumpPrint,"Infeasible when relaxing continuous!\n"); + } + model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) + << pumpPrint + << CoinMessageEol; } } if (returnCode && newSolutionValue < saveValue) { @@ -990,6 +1134,16 @@ double costValue = (1.0 - scaleFactor) * solver->getObjSense(); int numberChanged = 0; const double * oldObjective = solver->getObjCoefficients(); + bool fixOnesAtBound=false; + if (tryOneClosePass&&numberPasses==2) { + // take off + tryOneClosePass=false; + int n=solver->getNumRows()-1; + double rhs = solver->getRowUpper()[n]; + solver->setRowUpper(n,rhs+1.0e15); + useRhs+=1.0e15; + fixOnesAtBound=true; + } for (i = 0; i < numberColumns; i++) { // below so we can keep original code and allow for objective int iColumn = i; @@ -1008,11 +1162,15 @@ } double newValue = 0.0; if (newSolution[iColumn] < lower[iColumn] + primalTolerance) { - newValue = costValue + scaleFactor * saveObjective[iColumn]; + newValue = costValue + scaleFactor * saveObjective[iColumn]; + if (fixOnesAtBound) + newValue = 100.0*costValue; } else { - if (newSolution[iColumn] > upper[iColumn] - primalTolerance) { - newValue = -costValue + scaleFactor * saveObjective[iColumn]; - } + if (newSolution[iColumn] > upper[iColumn] - primalTolerance) { + newValue = -costValue + scaleFactor * saveObjective[iColumn]; + if (fixOnesAtBound) + newValue = -100.0*costValue; + } } #ifdef RAND_RAND if (!offRandom) @@ -1235,15 +1393,16 @@ newNumberInfeas = 0; { const double * newSolution = solver->getColSolution(); - for ( i = 0 ; i < numberColumns ; i++ ) { - if (solver->isInteger(i)) { - double value = newSolution[i]; + for (int iColumn = 0 ; iColumn < numberColumns ; iColumn++ ) { + if (solver->isInteger(iColumn)) { + double value = newSolution[iColumn]; double nearest = floor(value + 0.5); newSumInfeas += fabs(value - nearest); - if (fabs(value - nearest) > 1.0e-6) + if (fabs(value - nearest) > 1.0e-6) { newNumberInfeas++; + } } - newTrueSolutionValue += saveObjective[i] * newSolution[i]; + newTrueSolutionValue += saveObjective[iColumn] * newSolution[iColumn]; } newTrueSolutionValue *= direction; if (numberPasses == 1 && secondPassOpt) { @@ -1545,6 +1704,36 @@ model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) << pumpPrint << CoinMessageEol; + CbcEventHandler *eventHandler = model_->getEventHandler() ; + if (eventHandler) { + typedef struct { + double newSumInfeas; + double trueSolutionValue; + double spareDouble[2]; + OsiSolverInterface * solver; + void * sparePointer[2]; + int numberPasses; + int totalNumberPasses; + int numberInfeas; + int numberIterations; + int spareInt[3]; + } HeurPass; + HeurPass temp; + temp.solver=solver; + temp.newSumInfeas = newSumInfeas; + temp.trueSolutionValue = newTrueSolutionValue; + temp.numberPasses=numberPasses; + temp.totalNumberPasses=totalNumberPasses; + temp.numberInfeas=newNumberInfeas; + temp.numberIterations=numberIterations; + CbcEventHandler::CbcAction status = + eventHandler->event(CbcEventHandler::heuristicPass, + &temp); + if (status==CbcEventHandler::killSolution) { + exitAll = true; + break; + } + } if (closestSolution && solver->getObjValue() < closestObjectiveValue) { int i; const double * objective = solver->getObjCoefficients(); @@ -1937,7 +2126,11 @@ //simplex->writeMps("test.mps",2,1); if (nFixed*3 > numberColumns*2) simplex->allSlackBasis(); // may as well go from all slack + int logLevel=simplex->logLevel(); + if (logLevel<=1) + simplex->setLogLevel(0); simplex->primal(1); + simplex->setLogLevel(logLevel); clpSolver->setWarmStart(NULL); } #endif @@ -1945,7 +2138,7 @@ if (newSolver->isProvenOptimal()) { double value = newSolver->getObjValue() * newSolver->getObjSense(); if (value < newSolutionValue) { - //newSolver->writeMps("query","mps"); + //newSolver->writeMpsNative("query.mps", NULL, NULL, 2); #ifdef JJF_ZERO { double saveOffset; @@ -2015,6 +2208,7 @@ model_->messageHandler()->message(CBC_FPUMP1, model_->messages()) << pumpPrint << CoinMessageEol; + //newSolver->writeMpsNative("query2.mps", NULL, NULL, 2); newSolutionValue = value; memcpy(betterSolution, newSolver->getColSolution(), numberColumns*sizeof(double)); gotSolution = true; @@ -2363,14 +2557,18 @@ const double * columnLower = solver->getColLower(); const double * columnUpper = solver->getColUpper(); // Check if valid with current solution (allow for 0.99999999s) + double newSumInfeas = 0.0; + int newNumberInfeas = 0; for (i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = solution[iColumn]; double round = floor(value + 0.5); - if (fabs(value - round) > primalTolerance) - break; + if (fabs(value - round) > primalTolerance) { + newSumInfeas += fabs(value-round); + newNumberInfeas++; + } } - if (i == numberIntegers) { + if (!newNumberInfeas) { // may be able to use solution even if 0.99999's double * saveLower = CoinCopyOfArray(columnLower, numberColumns); double * saveUpper = CoinCopyOfArray(columnUpper, numberColumns); diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicGreedy.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicGreedy.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicGreedy.cpp 2013-04-06 20:52:59.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicGreedy.cpp 2015-10-06 16:10:41.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicGreedy.cpp 1888 2013-04-06 20:52:59Z stefan $ */ +/* $Id: CbcHeuristicGreedy.cpp 2217 2015-10-06 16:10:41Z forrest $ */ // Copyright (C) 2005, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -117,10 +117,14 @@ return 0; // switched off if (model_->getNodeCount() > numberTimes_) return 0; +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif // See if at root node bool atRoot = model_->getNodeCount() == 0; int passNumber = model_->getCurrentPassNumber(); - if (atRoot && passNumber != 1) + if (atRoot && passNumber > 1) return 0; OsiSolverInterface * solver = model_->solver(); const double * columnLower = solver->getColLower(); @@ -536,7 +540,7 @@ // See if at root node bool atRoot = model_->getNodeCount() == 0; int passNumber = model_->getCurrentPassNumber(); - if (atRoot && passNumber != 1) + if (atRoot && passNumber > 1) return 0; OsiSolverInterface * solver = model_->solver(); const double * columnLower = solver->getColLower(); @@ -972,7 +976,7 @@ // See if at root node bool atRoot = model_->getNodeCount() == 0; int passNumber = model_->getCurrentPassNumber(); - if (atRoot && passNumber != 1) + if (atRoot && passNumber > 1) return 0; OsiSolverInterface * solver = model_->solver(); int numberColumns = solver->getNumCols(); @@ -991,6 +995,8 @@ const CoinBigIndex * columnStart = matrix_.getVectorStarts(); const int * columnLength = matrix_.getVectorLengths(); int * sosRow = new int [numberColumns]; + char * sos = new char [numberRows]; + memset(sos,'a',numberRows); int nonSOS=0; // If bit set then use current if ((algorithm_&1)!=0) { @@ -1013,8 +1019,12 @@ good = false; } else if (rowUpper[iRow] < 1.0e10) { rhs[iRow]=rowUpper[iRow]; + if (rhs[iRow]<0) + sos[iRow]=0; // can't be SOS } else { rhs[iRow]=rowLower[iRow]; + if (rhs[iRow]<0) + sos[iRow]=0; // can't be SOS } } for (int iColumn = 0; iColumn < numberColumns; iColumn++) { @@ -1032,7 +1042,7 @@ if (element[j] < 0.0) good = false; int iRow = row[j]; - if (rhs[iRow]==-1.0) { + if (rhs[iRow]==-1.0 && sos[iRow] == 'a') { if (element[j] != 1.0) good = false; iSOS=iRow; @@ -1048,6 +1058,7 @@ if (!good) { delete [] sosRow; delete [] rhs; + delete [] sos; setWhen(0); // switch off return 0; } @@ -1087,21 +1098,23 @@ } } double offset2 = 0.0; - char * sos = new char [numberRows]; for (int iRow = 0;iRow < numberRows; iRow++) { - sos[iRow]=0; - if (rhs[iRow]<0.0) { - sos[iRow]=1; - rhs[iRow]=1.0; - } else if (rhs[iRow] != rowUpper[iRow]) { - // G row - sos[iRow]=-1; - } - if( slackCost[iRow] == 1.0e30) { - slackCost[iRow]=0.0; - } else { - offset2 += slackCost[iRow]; - sos[iRow] = 2; + if (sos[iRow]=='a') { + // row is possible + sos[iRow]=0; + if (rhs[iRow]<0.0) { + sos[iRow]=1; + rhs[iRow]=1.0; + } else if (rhs[iRow] != rowUpper[iRow]) { + // G row + sos[iRow]=-1; + } + if( slackCost[iRow] == 1.0e30) { + slackCost[iRow]=0.0; + } else { + offset2 += slackCost[iRow]; + sos[iRow] = 2; + } } } for (int iColumn = 0; iColumn < numberColumns; iColumn++) { diff -Nru coinor-cbc-2.8.12/src/CbcHeuristic.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristic.hpp --- coinor-cbc-2.8.12/src/CbcHeuristic.hpp 2013-04-06 13:33:15.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristic.hpp 2014-11-18 11:15:36.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristic.hpp 1883 2013-04-06 13:33:15Z stefan $ */ +/* $Id: CbcHeuristic.hpp 2094 2014-11-18 11:15:36Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -169,6 +169,7 @@ try keep halving distance to known cutoff 16 bit - needs new solution to run 1024 bit - stop all heuristics on max time + 65536 bit and above used for temporary communication */ inline int switches() const { return switches_; @@ -331,7 +332,7 @@ std::string heuristicName_; /// How often to do (code can change) - int howOften_; + mutable int howOften_; /// How much to increase how often double decayFactor_; /** Switches (does not apply equally to all heuristics) @@ -458,6 +459,15 @@ void setSeed(int value) { seed_ = value; } + /** Check whether the heuristic should run at all + 0 - before cuts at root node (or from doHeuristics) + 1 - during cuts at root + 2 - after root node cuts + 3 - after cuts at other nodes + 4 - during cuts at other nodes + 8 added if previous heuristic in loop found solution + */ + virtual bool shouldHeurRun(int whereFrom); protected: // Data diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicLocal.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicLocal.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicLocal.cpp 2013-01-16 18:41:25.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicLocal.cpp 2015-01-05 13:11:11.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicLocal.cpp 1839 2013-01-16 18:41:25Z forrest $ */ +/* $Id: CbcHeuristicLocal.cpp 2105 2015-01-05 13:11:11Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -372,6 +372,10 @@ numberSolutions_ = model_->getSolutionCount(); if (nodeCountgetNumCols() > 10000 && model_->getNumCols() > - 10*model_->getNumRows()) + 10*model_->getNumRows()&&swap<10) tryHeuristic = false; /* Try the inc/dec heuristic? @@ -561,8 +565,30 @@ double bestChange = 0.0; // maybe just do 1000 int maxIntegers = numberIntegers; - if (((swap/10) &1) != 0) { - maxIntegers = CoinMin(1000,numberIntegers); + // stop if too many goes + int maxTries=COIN_INT_MAX; + // integerVariable may be randomized copy! + int * integerVariable = + CoinCopyOfArray(model_->integerVariable(),numberIntegers); + if (swap>9 && numberIntegers>500) { + int type=swap/10; + if (type==1) { + // reduce + maxIntegers = CoinMin(1000,numberIntegers); + } else if (type==2) { + // reduce even more + maxTries=100000; + maxIntegers = CoinMin(500,numberIntegers); + } else if (type>2) { + assert (type<10); + int totals[7]={1000,500,100,50,50,50,50}; + maxIntegers=CoinMin(totals[type-3],numberIntegers); + double * weight = new double[numberIntegers]; + for (int i=0;irandomNumberGenerator()->randomDouble(); + } + CoinSort_2(weight,weight+numberIntegers,integerVariable); + } } /* Outer loop to walk integer variables. Call the current variable x. At the @@ -617,6 +643,9 @@ */ // try down for (k = i + 1; k < endInner; k++) { + if (!maxTries) + break; + maxTries--; if ((way[k]&1) != 0) { // try down if (-objectiveCoefficient - cost[k] < bestChange) { @@ -707,6 +736,8 @@ } // try up for (k = i + 1; k < endInner; k++) { + if (!maxTries) + break; if ((way[k]&1) != 0) { // try down if (objectiveCoefficient - cost[k] < bestChange) { @@ -892,6 +923,8 @@ numberBad, sumBad)); } } + // This is just a copy! + delete [] integerVariable; } /* We're done. Clean up. @@ -935,6 +968,7 @@ CbcHeuristicProximity::CbcHeuristicProximity() : CbcHeuristic() { + increment_ = 0.01; feasibilityPump_ = NULL; numberSolutions_ = 0; used_ = NULL; @@ -947,6 +981,7 @@ CbcHeuristicProximity::CbcHeuristicProximity(CbcModel & model) : CbcHeuristic(model) { + increment_ = 0.01; feasibilityPump_ = NULL; numberSolutions_ = 0; lastRunDeep_ = -1000000; @@ -986,6 +1021,7 @@ CbcHeuristic(rhs), numberSolutions_(rhs.numberSolutions_) { + increment_ = rhs.increment_; feasibilityPump_ = NULL; if (model_ && rhs.used_) { int numberColumns = model_->solver()->getNumCols(); @@ -1003,6 +1039,7 @@ { if (this != &rhs) { CbcHeuristic::operator=(rhs); + increment_ = rhs.increment_; numberSolutions_ = rhs.numberSolutions_; delete [] used_; delete feasibilityPump_; @@ -1094,8 +1131,9 @@ } double cutoff=model_->getCutoff(); assert (cutoff<1.0e20); - if (model_->getCutoffIncrement()<1.0e-4) - cutoff -= 0.01; + if (model_->getCutoffIncrement()<1.0e-4) { + cutoff -= increment_; + } double offset; newSolver->getDblParam(OsiObjOffset, offset); newSolver->setDblParam(OsiObjOffset, 0.0); @@ -1184,6 +1222,11 @@ sprintf(proxPrint,"Proximity search ran %d nodes (out of %d) - in new solution %d increased (%d), %d decreased (%d)", numberNodesDone_,numberNodes_, numberIncrease,sumIncrease,numberDecrease,sumDecrease); + if (!numberIncrease&&!numberDecrease) { + // somehow tolerances are such that we can slip through + // change for next time + increment_ += CoinMax(increment_,fabs(solutionValue+offset)*1.0e-10); + } } else { sprintf(proxPrint,"Proximity search ran %d nodes - no new solution", numberNodesDone_); @@ -1281,7 +1324,7 @@ // See if to do bool atRoot = model_->getNodeCount() == 0; int passNumber = model_->getCurrentPassNumber(); - if (!when() || (when() == 1 && model_->phase() != 1) || !atRoot || passNumber != 1) + if (!when() || (when() == 1 && model_->phase() != 1) || !atRoot || passNumber > 1) return 0; // switched off // Don't do if it was this heuristic which found solution! if (this == model_->lastHeuristic()) diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicLocal.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicLocal.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicLocal.hpp 2012-11-21 09:38:56.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicLocal.hpp 2013-07-21 09:05:45.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicLocal.hpp 1802 2012-11-21 09:38:56Z forrest $ */ +/* $Id: CbcHeuristicLocal.hpp 1943 2013-07-21 09:05:45Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -124,7 +124,9 @@ */ virtual int solution(double & objectiveValue, double * newSolution); - + /// Set extra increment + inline void setIncrement(double value) + { increment_ = value;} /// Used array so we can set inline int * used() const { return used_; @@ -132,9 +134,11 @@ protected: // Data - // Copy of Feasibility pump + /// Increment to use if no change + double increment_; + /// Copy of Feasibility pump CbcHeuristicFPump * feasibilityPump_; - // Number of solutions so we only do after new solution + /// Number of solutions so we only do after new solution int numberSolutions_; /// Whether a variable has been in a solution (also when) int * used_; diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicPivotAndFix.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicPivotAndFix.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicPivotAndFix.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicPivotAndFix.cpp 2014-11-18 11:15:36.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicPivotAndFix.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicPivotAndFix.cpp 2094 2014-11-18 11:15:36Z forrest $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -91,6 +91,10 @@ numCouldRun_++; // Todo: Ask JJHF what this for. std::cout << "Entering Pivot-and-Fix Heuristic" << std::endl; +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif #ifdef FORNOW std::cout << "Lucky you! You're in the Pivot-and-Fix Heuristic" << std::endl; // The struct should be moved to member data diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicPivotAndFix.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicPivotAndFix.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicPivotAndFix.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicPivotAndFix.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicPivotAndFix.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicPivotAndFix.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicRandRound.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicRandRound.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicRandRound.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicRandRound.cpp 2014-11-18 11:15:36.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicRandRound.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicRandRound.cpp 2094 2014-11-18 11:15:36Z forrest $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -107,7 +107,7 @@ bool atRoot = model_->getNodeCount() == 0; int passNumber = model_->getCurrentPassNumber(); // Just do once - if (!atRoot || passNumber != 1) { + if (!atRoot || passNumber > 1) { // std::cout << "Leaving the Randomized Rounding Heuristic" << std::endl; return 0; } @@ -123,6 +123,10 @@ double start = CoinCpuTime(); numCouldRun_++; // +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif // Todo: Ask JJHF what "number of times // the heuristic could run" means. diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicRandRound.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicRandRound.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicRandRound.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicRandRound.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicRandRound.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicRandRound.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2008, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicRENS.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicRENS.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicRENS.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicRENS.cpp 2015-01-05 13:11:11.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcHeuristicRENS.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcHeuristicRENS.cpp 2105 2015-01-05 13:11:11Z forrest $ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -32,7 +32,6 @@ rensType_ = 0; whereFrom_ = 256 + 1; } - // Constructor with model - assumed before cuts CbcHeuristicRENS::CbcHeuristicRENS(CbcModel & model) @@ -86,9 +85,26 @@ { int returnCode = 0; const double * bestSolution = model_->bestSolution(); + bool returnNow=false; if ((numberTries_&&(rensType_&16)==0) || numberTries_>1 || (when() < 2 && bestSolution)) + returnNow=true;; + // If 32 bit set then do once with bestSolution + if ((rensType_&32)!=0&&bestSolution) + returnNow=false; + if (returnNow) return 0; + // switch off next time if bestSolution + if (bestSolution) { + if ((rensType_&32)!=0) + rensType_ &= ~32; // switch off but leave bestSolution + else + bestSolution=NULL; // null bestSolution so won't use + } numberTries_++; +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif double saveFractionSmall=fractionSmall_; OsiSolverInterface * solver = model_->solver(); @@ -735,7 +751,42 @@ int numberTightened = 0; int numberAtBound = 0; int numberContinuous = numberColumns - numberIntegers; - + /* + 0 - allow fixing + 1 - don't allow fixing + */ + char * marked = new char [numberColumns]; + memset(marked,0,numberColumns); + if (bestSolution) { + for (i = 0; i < numberIntegers; i++) { + int iColumn = integerVariable[i]; + double value = currentSolution[iColumn]; + double lower = colLower[iColumn]; + double upper = colUpper[iColumn]; + value = CoinMax(value, lower); + value = CoinMin(value, upper); + if (fabs(bestSolution[iColumn]-value)>0.999) + marked[iColumn]=1; + } + } + if ((rensType_&(64|128))!=0&&model_->objects()) { + int lowPriority=-COIN_INT_MAX; + int highPriority=COIN_INT_MAX; + for (i = 0; i < numberIntegers; i++) { + int priority=model_->priority(i); + lowPriority=CoinMax(lowPriority,priority); + highPriority=CoinMin(highPriority,priority); + } + if (highPrioritypriority(i); + if (priority==keepPriority) + marked[iColumn]=1; + } + } + } for (i = 0; i < numberIntegers; i++) { int iColumn = integerVariable[i]; double value = currentSolution[iColumn]; @@ -744,10 +795,14 @@ value = CoinMax(value, lower); value = CoinMin(value, upper); double djValue=dj[iColumn]*direction; + bool dontFix=marked[iColumn]!=0; #define RENS_FIX_ONLY_LOWER #ifndef RENS_FIX_ONLY_LOWER if (fabs(value - floor(value + 0.5)) < 1.0e-8) { value = floor(value + 0.5); + if (dontFix) { + continue; + } if (value == lower || value == upper) numberAtBound++; newSolver->setColLower(iColumn, value); @@ -762,6 +817,9 @@ if (fabs(value - floor(value + 0.5)) < 1.0e-8 && floor(value + 0.5) == lower && djValue > djTolerance ) { + if (dontFix) { + continue; + } value = floor(value + 0.5); numberAtBound++; newSolver->setColLower(iColumn, value); @@ -771,6 +829,9 @@ floor(value + 0.5) == upper && -djValue > djTolerance && (djTolerance > 0.0||type==2)) { value = floor(value + 0.5); + if (dontFix) { + continue; + } numberAtBound++; newSolver->setColLower(iColumn, value); newSolver->setColUpper(iColumn, value); @@ -793,6 +854,7 @@ } #endif } + delete [] marked; delete [] dj; if (numberFixed > numberIntegers / 5) { if ( numberFixed < numberColumns / 5) { diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicRENS.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicRENS.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicRENS.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicRENS.hpp 2015-01-05 13:11:11.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcHeuristicRENS.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcHeuristicRENS.hpp 2105 2015-01-05 13:11:11Z forrest $ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -66,6 +66,9 @@ 2 - fix at UB as well 3 - fix on 0.01*average dj add 16 to allow two tries + 32 - if solution exists use to keep more variables + 64 - if priorities keep high priority + 128 - if priorities keep low priority */ int rensType_; }; diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicRINS.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicRINS.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicRINS.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicRINS.cpp 2014-11-18 11:15:36.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicRINS.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicRINS.cpp 2094 2014-11-18 11:15:36Z forrest $ */ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -157,6 +157,10 @@ const double * bestSolution = model_->bestSolution(); if (!bestSolution) return 0; // No solution found yet +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif if (numberSolutions_ < model_->getSolutionCount()) { // new solution - add info numberSolutions_ = model_->getSolutionCount(); @@ -197,7 +201,7 @@ if (howOften_ >= 100 && numberNodes >= lastNode_ + 2*howOften_) { numberNodes = howOften_; } - if ((numberNodes % howOften_) == 0 && (model_->getCurrentPassNumber() == 1 || + if ((numberNodes % howOften_) == 0 && (model_->getCurrentPassNumber() <= 1 || model_->getCurrentPassNumber() == 999999)) { lastNode_ = model_->getNodeCount(); OsiSolverInterface * solver = model_->solver(); @@ -324,7 +328,20 @@ } #endif } - //printf("%d integers have same value\n",nFix); + if (solutionValue==-COIN_DBL_MAX) { + // return fixings in betterSolution + const double * colLower = newSolver->getColLower(); + const double * colUpper = newSolver->getColUpper(); + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + if (colLower[iColumn]==colUpper[iColumn]) + betterSolution[iColumn]=colLower[iColumn]; + else + betterSolution[iColumn]=COIN_DBL_MAX; + } + delete newSolver; + return 0; + } + //printf("RINS %d integers have same value\n",nFix); returnCode = smallBranchAndBound(newSolver, numberNodes_, betterSolution, solutionValue, model_->getCutoff(), "CbcHeuristicRINS"); if (returnCode < 0) { diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicRINS.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicRINS.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicRINS.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicRINS.hpp 2013-08-17 15:28:45.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcHeuristicRINS.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcHeuristicRINS.hpp 1956 2013-08-17 15:28:45Z forrest $ */ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -71,6 +71,10 @@ inline void setLastNode(int value) { lastNode_ = value; } + /// Resets number of solutions + inline void setSolutionCount(int value) { + numberSolutions_ = value; + } protected: // Data diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicVND.cpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicVND.cpp --- coinor-cbc-2.8.12/src/CbcHeuristicVND.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicVND.cpp 2014-11-18 11:15:36.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcHeuristicVND.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcHeuristicVND.cpp 2094 2014-11-18 11:15:36Z forrest $ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -167,6 +167,10 @@ const double * bestSolution = model_->bestSolution(); if (!bestSolution) return 0; // No solution found yet +#ifdef HEURISTIC_INFORM + printf("Entering heuristic %s - nRuns %d numCould %d when %d\n", + heuristicName(),numRuns_,numCouldRun_,when_); +#endif if (numberSolutions_ < model_->getSolutionCount()) { // new solution - add info numberSolutions_ = model_->getSolutionCount(); @@ -198,7 +202,7 @@ if ((numberNodes > 40 && numberNodes <= 50) || (numberNodes > 90 && numberNodes < 100)) numberNodes = howOften_; } - if ((numberNodes % howOften_) == 0 && (model_->getCurrentPassNumber() == 1 || + if ((numberNodes % howOften_) == 0 && (model_->getCurrentPassNumber() <= 1 || model_->getCurrentPassNumber() == 999999)) { lastNode_ = model_->getNodeCount(); OsiSolverInterface * solver = model_->solver(); diff -Nru coinor-cbc-2.8.12/src/CbcHeuristicVND.hpp coinor-cbc-2.9.9+repack1/src/CbcHeuristicVND.hpp --- coinor-cbc-2.8.12/src/CbcHeuristicVND.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcHeuristicVND.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcHeuristicVND.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcHeuristicVND.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcLinked.cpp coinor-cbc-2.9.9+repack1/src/CbcLinked.cpp --- coinor-cbc-2.8.12/src/CbcLinked.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcLinked.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcLinked.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcLinked.cpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcLinked.hpp coinor-cbc-2.9.9+repack1/src/CbcLinked.hpp --- coinor-cbc-2.8.12/src/CbcLinked.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcLinked.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcLinked.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcLinked.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcLinkedUtils.cpp coinor-cbc-2.9.9+repack1/src/CbcLinkedUtils.cpp --- coinor-cbc-2.8.12/src/CbcLinkedUtils.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcLinkedUtils.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -2,7 +2,7 @@ // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). -/* $Id: CbcLinkedUtils.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcLinkedUtils.cpp 1899 2013-04-09 18:12:08Z stefan $ */ /*! \file CbcAugmentClpSimplex.cpp \brief Hooks to Ampl (for CbcLinked) diff -Nru coinor-cbc-2.8.12/src/CbcMessage.cpp coinor-cbc-2.9.9+repack1/src/CbcMessage.cpp --- coinor-cbc-2.8.12/src/CbcMessage.cpp 2013-04-26 16:21:11.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcMessage.cpp 2014-11-18 11:15:36.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcMessage.cpp 1916 2013-04-26 16:21:11Z tkr $ */ +/* $Id: CbcMessage.cpp 2094 2014-11-18 11:15:36Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -53,11 +53,11 @@ {CBC_UNBOUNDED, 34, 1, "The LP relaxation is unbounded!"}, {CBC_OTHER_STATS, 35, 1, "Maximum depth %d, %g variables fixed on reduced cost"}, {CBC_HEURISTICS_OFF, 36, 1, "Heuristics switched off as %d branching objects are of wrong type"}, - {CBC_STATUS2, 37, 1, "%d nodes, %d on tree, best %g - possible %g depth %d unsat %d its %d (%.2f seconds)"}, + {CBC_STATUS2, 37, 1, "%d nodes, %d on tree, best %g - possible %g depth %d unsat %d value %g its %d (%.2f seconds)"}, {CBC_FPUMP1, 38, 1, "%s"}, {CBC_FPUMP2, 39, 2, "%s"}, - {CBC_STATUS3, 40, 1, "%d nodes (+%d), %d on tree, best %g - possible %g depth %d unsat %d its %d (+%d) (%.2f seconds)"}, - {CBC_OTHER_STATS2, 41, 1, "Maximum depth %d, %g variables fixed on reduced cost (%d nodes in complete fathoming taking %d iterations)"}, + {CBC_STATUS3, 40, 1, "%d nodes (+%d/%d), %d on tree, best %g - possible %g depth %d unsat %d its %d (+%d) (%.2f seconds)"}, + {CBC_OTHER_STATS2, 41, 1, "Maximum depth %d, %g variables fixed on reduced cost (complete fathoming %d times, %d nodes taking %d iterations)"}, {CBC_RELAXED1, 42, 1, "Possible objective of %.18g but variable %d is %g from integer value, integer tolerance %g"}, {CBC_RELAXED2, 43, 2, "Possible objective of %.18g but had to fudge solution with tolerance of %g - check scaling of problem?"}, {CBC_RESTART, 44, 1, "Reduced cost fixing - %d rows, %d columns - restarting search"}, diff -Nru coinor-cbc-2.8.12/src/CbcMipStartIO.cpp coinor-cbc-2.9.9+repack1/src/CbcMipStartIO.cpp --- coinor-cbc-2.8.12/src/CbcMipStartIO.cpp 2014-03-07 16:57:49.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcMipStartIO.cpp 2015-05-05 13:04:34.000000000 +0000 @@ -23,7 +23,7 @@ const size_t l = strlen(str); for ( size_t i=0 ; imessageHandler()->message(CBC_GENERAL, model->messages()) - << printLine << CoinMessageEol; + model->messageHandler()->message(CBC_GENERAL, model->messages()) << printLine << CoinMessageEol; continue; } if (!isNumericStr(col[2])) { sprintf( printLine, "Reading: %s, line %d - Third column in mipstart file should be numeric, ignoring.", fileName, nLine ); - model->messageHandler()->message(CBC_GENERAL, model->messages()) - << printLine << CoinMessageEol; + model->messageHandler()->message(CBC_GENERAL, model->messages()) << printLine << CoinMessageEol; continue; } - //int idx = atoi( col[0] ); char *name = col[1]; double value = atof( col[2] ); - //double obj = 0.0; -// if (nread >= 4) -// obj = atof( col[3] ); colValues.push_back( pair(string(name),value) ); } } if (colValues.size()) { - sprintf( printLine,"mipstart values read for %d variables.", (int)colValues.size()); - model->messageHandler()->message(CBC_GENERAL, model->messages()) - << printLine << CoinMessageEol; + sprintf( printLine,"MIPStart values read for %d variables.", static_cast(colValues.size()) ); + model->messageHandler()->message(CBC_GENERAL, model->messages()) << printLine << CoinMessageEol; if (colValues.size()getNumCols()) { - int numberColumns = model->getNumCols(); - OsiSolverInterface * solver = model->solver(); - vector< pair< string, double > > fullValues; - /* for fast search of column names */ - map< string, int > colIdx; - for (int i=0;i(solver->getColName(i),0.0) ); - colIdx[solver->getColName(i)] = i; - } - for ( int i=0 ; (i<(int)colValues.size()) ; ++i ) - { - map< string, int >::const_iterator mIt = colIdx.find( colValues[i].first ); - if ( mIt != colIdx.end() ) { - const int idx = mIt->second; - double v = colValues[i].second; - fullValues[idx].second=v; - } - } - colValues=fullValues; + int numberColumns = model->getNumCols(); + OsiSolverInterface *solver = model->solver(); + vector< pair< string, double > > fullValues; + /* for fast search of column names */ + map< string, int > colIdx; + for (int i=0;i(solver->getColName(i),0.0) ); + colIdx[solver->getColName(i)] = i; + } + for ( int i=0 ; (i(colValues.size())) ; ++i ) { + map< string, int >::const_iterator mIt = colIdx.find( colValues[i].first ); + if ( mIt != colIdx.end() ) { + const int idx = mIt->second; + double v = colValues[i].second; + fullValues[idx].second=v; + } + } + colValues=fullValues; } - } else - { + } + else { sprintf( printLine, "No mipstart solution read from %s", fileName ); - model->messageHandler()->message(CBC_GENERAL, model->messages()) - << printLine << CoinMessageEol; + model->messageHandler()->message(CBC_GENERAL, model->messages()) << printLine << CoinMessageEol; return 1; } @@ -119,15 +110,17 @@ const std::vector< std::pair< std::string, double > > &colValues, double *sol, double &obj ) { + if (!model->getNumCols()) + return 0; + int status = 0; double compObj = COIN_DBL_MAX; bool foundIntegerSol = false; OsiSolverInterface *lp = model->solver()->clone(); map< string, int > colIdx; - assert( ((int)colNames.size()) == lp->getNumCols() ); - + assert( (static_cast(colNames.size())) == lp->getNumCols() ); /* for fast search of column names */ - for ( int i=0 ; (i<(int)colNames.size()) ; ++i ) + for ( int i=0 ; (i(colNames.size())) ; ++i ) colIdx[colNames[i]] = i; char printLine[STR_SIZE]; @@ -135,7 +128,20 @@ int notFound = 0; char colNotFound[256] = ""; int nContinuousFixed = 0; - for ( int i=0 ; (i<(int)colValues.size()) ; ++i ) + +#ifndef JUST_FIX_INTEGER +#define JUST_FIX_INTEGER 0 +#endif + +#if JUST_FIX_INTEGER > 1 + // all not mentioned are at zero + for ( int i=0 ; (igetNumCols()) ; ++i ) + { + if (lp->isInteger(i)) + lp->setColBounds( i, 0.0, 0.0 ); + } +#endif + for ( int i=0 ; (i(colValues.size())) ; ++i ) { map< string, int >::const_iterator mIt = colIdx.find( colValues[i].first ); if ( mIt == colIdx.end() ) @@ -148,12 +154,17 @@ { const int idx = mIt->second; double v = colValues[i].second; +#if JUST_FIX_INTEGER + if (!lp->isInteger(idx)) + continue; +#endif if (v<1e-8) v = 0.0; if (lp->isInteger(idx)) // just to avoid small v = floor( v+0.5 ); // fractional garbage - else - nContinuousFixed++; + else + nContinuousFixed++; + lp->setColBounds( idx, v, v ); ++fixed; } @@ -162,49 +173,71 @@ if (!fixed) { model->messageHandler()->message(CBC_GENERAL, model->messages()) - << "Warning: MIPstart solution is not valid, ignoring it." - << CoinMessageEol; + << "Warning: MIPstart solution is not valid, column names do not match, ignoring it." + << CoinMessageEol; goto TERMINATE; } - if ( notFound >= ( ((double)colNames.size()) * 0.5 ) ) { + if ( notFound >= ( (static_cast(colNames.size())) * 0.5 ) ) { sprintf( printLine, "Warning: %d column names were not found (e.g. %s) while filling solution.", notFound, colNotFound ); - model->messageHandler()->message(CBC_GENERAL, model->messages()) - << printLine << CoinMessageEol; + model->messageHandler()->message(CBC_GENERAL, model->messages()) + << printLine << CoinMessageEol; } - +#if JUST_FIX_INTEGER + lp->setHintParam(OsiDoPresolveInInitial, true, OsiHintDo) ; +#endif + lp->setDblParam(OsiDualObjectiveLimit,COIN_DBL_MAX); lp->initialSolve(); - if (!lp->isProvenOptimal()) + + if ( (lp->isProvenPrimalInfeasible()) || (lp->isProvenDualInfeasible()) ) { - model->messageHandler()->message(CBC_GENERAL, model->messages()) - << "Warning: mipstart values could not be used to build a solution." << CoinMessageEol; if (nContinuousFixed) { - model->messageHandler()->message(CBC_GENERAL, model->messages()) - << "Trying just fixing integer variables." << CoinMessageEol; - int numberColumns = lp->getNumCols(); - const double * oldLower = model->solver()->getColLower(); - const double * oldUpper = model->solver()->getColUpper(); - for ( int i=0 ; iisInteger(i)) { - lp->setColLower(i,oldLower[i]); - lp->setColUpper(i,oldUpper[i]); - } - } - lp->initialSolve(); - if (!lp->isProvenOptimal()) - model->messageHandler()->message(CBC_GENERAL, model->messages()) - << "Still no good." << CoinMessageEol; - } - if (!lp->isProvenOptimal()) { - status = 1; - goto TERMINATE; + model->messageHandler()->message(CBC_GENERAL, model->messages()) + << "Trying just fixing integer variables." << CoinMessageEol; + int numberColumns = lp->getNumCols(); + const double *oldLower = model->solver()->getColLower(); + const double *oldUpper = model->solver()->getColUpper(); + for ( int i=0 ; iisInteger(i)) { + lp->setColLower(i,oldLower[i]); + lp->setColUpper(i,oldUpper[i]); + } + } + + lp->initialSolve(); + } + else + { + model->messageHandler()->message(CBC_GENERAL, model->messages()) + << "Fixing only non-zero variables." << CoinMessageEol; + /* unfix all variables which are zero */ + int notZeroAnymore = 0; + for ( int i=0 ; (igetNumCols()) ; ++i ) + if ( ((fabs(lp->getColLower()[i])) <= 1e-8) && (fabs(lp->getColLower()[i]-lp->getColUpper()[i]) <= 1e-8) ) + { + const double *oldLower = model->solver()->getColLower(); + const double *oldUpper = model->solver()->getColUpper(); + lp->setColLower(i,oldLower[i]); + lp->setColUpper(i,oldUpper[i]); + notZeroAnymore++; + } + if (notZeroAnymore) + lp->initialSolve(); } } + if (!lp->isProvenOptimal()) + { + model->messageHandler()->message(CBC_GENERAL, model->messages()) + << "Warning: mipstart values could not be used to build a solution." << CoinMessageEol; + status = 1; + goto TERMINATE; + } + /* some additional effort is needed to provide an integer solution */ if ( lp->getFractionalIndices().size() > 0 ) { - sprintf( printLine,"MIPStart solution provided values for %d of %d integer variables, %d variables are still fractional.", fixed, lp->getNumIntegers(), (int)lp->getFractionalIndices().size() ); + sprintf( printLine,"MIPStart solution provided values for %d of %d integer variables, %d variables are still fractional.", fixed, lp->getNumIntegers(), static_cast(lp->getFractionalIndices().size()) ); model->messageHandler()->message(CBC_GENERAL, model->messages()) << printLine << CoinMessageEol; double start = CoinCpuTime(); @@ -227,8 +260,9 @@ } #else CbcModel babModel( *lp ); - babModel.setLogLevel( 0 ); - babModel.setMaximumNodes( 500 ); + lp->writeLp("lessFix"); + babModel.setLogLevel( 2 ); + babModel.setMaximumNodes( 1000 ); babModel.setMaximumSeconds( 60 ); babModel.branchAndBound(); if (babModel.bestSolution()) @@ -244,8 +278,8 @@ #endif else { - model->messageHandler()->message(CBC_GENERAL, model->messages()) - << "Warning: mipstart values could not be used to build a solution." << CoinMessageEol; + model->messageHandler()->message(CBC_GENERAL, model->messages()) + << "Warning: mipstart values could not be used to build a solution." << CoinMessageEol; status = 1; goto TERMINATE; } @@ -259,17 +293,242 @@ if ( foundIntegerSol ) { - sprintf( printLine,"mipstart provided solution with cost %g", compObj); + sprintf( printLine,"MIPStart provided solution with cost %g", compObj); model->messageHandler()->message(CBC_GENERAL, model->messages()) - << printLine << CoinMessageEol; + << printLine << CoinMessageEol; +#if 0 + { + int numberColumns=lp->getNumCols(); + double largestInfeasibility = 0.0; + double primalTolerance ; + double offset; + lp->getDblParam(OsiObjOffset, offset); + lp->getDblParam(OsiPrimalTolerance, primalTolerance) ; + const double *objective = lp->getObjCoefficients() ; + const double * rowLower = lp->getRowLower() ; + const double * rowUpper = lp->getRowUpper() ; + const double * columnLower = lp->getColLower() ; + const double * columnUpper = lp->getColUpper() ; + int numberRows = lp->getNumRows() ; + double *rowActivity = new double[numberRows] ; + memset(rowActivity, 0, numberRows*sizeof(double)) ; + double *rowSum = new double[numberRows] ; + memset(rowSum, 0, numberRows*sizeof(double)) ; + const double * element = lp->getMatrixByCol()->getElements(); + const int * row = lp->getMatrixByCol()->getIndices(); + const CoinBigIndex * columnStart = lp->getMatrixByCol()->getVectorStarts(); + const int * columnLength = lp->getMatrixByCol()->getVectorLengths(); + const CoinPackedMatrix * rowCopy = lp->getMatrixByRow(); + const int * column = rowCopy->getIndices(); + const int * rowLength = rowCopy->getVectorLengths(); + const CoinBigIndex * rowStart = rowCopy->getVectorStarts(); + const double * elementByRow = rowCopy->getElements(); + double objValue=-offset; + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + double value = sol[iColumn]; + if (lp->isInteger(iColumn)) + assert (fabs(value-floor(value+0.5))<1.0e-6); + objValue += value*objective[iColumn]; + if (value>columnUpper[iColumn]) { + if (value-columnUpper[iColumn]>1.0e-8) + printf("column %d has value %.12g above %.12g\n",iColumn,value,columnUpper[iColumn]); + value=columnUpper[iColumn]; + } else if (value1.0e-5) + printf("Column %d row %d value %.8g element %g %s\n", + iColumn,iRow,value,element[j],lp->isInteger(iColumn) ? "integer" : ""); + rowActivity[iRow] += value * element[j]; + rowSum[iRow] += fabs(value * element[j]); + } + } + } + for (int i = 0 ; i < numberRows ; i++) { +#if 0 //def CLP_INVESTIGATE + double inf; + inf = rowLower[i] - rowActivity[i]; + if (inf > primalTolerance) + printf("Row %d inf %g sum %g %g <= %g <= %g\n", + i, inf, rowSum[i], rowLower[i], rowActivity[i], rowUpper[i]); + inf = rowActivity[i] - rowUpper[i]; + if (inf > primalTolerance) + printf("Row %d inf %g sum %g %g <= %g <= %g\n", + i, inf, rowSum[i], rowLower[i], rowActivity[i], rowUpper[i]); +#endif + double infeasibility = CoinMax(rowActivity[i]-rowUpper[i], + rowLower[i]-rowActivity[i]); + // but allow for errors + double factor = CoinMax(1.0,rowSum[i]*1.0e-3); + if (infeasibility>largestInfeasibility*factor) { + largestInfeasibility = infeasibility/factor; + printf("Cinf of %g on row %d sum %g scaled %g\n", + infeasibility,i,rowSum[i],largestInfeasibility); + if (infeasibility>1.0e10) { + for (CoinBigIndex j=rowStart[i]; + j 10.0*primalTolerance) + printf("Clargest infeasibility is %g - obj %g\n", largestInfeasibility,objValue); + else + printf("Cfeasible (%g) - obj %g\n", largestInfeasibility,objValue); + } +#endif for ( int i=0 ; (igetNumCols()) ; ++i ) { +#if 0 if (sol[i]<1e-8) sol[i] = 0.0; else if (lp->isInteger(i)) sol[i] = floor( sol[i]+0.5 ); +#else + if (lp->isInteger(i)) { + //if (fabs(sol[i] - floor( sol[i]+0.5 ))>1.0e-8) + //printf("bad sol for %d - %.12g\n",i,sol[i]); + sol[i] = floor( sol[i]+0.5 ); + } +#endif + } +#if 0 + { + int numberColumns=lp->getNumCols(); + double largestInfeasibility = 0.0; + double primalTolerance ; + double offset; + lp->getDblParam(OsiObjOffset, offset); + lp->getDblParam(OsiPrimalTolerance, primalTolerance) ; + const double *objective = lp->getObjCoefficients() ; + const double * rowLower = lp->getRowLower() ; + const double * rowUpper = lp->getRowUpper() ; + const double * columnLower = lp->getColLower() ; + const double * columnUpper = lp->getColUpper() ; + int numberRows = lp->getNumRows() ; + double *rowActivity = new double[numberRows] ; + memset(rowActivity, 0, numberRows*sizeof(double)) ; + double *rowSum = new double[numberRows] ; + memset(rowSum, 0, numberRows*sizeof(double)) ; + const double * element = lp->getMatrixByCol()->getElements(); + const int * row = lp->getMatrixByCol()->getIndices(); + const CoinBigIndex * columnStart = lp->getMatrixByCol()->getVectorStarts(); + const int * columnLength = lp->getMatrixByCol()->getVectorLengths(); + const CoinPackedMatrix * rowCopy = lp->getMatrixByRow(); + const int * column = rowCopy->getIndices(); + const int * rowLength = rowCopy->getVectorLengths(); + const CoinBigIndex * rowStart = rowCopy->getVectorStarts(); + const double * elementByRow = rowCopy->getElements(); + double objValue=-offset; + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + double value = sol[iColumn]; + if (lp->isInteger(iColumn)) + assert (fabs(value-floor(value+0.5))<1.0e-6); + objValue += value*objective[iColumn]; + if (value>columnUpper[iColumn]) { + if (value-columnUpper[iColumn]>1.0e-8) + printf("column %d has value %.12g above %.12g\n",iColumn,value,columnUpper[iColumn]); + value=columnUpper[iColumn]; + } else if (value primalTolerance) + printf("Row %d inf %g sum %g %g <= %g <= %g\n", + i, inf, rowSum[i], rowLower[i], rowActivity[i], rowUpper[i]); + inf = rowActivity[i] - rowUpper[i]; + if (inf > primalTolerance) + printf("Row %d inf %g sum %g %g <= %g <= %g\n", + i, inf, rowSum[i], rowLower[i], rowActivity[i], rowUpper[i]); +#endif + double infeasibility = CoinMax(rowActivity[i]-rowUpper[i], + rowLower[i]-rowActivity[i]); + // but allow for errors + double factor = CoinMax(1.0,rowSum[i]*1.0e-3); + if (infeasibility>largestInfeasibility*factor) { + largestInfeasibility = infeasibility/factor; + printf("Dinf of %g on row %d sum %g scaled %g\n", + infeasibility,i,rowSum[i],largestInfeasibility); + if (infeasibility>1.0e10) { + for (CoinBigIndex j=rowStart[i]; + j 10.0*primalTolerance) + printf("Dlargest infeasibility is %g - obj %g\n", largestInfeasibility,objValue); + else + printf("Dfeasible (%g) - obj %g\n", largestInfeasibility,objValue); + } +#endif +#if JUST_FIX_INTEGER + const double * oldLower = model->solver()->getColLower(); + const double * oldUpper = model->solver()->getColUpper(); + const double * dj = lp->getReducedCost(); + int nNaturalLB=0; + int nMaybeLB=0; + int nForcedLB=0; + int nNaturalUB=0; + int nMaybeUB=0; + int nForcedUB=0; + int nOther=0; + for ( int i=0 ; igetNumCols() ; ++i ) { + if (lp->isInteger(i)) { + if (sol[i]==oldLower[i]) { + if (dj[i]>1.0e-5) + nNaturalLB++; + else if (dj[i]<-1.0e-5) + nForcedLB++; + else + nMaybeLB++; + } else if (sol[i]==oldUpper[i]) { + if (dj[i]<-1.0e-5) + nNaturalUB++; + else if (dj[i]>1.0e-5) + nForcedUB++; + else + nMaybeUB++; + } else { + nOther++; + } + } } + printf("%d other, LB %d natural, %d neutral, %d forced, UB %d natural, %d neutral, %d forced\n", + nOther,nNaturalLB,nMaybeLB,nForcedLB, + nNaturalUB,nMaybeUB,nForcedUB=0); +#endif } TERMINATE: diff -Nru coinor-cbc-2.8.12/src/CbcModel.cpp coinor-cbc-2.9.9+repack1/src/CbcModel.cpp --- coinor-cbc-2.8.12/src/CbcModel.cpp 2014-08-11 17:44:45.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcModel.cpp 2017-06-01 10:49:03.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcModel.cpp 2056 2014-08-11 17:44:45Z forrest $ */ +/* $Id: CbcModel.cpp 2334 2017-06-01 10:49:03Z stefan $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -61,6 +61,9 @@ #include "CbcFeasibilityBase.hpp" #include "CbcFathom.hpp" #include "CbcFullNodeInfo.hpp" +#ifdef COIN_HAS_NTY +#include "CbcSymmetry.hpp" +#endif // include Probing #include "CglProbing.hpp" #include "CglGomory.hpp" @@ -70,6 +73,7 @@ #include "CglDuplicateRow.hpp" #include "CglStored.hpp" #include "CglClique.hpp" +#include "CglKnapsackCover.hpp" #include "CoinTime.hpp" #include "CoinMpsIO.hpp" @@ -440,12 +444,12 @@ int iType = 0; if (!numberContinuousObj && numberIntegerObj <= 5 && numberIntegerWeight <= 100 && numberIntegerObj*3 < numberObjects_ && !parentModel_ && solver_->getNumRows() > 100) - iType = 1 + 4 + ((moreSpecialOptions_&536870912)==0) ? 2 : 0; + iType = 1 + 4 + (((moreSpecialOptions_&536870912)==0) ? 2 : 0); else if (!numberContinuousObj && numberIntegerObj <= 100 && numberIntegerObj*5 < numberObjects_ && numberIntegerWeight <= 100 && !parentModel_ && solver_->getNumRows() > 100 && cost != -COIN_DBL_MAX) - iType = 4 + ((moreSpecialOptions_&536870912)==0) ? 2 : 0; + iType = 4 + (((moreSpecialOptions_&536870912)==0) ? 2 : 0); else if (!numberContinuousObj && numberIntegerObj <= 100 && numberIntegerObj*5 < numberObjects_ && !parentModel_ && @@ -582,7 +586,7 @@ } else if (largestObj < smallestObj*5.0 && !parentModel_ && !numberContinuousObj && !numberGeneralIntegerObj && - numberIntegerObj*2 < numberColumns) { + numberIntegerObj*2 < CoinMin(numberColumns,20)) { // up priorities on costed int iPriority = -1; for (int i = 0; i < numberObjects_; i++) { @@ -593,7 +597,7 @@ iPriority = -2; } if (iPriority >= 100) { -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("Setting variables with obj to high priority\n"); #endif for (int i = 0; i < numberObjects_; i++) { @@ -1083,7 +1087,7 @@ (*checkCutoffForRestart < 1.0e20); int numberColumns = getNumCols(); if (tryNewSearch) { -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("after %d nodes, cutoff %g - looking\n", numberNodes_, getCutoff()); #endif @@ -1229,9 +1233,9 @@ { int numberColumns = continuousSolver_->getNumCols(); int numberRows = continuousSolver_->getNumRows(); + int numberOriginalIntegers = numberIntegers_; int * del = new int [CoinMax(numberColumns, numberRows)]; int * original = new int [numberColumns]; - int numberOriginalIntegers=numberIntegers_; char * possibleRow = new char [numberRows]; { const CoinPackedMatrix * rowCopy = continuousSolver_->getMatrixByRow(); @@ -1262,18 +1266,15 @@ for (CoinBigIndex j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) { int iColumn = column[j]; - double value = fabs(element[j]); if (continuousSolver_->isInteger(iColumn)) { - if (value != 1.0) + if (fabs(element[j]) != 1.0) possible = false; } else { nLeft++; - if (value>100.0) - allSame=-1.0; // not safe if (!allSame) { - allSame = value; + allSame = fabs(element[j]); } else if (allSame>0.0) { - if (allSame!=value) + if (allSame!=fabs(element[j])) allSame = -1.0; } } @@ -1466,7 +1467,7 @@ char * rotate = new char[numberRows]; int n = clpSolver->getModelPtr()->findNetwork(rotate, 1.0); delete [] rotate; -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("INTA network %d rows out of %d\n", n, numberRows); #endif if (CoinAbs(n) == numberRows) { @@ -1474,7 +1475,7 @@ for (int i = 0; i < numberRows; i++) { if (!possibleRow[i]) { couldBeNetwork = false; -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("but row %d is bad\n", i); #endif break; @@ -1554,7 +1555,7 @@ for (int i = 0; i < numberColumns; i++) assert(solver_->isInteger(i)); } -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 if (couldBeNetwork || nExtra) printf("INTA %d extra integers, %d left%s\n", nExtra, numberColumns, @@ -1563,7 +1564,7 @@ findIntegers(true, 2); convertToDynamic(); } -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 if (!couldBeNetwork && copy1->getNumCols() && copy1->getNumRows()) { printf("INTA %d rows and %d columns remain\n", @@ -1597,6 +1598,13 @@ */ +#ifdef CONFLICT_CUTS +#if PRINT_CONFLICT==1 +static int numberConflictCuts=0; +static int lastNumberConflictCuts=0; +static double lengthConflictCuts=0.0; +#endif +#endif /* The overall flow can be divided into three stages: * Prep: Check that the lp relaxation remains feasible at the root. If so, @@ -1617,20 +1625,24 @@ void CbcModel::branchAndBound(int doStatistics) { - if (!parentModel_) - /* - Capture a time stamp before we start (unless set). - */ - if (!dblParam_[CbcStartSeconds]) { - if (!useElapsedTime()) - dblParam_[CbcStartSeconds] = CoinCpuTime(); - else - dblParam_[CbcStartSeconds] = CoinGetTimeOfDay(); + if (!parentModel_) { + /* + Capture a time stamp before we start (unless set). + */ + if (!dblParam_[CbcStartSeconds]) { + if (!useElapsedTime()) + dblParam_[CbcStartSeconds] = CoinCpuTime(); + else + dblParam_[CbcStartSeconds] = CoinGetTimeOfDay(); + } } dblParam_[CbcSmallestChange] = COIN_DBL_MAX; dblParam_[CbcSumChange] = 0.0; dblParam_[CbcLargestChange] = 0.0; intParam_[CbcNumberBranches] = 0; + double lastBestPossibleObjective=-COIN_DBL_MAX; + // when to check for restart + int nextCheckRestart=50; // Force minimization !!!! bool flipObjective = (solver_->getObjSense()<0.0); if (flipObjective) @@ -2011,8 +2023,9 @@ if (clpSolver) { ClpSimplex * clpSimplex = clpSolver->getModelPtr(); if ((specialOptions_&32) == 0) { - // take off names - clpSimplex->dropNames(); + // take off names (unless going to be saving) + if (numberAnalyzeIterations_>=0||(-numberAnalyzeIterations_&64)==0) + clpSimplex->dropNames(); } // no crunch if mostly continuous if ((clpSolver->specialOptions()&(1 + 8)) != (1 + 8)) { @@ -2032,6 +2045,7 @@ } #endif bool feasible; + numberSolves_ = 0 ; { // check int numberOdd = 0; @@ -2044,7 +2058,6 @@ if (numberOdd) moreSpecialOptions_ |= 1073741824; } - numberSolves_ = 0 ; // If NLP then we assume already solved outside branchAndbound if (!solverCharacteristics_->solverType() || solverCharacteristics_->solverType() == 4) { feasible = resolve(NULL, 0) != 0 ; @@ -2073,6 +2086,45 @@ secondaryStatus_ = 7; } originalContinuousObjective_ = COIN_DBL_MAX; + if (bestSolution_ && + ((specialOptions_&8388608)==0||(specialOptions_&2048)!=0)) { + // best solution found by various heuristics - set solution + char general[200]; + sprintf(general,"Solution of %g already found by heuristic", + bestObjective_); + messageHandler()->message(CBC_GENERAL, + messages()) + << general << CoinMessageEol ; + setCutoff(1.0e50) ; // As best solution should be worse than cutoff + // change cutoff as constraint if wanted + if (cutoffRowNumber_>=0) { + if (solver_->getNumRows()>cutoffRowNumber_) + solver_->setRowUpper(cutoffRowNumber_,1.0e50); + } + // also in continuousSolver_ + if (continuousSolver_) { + // Solvers know about direction + double direction = solver_->getObjSense(); + continuousSolver_->setDblParam(OsiDualObjectiveLimit, 1.0e50*direction); + } else { + continuousSolver_ = solver_->clone(); + } + phase_ = 5; + double increment = getDblParam(CbcModel::CbcCutoffIncrement) ; + if ((specialOptions_&4) == 0) + bestObjective_ += 100.0 * increment + 1.0e-3; // only set if we are going to solve + setBestSolution(CBC_END_SOLUTION, bestObjective_, bestSolution_, 1) ; + continuousSolver_->resolve() ; + if (!continuousSolver_->isProvenOptimal()) { + continuousSolver_->messageHandler()->setLogLevel(1) ; + continuousSolver_->initialSolve() ; + } + delete solver_ ; + solverCharacteristics_=NULL; + solver_ = continuousSolver_ ; + setPointers(solver_); + continuousSolver_ = NULL ; + } solverCharacteristics_ = NULL; if (flipObjective) flipModel(); @@ -2218,7 +2270,7 @@ numberSOS++; } if (numberOdd) { - if (numberHeuristics_) { + if (numberHeuristics_ && (specialOptions_&1024)==0 ) { int k = 0; for (int i = 0; i < numberHeuristics_; i++) { if (!heuristic_[i]->canDealWithOdd()) @@ -2235,6 +2287,9 @@ } // If odd switch off AddIntegers specialOptions_ &= ~65536; + // switch off fast nodes for now + fastNodeDepth_ = -1; + moreSpecialOptions_ &= ~33554432; // no diving } else if (numberSOS) { specialOptions_ |= 128; // say can do SOS in dynamic mode // switch off fast nodes for now @@ -2243,7 +2298,7 @@ } if (numberThreads_ > 0) { // switch off fast nodes for now - fastNodeDepth_ = -1; + //fastNodeDepth_ = -1; } } // Save objective (just so user can access it) @@ -2305,7 +2360,24 @@ Create a copy of the solver, thus capturing the original (root node) constraint system (aka the continuous system). */ + delete continuousSolver_; continuousSolver_ = solver_->clone() ; +#ifdef COIN_HAS_NTY + // maybe allow on fix and restart later + if ((moreSpecialOptions2_&(128|256))!=0&&!parentModel_) { + symmetryInfo_ = new CbcSymmetry(); + symmetryInfo_->setupSymmetry(*continuousSolver_); + int numberGenerators = symmetryInfo_->statsOrbits(this,0); + if (!symmetryInfo_->numberUsefulOrbits()&&(moreSpecialOptions2_&(128|256))!=(128|256)) { + delete symmetryInfo_; + symmetryInfo_=NULL; + moreSpecialOptions2_ &= ~(128|256); + } + if ((moreSpecialOptions2_&(128|256))==(128|256)) { + //moreSpecialOptions2_ &= ~256; + } + } +#endif // add cutoff as constraint if wanted if (cutoffRowNumber_==-2) { @@ -2378,7 +2450,8 @@ the active subproblem. whichGenerator will be used to record the generator that produced a given cut. */ - maximumWhich_ = 1000 ; +#define INITIAL_MAXIMUM_WHICH 1000 + maximumWhich_ = INITIAL_MAXIMUM_WHICH ; delete [] whichGenerator_; whichGenerator_ = new int[maximumWhich_] ; memset(whichGenerator_, 0, maximumWhich_*sizeof(int)); @@ -2533,6 +2606,11 @@ } } } +#ifdef SWITCH_VARIABLES + // see if any switching variables + if (numberIntegers_getNumCols()) + findSwitching(); +#endif /* Run heuristics at the root. This is the only opportunity to run FPump; it will be removed from the heuristics list by doHeuristicsAtRoot. @@ -2573,7 +2651,6 @@ #endif } CoinWarmStartBasis * basis = dynamic_cast (solver_->getEmptyWarmStart()); - int numberIterations=0; for (int i=0;isetNumberThreads(0); @@ -2584,11 +2661,18 @@ // use seed rootModels[i]->setSpecialOptions(specialOptions_ |(4194304|8388608)); rootModels[i]->setMoreSpecialOptions(moreSpecialOptions_ & - (~134217728)); + (~(134217728|4194304))); + rootModels[i]->setMoreSpecialOptions2(moreSpecialOptions2_ & + (~(128|256))); rootModels[i]->solver_->setWarmStart(basis); #ifdef COIN_HAS_CLP OsiClpSolverInterface * clpSolver = dynamic_cast (rootModels[i]->solver_); +#define NEW_RANDOM_BASIS +#ifdef NEW_RANDOM_BASIS + if (i==0) + continue; +#endif if (clpSolver) { ClpSimplex * simplex = clpSolver->getModelPtr(); if (defaultHandler_) @@ -2599,20 +2683,39 @@ if (logLevel==1) simplex->setLogLevel(0); if (i!=0) { +#ifdef NEW_RANDOM_BASIS + int numberRows = simplex->numberRows(); + int throwOut=20;//2+numberRows/100; + for (int iThrow=0;iThrowrandomNumberGenerator()->randomDouble(); + int iStart=static_cast(random*numberRows); + for (int j=iStart;jgetRowStatus(j)!=ClpSimplex::basic) { + simplex->setRowStatus(j,ClpSimplex::basic); + break; + } + } + } + clpSolver->setWarmStart(NULL); +#else double random = simplex->randomNumberGenerator()->randomDouble(); int bias = static_cast(random*(numberIterations/4)); simplex->setMaximumIterations(numberIterations/2+bias); simplex->primal(); simplex->setMaximumIterations(COIN_INT_MAX); simplex->dual(); +#endif } else { +#ifndef NEW_RANDOM_BASIS simplex->primal(); - numberIterations=simplex->numberIterations(); +#endif +#endif } +#ifdef NEW_RANDOM_BASIS simplex->setLogLevel(logLevel); clpSolver->setWarmStart(NULL); - } #endif + } for (int j=0;jheuristic_[j]->setSeed(rootModels[i]->heuristic_[j]->getSeed()+100000000*i); for (int j=0;jgetNumCols() && (specialOptions_&65536) != 0 && !parentModel_) - AddIntegers(); + // taken out in stable as causes problems + if (noObjects && numberIntegers_ < solver_->getNumCols() && (specialOptions_&65536) != 0 && !parentModel_ && false) + AddIntegers(); /* Do an initial round of cut generation for the root node. Depending on the type of underlying solver, we may want to do this even if the initial query @@ -2757,7 +2861,6 @@ adjusted accordingly). */ int iObject ; - int preferredWay ; int numberUnsatisfied = 0 ; delete [] currentSolution_; currentSolution_ = new double [numberColumns]; @@ -2769,7 +2872,7 @@ for (iObject = 0 ; iObject < numberObjects_ ; iObject++) { double infeasibility = - object_[iObject]->infeasibility(&usefulInfo, preferredWay) ; + object_[iObject]->checkInfeasibility(&usefulInfo) ; if (infeasibility ) numberUnsatisfied++ ; } // replace solverType @@ -2848,38 +2951,32 @@ //globalCuts_=rowCutrowCut.addCuts(globalCuts_); //rowCut.addCuts(globalCuts_); int nTightened=0; - bool feasible=true; + assert(feasible); { double tolerance=1.0e-5; const double * lower = solver_->getColLower(); const double * upper = solver_->getColUpper(); for (int i=0;itightBounds[2*i+1]) { + if (tightBounds[2*i+0]>tightBounds[2*i+1]+1.0e-9) { feasible=false; - printf("Bad bounds on %d %g,%g was %g,%g\n", - i,tightBounds[2*i+0],tightBounds[2*i+1], - lower[i],upper[i]); + char general[200]; + sprintf(general,"Solvers give infeasible bounds on %d %g,%g was %g,%g - search finished\n", + i,tightBounds[2*i+0],tightBounds[2*i+1],lower[i],upper[i]); + messageHandler()->message(CBC_GENERAL,messages()) + << general << CoinMessageEol ; + break; } - //int k=0; double oldLower=lower[i]; double oldUpper=upper[i]; if (tightBounds[2*i+0]>oldLower+tolerance) { nTightened++; - //k++; solver_->setColLower(i,tightBounds[2*i+0]); } if (tightBounds[2*i+1]setColUpper(i,tightBounds[2*i+1]); } - //if (k) - //printf("new bounds on %d %g,%g was %g,%g\n", - // i,tightBounds[2*i+0],tightBounds[2*i+1], - // oldLower,oldUpper); } - if (!feasible) - abort(); // deal with later } delete [] tightBounds; tightBounds=NULL; @@ -2985,7 +3082,8 @@ } } } - feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_, + if (feasible) + feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_, NULL); if (multipleRootTries_&& (moreSpecialOptions_&134217728)!=0) { @@ -3312,7 +3410,12 @@ CPXLPptr lpPtr = cpxSolver.getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL); cpxSolver.switchToMIP(); if (bestSolution_) { +#if 0 CPXcopymipstart(env, lpPtr, numberIntegers_, setVar, setSol); +#else + int zero = 0; + CPXaddmipstarts(env, lpPtr, 1, numberIntegers_, &zero, setVar, setSol, NULL, NULL); +#endif } if (clpSolver->getNumRows() > continuousSolver_->getNumRows() && false) { // add cuts @@ -3486,9 +3589,42 @@ CbcNode *newNode = NULL ; numberFixedAtRoot_ = 0; numberFixedNow_ = 0; + if (!parentModel_&&(moreSpecialOptions2_&2)!=0) { +#ifdef COIN_HAS_CLP + OsiClpSolverInterface * clpSolver + = dynamic_cast (solver_); + if (clpSolver) { + if (getCutoff()>1.0e20) { + printf("Zapping costs\n"); + int numberColumns=solver_->getNumCols(); + double * zeroCost = new double [numberColumns]; + // could make small random + memset(zeroCost,0,numberColumns*sizeof(double)); + solver_->setObjective(zeroCost); + double objValue = solver_->getObjValue(); + solver_->setDblParam(OsiObjOffset,-objValue); + clpSolver->getModelPtr()->setObjectiveValue(objValue); + delete [] zeroCost; + } else { + moreSpecialOptions2_ &= ~2; + } + } else { +#endif + moreSpecialOptions2_ &= ~2; +#ifdef COIN_HAS_CLP + } +#endif + } int numberIterationsAtContinuous = numberIterations_; //solverCharacteristics_->setSolver(solver_); if (feasible) { + // mark all cuts as globally valid + int numberCuts=cuts.sizeRowCuts(); + resizeWhichGenerator(0,numberCuts); + for (int i=0;isetGloballyValid(); + whichGenerator_[i]=20000+(whichGenerator_[i]%10000); + } #define HOTSTART -1 #if HOTSTART<0 if (bestSolution_ && !parentModel_ && !hotstartSolution_ && @@ -3587,7 +3723,7 @@ } } } -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("%d forced, %d naturally at lower, %d at upper - %d zero dj\n", nForced, nAtLbNatural, nAtUbNatural, nZeroDj); #endif @@ -3809,9 +3945,10 @@ // only allow 1000 passes int numberPassesLeft = 1000; // This is first crude step - if (numberAnalyzeIterations_) { + if (numberAnalyzeIterations_ && !parentModel_) { delete [] analyzeResults_; - analyzeResults_ = new double [4*numberIntegers_]; + //int numberColumns = solver_->getNumCols(); + analyzeResults_ = new double [5*numberIntegers_]; numberFixedAtRoot_ = newNode->analyze(this, analyzeResults_); if (numberFixedAtRoot_ > 0) { COIN_DETAIL_PRINT(printf("%d fixed by analysis\n", numberFixedAtRoot_)); @@ -3826,13 +3963,14 @@ } } OsiSolverBranch * branches = NULL; - anyAction = chooseBranch(newNode, numberPassesLeft, NULL, cuts, resolved, + if (feasible) + anyAction = chooseBranch(newNode, numberPassesLeft, NULL, cuts, resolved, NULL, NULL, NULL, branches); if (anyAction == -2 || newNode->objectiveValue() >= cutoff) { if (anyAction != -2) { // zap parent nodeInfo #ifdef COIN_DEVELOP - printf("zapping CbcNodeInfo %x\n", reinterpret_cast(newNode->nodeInfo()->parent())); + printf("zapping CbcNodeInfo %x\n", newNode->nodeInfo()->parent()); #endif if (newNode->nodeInfo()) newNode->nodeInfo()->nullParent(); @@ -3850,30 +3988,86 @@ //const int * integerVariable = probingInfo_->integerVariable(); if (toZero[number01]) { CglTreeProbingInfo info(*probingInfo_); -#ifdef JJF_ZERO - /* - Marginal idea. Further exploration probably good. Build some extra - cliques from probing info. Not quite worth the effort? - */ - OsiSolverInterface * fake = info.analyze(*solver_, 1); - if (fake) { - fake->writeMps("fake"); + if ((moreSpecialOptions2_&64)!=0&&!parentModel_) { + /* + Marginal idea. Further exploration probably good. Build some extra + cliques from probing info. Not quite worth the effort? + */ + CglProbing generator1; + generator1.setUsingObjective(false); + generator1.setMaxPass(1); + generator1.setMaxPassRoot(1); + generator1.setMaxLook(100); + generator1.setRowCuts(3); + generator1.setMaxElements(300); + generator1.setMaxProbeRoot(solver_->getNumCols()); + CoinThreadRandom randomGenerator; + //CglTreeProbingInfo info(solver_); + info.level = 0; + info.formulation_rows = solver_->getNumRows(); + info.inTree = false; + info.randomNumberGenerator=&randomGenerator; + info.pass=4; + generator1.setMode(8); + OsiCuts cs; + generator1.generateCutsAndModify(*solver_,cs,&info); + // very clunky + OsiSolverInterface * temp = generator1.cliqueModel(solver_,2); + CglPreProcess dummy; + OsiSolverInterface * newSolver=dummy.cliqueIt(*temp,0.0001); + delete temp; + OsiSolverInterface * fake = NULL; + if (newSolver) { +#if 0 + int numberCliques = generator1.numberCliques(); + cliqueEntry * entry = generator1.cliqueEntry(); + cliqueType * type = new cliqueType [numberCliques]; + int * start = new int [numberCliques+1]; + start[numberCliques]=2*numberCliques; + int n=0; + for (int i=0;iwriteMps("fake"); CglFakeClique cliqueGen(fake); cliqueGen.setStarCliqueReport(false); cliqueGen.setRowCliqueReport(false); cliqueGen.setMinViolation(0.1); addCutGenerator(&cliqueGen, 1, "Fake cliques", true, false, false, -200); generator_[numberCutGenerators_-1]->setTiming(true); - } -#endif + for (int i = 0; i < numberCutGenerators_; i++) { + CglKnapsackCover * cutGen = + dynamic_cast(generator_[i]->generator()); + if (cutGen) { + cutGen->createCliques(*fake,2,200,false); + } + } + } + } if (probingInfo_->packDown()) { -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("%d implications on %d 0-1\n", toZero[number01], number01); #endif // Create a cut generator that remembers implications discovered at root. CglImplication implication(probingInfo_); addCutGenerator(&implication, 1, "ImplicationCuts", true, false, false, -200); generator_[numberCutGenerators_-1]->setGlobalCuts(true); + generator_[numberCutGenerators_-1]->setTiming(true); } else { delete probingInfo_; probingInfo_ = NULL; @@ -3891,11 +4085,6 @@ */ assert (!newNode || newNode->objectiveValue() <= cutoff) ; // Save address of root node as we don't want to delete it - // initialize for print out - int lastDepth = 0; - int lastUnsatisfied = 0; - if (newNode) - lastUnsatisfied = newNode->numberUnsatisfied(); /* The common case is that the lp relaxation is feasible but doesn't satisfy integrality (i.e., newNode->branchingObject(), indicating we've been able to @@ -4101,15 +4290,19 @@ } else { unlockThread(); } - // If done 100 nodes see if worth trying reduction - if (numberNodes_ == 50 || numberNodes_ == 100) { + // If done 50/100 nodes see if worth trying reduction + if (numberNodes_ >= nextCheckRestart) { + if (nextCheckRestart<100) + nextCheckRestart=100; + else + nextCheckRestart=COIN_INT_MAX; #ifdef COIN_HAS_CLP OsiClpSolverInterface * clpSolver = dynamic_cast (solver_); if (clpSolver && ((specialOptions_&131072) == 0) && true) { ClpSimplex * simplex = clpSolver->getModelPtr(); int perturbation = simplex->perturbation(); -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("Testing its n,s %d %d solves n,s %d %d - pert %d\n", numberIterations_, saveNumberIterations, numberSolves_, saveNumberSolves, perturbation); @@ -4118,7 +4311,7 @@ 8*(numberSolves_ - saveNumberSolves)) { // switch off perturbation simplex->setPerturbation(100); -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("Perturbation switched off\n"); #endif } @@ -4132,8 +4325,9 @@ (getCutoff() < 1.0e20 && getCutoff() < checkCutoffForRestart); int numberColumns = getNumCols(); if (tryNewSearch) { - checkCutoffForRestart = getCutoff() ; -#ifdef CLP_INVESTIGATE + // adding increment back allows current best - tiny bit weaker + checkCutoffForRestart = getCutoff() + getCutoffIncrement() ; +#if CBC_USEFUL_PRINTING>1 printf("after %d nodes, cutoff %g - looking\n", numberNodes_, getCutoff()); #endif @@ -4210,6 +4404,11 @@ if (numberFixed*10 < numberColumns && numberFixed*4 < numberIntegers_) tryNewSearch = false; } +#ifdef CONFLICT_CUTS + // temporary + if ((moreSpecialOptions_&4194304)!=0) + tryNewSearch=false; +#endif if (tryNewSearch) { // back to solver without cuts? OsiSolverInterface * solver2 = saveSolver->clone(); @@ -4342,8 +4541,26 @@ newCutoff = -COIN_DBL_MAX; break; } + // add as global cut + objLower[i]=-COIN_DBL_MAX; + OsiRowCut rc; + rc.setLb(newLower[i]); + rc.setUb(COIN_DBL_MAX); + double one=1.0; + rc.setRow(1,integerVariable_+i,&one,false); + rc.setGloballyValidAsInteger(2); + globalCuts_.addCutIfNotDuplicate(rc) ; } else if (objUpper[i] > newCutoff) { n++; + // add as global cut + objUpper[i]=-COIN_DBL_MAX; + OsiRowCut rc; + rc.setLb(-COIN_DBL_MAX); + rc.setUb(newUpper[i]); + double one=1.0; + rc.setRow(1,integerVariable_+i,&one,false); + rc.setGloballyValidAsInteger(2); + globalCuts_.addCutIfNotDuplicate(rc) ; } } if (newCutoff == -COIN_DBL_MAX) { @@ -4432,7 +4649,7 @@ } #endif unlockThread(); -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 if (getCutoff() < 1.0e20) { if (fabs(getCutoff() - (bestObjective_ - getCutoffIncrement())) > 1.0e-6 && !parentModel_) @@ -4443,29 +4660,49 @@ } #endif if (!intParam_[CbcPrinting]) { + // Parallel may not have any nodes + if (!nNodes) + bestPossibleObjective_ = lastBestPossibleObjective; + else + lastBestPossibleObjective = bestPossibleObjective_; messageHandler()->message(CBC_STATUS, messages()) - << numberNodes_ << nNodes << bestObjective_ << bestPossibleObjective_ + << numberNodes_ << CoinMax(nNodes,1) << bestObjective_ << bestPossibleObjective_ << getCurrentSeconds() << CoinMessageEol ; } else if (intParam_[CbcPrinting] == 1) { messageHandler()->message(CBC_STATUS2, messages()) << numberNodes_ << nNodes << bestObjective_ << bestPossibleObjective_ - << lastDepth << lastUnsatisfied << numberIterations_ + << tree_->lastDepth() << tree_->lastUnsatisfied() + << tree_->lastObjective() << numberIterations_ << getCurrentSeconds() << CoinMessageEol ; } else if (!numberExtraIterations_) { messageHandler()->message(CBC_STATUS2, messages()) << numberNodes_ << nNodes << bestObjective_ << bestPossibleObjective_ - << lastDepth << lastUnsatisfied << numberIterations_ + << tree_->lastDepth() << tree_->lastUnsatisfied() << numberIterations_ << getCurrentSeconds() << CoinMessageEol ; } else { messageHandler()->message(CBC_STATUS3, messages()) - << numberNodes_ << numberExtraNodes_ << nNodes << bestObjective_ << bestPossibleObjective_ - << lastDepth << lastUnsatisfied << numberIterations_ << numberExtraIterations_ + << numberNodes_ << numberFathoms_ << numberExtraNodes_ << nNodes + << bestObjective_ << bestPossibleObjective_ + << tree_->lastDepth() << tree_->lastUnsatisfied() << numberIterations_ << numberExtraIterations_ << getCurrentSeconds() << CoinMessageEol ; } +#ifdef COIN_HAS_NTY + if (symmetryInfo_) + symmetryInfo_->statsOrbits(this,1); +#endif +#if PRINT_CONFLICT==1 + if (numberConflictCuts>lastNumberConflictCuts) { + double length = lengthConflictCuts/numberConflictCuts; + printf("%d new conflict cuts - total %d - average length %g\n", + numberConflictCuts-lastNumberConflictCuts, + numberConflictCuts,length); + lastNumberConflictCuts = numberConflictCuts; + } +#endif if (eventHandler && !eventHandler->event(CbcEventHandler::treeStatus)) { eventHappened_ = true; // exit } @@ -4540,7 +4777,8 @@ //unlockThread(); } else { // Deterministic parallel - if (tree_->size() < CoinMax(numberThreads_, 8) && !goneParallel) { + if ((tree_->size() < CoinMax(numberThreads_, 8)|| + hotstartSolution_) && !goneParallel) { node = tree_->bestNode(cutoff) ; // Possible one on tree worse than cutoff if (!node || node->objectiveValue() > cutoff) @@ -4599,9 +4837,6 @@ if (master_) { master_->stopThreads(-1); master_->waitForThreadsInTree(2); - delete master_; - master_ = NULL; - masterThread_ = NULL; // adjust time to allow for children on some systems //dblParam_[CbcStartSeconds] -= CoinCpuTimeJustChildren(); } @@ -4623,6 +4858,18 @@ if (tree_->size()) { double dummyBest; tree_->cleanTree(this, -COIN_DBL_MAX, dummyBest) ; +#if 0 // Does not seem to be needed def CBC_THREAD + if (parallelMode() > 0 && master_) { + // see if any dangling nodes + int numberThreads = master_->numberThreads(); + for (int i=0;ichild(i); + //if (child->createdNode()) + //printf("CHILD_NODE %p\n",child->createdNode()); + delete child->createdNode(); + } + } +#endif } delete nextRowCut_; /* order is important here: @@ -4661,6 +4908,13 @@ status_ = 5 ; } } +#ifdef CBC_THREAD + if (master_) { + delete master_; + master_ = NULL; + masterThread_ = NULL; + } +#endif /* That's it, we've exhausted the search tree, or broken out of the loop because we hit some limit on evaluation. @@ -4691,6 +4945,28 @@ << numberIterations_ << numberNodes_ << getCurrentSeconds() << CoinMessageEol ; } + if ((moreSpecialOptions_&4194304)!=0) { + // Conflict cuts + int numberCuts = globalCuts_.sizeRowCuts(); + int nConflict=0; + double sizeConflict = 0.0; + for (int i=0;iwhichRow()==1) { + nConflict++; + sizeConflict += cut->row().getNumElements(); + } + } + if (nConflict) { + sizeConflict /= nConflict; + char general[200]; + sprintf(general, "%d conflict cuts generated - average length %g", + nConflict,sizeConflict); + messageHandler()->message(CBC_GENERAL, + messages()) + << general << CoinMessageEol ; + } + } if (numberStrongIterations_) handler_->message(CBC_STRONG_STATS, messages_) << strongInfo_[0] << numberStrongIterations_ << strongInfo_[2] @@ -4702,8 +4978,12 @@ else handler_->message(CBC_OTHER_STATS2, messages_) << maximumDepthActual_ - << numberDJFixed_ << numberExtraNodes_ << numberExtraIterations_ + << numberDJFixed_ << numberFathoms_ << numberExtraNodes_ << numberExtraIterations_ << CoinMessageEol ; +#ifdef COIN_HAS_NTY + if (symmetryInfo_) + symmetryInfo_->statsOrbits(this,1); +#endif if (doStatistics == 100) { for (int i = 0; i < numberObjects_; i++) { CbcSimpleIntegerDynamicPseudoCost * obj = @@ -4962,7 +5242,7 @@ globalCuts_ = CbcRowCuts() ; delete globalConflictCuts_; globalConflictCuts_=NULL; - if (!bestSolution_ && (specialOptions_&8388608)==0) { + if (!bestSolution_ && (specialOptions_&8388608)==0 && false) { // make sure lp solver is infeasible int numberColumns = solver_->getNumCols(); const double * columnLower = solver_->getColLower(); @@ -4971,6 +5251,18 @@ if (solver_->isInteger(iColumn)) solver_->setColUpper(iColumn, columnLower[iColumn]); } +#ifdef COIN_HAS_CLP + { + OsiClpSolverInterface * clpSolver + = dynamic_cast (solver_); + if (clpSolver) { + solver_->setHintParam(OsiDoPresolveInInitial, true, OsiHintDo) ; + solver_->setHintParam(OsiDoDualInInitial, true, OsiHintDo) ; + ClpSimplex * simplex = clpSolver->getModelPtr(); + simplex->allSlackBasis(); + } + } +#endif solver_->initialSolve(); } #ifdef COIN_HAS_CLP @@ -5196,6 +5488,7 @@ usedInSolution_(NULL), specialOptions_(0), moreSpecialOptions_(0), + moreSpecialOptions2_(0), topOfTree_(NULL), subTreeModel_(NULL), heuristicModel_(NULL), @@ -5219,6 +5512,9 @@ lastHeuristic_(NULL), fastNodeDepth_(-1), eventHandler_(NULL), +#ifdef COIN_HAS_NTY + symmetryInfo_(NULL), +#endif numberObjects_(0), object_(NULL), ownObjects_(true), @@ -5227,6 +5523,7 @@ numberGlobalViolations_(0), numberExtraIterations_(0), numberExtraNodes_(0), + numberFathoms_(0), continuousObjective_(COIN_DBL_MAX), originalContinuousObjective_(COIN_DBL_MAX), continuousInfeasibilities_(COIN_INT_MAX), @@ -5234,7 +5531,7 @@ maximumCutPasses_(10), preferredWay_(0), currentPassNumber_(0), - maximumWhich_(1000), + maximumWhich_(INITIAL_MAXIMUM_WHICH), maximumRows_(0), randomSeed_(-1), multipleRootTries_(0), @@ -5264,6 +5561,7 @@ storedRowCuts_(NULL), numberThreads_(0), threadMode_(0), + numberGlobalCutsIn_(0), master_(NULL), masterThread_(NULL) { @@ -5360,6 +5658,7 @@ integerInfo_(NULL), specialOptions_(0), moreSpecialOptions_(0), + moreSpecialOptions2_(0), topOfTree_(NULL), subTreeModel_(NULL), heuristicModel_(NULL), @@ -5383,6 +5682,9 @@ lastHeuristic_(NULL), fastNodeDepth_(-1), eventHandler_(NULL), +#ifdef COIN_HAS_NTY + symmetryInfo_(NULL), +#endif numberObjects_(0), object_(NULL), ownObjects_(true), @@ -5391,6 +5693,7 @@ numberGlobalViolations_(0), numberExtraIterations_(0), numberExtraNodes_(0), + numberFathoms_(0), continuousObjective_(COIN_DBL_MAX), originalContinuousObjective_(COIN_DBL_MAX), continuousInfeasibilities_(COIN_INT_MAX), @@ -5398,7 +5701,7 @@ maximumCutPasses_(10), preferredWay_(0), currentPassNumber_(0), - maximumWhich_(1000), + maximumWhich_(INITIAL_MAXIMUM_WHICH), maximumRows_(0), randomSeed_(-1), multipleRootTries_(0), @@ -5428,6 +5731,7 @@ storedRowCuts_(NULL), numberThreads_(0), threadMode_(0), + numberGlobalCutsIn_(0), master_(NULL), masterThread_(NULL) { @@ -5488,7 +5792,7 @@ if (numberColumns) { // Space for current solution currentSolution_ = new double[numberColumns]; - continuousSolution_ = new double[numberColumns]; + continuousSolution_ = CoinCopyOfArray(solver_->getColSolution(),numberColumns); usedInSolution_ = new int[numberColumns]; CoinZeroN(usedInSolution_, numberColumns); for (iColumn = 0; iColumn < numberColumns; iColumn++) { @@ -5655,6 +5959,7 @@ secondaryStatus_(rhs.secondaryStatus_), specialOptions_(rhs.specialOptions_), moreSpecialOptions_(rhs.moreSpecialOptions_), + moreSpecialOptions2_(rhs.moreSpecialOptions2_), topOfTree_(NULL), subTreeModel_(rhs.subTreeModel_), heuristicModel_(NULL), @@ -5675,6 +5980,7 @@ numberGlobalViolations_(rhs.numberGlobalViolations_), numberExtraIterations_(rhs.numberExtraIterations_), numberExtraNodes_(rhs.numberExtraNodes_), + numberFathoms_(rhs.numberFathoms_), continuousObjective_(rhs.continuousObjective_), originalContinuousObjective_(rhs.originalContinuousObjective_), continuousInfeasibilities_(rhs.continuousInfeasibilities_), @@ -5712,6 +6018,7 @@ storedRowCuts_(NULL), numberThreads_(rhs.numberThreads_), threadMode_(rhs.threadMode_), + numberGlobalCutsIn_(rhs.numberGlobalCutsIn_), master_(NULL), masterThread_(NULL) { @@ -5784,6 +6091,11 @@ numberObjects_ = 0; object_ = NULL; } + if (rhs.continuousSolver_) { + continuousSolver_ = rhs.continuousSolver_->clone() ; + } else { + continuousSolver_ = NULL ; + } if (rhs.referenceSolver_) referenceSolver_ = rhs.referenceSolver_->clone(); else @@ -5865,10 +6177,16 @@ savedSolutions_ = NULL; } // Space for current solution - currentSolution_ = new double[numberColumns]; - continuousSolution_ = new double[numberColumns]; - usedInSolution_ = new int[numberColumns]; - CoinZeroN(usedInSolution_, numberColumns); + if (numberColumns) { + currentSolution_ = new double[numberColumns]; + continuousSolution_ = CoinCopyOfArray(solver_->getColSolution(),numberColumns); + usedInSolution_ = new int[numberColumns]; + CoinZeroN(usedInSolution_, numberColumns); + } else { + currentSolution_ = NULL; + continuousSolution_ = NULL; + usedInSolution_ = NULL; + } testSolution_ = currentSolution_; numberRowsAtContinuous_ = rhs.numberRowsAtContinuous_; cutoffRowNumber_ = rhs.cutoffRowNumber_; @@ -5900,6 +6218,12 @@ } else { lastCut_ = NULL; } +#ifdef COIN_HAS_NTY + if (rhs.symmetryInfo_) + symmetryInfo_ = new CbcSymmetry(*rhs.symmetryInfo_); + else + symmetryInfo_ = NULL; +#endif synchronizeModel(); if (cloneHandler && !defaultHandler_) { delete handler_; @@ -5978,7 +6302,7 @@ if (numberColumns) { // Space for current solution currentSolution_ = new double[numberColumns]; - continuousSolution_ = new double[numberColumns]; + continuousSolution_ = CoinCopyOfArray(solver_->getColSolution(),numberColumns); usedInSolution_ = new int[numberColumns]; CoinZeroN(usedInSolution_, numberColumns); } else { @@ -6009,6 +6333,7 @@ secondaryStatus_ = rhs.secondaryStatus_; specialOptions_ = rhs.specialOptions_; moreSpecialOptions_ = rhs.moreSpecialOptions_; + moreSpecialOptions2_ = rhs.moreSpecialOptions2_; subTreeModel_ = rhs.subTreeModel_; heuristicModel_ = NULL; numberStoppedSubTrees_ = rhs.numberStoppedSubTrees_; @@ -6028,6 +6353,7 @@ numberGlobalViolations_ = rhs.numberGlobalViolations_; numberExtraIterations_ = rhs.numberExtraIterations_; numberExtraNodes_ = rhs.numberExtraNodes_; + numberFathoms_ = rhs.numberFathoms_; continuousObjective_ = rhs.continuousObjective_; originalContinuousObjective_ = rhs.originalContinuousObjective_; continuousInfeasibilities_ = rhs.continuousInfeasibilities_; @@ -6088,6 +6414,7 @@ } numberThreads_ = rhs.numberThreads_; threadMode_ = rhs.threadMode_; + numberGlobalCutsIn_ = rhs.numberGlobalCutsIn_; delete master_; master_ = NULL; masterThread_ = NULL; @@ -6233,6 +6560,12 @@ } else { lastCut_ = NULL; } +#ifdef COIN_HAS_NTY + if (rhs.symmetryInfo_) + symmetryInfo_ = new CbcSymmetry(*rhs.symmetryInfo_); + else + symmetryInfo_ = NULL; +#endif synchronizeModel(); cbcColLower_ = NULL; cbcColUpper_ = NULL; @@ -6324,6 +6657,10 @@ cutModifier_ = NULL; topOfTree_ = NULL; resetModel(); +#ifdef COIN_HAS_NTY + delete symmetryInfo_; + symmetryInfo_ = NULL; +#endif } // Clears out enough to reset CbcModel void @@ -6432,6 +6769,7 @@ numberGlobalViolations_ = 0; numberExtraIterations_ = 0; numberExtraNodes_ = 0; + numberFathoms_ = 0; continuousObjective_ = 0.0; originalContinuousObjective_ = 0.0; continuousInfeasibilities_ = 0; @@ -6465,6 +6803,7 @@ minimumDrop_ = rhs.minimumDrop_; specialOptions_ = rhs.specialOptions_; moreSpecialOptions_ = rhs.moreSpecialOptions_; + moreSpecialOptions2_ = rhs.moreSpecialOptions2_; numberStrong_ = rhs.numberStrong_; numberBeforeTrust_ = rhs.numberBeforeTrust_; numberPenalties_ = rhs.numberPenalties_; @@ -6489,6 +6828,7 @@ continuousPriority_ = rhs.continuousPriority_; numberThreads_ = rhs.numberThreads_; threadMode_ = rhs.threadMode_; + numberGlobalCutsIn_ = rhs.numberGlobalCutsIn_; delete master_; master_ = NULL; masterThread_ = NULL; @@ -6519,8 +6859,9 @@ generator_[i] = new CbcCutGenerator(*rhs.generator_[i]); } else { generator_[i] = new CbcCutGenerator(*rhs.virginGenerator_[i]); - // But copy across maximumTries + // But copy across maximumTries and switches generator_[i]->setMaximumTries(rhs.generator_[i]->maximumTries()); + generator_[i]->setSwitches(rhs.generator_[i]->switches()); } virginGenerator_[i] = new CbcCutGenerator(*rhs.virginGenerator_[i]); } @@ -6548,6 +6889,12 @@ branchingMethod_ = NULL; messageHandler()->setLogLevel(rhs.messageHandler()->logLevel()); whenCuts_ = rhs.whenCuts_; +#ifdef COIN_HAS_NTY + if (rhs.symmetryInfo_) + symmetryInfo_ = new CbcSymmetry (*rhs.symmetryInfo_); + else + symmetryInfo_ = NULL; +#endif synchronizeModel(); } // Move status, nodes etc etc across @@ -6773,7 +7120,11 @@ heuristic_[where] = generator->clone(); if (name) heuristic_[where]->setHeuristicName(name) ; +#ifndef SAME_HEURISTIC_SEED heuristic_[where]->setSeed(987654321 + where); +#else + heuristic_[where]->setSeed(987654321); +#endif numberHeuristics_++ ; } @@ -6819,6 +7170,7 @@ redoWalkBack(); } } + resizeWhichGenerator(currentNumberCuts_,currentNumberCuts); currentNumberCuts_ = currentNumberCuts; if (currentNumberCuts > maximumNumberCuts_) { maximumNumberCuts_ = currentNumberCuts; @@ -6912,7 +7264,8 @@ because we need the parameter to return the allocated basis, and it's an easy way to pass in the size. But we take a hit for memory allocation. */ - lastws->setSize(numberColumns, numberRowsAtContinuous_ + currentNumberCuts); + if (lastws) + lastws->setSize(numberColumns, numberRowsAtContinuous_ + currentNumberCuts); currentNumberCuts = 0; while (nNode) { --nNode; @@ -6920,7 +7273,7 @@ addedCuts_, currentNumberCuts); } #ifndef NDEBUG - if (!lastws->fullBasis()) { + if (lastws&&!lastws->fullBasis()) { #ifdef COIN_DEVELOP printf("******* bad basis\n"); #endif @@ -6945,7 +7298,7 @@ reference counts to reflect that we're about to prune this node and its descendants. */ -int CbcModel::addCuts (CbcNode *node, CoinWarmStartBasis *&lastws, bool canFix) +int CbcModel::addCuts (CbcNode *node, CoinWarmStartBasis *&lastws) { /* addCuts1 performs step 1 of restoring the subproblem at this node; see the @@ -6962,57 +7315,6 @@ CbcNodeInfo * nodeInfo = node->nodeInfo(); double cutoff = getCutoff() ; int currentNumberCuts = currentNumberCuts_; - if (canFix) { - bool feasible = true; - const double *lower = solver_->getColLower() ; - const double *upper = solver_->getColUpper() ; - double * newLower = analyzeResults_; - double * objLower = newLower + numberIntegers_; - double * newUpper = objLower + numberIntegers_; - double * objUpper = newUpper + numberIntegers_; - int n = 0; - for (i = 0; i < numberIntegers_; i++) { - int iColumn = integerVariable_[i]; - bool changed = false; - double lo = 0.0; - double up = 0.0; - if (objLower[i] > cutoff) { - lo = lower[iColumn]; - up = upper[iColumn]; - if (lo < newLower[i]) { - lo = newLower[i]; - solver_->setColLower(iColumn, lo); - changed = true; - n++; - } - if (objUpper[i] > cutoff) { - if (up > newUpper[i]) { - up = newUpper[i]; - solver_->setColUpper(iColumn, up); - changed = true; - n++; - } - } - } else if (objUpper[i] > cutoff) { - lo = lower[iColumn]; - up = upper[iColumn]; - if (up > newUpper[i]) { - up = newUpper[i]; - solver_->setColUpper(iColumn, up); - changed = true; - n++; - } - } - if (changed && lo > up) { - feasible = false; - break; - } - } - if (!feasible) { - COIN_DETAIL_PRINT(printf("analysis says node infeas\n")); - cutoff = -COIN_DBL_MAX; - } - } /* If the node can't be fathomed by bound, reinstall tight cuts in the constraint system. Even if there are no cuts, we'll want to set the @@ -7044,6 +7346,10 @@ addCuts = new const OsiRowCut* [currentNumberCuts]; cutsToDrop = new int[currentNumberCuts] ; assert (currentNumberCuts + numberRowsAtContinuous_ <= lastws->getNumArtificial()); + assert (currentNumberCuts <= maximumWhich_); // we will read from whichGenerator_[0..currentNumberCuts-1] below, so should have all these entries + // the above assert fails in certain situations, which indicates a bug in the code below + // as a workaround, resize whichGenerator_ to make sure we can read all entries without an invalid read from valgrind (and subsequent crash somewhere, seems so) + resizeWhichGenerator(maximumWhich_, currentNumberCuts); for (i = 0; i < currentNumberCuts; i++) { CoinWarmStartBasis::Status status = lastws->getArtifStatus(i + numberRowsAtContinuous_); @@ -7055,6 +7361,8 @@ printf("Using cut %d %x as row %d\n", i, addedCuts_[i], numberRowsAtContinuous_ + numberToAdd); # endif + assert (igetNumRows(); - //for (int j=0;jprint(); solver_->applyRowCuts(numberToAdd, addCuts); - //int n3=solver_->getNumRows(); - //printf("NBefore %d, after del %d, now %d\n",n1,n2,n3); } # ifdef CBC_CHECK_BASIS printf("addCuts: stripped basis; rows %d + %d\n", numberRowsAtContinuous_, numberToAdd); lastws->print(); # endif - //for (i=0;i maximumWhich_) { - maximumWhich_ = CoinMax(maximumWhich_ * 2 + 100, numberAfter) ; +#define MAXIMUM_WHICH_INCREMENT 100 +#define MAXIMUM_WHICH_MULTIPLIER 2 + //printf("maximumWhich from %d to %d (%d needed)\n",maximumWhich_, + // CoinMax(maximumWhich_ * MAXIMUM_WHICH_MULTIPLIER + MAXIMUM_WHICH_INCREMENT, numberAfter), + // numberAfter); + maximumWhich_ = CoinMax(maximumWhich_ * MAXIMUM_WHICH_MULTIPLIER + MAXIMUM_WHICH_INCREMENT, numberAfter) ; + //maximumWhich_ = numberAfter ; int * temp = new int[2*maximumWhich_] ; memcpy(temp, whichGenerator_, numberNow*sizeof(int)) ; delete [] whichGenerator_ ; @@ -7502,22 +7813,38 @@ moreSpecialOptions_ |= 8388608; int returnCode = resolve(node ? node->nodeInfo() : NULL, 1); moreSpecialOptions_=save; -#ifdef CONFLICT_CUTS +#ifdef CONFLICT_CUTS #ifdef COIN_HAS_CLP // if infeasible conflict analysis if (solver_->isProvenPrimalInfeasible()&&!parentModel_&& (moreSpecialOptions_&4194304)!=0&&clpSolver) { - //printf("infeasible - do conflict analysis\n"); + if (!topOfTree_ && masterThread_) + topOfTree_ = masterThread_->master_->baseModel_->topOfTree_; assert (topOfTree_); - int iType=1; + int iType=0; OsiRowCut * cut = clpSolver->modelCut(topOfTree_->lower(), topOfTree_->upper(), numberRowsAtContinuous_,whichGenerator_,iType); if (cut) { - printf("XXXXXX cut\n"); //cut->print(); if (!iType) { - makeGlobalCut(cut) ; + int badCut = makeGlobalCut(cut) ; + if (!badCut) { +#if PRINT_CONFLICT==1 + numberConflictCuts++; + lengthConflictCuts += cut->row().getNumElements(); +#endif +#if PRINT_CONFLICT<2 + if (handler_->logLevel() > 1) { +#endif + printf("Conflict cut at depth %d (%d elements)\n", + currentDepth_,cut->row().getNumElements()); + if (cut->row().getNumElements()<3) + cut->print(); +#if PRINT_CONFLICT<2 + } +#endif + } if ((specialOptions_&1) != 0) { debugger = continuousSolver_->getRowCutDebugger() ; if (debugger) { @@ -7542,10 +7869,6 @@ } #endif #endif -#if COIN_DEVELOP>1 - //if (!solver_->getIterationCount()&&solver_->isProvenOptimal()) - //printf("zero iterations on first solve of branch\n"); -#endif double lastObjective = solver_->getObjValue() * solver_->getObjSense(); cut_obj[CUT_HISTORY-1] = lastObjective; //double firstObjective = lastObjective+1.0e-8+1.0e-12*fabs(lastObjective); @@ -7573,6 +7896,13 @@ if (problemFeasibility_->feasible(this, 0) < 0) { feasible = false; // pretend infeasible } + //#define CHECK_KNOWN_SOLUTION +#ifdef CHECK_KNOWN_SOLUTION + if (onOptimalPath && (solver_->isDualObjectiveLimitReached()|| + !feasible)) { + printf("help 1\n"); + } +#endif /* NEW_UPDATE_OBJECT is defined to 0 when unthreaded (CBC_THREAD undefined), 2 when threaded. No sign of 1 as of 071220. @@ -7705,7 +8035,6 @@ double originalValue = node->objectiveValue(); double objectiveValue = solver_->getObjValue() * solver_->getObjSense(); double changeInObjective = CoinMax(0.0, objectiveValue - originalValue); - int iStatus = (feasible) ? 0 : 0; double value = obj->value(); double movement; if (branch) @@ -7713,7 +8042,7 @@ else movement = value - floor(value); branchingMethod_->chooseMethod()->updateInformation(iObject, branch, changeInObjective, - movement, iStatus); + movement, 0 /*(feasible) ? 0 : 1; */); } } } @@ -7769,6 +8098,27 @@ - objectiveValue ; if ( maximumSecondsReached() ) numberTries = 0; // exit + if ((moreSpecialOptions2_&(2048|4096))!=0 && currentDepth_>5) { + // howOftenGlobalScan_ = 10; + int type = (moreSpecialOptions2_&(2048|4096))>>11; + if (type==1) { + int n=0; + int k=currentDepth_; + while (k) { + if ((k&1)!=0) + n++; + k = k >>1; + } + if (n>1) + numberTries=0; + } else if (type==2) { + if ((currentDepth_%4)!=0) + numberTries=0; + } else { + if ((currentDepth_%8)!=0) + numberTries=0; + } + } //if ((numberNodes_%100)==0) //printf("XXa sum obj changed by %g\n",sumChangeObjective1_); objectiveValue = solver_->getObjValue() * solver_->getObjSense(); @@ -7920,7 +8270,7 @@ thisCut->effectiveness() == COIN_DBL_MAX); #define CHECK_DEBUGGER #ifdef CHECK_DEBUGGER - if ((specialOptions_&1) != 0 ) { + if ((specialOptions_&1) != 0 && ! parentModel_) { CoinAssert (!solver_->getRowCutDebuggerAlways()->invalidCut(*thisCut)); } #endif @@ -7928,7 +8278,7 @@ printf("Global cut added - violation %g\n", thisCut->violated(cbcColSolution_)) ; #endif - whichGenerator_[numberViolated++] = -1; + whichGenerator_[numberViolated++] = 20099; #ifndef GLOBAL_CUTS_JUST_POINTERS theseCuts.insert(*thisCut) ; #else @@ -7979,7 +8329,7 @@ #ifdef JJF_ZERO//def COIN_HAS_CLP if (clpSolver) clpSolver->setSpecialOptions(save); -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 if (clpSolver->getModelPtr()->numberIterations()) printf("ITS %d pass %d\n", clpSolver->getModelPtr()->numberIterations(), @@ -8013,7 +8363,7 @@ // possibly extend whichGenerator resizeWhichGenerator(numberViolated, numberViolated + 1); // set whichgenerator (also serves as marker to say don't delete0 - whichGenerator_[numberViolated++] = -2; + whichGenerator_[numberViolated++] = 20098; } // reset probing info @@ -8095,7 +8445,7 @@ found = i ; incrementUsed(newSolution); lastHeuristic_ = heuristic_[found]; -#ifdef CLP_INVESTIGATE +#ifdef HEURISTIC_INFORM printf("HEUR %s where %d A\n", lastHeuristic_->heuristicName(), whereFrom); #endif @@ -8241,6 +8591,8 @@ #endif int numberToAdd = theseCuts.sizeRowCuts() ; numberNewCuts_ = lastNumberCuts + numberToAdd ; + // resize whichGenerator + resizeWhichGenerator(lastNumberCuts,numberNewCuts_); /* Now actually add the row cuts and reoptimise. @@ -8265,10 +8617,12 @@ if (numberRowCuts > 0 || numberColumnCuts > 0) { if (numberToAdd > 0) { int i ; + int * whichGenerator = whichGenerator_ + lastNumberCuts; // Faster to add all at once addCuts = new const OsiRowCut * [numberToAdd] ; for (i = 0 ; i < numberToAdd ; i++) { addCuts[i] = &theseCuts.rowCut(i) ; + whichGenerator[i]=90; } if ((specialOptions_&262144) != 0 && !parentModel_) { //save @@ -8300,6 +8654,7 @@ if ( maximumSecondsReached() ) { numberTries = -1000; // exit feasible = false; + delete [] addCuts ; break; } # ifdef CBC_DEBUG @@ -8412,7 +8767,7 @@ break; } } -#ifdef CLP_INVESTIGATE2 +#if CBC_USEFUL_PRINTING>12 if (!parentModel_ && !numberNodes_) printf("badObj %s nBad %d maxBad %d goodDrop %g minDrop %g thisDrop %g obj %g\n", badObj ? "true" : "false", @@ -8435,7 +8790,7 @@ double drop[12] = {1.0, 2.0, 3.0, 10.0, 10.0, 10.0, 10.0, 20.0, 100.0, 100.0, 1000.0, 1000.0}; if (thisObj - lastObjective > drop[currentDepth_]*minimumDrop) { numberTries++; -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 //printf("drop %g %g %d\n",thisObj,lastObjective,currentPassNumber_); #endif } @@ -8522,8 +8877,7 @@ // point to useful information OsiBranchingInformation usefulInfo = usefulInformation(); for (int i = 0; i < numberObjects_ && integerFeasible; i++) { - int preferredWay; - double infeasibility = object_[i]->infeasibility(&usefulInfo, preferredWay); + double infeasibility = object_[i]->checkInfeasibility(&usefulInfo); if (infeasibility) integerFeasible = false; } @@ -8550,7 +8904,7 @@ resizeWhichGenerator(numberCuts, numberToAdd + numberCuts); for (int i = numberGlobalBefore ; i < numberGlobalAfter ; i++) { - whichGenerator_[numberNewCuts_++] = -1; + whichGenerator_[numberNewCuts_++] = 20099; #ifndef GLOBAL_CUTS_JUST_POINTERS cuts.insert(*globalCuts_.rowCutPtr(i)) ; #else @@ -8633,7 +8987,7 @@ found = i ; incrementUsed(newSolution); lastHeuristic_ = heuristic_[found]; -#ifdef CLP_INVESTIGATE +#ifdef HEURISTIC_INFORM printf("HEUR %s where %d B\n", lastHeuristic_->heuristicName(), whereFrom); #endif @@ -8752,7 +9106,7 @@ int size = continuousSolver_->getNumRows() + continuousSolver_->getNumCols(); bool smallProblem = size <= 550; smallProblem = false; -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 int maxPass = maximumCutPasses_; #endif if (thisObjective - startObjective < 1.0e-5) { @@ -8849,7 +9203,7 @@ if (maximumCutPasses_ <= 5) whenCuts_ += 100000; //// end -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("changing whenCuts from %d to %d and cutPasses from %d to %d objchange %g\n", whenC, whenCuts_, maxPass, maximumCutPasses_, thisObjective - startObjective); #endif @@ -8906,7 +9260,7 @@ static_cast (currentPassNumber_)); if (numberColumns < 200) value = CoinMax(minimumDrop_, 0.1 * value); -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("Minimum drop for cuts was %g, now is %g\n", minimumDrop_, value); #endif minimumDrop_ = value; @@ -8916,12 +9270,19 @@ int numberActiveGenerators = 0; for (i = 0; i < numberNewCuts_; i++) { int iGenerator = whichGenerator_[i]; + //assert (iGenerator>=0); if (iGenerator>=0) iGenerator=iGenerator%10000; if (iGenerator >= 0 && iGenerator < numberCutGenerators_) count[iGenerator]++ ; } // add in any active cuts if at root node (for multiple solvers) +#ifdef CHECK_KNOWN_SOLUTION + if (onOptimalPath && (solver_->isDualObjectiveLimitReached()|| + !feasible)) { + printf("help 2\n"); + } +#endif if (!numberNodes_) { for (i = 0; i < numberCutGenerators_; i++) count[i] += generator_[i]->numberCutsActive(); @@ -9301,9 +9662,12 @@ if (feasible) { for (i = 0; i < numberNewCuts_; i++) { int iGenerator = whichGenerator_[i]; +#ifdef CONFLICT_CUTS + assert (iGenerator>=0); +#endif if (iGenerator>=0) iGenerator=iGenerator%10000; - if (iGenerator >= 0) + if (iGenerator >= 0 && iGenerator < numberCutGenerators_) generator_[iGenerator]->incrementNumberCutsActive(); } } @@ -9320,6 +9684,12 @@ delete basis; } #endif +#ifdef CHECK_KNOWN_SOLUTION + if (onOptimalPath && (solver_->isDualObjectiveLimitReached()|| + !feasible)) { + printf("help\n"); + } +#endif #ifdef CBC_DEBUG if (onOptimalPath && !solver_->isDualObjectiveLimitReached()) assert(feasible) ; @@ -9465,7 +9835,7 @@ } } #endif - if (mustResolve || (specialOptions_&1) != 0) { + if (mustResolve /*|| (specialOptions_&1) != 0*/) { int returnCode = resolve(node ? node->nodeInfo() : NULL, 2); if (returnCode == 0) status = -1; @@ -9536,7 +9906,7 @@ dodgyCuts = true; break; } - whichGenerator_[numberBefore++] = i ; + whichGenerator_[numberBefore++] = i+20000 ; if (!numberNodes_||generator_[i]->globalCuts()) whichGenerator_[numberBefore-1]=i+10000; if (thisCut->lb() > thisCut->ub()) @@ -9561,7 +9931,7 @@ numberRowCutsAfter = theseCuts.sizeRowCuts() ; for (; j < numberRowCutsAfter; j++) { const OsiRowCut * thisCut = theseCuts.rowCutPtr(j) ; - whichGenerator_[numberBefore++] = i ; + whichGenerator_[numberBefore++] = i+20000 ; if (!numberNodes_||generator_[i]->globalCuts()) whichGenerator_[numberBefore-1]=i+10000; if (thisCut->globallyValid()) { @@ -9612,7 +9982,7 @@ if (messageHandler()->logLevel() > 2) printf("Old cut added - violation %g\n", thisCut->violated(cbcColSolution_)) ; - whichGenerator_[numberOld++] = -3; + whichGenerator_[numberOld++] = 20097; theseCuts.insert(*thisCut) ; } } @@ -9672,10 +10042,20 @@ int numberDropped = 0; int firstOldCut = numberRowsAtContinuous_ ; int totalNumberCuts = numberNewCuts_ + numberOldActiveCuts_ ; + assert (numberRowsAtContinuous_+totalNumberCuts== + solver_->getNumRows()); int *solverCutIndices = new int[totalNumberCuts] ; int *newCutIndices = new int[numberNewCuts_] ; const CoinWarmStartBasis* ws ; CoinWarmStartBasis::Status status ; + //#define COIN_HAS_CLP_KEEP_STATUS +#ifdef COIN_HAS_CLP_KEEP_STATUS + int problemStatus=-1; + OsiClpSolverInterface * clpSolver + = dynamic_cast (solver_); + if (clpSolver) + problemStatus=clpSolver->getModelPtr()->status(); +#endif bool needPurge = true ; /* The outer loop allows repetition of purge in the event that reoptimisation @@ -9686,6 +10066,7 @@ int numberNewToDelete = 0 ; int numberOldToDelete = 0 ; int i ; + int kCut=0; ws = dynamic_cast(solver_->getWarmStart()) ; /* Scan the basis entries of the old cuts generated prior to this round of cut @@ -9711,6 +10092,7 @@ OsiRowCut * slackCut = addedCuts_[oldCutIndex]; if (slackCut->effectiveness() != -1.234) { slackCut->setEffectiveness(-1.234); + slackCut->setGloballyValid(); saveCuts->insert(*slackCut); } } @@ -9719,7 +10101,11 @@ addedCuts_[oldCutIndex] = NULL ; oldCutIndex++ ; } else { - oldCutIndex++ ; + int iGenerator = addedCuts_[oldCutIndex]->whichCutGenerator(); + if (iGenerator==-1) + iGenerator=100; + whichGenerator_[kCut++] = iGenerator ; + oldCutIndex++; } } unlockThread(); @@ -9732,7 +10118,6 @@ front. */ int firstNewCut = firstOldCut + numberOldActiveCuts_ ; - int k = 0 ; int nCuts = newCuts.sizeRowCuts(); for (i = 0 ; i < nCuts ; i++) { status = ws->getArtifStatus(i + firstNewCut) ; @@ -9741,8 +10126,8 @@ solverCutIndices[numberNewToDelete+numberOldToDelete] = i + firstNewCut ; newCutIndices[numberNewToDelete++] = i ; } else { // save which generator did it - // -2 means branch cut! assert (whichGenerator_[i]!=-2); // ?? what if it is - memory leak? - whichGenerator_[k++] = whichGenerator_[i] ; + // 20098 means branch cut! assert (whichGenerator_[i]!=20098); // ?? what if it is - memory leak? + whichGenerator_[kCut++] = whichGenerator_[i] ; } } int baseRow = firstNewCut + nCuts; @@ -9773,6 +10158,7 @@ OsiRowCut * slackCut = newCuts.rowCutPtrAndZap(iCut); if (slackCut->effectiveness() != -1.234) { slackCut->setEffectiveness(-1.234); + slackCut->setGloballyValid(); saveCuts->insert(slackCut); } else { delete slackCut; @@ -9822,6 +10208,12 @@ needPurge = false ; } } + +#ifdef COIN_HAS_CLP_KEEP_STATUS + // need to check further that only zero duals dropped + if (clpSolver) // status may have got to -1 + clpSolver->getModelPtr()->setProblemStatus(problemStatus); +#endif /* Clean up and return. */ @@ -9845,6 +10237,14 @@ void cbc_resolve_check(const OsiSolverInterface * solver); cbc_resolve_check(solver_); #endif + bool onOptimalPath = false; + if ((specialOptions_&1) != 0) { + const OsiRowCutDebugger *debugger = solver_->getRowCutDebugger() ; + if (debugger) { + onOptimalPath = true; + printf("On optimal path d\n") ; + } + } // We may have deliberately added in violated cuts - check to avoid message int iRow; int numberRows = solver_->getNumRows(); @@ -9877,14 +10277,6 @@ a solution where the objective is right on the cutoff. */ if (feasible) { - bool onOptimalPath = false; - if ((specialOptions_&1) != 0) { - const OsiRowCutDebugger *debugger = solver_->getRowCutDebugger() ; - if (debugger) { - onOptimalPath = true; - printf("On optimal path d\n") ; - } - } int nTightened = 0; #ifdef COIN_HAS_CLP // Pierre pointed out that this is not valid for all solvers @@ -9922,7 +10314,7 @@ solver_->getObjValue(); //double cutoff = getCutoff(); if (bestObjective_ - getCutoffIncrement() < testValue) { -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 double value ; solver_->getDblParam(OsiDualObjectiveLimit, value) ; printf("Should cutoff as obj %.18g, best %.18g, inc %.18g - solver cutoff %.18g model cutoff %.18g\n", @@ -10170,6 +10562,20 @@ returnStatus = 0; } } +#if 0 + if ((specialOptions_&1) != 0 && onOptimalPath) { + const OsiRowCutDebugger *debugger = solver_->getRowCutDebugger() ; + if (!debugger) { + // tighten did something??? + solver_->getRowCutDebuggerAlways()->printOptimalSolution(*solver_); + solver_->writeMpsNative("infeas4.mps", NULL, NULL, 2); + printf("Not on optimalpath aaaa\n"); + //abort(); + } else { + printf("Still on optimal path\n"); + } + } +#endif return returnStatus ; } @@ -10415,7 +10821,7 @@ if (numberCliques) printf("%d cliques of average size %g found, %d P1, %d M1\n", numberCliques, - (static_cast(totalP1 + totalM1)) / (static_cast numberCliques), + (static_cast(totalP1 + totalM1)) / (static_cast (numberCliques)), totalP1, totalM1); else printf("No cliques found\n"); @@ -11101,8 +11507,13 @@ double costValue = CoinMax(1.0e-5, fabs(cost[iColumn])); // treat as if will cost what it says up double upCost = costValue; +#ifndef BRANCH_BREAKEVEN +#define BRANCH_BREAKEVEN 0.3 +#else + preferredWay=1; +#endif // and balance at breakeven of 0.3 - double downCost = (0.7 * upCost) / 0.3; + double downCost = ((1.0-BRANCH_BREAKEVEN) * upCost) / BRANCH_BREAKEVEN; if (obj1a) { upCost = obj1a->upPseudoCost(); downCost = obj1a->downPseudoCost(); @@ -11138,8 +11549,283 @@ // create one branchingMethod_ = new CbcBranchDynamicDecision(); } +#ifdef SWITCH_VARIABLES + // see if any switching variables + if (numberIntegers_getNumCols()) + findSwitching(); +#endif synchronizeNumberBeforeTrust(); } +#ifdef SWITCH_VARIABLES +// Convert Dynamic to Switching +int +CbcModel::findSwitching() +{ + if ((moreSpecialOptions2_&1)==0) + return 0; + const CoinPackedMatrix * rowCopy = solver_->getMatrixByRow(); + const int * column = rowCopy->getIndices(); + const int * rowLength = rowCopy->getVectorLengths(); + const CoinBigIndex * rowStart = rowCopy->getVectorStarts(); + const double * rowLower = solver_->getRowLower(); + const double * rowUpper = solver_->getRowUpper(); + const double * columnLower = solver_->getColLower(); + const double * columnUpper = solver_->getColUpper(); + const double * element = rowCopy->getElements(); + //const double * element = solver_->getMatrixByCol()->getElements(); + const int * row = solver_->getMatrixByCol()->getIndices(); + const CoinBigIndex * columnStart = solver_->getMatrixByCol()->getVectorStarts(); + const int * columnLength = solver_->getMatrixByCol()->getVectorLengths(); + int numberRows = solver_->getNumRows(); + int numberColumns = solver_->getNumCols(); + int * sort = new int[2*numberRows+2+numberColumns]; + int * whichRow = sort+numberRows+1; + int * marked = whichRow+numberRows+1; + memset(marked,0,numberColumns*sizeof(int)); + int nnSwitch=0; + int nnSwitchTotal=0; + int n2Switch=0; + double largeRatio1=1000.0; + double largeRatio2=100.0; + for (int i=0;i (object_[i])) + continue; + int nAdd=0; + bool takeThis=false; + CoinBigIndex start = columnStart[iColumn]; + CoinBigIndex end = start + columnLength[iColumn]; + for (CoinBigIndex j = start; j < end; j++) { + int iRow = row[j]; + if (rowLength[iRow]!=2) { + continue; + } + // for now just 0.0 in rhs + if (!rowLower[iRow]) { + if (rowUpper[iRow]!=COIN_DBL_MAX) + continue; + } else if (rowLower[iRow]!=-COIN_DBL_MAX) { + continue; + } else if (rowUpper[iRow]) { + continue; + } + CoinBigIndex k = rowStart[iRow]; + double bValue, cValue; + int cColumn; + if (column[k]==iColumn) { + bValue=element[k]; + cValue=element[k+1]; + cColumn=column[k+1]; + } else { + bValue=element[k+1]; + cValue=element[k]; + cColumn=column[k]; + } + if (solver_->isInteger(cColumn)) + continue; + if (columnLower[cColumn]<0.0) + continue; + if (bValue*cValue>0.0) + continue; + if (fabs(bValue)>largeRatio1*fabs(cValue)) + takeThis=true; + // add to list + whichRow[nAdd]=iRow; + sort[nAdd++]=cColumn; + } + if (nAdd) { + n2Switch++; + CoinSort_2(sort,sort+nAdd,whichRow); + int last=sort[0]; + for (int k=1;k (object_[i]); + if (thisOne) { + assert(iColumn == thisOne->columnNumber()); + object_[i]=new CbcSwitchingBinary(thisOne,nAdd,sort,whichRow); + delete thisOne; + } else { + CbcSimpleInteger * thisOne = + dynamic_cast (object_[i]); + assert (thisOne); + assert(iColumn == thisOne->columnNumber()); + CbcSimpleIntegerDynamicPseudoCost tempObj(this,iColumn,0.1); + object_[i]=new CbcSwitchingBinary(&tempObj,nAdd,sort,whichRow); + delete thisOne; + } + } + } + // see if there is an interesting row + for (CoinBigIndex j = start; j < end; j++) { + int iRow = row[j]; + // for now just 0.0 in rhs + if (!rowLower[iRow]) { + if (rowUpper[iRow]!=COIN_DBL_MAX) + continue; + } else if (rowLower[iRow]!=-COIN_DBL_MAX) { + continue; + } else if (rowUpper[iRow]) { + continue; + } + int nOther=0; + double bEl=0.0; + double cMax=-COIN_DBL_MAX; + double cMin=COIN_DBL_MAX; + for (CoinBigIndex k = rowStart[iRow]; + kisInteger(jColumn)) { + cMin=-1.0; + cMax=1.0; + break; + } else { + cMax=CoinMax(cMax,element[k]); + cMin=CoinMin(cMin,element[k]); + if (columnLower[jColumn]<0.0) { + cMin=-1.0; + cMax=1.0; + break; + } + } + } + } + double largestC = CoinMax(fabs(cMin),fabs(cMax)); + if (((cMin>0.0&&bEl<0.0&&!rowUpper[iRow])|| + (cMin<0.0&&bEl>0.0&&!rowLower[iRow]))&&cMin*cMax>0.0&& + fabs(bEl)>largeRatio2*largestC) { + // forces to zero + CbcSwitchingBinary * object = + dynamic_cast (object_[i]); + if (!object) { + // create empty one + CbcSimpleIntegerDynamicPseudoCost * thisOne = + dynamic_cast (object_[i]); + if (thisOne) { + assert(iColumn == thisOne->columnNumber()); + object=new CbcSwitchingBinary(thisOne,0,sort,whichRow); + delete thisOne; + } else { + CbcSimpleInteger * thisOne = + dynamic_cast (object_[i]); + assert (thisOne); + assert(iColumn == thisOne->columnNumber()); + CbcSimpleIntegerDynamicPseudoCost tempObj(this,iColumn,0.1); + object=new CbcSwitchingBinary(&tempObj,0,sort,whichRow); + delete thisOne; + } + object_[i]=object; + } + object->addZeroSwitches(nOther,sort); + nnSwitch++; + nnSwitchTotal+=nOther; + } + } + } + if (n2Switch+nnSwitch) { + if (handler_->logLevel()>2) + printf("%d two switch variables - %d multi (total multi %d)\n", + n2Switch,nnSwitch,nnSwitchTotal); + memset(whichRow,0,(numberRows+1)*sizeof(int)); + for (int i=0;ilogLevel()>2) { + for (int i=0;i (object_[i]); + if (object) { + n += object->setAssociatedBounds(solver,cleanBasis); + } + } + nChanged+=n; + } + } + return nChanged; +} +/* Debug associated variables + printLevel - 1 summary if bad on fixed + 2 summary if bad on satisfied + 3 for individuals + */ +int +CbcModel::checkAssociated(const OsiSolverInterface * solver, + const double * solution,int printLevel) +{ + int nBad=0; + int nBadFixed=0; + if ((moreSpecialOptions2_&4)!=0) { + int nAt0=0; + int nAt1=0; + int nBetween=0; + for (int i=0;i (object_[i]); + if (object) { + int state[3]; + nBad += object->checkAssociatedBounds(solver,solution,printLevel,state, + nBadFixed); + if (state[0]==0) + nBetween++; + else if (state[0]==-1) + nAt0++; + else + nAt1++; + } + } + if (handler_->logLevel()>2) { + if (printLevel>1||(printLevel==1&&nBadFixed)) { + printf("%d switches, %d at 0, %d at 1, %d between - %d bad values (%d when fixed)\n", + nBetween+nAt0+nAt1,nAt0,nAt1,nBetween,nBad,nBadFixed); + if (nBadFixed && printLevel!=3) + checkAssociated(solver,solution,3); + } + } + } + return nBad; +} +#endif // Set numberBeforeTrust in all objects void CbcModel::synchronizeNumberBeforeTrust(int type) @@ -11330,6 +12016,8 @@ newNumberObjects++; mark[iColumn] = i; } + } else { + newNumberObjects++; } } delete [] integerVariable_; @@ -11460,9 +12148,55 @@ int fixVariables, double objectiveValue) { + int numberContinuousColumns=continuousSolver_->getNumCols(); if (!solverCharacteristics_->solutionAddsCuts()) { // Can trust solution int numberColumns = solver_->getNumCols(); +#ifdef COIN_HAS_CLP + OsiClpSolverInterface * clpContinuousSolver + = dynamic_cast (continuousSolver_); + int modifiedTolerances=0; +#ifndef CBC_LEAVE_PERTURBATION_ON_CHECK_SOLUTION + int savePerturbation=-1; +#endif +#ifndef CBC_LEAVE_TOLERANCE_ON_CHECK_SOLUTION + double savePrimalTolerance=0.0; +#endif +#ifndef CBC_LEAVE_SCALING_ON_CHECK_SOLUTION + int saveScaling=-1; +#endif + if (clpContinuousSolver ) { + // be more accurate if possible + ClpSimplex * clp = clpContinuousSolver->getModelPtr(); +#ifndef CBC_LEAVE_PERTURBATION_ON_CHECK_SOLUTION + savePerturbation=clp->perturbation(); +#endif +#ifndef CBC_LEAVE_TOLERANCE_ON_CHECK_SOLUTION + savePrimalTolerance=clp->primalTolerance(); +#endif +#ifndef CBC_LEAVE_SCALING_ON_CHECK_SOLUTION + saveScaling=clp->scalingFlag(); +#endif +#ifndef CBC_LEAVE_TOLERANCE_ON_CHECK_SOLUTION + if (savePrimalTolerance>0.9999999e-7) { + modifiedTolerances |= 1; + clp->setPrimalTolerance(1.0e-8); + } +#endif +#ifndef CBC_LEAVE_PERTURBATION_ON_CHECK_SOLUTION + if (savePerturbation<100) { + modifiedTolerances |= 2; + clp->setPerturbation(100); + } +#endif +#ifndef CBC_LEAVE_SCALING_ON_CHECK_SOLUTION + if (saveScaling) { + modifiedTolerances |= 4; + clp->scaling(0); + } +#endif + } +#endif /* Grab the continuous solver (the pristine copy of the problem, made before @@ -11497,6 +12231,115 @@ double * saveLower = new double[numberColumns]; memcpy(saveUpper, getColUpper(), numberColumns*sizeof(double)); memcpy(saveLower, getColLower(), numberColumns*sizeof(double)); + //#define CLP_INVESTIGATE4 +#if CBC_USEFUL_PRINTING>14 + { + int nBad=checkAssociated(solver_,solver_->getColSolution(),1); + if (nBad) + checkAssociated(solver_,solver_->getColSolution(),3); + double largestInfeasibility = 0.0; + double primalTolerance ; + double offset; + solver_->getDblParam(OsiObjOffset, offset); + solver_->getDblParam(OsiPrimalTolerance, primalTolerance) ; + const double *objective = getObjCoefficients() ; + const double * rowLower = solver_->getRowLower() ; + const double * rowUpper = solver_->getRowUpper() ; + const double * columnLower = solver_->getColLower() ; + const double * columnUpper = solver_->getColUpper() ; + int numberRows = solver_->getNumRows() ; + double *rowActivity = new double[numberRows] ; + memset(rowActivity, 0, numberRows*sizeof(double)) ; + double *rowSum = new double[numberRows] ; + memset(rowSum, 0, numberRows*sizeof(double)) ; + int * marked = new int [numberColumns]; + for (int i=0;i (object_[i]); + if (object) { + int iColumn = object->columnNumber(); + const int * other = object->otherVariable(); + marked[iColumn]=-3-other[0]; + int n=object->numberOther(); + for (int k=0;kgetMatrixByCol()->getElements(); + const int * row = solver_->getMatrixByCol()->getIndices(); + const CoinBigIndex * columnStart = solver_->getMatrixByCol()->getVectorStarts(); + const int * columnLength = solver_->getMatrixByCol()->getVectorLengths(); + const CoinPackedMatrix * rowCopy = solver_->getMatrixByRow(); + const int * column = rowCopy->getIndices(); + const int * rowLength = rowCopy->getVectorLengths(); + const CoinBigIndex * rowStart = rowCopy->getVectorStarts(); + const double * elementByRow = rowCopy->getElements(); + double objValue=-offset; + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + double value = solution[iColumn]; + objValue += value*objective[iColumn]; + if (value>columnUpper[iColumn]) { + if (value-columnUpper[iColumn]>1.0e-8) + printf("column %d has value %.12g above %.12g\n",iColumn,value,columnUpper[iColumn]); + value=columnUpper[iColumn]; + } else if (value primalTolerance) + printf("Row %d inf %g sum %g %g <= %g <= %g\n", + i, inf, rowSum[i], rowLower[i], rowActivity[i], rowUpper[i]); + inf = rowActivity[i] - rowUpper[i]; + if (inf > primalTolerance) + printf("Row %d inf %g sum %g %g <= %g <= %g\n", + i, inf, rowSum[i], rowLower[i], rowActivity[i], rowUpper[i]); +#endif + double infeasibility = CoinMax(rowActivity[i]-rowUpper[i], + rowLower[i]-rowActivity[i]); + // but allow for errors + double factor = CoinMax(1.0,rowSum[i]*1.0e-3); + if (infeasibility>largestInfeasibility*factor) { + largestInfeasibility = infeasibility/factor; + printf("Ainf of %g on row %d sum %g scaled %g\n", + infeasibility,i,rowSum[i],largestInfeasibility); + if (infeasibility>1.0e10) { + for (CoinBigIndex j=rowStart[i]; + j 10.0*primalTolerance) + printf("Alargest infeasibility is %g - obj %g\n", largestInfeasibility,objValue); + else + printf("Afeasible (%g) - obj %g\n", largestInfeasibility,objValue); + } +#endif // point to useful information OsiBranchingInformation usefulInfo = usefulInformation(); @@ -11509,6 +12352,114 @@ int i; for (i = 0; i < numberObjects_; i++) object_[i]->feasibleRegion(solver_, &usefulInfo); +#if CBC_USEFUL_PRINTING>14 + { + int nBad=checkAssociated(solver_,solver_->getColSolution(),1); + if (nBad) + checkAssociated(solver_,solver_->getColSolution(),3); + double largestInfeasibility = 0.0; + double primalTolerance ; + double offset; + solver_->getDblParam(OsiObjOffset, offset); + solver_->getDblParam(OsiPrimalTolerance, primalTolerance) ; + const double *objective = getObjCoefficients() ; + const double * rowLower = solver_->getRowLower() ; + const double * rowUpper = solver_->getRowUpper() ; + const double * columnLower = solver_->getColLower() ; + const double * columnUpper = solver_->getColUpper() ; + int numberRows = solver_->getNumRows() ; + double *rowActivity = new double[numberRows] ; + memset(rowActivity, 0, numberRows*sizeof(double)) ; + double *rowSum = new double[numberRows] ; + memset(rowSum, 0, numberRows*sizeof(double)) ; + int * marked = new int [numberColumns]; + for (int i=0;i (object_[i]); + if (object) { + int iColumn = object->columnNumber(); + const int * other = object->otherVariable(); + marked[iColumn]=-3-other[0]; + int n=object->numberOther(); + for (int k=0;kgetMatrixByCol()->getElements(); + const int * row = solver_->getMatrixByCol()->getIndices(); + const CoinBigIndex * columnStart = solver_->getMatrixByCol()->getVectorStarts(); + const int * columnLength = solver_->getMatrixByCol()->getVectorLengths(); + const CoinPackedMatrix * rowCopy = solver_->getMatrixByRow(); + const int * column = rowCopy->getIndices(); + const int * rowLength = rowCopy->getVectorLengths(); + const CoinBigIndex * rowStart = rowCopy->getVectorStarts(); + const double * elementByRow = rowCopy->getElements(); + double objValue=-offset; + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + double value = solution[iColumn]; + objValue += value*objective[iColumn]; + if (value>columnUpper[iColumn]) { + if (value-columnUpper[iColumn]>1.0e-8) + printf("column %d has value %.12g above %.12g\n",iColumn,value,columnUpper[iColumn]); + value=columnUpper[iColumn]; + } else if (value primalTolerance) + printf("Row %d inf %g sum %g %g <= %g <= %g\n", + i, inf, rowSum[i], rowLower[i], rowActivity[i], rowUpper[i]); + inf = rowActivity[i] - rowUpper[i]; + if (inf > primalTolerance) + printf("Row %d inf %g sum %g %g <= %g <= %g\n", + i, inf, rowSum[i], rowLower[i], rowActivity[i], rowUpper[i]); +#endif + double infeasibility = CoinMax(rowActivity[i]-rowUpper[i], + rowLower[i]-rowActivity[i]); + // but allow for errors + double factor = CoinMax(1.0,rowSum[i]*1.0e-3); + if (infeasibility>largestInfeasibility*factor) { + largestInfeasibility = infeasibility/factor; + printf("inf of %g on row %d sum %g scaled %g\n", + infeasibility,i,rowSum[i],largestInfeasibility); + if (infeasibility>1.0e10) { + for (CoinBigIndex j=rowStart[i]; + j 10.0*primalTolerance) + printf("Largest infeasibility is %g - obj %g\n", largestInfeasibility,objValue); + else + printf("Feasible (%g) - obj %g\n", largestInfeasibility,objValue); + } +#endif // If relaxed then leave bounds on basic variables if (fixVariables == -1 && (specialOptions_&16) == 0) { CoinWarmStartBasis * basis = dynamic_cast(saveSolver->getWarmStart()) ; @@ -11529,8 +12480,12 @@ delete basis; } // We can switch off check - if ((specialOptions_&4) == 0) { - if ((specialOptions_&2) == 0 && solverCharacteristics_->warmStart()) { + if ((specialOptions_&4) == 0 && (moreSpecialOptions2_&10) != 8) { + // Be on safe side - unless very few integers and large + bool allSlack = (specialOptions_&2) == 0 && solverCharacteristics_->warmStart(); + if (numberIntegers_*4>solver_->getNumCols()||solver_->getNumCols()<10000) + allSlack = true; + if (allSlack) { /* Remove any existing warm start information to be sure there is no residual influence on initialSolve(). @@ -11555,20 +12510,34 @@ #endif solver_->setHintParam(OsiDoDualInInitial, true, OsiHintTry); solver_->initialSolve(); +#ifdef SWITCH_VARIABLES + if (solver_->isProvenOptimal()) { + int nBad=checkAssociated(solver_,solver_->getColSolution(),1); + if (nBad) + checkAssociated(solver_,solver_->getColSolution(),3); + } +#endif #ifdef JJF_ZERO if (solver_->isProvenOptimal()) { - solver_->writeMps("feasible"); + solver_->writeMpsNative("feasible.mps",NULL,NULL,2); +#ifdef COIN_HAS_CLP + OsiClpSolverInterface * clpSolver + = dynamic_cast (solver_); + if (clpSolver ) { + clpSolver->getModelPtr()->writeBasis("feasible.bas",true); + } +#endif printf("XXXXXXXXXXXX - saving feasible\n"); } #endif if (!solver_->isProvenOptimal()) { -#if COIN_DEVELOP>1 +#if CBC_FEASIBILITY_INVESTIGATE printf("checkSolution infeas! Retrying with primal.\n"); #endif //bool saveTakeHint; //OsiHintStrength saveStrength; //bool savePrintHint; - //solver_->writeMps("infeas"); + //solver_->writeMpsNative("infeas.mps", NULL, NULL, 2); //bool gotHint = (solver_->getHintParam(OsiDoReducePrint,savePrintHint,saveStrength)); //gotHint = (solver_->getHintParam(OsiDoScale,saveTakeHint,saveStrength)); //solver_->setHintParam(OsiDoScale,false,OsiHintTry); @@ -11584,11 +12553,28 @@ dynamic_cast(solver_->getEmptyWarmStart()) ; solver_->setWarmStart(slack); delete slack ; -#if COIN_DEVELOP>1 +#if CBC_FEASIBILITY_INVESTIGATE printf("checkSolution infeas! Retrying wihout basis and with primal.\n"); #endif solver_->initialSolve(); -#if COIN_DEVELOP>1 + //solver_->writeMps("bad"); +#ifdef COIN_HAS_CLP + if (!solver_->isProvenOptimal()&&modifiedTolerances) { + // Restore + ClpSimplex * clp = clpContinuousSolver->getModelPtr(); +#ifndef CBC_LEAVE_TOLERANCE_ON_CHECK_SOLUTION + clp->setPrimalTolerance(savePrimalTolerance); +#endif +#ifndef CBC_LEAVE_PERTURBATION_ON_CHECK_SOLUTION + clp->setPerturbation(savePerturbation); +#endif +#ifndef CBC_LEAVE_SCALING_ON_CHECK_SOLUTION + clp->scaling(saveScaling); +#endif + solver_->resolve(); + } +#endif +#if CBC_FEASIBILITY_INVESTIGATE if (!solver_->isProvenOptimal()) { printf("checkSolution still infeas!\n"); } @@ -11620,7 +12606,7 @@ #ifndef NDEBUG double integerTolerance = getIntegerTolerance() ; #endif -#if COIN_DEVELOP>1 +#if CBC_FEASIBILITY_INVESTIGATE const double * dj = solver_->getReducedCost(); const double * colLower = saveSolver->getColLower(); const double * colUpper = saveSolver->getColUpper(); @@ -11634,13 +12620,13 @@ int nAtOtherNatural = 0; int nNotNeeded = 0; #endif - for (iColumn = 0 ; iColumn < numberColumns ; iColumn++) { + for (iColumn = 0 ; iColumn < numberContinuousColumns ; iColumn++) { double value = solution[iColumn] ; value = CoinMax(value, saveLower[iColumn]) ; value = CoinMin(value, saveUpper[iColumn]) ; if (solver_->isInteger(iColumn)) { assert(fabs(value - solution[iColumn]) <= 100.0*integerTolerance) ; -#if COIN_DEVELOP>1 +#if CBC_FEASIBILITY_INVESTIGATE double value2 = floor(value + 0.5); if (dj[iColumn] < -1.0e-6) { // negative dj @@ -11691,7 +12677,7 @@ } solution[iColumn] = value ; } -#if COIN_DEVELOP>1 +#if CBC_FEASIBILITY_INVESTIGATE printf("nAtLbNat %d,nAtUbNat %d,nAtLbNatZero %d,nAtUbNatZero %d,nAtLbFixed %d,nAtUbFixed %d,nAtOther %d,nAtOtherNat %d, useless %d\n", nAtLbNatural, nAtUbNatural, @@ -11730,8 +12716,13 @@ const int * row = solver_->getMatrixByCol()->getIndices(); const CoinBigIndex * columnStart = solver_->getMatrixByCol()->getVectorStarts(); const int * columnLength = solver_->getMatrixByCol()->getVectorLengths(); - for (iColumn = 0; iColumn < numberColumns; iColumn++) { - double value = solution[iColumn]; + double offset; + solver_->getDblParam(OsiObjOffset, offset); + double objValue=-offset; + const double *objective = getObjCoefficients() ; + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + double value = solution[iColumn]; + objValue += value*objective[iColumn]; if (value) { CoinBigIndex start = columnStart[iColumn]; CoinBigIndex end = start + columnLength[iColumn]; @@ -11743,7 +12734,7 @@ } } for (i = 0 ; i < numberRows ; i++) { -#ifdef CLP_INVESTIGATE +#if CBC_FEASIBILITY_INVESTIGATE>1 double inf; inf = rowLower[i] - rowActivity[i]; if (inf > primalTolerance) @@ -11758,16 +12749,35 @@ rowLower[i]-rowActivity[i]); // but allow for errors double factor = CoinMax(1.0,rowSum[i]*1.0e-3); - if (infeasibility>largestInfeasibility*factor) + if (infeasibility>largestInfeasibility*factor) { largestInfeasibility = infeasibility/factor; + //printf("inf of %g on row %d sum %g scaled %g\n", + // infeasibility,i,rowSum[i],largestInfeasibility); + } } delete [] rowActivity ; delete [] rowSum; -#ifdef CLP_INVESTIGATE +#if CBC_FEASIBILITY_INVESTIGATE==0 + if (handler_->logLevel()>2) { +#endif + if (largestInfeasibility > 10.0*primalTolerance) + printf("BLargest infeasibility is %g - obj %g (%g)\n", largestInfeasibility,objValue,objectiveValue); + else + printf("BFeasible (%g) - obj %g %g\n", largestInfeasibility,objValue,objectiveValue); +#if CBC_FEASIBILITY_INVESTIGATE==0 + } +#else + solver_->writeMpsNative("BFeasible.mps",NULL,NULL,2); +#endif + //if (fabs(objValue-objectiveValue)>1.0e-7*fabs(objectiveValue)) { + //printf("Bad obj values\n"); + objectiveValue = objValue; + //} +#if CBC_FEASIBILITY_INVESTIGATE if (largestInfeasibility > 10.0*primalTolerance) - printf("largest infeasibility is %g\n", largestInfeasibility); + printf("XX largest infeasibility is %g\n", largestInfeasibility); #endif - if (largestInfeasibility > 1000.0*primalTolerance) { + if (largestInfeasibility > 200.0*primalTolerance) { handler_->message(CBC_NOTFEAS3, messages_) << largestInfeasibility << CoinMessageEol ; objectiveValue = 1.0e50 ; @@ -11799,6 +12809,21 @@ */ solver_ = saveSolver; testSolution_ = save; +#ifdef COIN_HAS_CLP + if (modifiedTolerances) { + // Restore + ClpSimplex * clp = clpContinuousSolver->getModelPtr(); +#ifndef CBC_LEAVE_TOLERANCE_ON_CHECK_SOLUTION + clp->setPrimalTolerance(savePrimalTolerance); +#endif +#ifndef CBC_LEAVE_PERTURBATION_ON_CHECK_SOLUTION + clp->setPerturbation(savePerturbation); +#endif +#ifndef CBC_LEAVE_SCALING_ON_CHECK_SOLUTION + clp->scaling(saveScaling); +#endif + } +#endif return objectiveValue; } else { // Outer approximation or similar @@ -11939,6 +12964,7 @@ int fixVariables) { + double * solution = CoinCopyOfArray(solutionIn, solver_->getNumCols()); #ifdef JJF_ZERO { @@ -11976,8 +13002,11 @@ CoinWarmStartBasis * basis = dynamic_cast(solver_->getWarmStart()) ; assert(basis != NULL); objectiveValue = checkSolution(cutoff, solution, fixVariables, objectiveValue); - if (saveObjectiveValue + 1.0e-3 < objectiveValue) { -#if COIN_DEVELOP>1 + if (cutoff>1.0e40&&objectiveValue<1.0e10) + saveObjectiveValue = objectiveValue; // take anyway + if (saveObjectiveValue + 1.0e-3 +1.0e-7*fabs(saveObjectiveValue) + < objectiveValue) { +#if CBC_FEASIBILITY_INVESTIGATE printf("First try at solution had objective %.16g, rechecked as %.16g\n", saveObjectiveValue, objectiveValue); #endif @@ -11991,7 +13020,7 @@ double * solution2 = CoinCopyOfArray(solutionIn, numberColumns); double objectiveValue2 = saveObjectiveValue; objectiveValue2 = checkSolution(cutoff, solution2, -1, objectiveValue2); -#if COIN_DEVELOP>1 +#if CBC_FEASIBILITY_INVESTIGATE printf("Relaxed second try had objective of %.16g\n", objectiveValue2); #endif @@ -12003,7 +13032,7 @@ double largestAway = 0.0; int iAway = -1; double largestInfeasibility = tolerance; -#if COIN_DEVELOP>1 +#if CBC_FEASIBILITY_INVESTIGATE int iInfeas = -1; #endif const double * columnLower = continuousSolver_->getColLower(); @@ -12012,12 +13041,12 @@ for (i = 0; i < numberColumns; i++) { double value = solution2[i]; if (value > columnUpper[i] + largestInfeasibility) { -#if COIN_DEVELOP>1 +#if CBC_FEASIBILITY_INVESTIGATE iInfeas = i; #endif largestInfeasibility = value - columnUpper[i]; } else if (value < columnLower[i] - largestInfeasibility) { -#if COIN_DEVELOP>1 +#if CBC_FEASIBILITY_INVESTIGATE iInfeas = i; #endif largestInfeasibility = columnLower[i] - value; @@ -12036,7 +13065,7 @@ } } } -#if COIN_DEVELOP>1 +#if CBC_FEASIBILITY_INVESTIGATE if (iInfeas >= 0) printf("Largest infeasibility of %g on column %d - tolerance %g\n", largestInfeasibility, iInfeas, tolerance); @@ -12057,7 +13086,12 @@ CoinCopyN(solution2, numberColumns, solution); objectiveValue = objectiveValue2; } - } + } else if (!parentModel_) { + // not good + messageHandler()->message(CBC_FPUMP2, messages()) + << "On closer inspection - solution discarded" + << CoinMessageEol ; + } delete [] solution2; solver_->setWarmStart(basis2); delete basis2 ; @@ -12095,7 +13129,7 @@ cutoff = bestObjective_ - dblParam_[CbcCutoffIncrement]; // But allow for rounding errors if (dblParam_[CbcCutoffIncrement] == 1e-5) { -#if COIN_DEVELOP>5 +#if CBC_FEASIBILITY_INVESTIGATE if (saveObjectiveValue + 1.0e-7 < bestObjective_) printf("First try at solution had objective %.16g, rechecked as %.16g\n", saveObjectiveValue, bestObjective_); @@ -12105,6 +13139,14 @@ if (fabs(cutoff + 1.0e-5 - floor(cutoff + 0.5)) < 1.0e-8) cutoff -= 2.0e-5; } + if (!parentModel_&&(moreSpecialOptions2_&2)!=0) { + // put back objective + solver_->setObjective(continuousSolver_->getObjCoefficients()); + double offset; + continuousSolver_->getDblParam(OsiObjOffset,offset); + solver_->setDblParam(OsiObjOffset,offset); + moreSpecialOptions2_ &= ~2; + } // This is not correct - that way cutoff can go up if maximization //double direction = solver_->getObjSense(); //setCutoff(cutoff*direction); @@ -12368,7 +13410,6 @@ { int numberUnsatisfied = 0; //double sumUnsatisfied=0.0; - int preferredWay; int j; // Point to current solution const double * save = testSolution_; @@ -12389,7 +13430,7 @@ for (j = 0; j < numberIntegers_; j++) { #ifndef SIMPLE_INTEGER const OsiObject * object = object_[j]; - double infeasibility = object->infeasibility(&usefulInfo, preferredWay); + double infeasibility = object->checkInfeasibility(&usefulInfo); if (infeasibility) { assert (infeasibility > 0); numberUnsatisfied++; @@ -12409,7 +13450,7 @@ numberIntegerInfeasibilities = numberUnsatisfied; for (; j < numberObjects_; j++) { const OsiObject * object = object_[j]; - double infeasibility = object->infeasibility(&usefulInfo, preferredWay); + double infeasibility = object->checkInfeasibility(&usefulInfo); if (infeasibility) { assert (infeasibility > 0); numberUnsatisfied++; @@ -12654,7 +13695,7 @@ value = floor(value + 0.00001); } else { // relax a bit - value = CoinMin(saveUpper, value + 1.0e-5 * (fabs(saveUpper) + 1)); + value = CoinMin(saveUpper, value + 1.0e-8 * (fabs(saveUpper) + 1)); } if (value - saveLower < 1.0e-7) value = saveLower; // make sure exactly same @@ -12668,7 +13709,7 @@ value = ceil(value - 0.00001); } else { // relax a bit - value = CoinMax(saveLower, value - 1.0e-5 * (fabs(saveLower) + 1)); + value = CoinMax(saveLower, value - 1.0e-8 * (fabs(saveLower) + 1)); } if (saveUpper - value < 1.0e-7) value = saveUpper; // make sure exactly same @@ -12716,10 +13757,10 @@ // relax newLower = CoinMax(lower[jColumn], newLower - - 1.0e-5 * (fabs(lower[jColumn]) + 1)); + - 1.0e-8 * (fabs(lower[jColumn]) + 1)); newUpper = CoinMin(upper[jColumn], newUpper - + 1.0e-5 * (fabs(upper[jColumn]) + 1)); + + 1.0e-8 * (fabs(upper[jColumn]) + 1)); } solver->setColLower(jColumn, newLower); solver->setColUpper(jColumn, newUpper); @@ -12924,22 +13965,73 @@ delete [] whichDelete; } // Make given cut into a global cut -void +int CbcModel::makeGlobalCut(const OsiRowCut * cut) { + if (cut->row().getNumElements()>1-1) { OsiRowCut newCut(*cut); newCut.setGloballyValidAsInteger(2); newCut.mutableRow().setTestForDuplicateIndex(false); - globalCuts_.addCutIfNotDuplicate(newCut) ; + return globalCuts_.addCutIfNotDuplicate(newCut,1) ; + } else { + assert (cut->row().getNumElements()==1); + int iColumn = cut->row().getIndices()[0]; + double value = cut->row().getElements()[0]; + double lb = cut->lb(); + double ub = cut->ub(); + if (value>0) { + if (lb>-COIN_DBL_MAX) + lb /= value; + if (ub-COIN_DBL_MAX) + ub = lb/value; + else + ub = COIN_DBL_MAX; + if (saveUblogLevel() > 1) { +#endif + printf("Conflict cut at depth %d (%d elements)\n", + currentDepth_,cut->row().getNumElements()); + cut->print(); +#if PRINT_CONFLICT==0 + } +#endif + const double * lower; + const double * upper; + if (topOfTree_) { + lower = topOfTree_->lower(); + upper = topOfTree_->upper(); + lb = CoinMax(lb,lower[iColumn]); + topOfTree_->setColLower(iColumn,lb); + ub = CoinMin(ub,upper[iColumn]); + topOfTree_->setColUpper(iColumn,ub); + } else { + lower = solver_->getColLower(); + upper = solver_->getColUpper(); + lb = CoinMax(lb,lower[iColumn]); + solver_->setColLower(iColumn,lb); + ub = CoinMin(ub,upper[iColumn]); + solver_->setColUpper(iColumn,ub); + } + return 1; + } } // Make given cut into a global cut -void +int CbcModel::makeGlobalCut(const OsiRowCut & cut) { OsiRowCut newCut(cut); newCut.setGloballyValid(true); newCut.mutableRow().setTestForDuplicateIndex(false); - globalCuts_.addCutIfNotDuplicate(newCut) ; + return globalCuts_.addCutIfNotDuplicate(newCut) ; } // Make given column cut into a global cut void @@ -13063,7 +14155,7 @@ } newCut.setLb(lo); newCut.setRow(nConflict,column,values); - printf("CUTa has %d (started at %d) - final bSum %g\n",nConflict,nC,bSum); + printf("CUTa has %d (started at %d) - final bSum %g - depth %d\n",nConflict,nC,bSum,currentDepth_); if (nConflict>1) { if ((specialOptions_&1) != 0) { const OsiRowCutDebugger *debugger = continuousSolver_->getRowCutDebugger() ; @@ -13143,11 +14235,13 @@ void CbcModel::incrementUsed(const double * solution) { - // might as well mark all including continuous - int numberColumns = solver_->getNumCols(); - for (int i = 0; i < numberColumns; i++) { + if(usedInSolution_) { + // might as well mark all including continuous + int numberColumns = solver_->getNumCols(); + for (int i = 0; i < numberColumns; i++) { if (solution[i]) - usedInSolution_[i]++; + usedInSolution_[i]++; + } } } // Are there numerical difficulties (for initialSolve) ? @@ -13254,6 +14348,10 @@ #ifdef CLIQUE_ANALYSIS if (probingInfo_ && currentDepth_ > 0) { int nFix = probingInfo_->fixColumns(*solver); +#ifdef SWITCH_VARIABLES + if (nFix>0) + fixAssociated(solver_,0); +#endif if (nFix < 0) { #ifdef COIN_HAS_CLP if (clpSolver) @@ -13300,12 +14398,33 @@ clpSolver->setSpecialOptions(save2 | 2048); } } +#ifdef CHECK_KNOWN_SOLUTION + bool onOptimalPath = false; + if ((specialOptions_&1) != 0) { + const OsiRowCutDebugger *debugger = solver_->getRowCutDebugger() ; + if (debugger) { + onOptimalPath = true; + printf("On optimal path before resolve\n") ; + } + } +#endif clpSolver->resolve(); +#ifdef CHECK_KNOWN_SOLUTION + if ((specialOptions_&1) != 0&&onOptimalPath) { + const OsiRowCutDebugger *debugger = solver_->getRowCutDebugger() ; + if (debugger) { + printf("On optimal path after resolve\n") ; + } else { + solver_->writeMpsNative("badSolve.mps", NULL, NULL, 2); + printf("NOT on optimal path after resolve\n") ; + } + } +#endif if (!numberNodes_) { double error = CoinMax(clpSimplex->largestDualError(), clpSimplex->largestPrimalError()); if (error > 1.0e-2 || !clpSolver->isProvenOptimal()) { -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("Problem was %s largest dual error %g largest primal %g - safer cuts\n", clpSolver->isProvenOptimal() ? "optimal" : "!infeasible", clpSimplex->largestDualError(), @@ -13339,7 +14458,7 @@ } } clpSolver->setSpecialOptions(save2); -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 if (clpSimplex->numberIterations() > 1000) printf("node %d took %d iterations\n", numberNodes_, clpSimplex->numberIterations()); #endif @@ -13352,6 +14471,13 @@ #else solver->resolve(); #endif +#ifdef SWITCH_VARIABLES + if (solver_->isProvenOptimal()) { + int nBad=checkAssociated(solver_,solver_->getColSolution(),0); + if (nBad) + checkAssociated(solver_,solver_->getColSolution(),1); + } +#endif return solver->isProvenOptimal() ? 1 : 0; } #ifdef CLP_RESOLVE @@ -13369,7 +14495,7 @@ double error = CoinMax(clpSimplex->largestDualError(), clpSimplex->largestPrimalError()); if (error > 1.0e-2 || !clpSolver->isProvenOptimal()) { -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("Problem was %s largest dual error %g largest primal %g - safer cuts\n", clpSolver->isProvenOptimal() ? "optimal" : "!infeasible", clpSimplex->largestDualError(), @@ -13403,7 +14529,7 @@ } } clpSolver->setSpecialOptions(save2); -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 if (clpSimplex->numberIterations() > 1000) printf("node %d took %d iterations\n", numberNodes_, clpSimplex->numberIterations()); #endif @@ -13852,6 +14978,44 @@ clpSimplex->setSpecialOptions(save | 0x11200000); // say is Cbc (and in branch and bound - but save ray) } #endif +#ifdef COIN_HAS_NTY + if (symmetryInfo_) { + CbcNodeInfo * infoX = oldNode ? oldNode->nodeInfo() : NULL; + bool worthTrying = false; + if (infoX) { + CbcNodeInfo * info = infoX; + for (int i=0;iparent()) { + worthTrying = true; + break; + } + info = info->parent(); + if (info->symmetryWorked()) { + worthTrying = true; + break; + } + } + } else { + worthTrying=true; + } + if ((moreSpecialOptions2_&(128|256))==(128|256)&¤tDepth_>5) + worthTrying=false; + if (worthTrying) { + int n=symmetryInfo_->orbitalFixing(solver_); + if (n) { +#if PRINT_MORE==0 + if (logLevel()>1) + printf("%d orbital fixes\n",n); +#endif + solver_->resolve(); + if(!isProvenOptimal()) { + if (logLevel()>1) + printf("infeasible after orbital fixing\n"); + } + } + } + } +#endif if (numberBeforeTrust_ == 0 ) { anyAction = newNode->chooseBranch(this, oldNode, numberPassesLeft) ; } else { @@ -13903,6 +15067,16 @@ //in the present case we need to check here integer infeasibility if the node is not fathomed we will have to do the loop // again //std::cout< normal () && + (!generator_ [i] -> needsOptimalBasis () || solver_ -> basisIsAvailable ())) + generator_ [i] -> generateCuts (feasCuts, 1 /* = fullscan */, solver_, NULL); + } + solver_ -> applyCuts (feasCuts); + resolve(solver_); double objval = solver_->getObjValue(); lastHeuristic_ = NULL; @@ -14110,7 +15284,7 @@ anyAction = -2; // say bad after all // zap parent nodeInfo #ifdef COIN_DEVELOP - printf("zapping3 CbcNodeInfo %x\n", reinterpret_cast(newNode->nodeInfo()->parent())); + printf("zapping3 CbcNodeInfo %x\n", newNode->nodeInfo()->parent()); #endif if (newNode->nodeInfo()) newNode->nodeInfo()->nullParent(); @@ -14252,6 +15426,10 @@ double offset; solver_->getDblParam(OsiObjOffset, offset); solver_->setRowUpper(cutoffRowNumber_,cutoff+offset); + if (continuousSolver_&&solver_->getNumCols()>continuousSolver_->getNumCols()) { + solver_->setRowUpper(cutoffRowNumber_,floor(cutoff)+offset); + solver_->setRowLower(cutoffRowNumber_,floor(cutoff)+offset); + } } } } @@ -14443,6 +15621,37 @@ handler_->message(CBC_GENERAL, messages_) << line << CoinMessageEol ; } + //#define DEBUG_BEST +#ifdef DEBUG_BEST + FILE * fp = fopen("solution.data","rb"); + if (!fp&&ifSol>0) { + int numberColumns=getNumCols(); + fp = fopen("solution.data","wb"); + printf("Solution data on file solution.data\n"); + size_t numberWritten; + numberWritten=fwrite(&numberColumns,sizeof(int),1,fp); + assert (numberWritten==1); + numberWritten=fwrite(&heuristicValue,sizeof(double),1,fp); + assert (numberWritten==1); + numberWritten=fwrite(newSolution,sizeof(double),numberColumns,fp); + assert (numberWritten==numberColumns); + fclose(fp); + } else if (fp) { + int numberColumns=getNumCols(); + int numberColumnsX; + size_t numberRead; + numberRead=fread(&numberColumnsX,sizeof(int),1,fp); + assert (numberRead==1); + if (numberColumns==numberColumnsX) { + numberRead=fread(&heuristicValue,sizeof(double),1,fp); + assert (numberRead==1); + numberRead=fread(newSolution,sizeof(double),numberColumns,fp); + assert (numberRead==numberColumns); + ifSol=1; + } + fclose(fp); + } +#endif if (ifSol > 0) { // better solution found double currentObjective = bestObjective_; @@ -14457,7 +15666,7 @@ // increment number of solutions so other heuristics can test // numberSolutions_++; numberHeuristicSolutions_++; -#ifdef CLP_INVESTIGATE +#ifdef HEURISTIC_INFORM printf("HEUR %s where %d C\n", lastHeuristic_->heuristicName(), whereFrom); #endif @@ -14487,7 +15696,7 @@ reducedCostFix(); } else { // NOT better solution -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("HEUR %s where %d REJECTED i==%d\n", heuristic_[i]->heuristicName(), whereFrom, i); #endif @@ -14840,7 +16049,10 @@ lastNumberCuts2_ = baseModel->lastNumberCuts2_; } int save2 = maximumDepth_; - int retCode = addCuts(node, lastws, numberFixedNow_ > numberFixedAtRoot_); + int retCode = addCuts(node, lastws); +#ifdef SWITCH_VARIABLES + fixAssociated(solver_,0); +#endif //if (save1maximumNumberCuts_ = maximumNumberCuts_; @@ -14927,7 +16139,6 @@ feasible = returnCode != 0; if (feasible) { int iObject ; - int preferredWay ; int numberUnsatisfied = 0 ; memcpy(currentSolution_, solver_->getColSolution(), numberColumns*sizeof(double)) ; @@ -14936,7 +16147,7 @@ for (iObject = 0 ; iObject < numberObjects_ ; iObject++) { double infeasibility = - object_[iObject]->infeasibility(&usefulInfo, preferredWay) ; + object_[iObject]->checkInfeasibility(&usefulInfo) ; if (infeasibility ) numberUnsatisfied++ ; } if (returnCode > 0) { @@ -14966,7 +16177,6 @@ printf("%d fixed to %g\n", i, lower[i]); } #ifdef COIN_HAS_CLP - bool fathomDone = false; OsiClpSolverInterface * clpSolver = dynamic_cast (solver_); if ((clpSolver || (specialOptions_&16384) != 0) && fastNodeDepth_ < -1 @@ -15095,8 +16305,8 @@ feasible = simplex->fathom(info) != 0; simplex->setMoreSpecialOptions(saveMoreOptions); simplex->setPerturbation(perturbation); - numberExtraNodes_ += info->numberNodesExplored_; - numberExtraIterations_ += info->numberIterations_; + incrementExtra(info->numberNodesExplored_, + info->numberIterations_); char general[200]; int fathomStatus=info->nNodes_; if (feasible) @@ -15115,7 +16325,7 @@ handler_->message(CBC_FATHOM_CHANGE, messages_) << FATHOM_BIAS - fastNodeDepth_ << CoinMessageEol ; #endif -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>0 printf(">10000 - depth now %d so at depth >= %d\n", fastNodeDepth_, FATHOM_BIAS - fastNodeDepth_); #endif @@ -15123,14 +16333,14 @@ if (info->nNodes_ < 0) { // we gave up //abort(); - fastNodeDepth_ -= 3; + fastNodeDepth_ -= (info->nNodes_==-10) ? 5 : 2; #ifndef NO_FATHOM_PRINT if ((moreSpecialOptions_&262144) != 0) handler_->message(CBC_FATHOM_CHANGE, messages_) << FATHOM_BIAS - fastNodeDepth_ << CoinMessageEol ; #endif -#ifdef CLP_INVESTIGATE - printf("fastNodeDepth now %d - so at depth >= %d\n", +#if CBC_USEFUL_PRINTING>0 + printf("gave up fastNodeDepth now %d - so at depth >= %d\n", fastNodeDepth_, FATHOM_BIAS - fastNodeDepth_); #endif if (feasible) { @@ -15141,8 +16351,7 @@ // numberColumns); clpSolver->setWarmStart(NULL); // try and do solution - double value = simplex->objectiveValue() * - simplex->optimizationDirection(); + double value = simplex->objectiveValue(); double * newSolution = CoinCopyOfArray(simplex->primalColumnSolution(), numberColumns); @@ -15159,12 +16368,14 @@ if (feasible) { clpSolver->setWarmStart(NULL); // try and do solution - double value = simplex->objectiveValue() * - simplex->optimizationDirection(); + double value = simplex->objectiveValue(); double * newSolution = CoinCopyOfArray(simplex->primalColumnSolution(), numberColumns); setBestSolution(CBC_STRONGSOL, value, newSolution) ; + // in case of inaccuracy + simplex->setObjectiveValue(CoinMax(bestObjective_, + simplex->objectiveValue())); delete [] newSolution; } // update pseudo costs @@ -15194,10 +16405,6 @@ } } //printf("range of costs %g to %g\n",smallest,largest); - // If value of objective borderline then may not be feasible - double value = simplex->objectiveValue() * simplex->optimizationDirection(); - if (value - getCutoff() < -1.0e-1) - fathomDone = true; } simplex->setLogLevel(saveLevel); #ifdef COIN_HAS_CPX @@ -15231,7 +16438,12 @@ CPXLPptr lpPtr = cpxSolver.getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL); cpxSolver.switchToMIP(); if (bestSolution_) { +#if 0 CPXcopymipstart(env, lpPtr, numberIntegers_, setVar, setSol); +#else + int zero = 0; + CPXaddmipstarts(env, lpPtr, 1, numberIntegers_, &zero, setVar, setSol, NULL, NULL); +#endif } if (getCutoff() < 1.0e50) { double useCutoff = getCutoff() + offset; @@ -15268,9 +16480,6 @@ getNumCols()); setBestSolution(CBC_STRONGSOL, value, newSolution) ; delete [] newSolution; - fathomDone = true; - } else { - feasible = false; } #endif } @@ -15280,8 +16489,6 @@ //int numberPasses = doCutsNow(1) ? maximumCutPasses_ : 0; int numberPasses = /*doCutsNow(1) ?*/ maximumCutPasses_ /*: 0*/; feasible = solveWithCuts(cuts, numberPasses, node); - if (fathomDone) - assert (feasible); } #else feasible = solveWithCuts(cuts, maximumCutPasses_, node); @@ -15798,6 +17005,8 @@ double heurValue = getCutoff() ; int iHeur ; int whereFrom = 3; + // allow more heuristics + currentPassNumber_=0; for (iHeur = 0 ; iHeur < numberHeuristics_ ; iHeur++) { // skip if can't run here if (!heuristic_[iHeur]->shouldHeurRun(whereFrom)) @@ -15814,7 +17023,7 @@ unlockThread(); } else { lastHeuristic_ = heuristic_[found]; -#ifdef CLP_INVESTIGATE +#ifdef HEURISTIC_INFORM printf("HEUR %s where %d D\n", lastHeuristic_->heuristicName(), whereFrom); #endif @@ -15823,13 +17032,13 @@ whereFrom |= 8; // say solution found } } else if (ifSol < 0) { // just returning an estimate - estValue = CoinMin(heurValue, estValue) ; + estValue = heurValue; //CoinMin(heurValue, estValue) ; heurValue = saveValue ; } } if (found >= 0 && parallelMode() > 0) { lastHeuristic_ = heuristic_[found]; -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 printf("HEUR %s where %d D\n", lastHeuristic_->heuristicName(), whereFrom); #endif @@ -15988,6 +17197,7 @@ solver_->deleteRows(numberToDelete, delRows) ; delete [] delRows ; } + numberNewCuts_=0; } #endif delete lastws ; @@ -16003,7 +17213,6 @@ baseModel->usedInSolution_[i] += usedInSolution_[i]; usedInSolution_[i] = 0; } - baseModel->numberSolutions_++; if (bestObjective_ < baseModel->bestObjective_ && bestObjective_ < baseModel->getCutoff()) { baseModel->bestObjective_ = bestObjective_ ; int numberColumns = solver_->getNumCols(); @@ -16011,7 +17220,14 @@ baseModel->bestSolution_ = new double[numberColumns]; CoinCopyN(bestSolution_, numberColumns, baseModel->bestSolution_); baseModel->setCutoff(getCutoff()); + baseModel->handler_->message(CBC_ROUNDING, messages_) + << bestObjective_ + << "heuristic" + << baseModel->numberIterations_ + << baseModel->numberNodes_ << getCurrentSeconds() + << CoinMessageEol; } + baseModel->numberSolutions_++; unlockThread(); } numberCutGenerators_=saveNumberCutGenerators; @@ -16127,7 +17343,7 @@ back[i] = -1; for (i = 0; i < numberIntegers_; i++) back[integerVariable_[i]] = i; -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 int numberNot = 0; #endif for ( i = 0; i < numberObjects_; i++) { @@ -16135,7 +17351,7 @@ dynamic_cast (object_[i]) ; if (!obj) continue; -#ifdef CLP_INVESTIGATE +#if CBC_USEFUL_PRINTING>1 if (obj->numberTimesDown() < numberBeforeTrust_ || obj->numberTimesUp() < numberBeforeTrust_) numberNot++; @@ -16156,7 +17372,7 @@ numberUpInfeasible[iColumn] = obj->numberTimesUpInfeasible(); } } -#ifdef CLP_INVESTIGATE4 +#if CBC_USEFUL_PRINTING>5 if (priority) printf("Before fathom %d not trusted out of %d\n", numberNot, numberIntegers_); @@ -16259,7 +17475,17 @@ CoinMax(fabs(bestObjective_), fabs(bestPossibleObjective_)) * dblParam_[CbcAllowableFractionGap]); returnCode = (bestObjective_ - bestPossibleObjective_ < testGap && getCutoffIncrement() >= 0.0); - } + } +#if 0 + if (returnCode) { + if (fabs(bestObjective_+1469650.0)<1.0) { + fprintf(stderr,"BAD - cr to continue\n"); + fflush(stdout); + char xx; + xx=getc(stdin); + } + } +#endif return returnCode; } // Adjust heuristics based on model @@ -16422,7 +17648,7 @@ if (!savePivotMethod && !parentModel_) { OsiClpSolverInterface * clpSolver = dynamic_cast (solver_); - if (clpSolver && numberNodes_ >= numberNodes && numberNodes_ < 2*numberNodes) { + if (clpSolver && numberNodes_ >= numberNodes && numberNodes_ < 2*numberNodes && clpSolver->getNumRows() < 10000) { if (numberIterations_ < (numberSolves_ + numberNodes_)*10) { //if (numberIterations_getModelPtr(); @@ -16726,7 +17952,7 @@ testSolution_ = currentSolution_; // better solution save lastHeuristic_ = heuristic_[found]; -#ifdef CLP_INVESTIGATE +#ifdef HEURISTIC_INFORM printf("HEUR %s where %d oddE\n", lastHeuristic_->heuristicName(), whereFrom); #endif @@ -16737,7 +17963,7 @@ } delete [] newSolution; // Space for type of cuts - maximumWhich_ = 1000; + maximumWhich_ = INITIAL_MAXIMUM_WHICH; delete [] whichGenerator_ ; whichGenerator_ = new int[maximumWhich_]; // save number of rows @@ -16925,7 +18151,7 @@ double maxSeconds = getMaximumSeconds(); bool hitMaxTime = (totalTime >= maxSeconds); if (parentModel_ && !hitMaxTime) { - // In a sub tree + // In a sub tree assert (parentModel_); maxSeconds = parentModel_->getMaximumSeconds(); hitMaxTime = (totalTime >= maxSeconds); @@ -17310,7 +18536,7 @@ the active subproblem. whichGenerator will be used to record the generator that produced a given cut. */ - maximumWhich_ = 1000 ; + maximumWhich_ = INITIAL_MAXIMUM_WHICH ; delete [] whichGenerator_ ; whichGenerator_ = new int[maximumWhich_] ; maximumNumberCuts_ = 0 ; @@ -17341,7 +18567,6 @@ numberNewCuts_ = 0 ; { int iObject ; - int preferredWay ; int numberUnsatisfied = 0 ; memcpy(currentSolution_, solver_->getColSolution(), numberColumns*sizeof(double)) ; @@ -17350,7 +18575,7 @@ OsiBranchingInformation usefulInfo = usefulInformation(); for (iObject = 0 ; iObject < numberObjects_ ; iObject++) { double infeasibility = - object_[iObject]->infeasibility(&usefulInfo, preferredWay) ; + object_[iObject]->checkInfeasibility(&usefulInfo) ; if (infeasibility) numberUnsatisfied++ ; } if (numberUnsatisfied) { @@ -17646,20 +18871,27 @@ = dynamic_cast (model->solver()); char general[200]; if (clpSolver) { - clpSolver->getModelPtr()->dual(); // probably not needed - clpSolver->setWarmStart(NULL); sprintf(general,"Starting multiple root solver"); + model->messageHandler()->message(CBC_GENERAL, + model->messages()) + << general << CoinMessageEol ; + clpSolver->setHintParam(OsiDoReducePrint, true, OsiHintTry); + ClpSimplex * simplex = clpSolver->getModelPtr(); + int logLevel=simplex->logLevel(); + if (logLevel<=1) + simplex->setLogLevel(0); + simplex->dual(); + simplex->setLogLevel(logLevel); + clpSolver->setWarmStart(NULL); } else { -#endif -#ifdef COIN_HAS_CLP model->initialSolve(); sprintf(general,"Solver did %d iterations in initialSolve\n", model->solver()->getIterationCount()); + model->messageHandler()->message(CBC_GENERAL, + model->messages()) + << general << CoinMessageEol ; } #endif - model->messageHandler()->message(CBC_GENERAL, - model->messages()) - << general << CoinMessageEol ; model->branchAndBound(); sprintf(general,"Ending multiple root solver"); model->messageHandler()->message(CBC_GENERAL, @@ -17731,7 +18963,7 @@ int badRows=0; for (int iRow=numberRowsAtContinuous_;iRow=0&&iType<10000)||iType<-1) { + if ((iType>=0&&iType<20000)) { if (fabs(ray[iRow])>1.0e-10) { badRows++; } else { @@ -18040,4 +19272,3 @@ #endif return cut; } - diff -Nru coinor-cbc-2.8.12/src/CbcModel.hpp coinor-cbc-2.9.9+repack1/src/CbcModel.hpp --- coinor-cbc-2.8.12/src/CbcModel.hpp 2014-08-09 16:05:41.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcModel.hpp 2015-07-07 20:44:40.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcModel.hpp 2055 2014-08-09 16:05:41Z forrest $ */ +/* $Id: CbcModel.hpp 2206 2015-07-07 20:44:40Z stefan $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -33,6 +33,7 @@ class CbcThread; class CbcTree; class CbcStrategy; +class CbcSymmetry; class CbcFeasibilityBase; class CbcStatistics; class CbcFullNodeInfo; @@ -349,9 +350,9 @@ /// Make given rows (L or G) into global cuts and remove from lp void makeGlobalCuts(int numberRows, const int * which); /// Make given cut into a global cut - void makeGlobalCut(const OsiRowCut * cut); + int makeGlobalCut(const OsiRowCut * cut); /// Make given cut into a global cut - void makeGlobalCut(const OsiRowCut & cut); + int makeGlobalCut(const OsiRowCut & cut); /// Make given column cut into a global cut void makeGlobalCut(const OsiColCut * cut); /// Make given column cut into a global cut @@ -512,6 +513,15 @@ void findIntegers(bool startAgain, int type = 0); +#ifdef SWITCH_VARIABLES + /// Convert Dynamic to Switching + int findSwitching(); + /// Fix associated variables + int fixAssociated(OsiSolverInterface * solver,int cleanBasis); + /// Debug associated variables + int checkAssociated(const OsiSolverInterface * solver, + const double * solution, int printLevel); +#endif //@} //--------------------------------------------------------------------------- @@ -757,6 +767,11 @@ inline int getCurrentPassNumber() const { return currentPassNumber_; } + /** Set current cut pass number in this round of cuts. + (1 is first pass) */ + inline void setCurrentPassNumber(int value) { + currentPassNumber_ = value; + } /** Set the maximum number of candidates to be evaluated for strong branching. @@ -923,6 +938,10 @@ inline int getExtraNodeCount() const { return numberExtraNodes_; } + /// Get how many times complete fathoming B&B was done + inline int getFathomCount() const { + return numberFathoms_; + } /** Final status of problem Some of these can be found out by is...... functions -1 before branchAndBound @@ -1769,6 +1788,7 @@ 20 bit (1048576) - waiting for sub model to return 22 bit (4194304) - do not initialize random seed in solver (user has) 23 bit (8388608) - leave solver_ with cuts + 24 bit (16777216) - just get feasible if no cutoff */ inline void setSpecialOptions(int value) { specialOptions_ = value; @@ -1837,6 +1857,27 @@ inline int moreSpecialOptions() const { return moreSpecialOptions_; } + /** Set more more special options + 0 bit (1) - find switching variables + 1 bit (2) - using fake objective until solution + 2 bit (4) - switching variables exist + 3 bit (8) - skip most of setBestSolution checks + 4 bit (16) - very lightweight preprocessing in smallB&B + 5 bit (32) - event handler needs to be cloned when parallel + 6 bit (64) - testing - use probing to make cliques + 7/8 bit (128) - try orbital branching (if nauty) + 9 bit (512) - branching on objective (later) + 10 bit (1024) - branching on constraints (later) + 11/12 bit 2048 - intermittent cuts + 13/14 bit 8192 - go to bitter end in strong branching (first time) + */ + inline void setMoreSpecialOptions2(int value) { + moreSpecialOptions2_ = value; + } + /// Get more special options2 + inline int moreSpecialOptions2() const { + return moreSpecialOptions2_; + } /// Set cutoff as constraint inline void setCutoffAsConstraint(bool yesNo) { cutoffRowNumber_ = (yesNo) ? -2 : -1; @@ -2161,9 +2202,8 @@ If it turns out that the node should really be fathomed by bound, addCuts() simply treats all the cuts as loose as it does the bookkeeping. - canFix true if extra information being passed */ - int addCuts(CbcNode * node, CoinWarmStartBasis *&lastws, bool canFix); + int addCuts(CbcNode * node, CoinWarmStartBasis *&lastws); /** Traverse the tree from node to root and prep the model @@ -2245,6 +2285,10 @@ inline CbcRowCuts * globalCuts() { return &globalCuts_; } + /// Get rid of global cuts + inline void zapGlobalCuts() { + globalCuts_ = CbcRowCuts(); + } /// Copy and set a pointer to a row cut which will be added instead of normal branching. void setNextRowCut(const OsiRowCut & cut); /// Get a pointer to current node (be careful) @@ -2275,6 +2319,9 @@ inline void setMaximumNumberIterations(int value) { maximumNumberIterations_ = value; } + /// Symmetry information + inline CbcSymmetry * symmetryInfo() const + { return symmetryInfo_;} /// Set depth for fast nodes inline void setFastNodeDepth(int value) { fastNodeDepth_ = value; @@ -2291,9 +2338,16 @@ inline void setContinuousPriority(int value) { continuousPriority_ = value; } - inline void incrementExtra(int nodes, int iterations) { + inline void incrementExtra(int nodes, int iterations, int fathoms=1) { numberExtraNodes_ += nodes; numberExtraIterations_ += iterations; + numberFathoms_ += fathoms; + } + /// Zero extra + inline void zeroExtra() { + numberExtraNodes_ = 0; + numberExtraIterations_ = 0; + numberFathoms_ = 0; } /// Number of extra iterations inline int numberExtraIterations() const { @@ -2339,6 +2393,15 @@ /// Redo walkback arrays void redoWalkBack(); //@} + + void setMIPStart( const std::vector< std::pair< std::string, double > > &mips ) { + this->mipStart_ = mips; + } + + const std::vector< std::pair< std::string, double > > &getMIPStart() { + return this->mipStart_; + } + //--------------------------------------------------------------------------- @@ -2414,7 +2477,11 @@ currentSolution_ or solver-->getColSolution() */ mutable const double * testSolution_; - /** Warm start object produced by heuristic or strong branching + /** MIPstart values + values for integer variables which will be converted to a complete integer initial feasible solution + */ + std::vector< std::pair< std::string, double > > mipStart_; + /** Warm start object produced by heuristic or strong branching If get a valid integer solution outside branch and bound then it can take a reasonable time to solve LP which produces clean solution. If this object has @@ -2562,6 +2629,10 @@ 17 bit (131072) - Perturbation switched off 18 bit (262144) - donor CbcModel 19 bit (524288) - recipient CbcModel + 20 bit (1048576) - waiting for sub model to return + 22 bit (4194304) - do not initialize random seed in solver (user has) + 23 bit (8388608) - leave solver_ with cuts + 24 bit (16777216) - just get feasible if no cutoff */ int specialOptions_; /** More special options @@ -2579,6 +2650,20 @@ 21 bit (2097152) - Reduce sum of infeasibilities after cuts */ int moreSpecialOptions_; + /** More more special options + 0 bit (1) - find switching variables + 1 bit (2) - using fake objective until solution + 2 bit (4) - switching variables exist + 3 bit (8) - skip most of setBestSolution checks + 4 bit (16) - very lightweight preprocessing in smallB&B + 5 bit (32) - event handler needs to be cloned when parallel + 6 bit (64) - testing - use probing to make cliques + 7/8 bit (128) - try orbital branching (if nauty) + 9 bit (512) - branching on objective (later) + 10 bit (1024) - branching on constraints (later) + 11/12 bit 2048 - intermittent cuts + */ + int moreSpecialOptions2_; /// User node comparison function CbcCompareBase * nodeCompare_; /// User feasibility function (see CbcFeasibleBase.hpp) @@ -2682,7 +2767,8 @@ # else CbcEventHandler *eventHandler_ ; # endif - + /// Symmetry information + CbcSymmetry * symmetryInfo_; /// Total number of objects int numberObjects_; @@ -2711,6 +2797,8 @@ int numberExtraIterations_; /// Number of extra nodes in fast lp int numberExtraNodes_; + /// Number of times fast lp entered + int numberFathoms_; /** Value of objective at continuous (Well actually after initial round of cuts) */ @@ -2824,6 +2912,8 @@ default is 0 */ int threadMode_; + /// Number of global cuts on entry to a node + int numberGlobalCutsIn_; /// Thread stuff for master CbcBaseModel * master_; /// Pointer to masterthread diff -Nru coinor-cbc-2.8.12/src/CbcNode.cpp coinor-cbc-2.9.9+repack1/src/CbcNode.cpp --- coinor-cbc-2.8.12/src/CbcNode.cpp 2014-08-09 16:05:41.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcNode.cpp 2016-02-22 00:12:18.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcNode.cpp 2055 2014-08-09 16:05:41Z forrest $ */ +/* $Id: CbcNode.cpp 2272 2016-02-22 00:12:18Z tkr $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -6,9 +6,18 @@ #if defined(_MSC_VER) // Turn off compiler warning about long names # pragma warning(disable:4786) +#include // for Sleep() +#ifdef small +#undef small +#endif +#else +#include // for usleep() #endif #include "CbcConfig.h" +#ifdef COIN_HAS_NTY +#include "CbcSymmetry.hpp" +#endif //#define DEBUG_SOLUTION #ifdef DEBUG_SOLUTION #define COIN_DETAIL @@ -42,6 +51,9 @@ #ifdef COIN_HAS_CLP #include "OsiClpSolverInterface.hpp" #include "ClpSimplexOther.hpp" +#include "ClpSolve.hpp" +#include "ClpDualRowSteepest.hpp" +#include "ClpPrimalColumnPivot.hpp" #endif using namespace std; #include "CglCutGenerator.hpp" @@ -59,7 +71,7 @@ state_(0) { #ifdef CHECK_NODE - printf("CbcNode %x Constructor\n", this); + printf("CbcNode %p Constructor\n", this); #endif } // Print @@ -82,7 +94,7 @@ state_(0) { #ifdef CHECK_NODE - printf("CbcNode %x Constructor from model\n", this); + printf("CbcNode %p Constructor from model\n", this); #endif model->setObjectiveValue(this, lastNode); @@ -698,6 +710,9 @@ double targetValue = hotstartSolution[iColumn]; if (saveUpper[iColumn] > saveLower[iColumn]) { double value = saveSolution[iColumn]; + // clean + value = CoinMin(value,saveUpper[iColumn]); + value = CoinMax(value,saveLower[iColumn]); if (hotstartPriorities) priorityLevel = hotstartPriorities[iColumn]; //double originalLower = thisOne->originalLower(); @@ -878,6 +893,8 @@ bestChoice = i; } } + //if (!model->parentModel()) + //solver->writeMps("query"); // If we have hit max time don't do strong branching bool hitMaxTime = (model->getCurrentSeconds() > model->getDblParam(CbcModel::CbcMaximumSeconds)); @@ -1411,8 +1428,7 @@ CbcStrongInfo thisChoice = choice[i]; choice[i].possibleBranch = NULL; const OsiObject * object = model->object(thisChoice.objectNumber); - int preferredWay; - double infeasibility = object->infeasibility(&usefulInfo, preferredWay); + double infeasibility = object->checkInfeasibility(&usefulInfo); if (!infeasibility) { // take out delete thisChoice.possibleBranch; @@ -1537,6 +1553,9 @@ } // Set guessed solution value guessedObjectiveValue_ = objectiveValue_ + estimatedDegradation; + //printf ("Node %d depth %d unsatisfied %d sum %g obj %g guess %g\n", + // model->getNodeCount(),depth_,numberUnsatisfied_, + // sumInfeasibilities_,objectiveValue_,guessedObjectiveValue_); /* Cleanup, then we're outta here. */ @@ -1608,6 +1627,16 @@ delete branch_; branch_ = NULL; OsiSolverInterface * solver = model->solver(); + //#define CHECK_DEBUGGER_PATH +#ifdef CHECK_DEBUGGER_PATH + bool onOptimalPath=false; + if ((model->specialOptions()&1) != 0) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (debugger) { + onOptimalPath = true; + } + } +#endif // get information on solver type const OsiAuxInfo * auxInfo = solver->getAuxiliaryInfo(); const OsiBabSolver * auxiliaryInfo = dynamic_cast (auxInfo); @@ -1625,8 +1654,7 @@ OsiObject * object = model->modifiableObject(i); CbcObject * obj = dynamic_cast (object) ; if (!obj || !obj->optionalObject()) { - int preferredWay; - double infeasibility = object->infeasibility(&usefulInfo, preferredWay); + double infeasibility = object->checkInfeasibility(&usefulInfo); if (infeasibility) { useOldWay = true; break; @@ -1945,6 +1973,7 @@ #endif // so we can save lots of stuff CbcStrongInfo choice; + memset (&choice, 0, sizeof(CbcStrongInfo)); CbcDynamicPseudoCostBranchingObject * choiceObject = NULL; if (model->allDynamic()) { CbcSimpleIntegerDynamicPseudoCost * object = NULL; @@ -1952,6 +1981,16 @@ } choice.possibleBranch = choiceObject; numberPassesLeft = CoinMax(numberPassesLeft, 2); + /* How dogged to be in strong branching + 0 - default + 1 - go to end on first time + 2 - always go to end + */ + int goToEndInStrongBranching = (model->moreSpecialOptions2()&(3*8192))>>13; +#ifdef COIN_HAS_NTY + // 1 after, 2 strong, 3 until depth 5 + int orbitOption = (model->moreSpecialOptions2()&(128|256))>>7; +#endif //#define DEBUG_SOLUTION #ifdef DEBUG_SOLUTION bool onOptimalPath=false; @@ -2046,8 +2085,7 @@ OsiObject * object = model->modifiableObject(i); CbcSimpleIntegerDynamicPseudoCost * dynamicObject = dynamic_cast (object) ; - int preferredWay; - double infeasibility = object->infeasibility(&usefulInfo, preferredWay); + double infeasibility = object->checkInfeasibility(&usefulInfo); int priorityLevel = object->priority(); if (hotstartSolution) { // we are doing hot start @@ -2074,22 +2112,12 @@ //infeasibility = fabs(1.0e6-fabs(value-targetValue)); //else infeasibility = fabs(value - targetValue); - //if (targetValue==1.0) - //infeasibility += 1.0; - if (value > targetValue) { - preferredWay = -1; - } else { - preferredWay = 1; - } priorityLevel = CoinAbs(priorityLevel); } else if (priorityLevel < 0) { priorityLevel = CoinAbs(priorityLevel); - if (targetValue == saveLower[iColumn]) { + if (targetValue == saveLower[iColumn] || + targetValue == saveUpper[iColumn]) { infeasibility = integerTolerance + 1.0e-12; - preferredWay = -1; - } else if (targetValue == saveUpper[iColumn]) { - infeasibility = integerTolerance + 1.0e-12; - preferredWay = 1; } else { // can't priorityLevel += 10000000; @@ -2313,7 +2341,12 @@ rowActivity[iRow] = COIN_DBL_MAX; } } else if (columnLower[i] < columnUpper[i]) { - if (fabs(solution[i] - saveSolution[i]) > + double solutionValue = saveSolution[i]; + if (fabs(solution[i] - solutionValue) > + integerTolerance && + (solutionValue - columnLower[i]) > + integerTolerance && + (columnUpper[i] - solutionValue) > integerTolerance) { nFreeNon++; if (fabs(solution[i] - saveSolution[i]) > mostAway) { @@ -2339,7 +2372,6 @@ } } delete [] rowActivity; - delete [] solution; if (!satisfied) { #ifdef CLP_INVESTIGATE printf("%d free ok %d free off target %d fixed off target\n", @@ -2366,6 +2398,7 @@ break; } } + delete [] solution; } } else if (iPass == 1) { // looks like a solution - get paranoid @@ -2629,6 +2662,15 @@ assert(doneHotStart); solver->unmarkHotStart(); model->resolve(NULL, 11, saveSolution, saveLower, saveUpper); +#ifdef CHECK_DEBUGGER_PATH + if ((model->specialOptions()&1) != 0 && onOptimalPath) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (!debugger) { + printf("Strong branching down on %d went off optimal path\n",iObject); + abort(); + } + } +#endif double newObjValue = solver->getObjSense()*solver->getObjValue(); objectiveValue_ = CoinMax(objectiveValue_,newObjValue); solver->markHotStart(); @@ -2676,7 +2718,7 @@ if (numberStrongIterations > numberIterations + CoinMin(100, 10*numberRows) && depth_ >= 4 && numberNodes > 100) { if (20*numberInfeasible + 4*numberFixed < numberNodes) { // Say never do - if (numberBeforeTrust == 5) + if (numberBeforeTrust == 10) skipAll = -1; } } @@ -2811,6 +2853,127 @@ } } #endif +#ifdef COIN_HAS_NTY + const int * orbits = NULL; +#endif +#ifdef COIN_HAS_NTY + if (orbitOption==2 /* was >1*/) { + CbcSymmetry * symmetryInfo = model->symmetryInfo(); + CbcNodeInfo * infoX = lastNode ? lastNode->nodeInfo() : NULL; + bool worthTrying = false; + if (infoX) { + CbcNodeInfo * info = infoX; + for (int i=0;iparent()) { + worthTrying = true; + break; + } + info = info->parent(); + if (info->symmetryWorked()) { + worthTrying = true; + break; + } + } + } else { + worthTrying=true; + } + if (symmetryInfo && worthTrying) { + symmetryInfo->ChangeBounds(solver->getColLower(), + solver->getColUpper(), + solver->getNumCols(),false); + symmetryInfo->Compute_Symmetry(); + symmetryInfo->fillOrbits(); + orbits = symmetryInfo->whichOrbit(); + int iColumn=-1; + if (orbits && symmetryInfo->numberUsefulOrbits()) { + bool doBranch=true; + int numberUsefulOrbits = symmetryInfo->numberUsefulOrbits(); + if (numberUsefulOrbits<2) { + assert (numberUsefulOrbits); + double largest=-1.0; + for (int i=0;i=0) { + if (saveSolution[i]>largest) { + largest=saveSolution[i]; + iColumn=i; + } + } + } + } else { +#if COIN_HAS_NTY2 == 1 + // take largest + int iOrbit=symmetryInfo->largestOrbit(solver->getColLower(), + solver->getColUpper()); + double largest=-1.0; + for (int i=0;ilargest) { + largest=saveSolution[i]; + iColumn=i; + } + } + } +#endif + if (orbitOption==2) { + // strong + int nDo=0; + const double * lower = solver->getColLower(); + const double * upper = solver->getColUpper(); + const int * integerVariable = model->integerVariable(); + for (int iOrbit = 0; iOrbit < numberUsefulOrbits; iOrbit++) { + double distance=1.0; + int iColumn = -1; + int numberIntegers = model->numberIntegers(); + for (int j=0;j=0) + whichObject[nDo++]=iColumn; + } + if (nDo) + numberToDo=nDo; + doBranch=false; + } else if (orbitOption==3) { + // subset + int nDo=0; + for (int iDo = 0; iDo < numberToDo; iDo++) { + int iObject = whichObject[iDo]; + OsiObject * object = model->modifiableObject(iObject); + CbcSimpleIntegerDynamicPseudoCost * dynamicObject = + dynamic_cast (object) ; + int iColumn = dynamicObject ? dynamicObject->columnNumber() : -1; + if (iColumn<0||orbits[iColumn]>=0) + whichObject[nDo++]=whichObject[iDo]; + } + assert(nDo); + //printf("nDo %d\n",nDo); + numberToDo=nDo; + doBranch=false; + /* need NULL as if two in same orbit and strong branching fixes + then we may be in trouble. + Strong option should be OK as only one in set done. + */ + orbits=NULL; + } + } + if(doBranch) { + orbitOption=0; + branch_ = new CbcOrbitalBranchingObject(model,iColumn,1,0,NULL); + if (infoX) + infoX->setSymmetryWorked(); + numberToDo=0; + } + } + } + } +#endif for ( iDo = 0; iDo < numberToDo; iDo++) { int iObject = whichObject[iDo]; OsiObject * object = model->modifiableObject(iObject); @@ -2819,6 +2982,7 @@ int iColumn = dynamicObject ? dynamicObject->columnNumber() : numberColumns + iObject; int preferredWay; double infeasibility = object->infeasibility(&usefulInfo, preferredWay); + bool feasibleSolution=false; double predictedChange=0.0; // may have become feasible if (!infeasibility) { @@ -2857,8 +3021,8 @@ choice.upMovement = 0.1; choice.downMovement = 0.1; } - assert (choice.upMovement >= 0.0); - assert (choice.downMovement >= 0.0); + assert (choice.upMovement >= 0.0); + assert (choice.downMovement >= 0.0); choice.fix = 0; // say not fixed // see if can skip strong branching int canSkip = choice.possibleBranch->fillStrongInfo(choice); @@ -2901,6 +3065,25 @@ double objectiveChange ; double newObjectiveValue = 1.0e100; int j; +#ifdef COIN_HAS_CLP + int saveMaxHotIts=0; + int saveOsiClpOptions=0; + if (osiclp && goToEndInStrongBranching) { + /* How dogged to be in strong branching + 0 - default + 1 - go to end on first time + 2 - always go to end + */ + osiclp->getIntParam(OsiMaxNumIterationHotStart, saveMaxHotIts); + saveOsiClpOptions=osiclp->specialOptions(); + if (goToEndInStrongBranching==2 || + dynamicObject->numberTimesBranched()==0) { + osiclp->setIntParam(OsiMaxNumIterationHotStart, + 10*(osiclp->getNumRows()+numberColumns)); + osiclp->setSpecialOptions(saveOsiClpOptions & (~32)); + } + } +#endif // status is 0 finished, 1 infeasible and other int iStatus; /* @@ -2911,6 +3094,19 @@ */ choice.possibleBranch->way(-1) ; predictedChange = choice.possibleBranch->branch() ; +#ifdef COIN_HAS_NTY + if (orbits) { + // can fix all in orbit + int fixOrbit = orbits[iObject]; + if (fixOrbit>=0) { + //printf("fixing all in orbit %d for column %d\n",fixOrbit,iObject); + for (int i=0;isetColUpper(i,0.0); + } + } + } +#endif solver->solveFromHotStart() ; bool needHotStartUpdate = false; numberStrongDone++; @@ -2930,17 +3126,30 @@ } else { iStatus = 1; // infeasible #ifdef CONFLICT_CUTS +#undef CONFLICT_CUTS + //#define CONFLICT_CUTS 2 +#endif +#ifdef CONFLICT_CUTS # ifdef COIN_HAS_CLP if (osiclp&&(model->moreSpecialOptions()&4194304)!=0) { const CbcFullNodeInfo * topOfTree = model->topOfTree(); if (topOfTree) { +#if CONFLICT_CUTS==2 OsiRowCut * cut = osiclp->smallModelCut(topOfTree->lower(), topOfTree->upper(), model->numberRowsAtContinuous(), model->whichGenerator()); +#else + OsiRowCut * cut = osiclp->modelCut(topOfTree->lower(), + topOfTree->upper(), + model->numberRowsAtContinuous(), + model->whichGenerator(),0); +#endif if (cut) { - printf("XXXXXX found conflict cut in strong branching\n"); + if (model->messageHandler()->logLevel() > 1) + printf("Conflict cut found in strong branching (%d elements)\n", + cut->row().getNumElements()); //cut->print(); if ((model->specialOptions()&1) != 0) { const OsiRowCutDebugger *debugger = model->continuousSolver()->getRowCutDebugger() ; @@ -3007,8 +3216,10 @@ } #endif // See if integer solution - if (model->feasibleSolution(choice.numIntInfeasDown, - choice.numObjInfeasDown) + feasibleSolution = + model->feasibleSolution(choice.numIntInfeasDown, + choice.numObjInfeasDown); + if (feasibleSolution && model->problemFeasibility()->feasible(model, -1) >= 0) { if (auxiliaryInfo->solutionAddsCuts()) { needHotStartUpdate = true; @@ -3055,6 +3266,16 @@ if (needHotStartUpdate) { needHotStartUpdate = false; model->resolve(NULL, 11, saveSolution, saveLower, saveUpper); +#ifdef CHECK_DEBUGGER_PATH + if ((model->specialOptions()&1) != 0 && onOptimalPath) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (!debugger) { + printf("Strong branching down on %d went off optimal path\n",iObject); + model->solver()->writeMps("query"); + abort(); + } + } +#endif double newObjValue = solver->getObjSense()*solver->getObjValue(); objectiveValue_ = CoinMax(objectiveValue_,newObjValue); //we may again have an integer feasible solution @@ -3101,6 +3322,12 @@ // repeat the whole exercise, forcing the variable up predictedChange=choice.possibleBranch->branch(); solver->solveFromHotStart() ; +#ifdef COIN_HAS_CLP + if (osiclp && goToEndInStrongBranching) { + osiclp->setIntParam(OsiMaxNumIterationHotStart, saveMaxHotIts); + osiclp->setSpecialOptions(saveOsiClpOptions); + } +#endif numberStrongDone++; numberStrongIterations += solver->getIterationCount(); /* @@ -3123,12 +3350,19 @@ const CbcFullNodeInfo * topOfTree = model->topOfTree(); if (topOfTree) { +#if CONFLICT_CUTS==2 OsiRowCut * cut = osiclp->smallModelCut(topOfTree->lower(), topOfTree->upper(), model->numberRowsAtContinuous(), model->whichGenerator()); +#else + OsiRowCut * cut = osiclp->modelCut(topOfTree->lower(), + topOfTree->upper(), + model->numberRowsAtContinuous(), + model->whichGenerator(),0); +#endif if (cut) { - printf("XXXXXX found conflict cut in strong branching\n"); + //printf("XXXXXX found conflict cut in strong branching\n"); //cut->print(); if ((model->specialOptions()&1) != 0) { const OsiRowCutDebugger *debugger = model->continuousSolver()->getRowCutDebugger() ; @@ -3194,8 +3428,10 @@ } #endif // See if integer solution - if (model->feasibleSolution(choice.numIntInfeasUp, - choice.numObjInfeasUp) + feasibleSolution = + model->feasibleSolution(choice.numIntInfeasUp, + choice.numObjInfeasUp); + if (feasibleSolution && model->problemFeasibility()->feasible(model, -1) >= 0) { #ifdef BONMIN std::cout << "Node has become integer feasible" << std::endl; @@ -3222,6 +3458,15 @@ } if (needHotStartUpdate) { model->resolve(NULL, 11, saveSolution, saveLower, saveUpper); +#ifdef CHECK_DEBUGGER_PATH + if ((model->specialOptions()&1) != 0 && onOptimalPath) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (!debugger) { + printf("Strong branching up on %d went off optimal path\n",iObject); + abort(); + } + } +#endif newObjectiveValue = solver->getObjSense() * solver->getObjValue(); objectiveValue_ = CoinMax(objectiveValue_,newObjectiveValue); objectiveChange = CoinMax(newObjectiveValue - objectiveValue_, 0.0); @@ -3257,6 +3502,15 @@ if (needHotStartUpdate) { needHotStartUpdate = false; model->resolve(NULL, 11, saveSolution, saveLower, saveUpper); +#ifdef CHECK_DEBUGGER_PATH + if ((model->specialOptions()&1) != 0 && onOptimalPath) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (!debugger) { + printf("Strong branching up on %d went off optimal path\n",iObject); + abort(); + } + } +#endif double newObjValue = solver->getObjSense()*solver->getObjValue(); objectiveValue_ = CoinMax(objectiveValue_,newObjValue); //we may again have an integer feasible solution @@ -3271,6 +3525,15 @@ objValue, solver->getColSolution()) ; model->resolve(NULL, 11, saveSolution, saveLower, saveUpper); +#ifdef CHECK_DEBUGGER_PATH + if ((model->specialOptions()&1) != 0 && onOptimalPath) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (!debugger) { + printf("Strong branching up on %d went off optimal path\n",iObject); + abort(); + } + } +#endif double newObjValue = solver->getObjSense()*solver->getObjValue(); objectiveValue_ = CoinMax(objectiveValue_,newObjValue); cutoff = model->getCutoff(); @@ -3426,6 +3689,15 @@ assert(doneHotStart); solver->unmarkHotStart(); model->resolve(NULL, 11, saveSolution, saveLower, saveUpper); +#ifdef CHECK_DEBUGGER_PATH + if ((model->specialOptions()&1) != 0 && onOptimalPath) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (!debugger) { + printf("Strong branching down on %d went off optimal path\n",iObject); + abort(); + } + } +#endif double newObjValue = solver->getObjSense()*solver->getObjValue(); objectiveValue_ = CoinMax(objectiveValue_,newObjValue); bool goneInfeasible = (!solver->isProvenOptimal()||solver->isDualObjectiveLimitReached()); @@ -3478,6 +3750,16 @@ assert(doneHotStart); solver->unmarkHotStart(); model->resolve(NULL, 11, saveSolution, saveLower, saveUpper); +#ifdef CHECK_DEBUGGER_PATH + if ((model->specialOptions()&1) != 0 && onOptimalPath) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (!debugger) { + printf("Strong branching down on %d went off optimal path\n",iObject); + solver->writeMps("query"); + abort(); + } + } +#endif double newObjValue = solver->getObjSense()*solver->getObjValue(); objectiveValue_ = CoinMax(objectiveValue_,newObjValue); bool goneInfeasible = (!solver->isProvenOptimal()||solver->isDualObjectiveLimitReached()); @@ -3571,6 +3853,15 @@ int easy = 2; solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, &easy) ; model->resolve(NULL, 11, saveSolution, saveLower, saveUpper) ; +#ifdef CHECK_DEBUGGER_PATH + if ((model->specialOptions()&1) != 0 && onOptimalPath) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (!debugger) { + printf("Strong branching went off optimal path\n"); + abort(); + } + } +#endif double newObjValue = solver->getObjSense()*solver->getObjValue(); objectiveValue_ = CoinMax(objectiveValue_,newObjValue); solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ; @@ -3587,13 +3878,15 @@ // See if candidate still possible if (branch_) { const OsiObject * object = model->object(bestChoice); - int preferredWay; - double infeasibility = object->infeasibility(&usefulInfo, preferredWay); + double infeasibility = object->checkInfeasibility(&usefulInfo); if (!infeasibility) { // take out delete branch_; branch_ = NULL; } else { + // get preferred way + int preferredWay; + object->infeasibility(&usefulInfo, preferredWay); CbcBranchingObject * branchObj = dynamic_cast (branch_) ; assert (branchObj); @@ -3675,6 +3968,66 @@ // Set guessed solution value guessedObjectiveValue_ = objectiveValue_ + estimatedDegradation; + int kColumn=-1; + if (branch_) { + CbcObject * obj = (dynamic_cast(branch_))->object(); + CbcSimpleInteger * branchObj = + dynamic_cast (obj) ; + if (branchObj) { + kColumn=branchObj->columnNumber(); + } + } +#ifdef COIN_HAS_NTY + if (orbitOption&&kColumn>=0) { + CbcSymmetry * symmetryInfo = model->symmetryInfo(); + CbcNodeInfo * infoX = lastNode ? lastNode->nodeInfo() : NULL; + bool worthTrying = false; + if (infoX) { + CbcNodeInfo * info = infoX; + for (int i=0;iparent()) { + worthTrying = true; + break; + } + info = info->parent(); + if (info->symmetryWorked()) { + worthTrying = true; + break; + } + } + } else { + worthTrying=true; + } + if (orbitOption==3&&depth_>5) + worthTrying=false; + if (symmetryInfo && worthTrying) { + if ((orbitOption&1)==1) { + symmetryInfo->ChangeBounds(solver->getColLower(), + solver->getColUpper(), + solver->getNumCols(),false); + symmetryInfo->Compute_Symmetry(); + symmetryInfo->fillOrbits(); + } + const int * orbits = symmetryInfo->whichOrbit(); + if (orbits && orbits[kColumn]>=0) { + int numberUsefulOrbits = symmetryInfo->numberUsefulOrbits(); + if (solver->messageHandler()->logLevel() > 1) + printf("Orbital Branching on %d - way %d n %d\n",kColumn,way(),numberUsefulOrbits); + if (numberUsefulOrbits<1000||orbitOption==3) { + delete branch_; + branch_ = new CbcOrbitalBranchingObject(model,kColumn,1,0,NULL); + if (infoX) + infoX->setSymmetryWorked(); + } + } + } + } +#endif + if (model->logLevel()>1) + printf ("Node %d depth %d unsatisfied %d sum %g obj %g guess %g branching on %d\n", + model->getNodeCount(),depth_,numberUnsatisfied_, + sumInfeasibilities_,objectiveValue_,guessedObjectiveValue_, + kColumn); #ifdef DO_ALL_AT_ROOT if (strongType) { char general[200]; @@ -3739,401 +4092,1531 @@ } return anyAction; } +// 0 is down, 1 is up +typedef struct { + double initialValue; // initial value + double upLowerBound; // Lower bound when going up + double downUpperBound; // Upper bound when going down + double movement[2]; // cost (and initial away from feasible) + double sumModified[2]; // Sum of integer changes + int modified[2]; // Number integers changed + int numIntInfeas[2]; // without odd ones + int numObjInfeas[2]; // just odd ones + bool finished[2]; // true if solver finished + int numIters[2]; // number of iterations in solver (-1 if never solved) + double * integerSolution; // output if thinks integer solution +# ifdef COIN_HAS_CLP + ClpDualRowSteepest * steepest; +#endif + int columnNumber; // Which column it is +} StrongInfo; +typedef struct { + double integerTolerance; + double * originalSolution; + CoinWarmStart * ws; + double * newObjective; +# ifdef COIN_HAS_CLP + ClpDualRowSteepest * dualRowPivot; + ClpPrimalColumnPivot * primalColumnPivot; +# endif + int * back; + int solveType; +} StrongStaticInfo; +typedef struct { + StrongStaticInfo *staticInfo; + StrongInfo * choice; + OsiSolverInterface * solver; + double * tempSolution; + CoinWarmStart * tempBasis; + int whichChoice; +} StrongBundle; +/* return 1 if possible solution (for solveType 100 if infeasible) + 2 set if down was infeasible + 4 set if up was infeasible + */ +int solveAnalyze(void * info) { + StrongBundle * bundle = reinterpret_cast(info); + StrongInfo * choice = bundle->choice; + StrongStaticInfo * staticInfo = bundle->staticInfo; + OsiSolverInterface * solver = bundle->solver; + int solveType = staticInfo->solveType; + if (solveType==77) { + return 0; + } + const double * saveSolution = staticInfo->originalSolution; + int iColumn = choice->columnNumber; + const int * back = staticInfo->back; + double newObjectiveValue = 1.0e100; + double integerTolerance = staticInfo->integerTolerance; + double bestSolutionValue=COIN_DBL_MAX; + int returnStatus=0; + // status is 0 finished, 1 infeasible and other + int iStatus; + /* + Try the down direction first. (Specify the initial branching alternative as + down with a call to way(-1). Each subsequent call to branch() performs the + specified branch and advances the branch object state to the next branch + alternative.) + */ + for (int iWay=0;iWay<2;iWay++) { + if (choice->numIters[iWay]==0) { + int numberColumns=solver->getNumCols(); + if (solveType!=100) { + double saveBound; + if (iWay==0) { + saveBound = solver->getColUpper()[iColumn]; + solver->setColUpper(iColumn,choice->downUpperBound); + } else { + saveBound = solver->getColLower()[iColumn]; + solver->setColLower(iColumn,choice->upLowerBound); + } + if ((solveType&2)==0) { + solver->solveFromHotStart() ; + } else { + // restore basis + solver->setWarmStart(staticInfo->ws); +# ifdef COIN_HAS_CLP + if (staticInfo->dualRowPivot) { + OsiClpSolverInterface * osiclp = dynamic_cast(solver); + ClpSimplex * simplex = osiclp->getModelPtr(); + simplex->setDualRowPivotAlgorithm(*staticInfo->dualRowPivot); + //simplex->dualRowPivot()->saveWeights(simplex,4); + simplex->setWhatsChanged(ALL_SAME_EXCEPT_COLUMN_BOUNDS); + simplex->dual(0,5); + } else { +#endif + solver->resolve(); +# ifdef COIN_HAS_CLP + } +#endif + } + if (iWay==0) + solver->setColUpper(iColumn,saveBound); + else + solver->setColLower(iColumn,saveBound); + /* + We now have an estimate of objective degradation that we can use for strong + branching. If we're over the cutoff, the variable is monotone up. + If we actually made it to optimality, check for a solution, and if we have + a good one, call setBestSolution to process it. Note that this may reduce the + cutoff, so we check again to see if we can declare this variable monotone. + */ + if (solver->isProvenOptimal()) { + iStatus = 0; // optimal + } else if (solver->isIterationLimitReached() + && !solver->isDualObjectiveLimitReached()) { + iStatus = 2; // unknown + } else { + iStatus = 1; // infeasible + } + newObjectiveValue = solver->getObjSense() * solver->getObjValue(); + choice->numIters[iWay] = solver->getIterationCount(); + // Look at interaction + const double * thisSolution = solver->getColSolution(); + int numberModified=0; + double sumModified=0.0; + int numberInfeas=0; + for (int i=0;i=0) { + double value = thisSolution[i]; + if (iColumn!=i) { + double difference = fabs(saveSolution[i]-value); + if (difference>integerTolerance) { + numberModified++; + sumModified += difference; + } + } + if (fabs(value-floor(value+0.5))>integerTolerance) + numberInfeas++;; + } + } + choice->numIntInfeas[iWay]=numberInfeas; + choice->sumModified[iWay] = sumModified; + choice->modified[iWay] = numberModified; + if (!iStatus) { + choice->finished[iWay] = true ; + if (!numberInfeas) { + returnStatus=1; + if (!choice->integerSolution) { + bestSolutionValue=newObjectiveValue; + choice->integerSolution=CoinCopyOfArray(thisSolution,numberColumns);; + } else if (bestSolutionValue>newObjectiveValue) { + memcpy(choice->integerSolution,thisSolution,numberColumns*sizeof(double)); + } + } + } else if (iStatus == 1) { + newObjectiveValue = 1.0e100 ; + } else { + // Can't say much as we did not finish + choice->finished[iWay] = false ; + } + choice->movement[iWay] = newObjectiveValue ; + } else { +# ifdef COIN_HAS_CLP + OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); + ClpSimplex * simplex = osiclp ? osiclp->getModelPtr() : NULL; +#endif + // doing continuous and general integer + solver->setColSolution(staticInfo->originalSolution); + solver->setWarmStart(staticInfo->ws); + double saveBound; + double newBound; + if (iWay==0) { + saveBound=solver->getColUpper()[iColumn]; + solver->setColUpper(iColumn,choice->downUpperBound); + newBound=choice->downUpperBound; + } else { + saveBound=solver->getColLower()[iColumn]; + solver->setColLower(iColumn,choice->upLowerBound); + newBound=choice->upLowerBound; + } +# if 0 //def COIN_HAS_CLP + if (simplex) { + // set solution to new bound (if basic will be recomputed) + simplex->primalColumnSolution()[iColumn]=newBound; + } +#endif + solver->setHintParam(OsiDoDualInResolve, true, OsiHintDo) ; +#define PRINT_ANALYZE 0 +#if PRINT_ANALYZE>0 + osiclp->getModelPtr()->setLogLevel(1); + solver->setHintParam(OsiDoReducePrint, false, OsiHintTry); +#endif + solver->resolve(); + if (iWay==0) { +#if PRINT_ANALYZE>0 + printf("column %d down original %g <= %g <= %g upper now %g - result %s\n", + iColumn,solver->getColLower()[iColumn], + staticInfo->originalSolution[iColumn],saveBound, + newBound,solver->isProvenOptimal() ? "ok" : "infeas"); +#endif + solver->setColUpper(iColumn,saveBound); + } else { +#if PRINT_ANALYZE>0 + printf("column %d up original %g <= %g <= %g lower now %g - result %s\n", + iColumn,saveBound,staticInfo->originalSolution[iColumn], + solver->getColUpper()[iColumn], + newBound,solver->isProvenOptimal() ? "ok" : "infeas"); +#endif + solver->setColLower(iColumn,saveBound); + } + choice->numIters[iWay] = solver->getIterationCount(); + if (solver->isProvenOptimal()) { + //printf("Way %d - all way %d iterations - column %d\n", + // iWay,solver->getIterationCount(),iColumn); + // can go all way + choice->movement[iWay] = newBound; + } else { + // zero objective + double offset; + solver->getDblParam(OsiObjOffset,offset); + solver->setDblParam(OsiObjOffset, 0.0); + solver->setObjective(staticInfo->newObjective+numberColumns); + if (iWay==0) { + solver->setObjCoeff(iColumn,1.0); + } else { + solver->setObjCoeff(iColumn,-1.0); + } + solver->setColSolution(staticInfo->originalSolution); + solver->setWarmStart(staticInfo->ws); + solver->setHintParam(OsiDoDualInResolve, false, OsiHintDo) ; + solver->resolve(); + //printf("Way %d - first solve %d iterations, second %d - column %d\n", + // iWay,choice->numIters[iWay],solver->getIterationCount(),iColumn); + choice->movement[iWay] = solver->getColSolution()[iColumn]; + choice->numIters[iWay] += solver->getIterationCount(); +#if PRINT_ANALYZE>0 + if (iWay==0) { + printf("column %d down can get to %g - result %s\n", + iColumn,solver->getColSolution()[iColumn],solver->isProvenOptimal() ? "ok" : "infeas"); + } else { + printf("column %d up can get to %g - result %s\n", + iColumn,solver->getColSolution()[iColumn],solver->isProvenOptimal() ? "ok" : "infeas"); + } +#endif + // reset objective + solver->setDblParam(OsiObjOffset, offset); + solver->setObjective(staticInfo->newObjective); + if (!solver->isProvenOptimal()) { +# ifdef COIN_HAS_CLP + OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); + ClpSimplex * simplex = osiclp->getModelPtr(); + double sum = simplex->sumPrimalInfeasibilities(); + sum /= static_cast(simplex->numberPrimalInfeasibilities()); + if (sum>1.0e-3) { +#endif + choice->modified[0]=1; + returnStatus=1; + solver->writeMps("bad","mps"); + abort(); +# ifdef COIN_HAS_CLP + } +#endif + } + } + //solver->setObjCoeff(iColumn,0.0); + } + } + } + return returnStatus; +} +#ifdef THREADS_IN_ANALYZE +void * cbc_parallelManager(void * stuff) +{ + CoinPthreadStuff * driver = reinterpret_cast(stuff); + int whichThread=driver->whichThread(); + CoinThreadInfo * threadInfo = driver->threadInfoPointer(whichThread); + threadInfo->status=-1; + int * which = threadInfo->stuff; + pthread_barrier_wait(driver->barrierPointer()); +#if 0 + int status=-1; + while (status!=100) + status=timedWait(driver,1000,2); + pthread_cond_signal(driver->conditionPointer(1)); + pthread_mutex_unlock(driver->mutexPointer(1,whichThread)); +#endif + // so now mutex_ is locked + int whichLocked=0; + while (true) { + pthread_mutex_t * mutexPointer = driver->mutexPointer(whichLocked,whichThread); + // wait + //printf("Child waiting for %d - status %d %d %d\n", + // whichLocked,lockedX[0],lockedX[1],lockedX[2]); +#ifdef DETAIL_THREAD + printf("thread %d about to lock mutex %d\n",whichThread,whichLocked); +#endif + pthread_mutex_lock (mutexPointer); + whichLocked++; + if (whichLocked==3) + whichLocked=0; + int unLock=whichLocked+1; + if (unLock==3) + unLock=0; + //printf("child pointer %p status %d\n",threadInfo,threadInfo->status); + assert(threadInfo->status>=0); + if (threadInfo->status==1000) + pthread_exit(NULL); + int type=threadInfo->status; + int & returnCode=which[0]; + int iPass=which[1]; + //CoinIndexedVector * array; + //double dummy; + switch(type) { + // dummy + case 0: + break; + case 1: + returnCode=solveAnalyze(threadInfo->extraInfo); + threadInfo->stuff[3]=0; + break; + case 100: + // initialization + break; + } + threadInfo->status= (type!=1) ? -1 : -2; +#ifdef DETAIL_THREAD + printf("thread %d about to unlock mutex %d\n",whichThread,unLock); +#endif + pthread_mutex_unlock (driver->mutexPointer(unLock,whichThread)); + } +} +#endif int CbcNode::analyze (CbcModel *model, double * results) { - int i; - int numberIterationsAllowed = model->numberAnalyzeIterations(); - OsiSolverInterface * solver = model->solver(); - objectiveValue_ = solver->getObjSense() * solver->getObjValue(); - double cutoff = model->getCutoff(); - const double * lower = solver->getColLower(); - const double * upper = solver->getColUpper(); - const double * dj = solver->getReducedCost(); - int numberObjects = model->numberObjects(); - int numberColumns = model->getNumCols(); - // Initialize arrays - int numberIntegers = model->numberIntegers(); - int * back = new int[numberColumns]; - const int * integerVariable = model->integerVariable(); - for (i = 0; i < numberColumns; i++) - back[i] = -1; - // What results is - double * newLower = results; - double * objLower = newLower + numberIntegers; - double * newUpper = objLower + numberIntegers; - double * objUpper = newUpper + numberIntegers; - for (i = 0; i < numberIntegers; i++) { - int iColumn = integerVariable[i]; - back[iColumn] = i; - newLower[i] = 0.0; - objLower[i] = -COIN_DBL_MAX; - newUpper[i] = 0.0; - objUpper[i] = -COIN_DBL_MAX; +#define COIN_DETAIL + int i; + int numberIterationsAllowed = model->numberAnalyzeIterations(); + int numberColumns = model->getNumCols(); + int numberRows = model->getNumRows(); + int numberObjects = model->numberObjects(); + int numberIntegers = model->numberIntegers(); + int numberLookIntegers=0; + int highestPriority=COIN_INT_MAX; + int * back = new int[numberColumns]; + const int * integerVariable = model->integerVariable(); + for (i = 0; i < numberIntegers; i++) { + highestPriority = CoinMin(highestPriority,model->modifiableObject(i)->priority()); + } + for (i = 0; i < numberColumns; i++) + back[i] = -1; + for (i = 0; i < numberIntegers; i++) { + int iColumn = integerVariable[i]; + back[iColumn] = i; + if (model->modifiableObject(i)->priority()==highestPriority) { + numberLookIntegers++; + } else { + back[iColumn] = i+numberColumns; } - double * saveUpper = new double[numberColumns]; - double * saveLower = new double[numberColumns]; - // Save solution in case heuristics need good solution later - - double * saveSolution = new double[numberColumns]; - memcpy(saveSolution, solver->getColSolution(), numberColumns*sizeof(double)); - model->reserveCurrentSolution(saveSolution); - for (i = 0; i < numberColumns; i++) { - saveLower[i] = lower[i]; - saveUpper[i] = upper[i]; + } + /* + 0 - just look + 0 (1) bit - use to set priorities + 1 (2) bit - look at bounds on all variables and more iterations + 2 (4) bit - do threaded (if parallelMode()==1 then not repeatable if any fixed) + 3 (8) bit - + 4 (16) bit - do even if m*n>1,000,000 + 5 (32) bit - printing time + 6 (64) bit - save mps file + */ + int solveType; + char general[200]; + if (numberIterationsAllowed>0) { + solveType = 0; + } else { + solveType = - numberIterationsAllowed; + if ((solveType&16)==0) { + double size=numberRows; + size*=numberLookIntegers; + if (size>1000000) { + if ((solveType&32)!=0) + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << "Skipping analyze as problem too large" + << CoinMessageEol; + return 0; + } } - // Get arrays to sort - double * sort = new double[numberObjects]; - int * whichObject = new int[numberObjects]; - int numberToFix = 0; - int numberToDo = 0; - double integerTolerance = - model->getDblParam(CbcModel::CbcIntegerTolerance); - // point to useful information - OsiBranchingInformation usefulInfo = model->usefulInformation(); - // and modify - usefulInfo.depth_ = depth_; - - // compute current state - int numberObjectInfeasibilities; // just odd ones - int numberIntegerInfeasibilities; - model->feasibleSolution( - numberIntegerInfeasibilities, - numberObjectInfeasibilities); + sprintf(general,"Analyze options %d",solveType); + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << general + << CoinMessageEol; + if ((solveType&1)!=0) + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << "Using to set priorities (probably bad idea)" + << CoinMessageEol; + if ((solveType&2)!=0) + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << "Use more iterations and look at continuous/general integer variables" + << CoinMessageEol; + if ((solveType&4)!=0) + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << "Use threads" + << CoinMessageEol; + if ((solveType&32)!=0) + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << "32 switches on more printing, (16 bit allows large problems)" + << CoinMessageEol; + } + OsiSolverInterface * solver = model->solver(); + objectiveValue_ = solver->getObjSense() * solver->getObjValue(); + const double * lower = solver->getColLower(); + const double * upper = solver->getColUpper(); + const double * dj = solver->getReducedCost(); + // What results is + double * newLower = results; + double * objLower = newLower + numberIntegers; + double * newUpper = objLower + numberIntegers; + double * objUpper = newUpper + numberIntegers; + double * interAction = objUpper + numberIntegers; + for (i = 0; i < numberIntegers; i++) { + int iColumn = integerVariable[i]; + newLower[i] = lower[iColumn]; + objLower[i] = -COIN_DBL_MAX; + newUpper[i] = upper[iColumn]; + objUpper[i] = -COIN_DBL_MAX; + interAction[i] = 0.0; + } + double * objMovement=new double[2*numberIntegers]; + memset(objMovement,0,2*numberIntegers*sizeof(double)); + double * saveUpper = new double[numberColumns]; + double * saveLower = new double[numberColumns]; + // Save solution in case heuristics need good solution later + + double * saveSolution = new double[numberColumns]; + memcpy(saveSolution, solver->getColSolution(), numberColumns*sizeof(double)); + model->reserveCurrentSolution(saveSolution); + for (i = 0; i < numberColumns; i++) { + saveLower[i] = lower[i]; + saveUpper[i] = upper[i]; + } + // Get arrays to sort + double * sort = new double[numberObjects]; + int * whichObject = new int[numberObjects]; + int numberToFix = 0; + int numberToDo = 0; + double integerTolerance = + model->getDblParam(CbcModel::CbcIntegerTolerance); + // point to useful information + OsiBranchingInformation usefulInfo = model->usefulInformation(); + // and modify + usefulInfo.depth_ = depth_; + + // compute current state + int numberObjectInfeasibilities; // just odd ones + int numberIntegerInfeasibilities; + model->feasibleSolution( + numberIntegerInfeasibilities, + numberObjectInfeasibilities); + if (solveType) { + if ((solveType&2)==0) + numberIterationsAllowed=200*numberIntegerInfeasibilities; + else + numberIterationsAllowed=COIN_INT_MAX; + } + int saveAllowed=numberIterationsAllowed; # ifdef COIN_HAS_CLP - OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); - int saveClpOptions = 0; - bool fastIterations = (model->specialOptions() & 8) != 0; - if (osiclp && fastIterations) { - // for faster hot start - saveClpOptions = osiclp->specialOptions(); - osiclp->setSpecialOptions(saveClpOptions | 8192); - } + OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); + int saveClpOptions = 0; + bool fastIterations = (model->specialOptions() & 8) != 0; + if (osiclp) { + saveClpOptions = osiclp->specialOptions(); + // for faster hot start + if (fastIterations) + osiclp->setSpecialOptions(saveClpOptions | 8192); + else + osiclp->setSpecialOptions(saveClpOptions | 2048); // switch off crunch + } # else - bool fastIterations = false ; + bool fastIterations = false ; # endif - /* - Scan for branching objects that indicate infeasibility. Choose candidates - using priority as the first criteria, then integer infeasibility. - - The algorithm is to fill the array with a set of good candidates (by - infeasibility) with priority bestPriority. Finding a candidate with - priority better (less) than bestPriority flushes the choice array. (This - serves as initialization when the first candidate is found.) - - */ - numberToDo = 0; - for (i = 0; i < numberObjects; i++) { - OsiObject * object = model->modifiableObject(i); - CbcSimpleIntegerDynamicPseudoCost * dynamicObject = - dynamic_cast (object) ; - if (!dynamicObject) - continue; - int preferredWay; - double infeasibility = object->infeasibility(&usefulInfo, preferredWay); - int iColumn = dynamicObject->columnNumber(); - if (saveUpper[iColumn] == saveLower[iColumn]) - continue; - if (infeasibility) - sort[numberToDo] = -1.0e10 - infeasibility; - else - sort[numberToDo] = -fabs(dj[iColumn]); - whichObject[numberToDo++] = i; - } - // Save basis - CoinWarmStart * ws = solver->getWarmStart(); - int saveLimit; - solver->getIntParam(OsiMaxNumIterationHotStart, saveLimit); - int targetIterations = CoinMax(500, numberIterationsAllowed / numberObjects); - if (saveLimit < targetIterations) - solver->setIntParam(OsiMaxNumIterationHotStart, targetIterations); + /* + Scan for branching objects that indicate infeasibility. + + The algorithm is to fill the array with a set of good candidates (by + infeasibility). + + */ + numberToDo = 0; + for (i = 0; i < numberObjects; i++) { + OsiObject * object = model->modifiableObject(i); + CbcSimpleIntegerDynamicPseudoCost * dynamicObject = + dynamic_cast (object) ; + if (!dynamicObject) + continue; + if (dynamicObject->priority()!=highestPriority) + continue; + double infeasibility = object->checkInfeasibility(&usefulInfo); + int iColumn = dynamicObject->columnNumber(); + if (saveUpper[iColumn] == saveLower[iColumn]) + continue; + if (infeasibility) + sort[numberToDo] = -1.0e10 - infeasibility; + else + sort[numberToDo] = -fabs(dj[iColumn]); + whichObject[numberToDo++] = i; + } + // Save basis + CoinWarmStart * ws = solver->getWarmStart(); + int saveLimit; + solver->getIntParam(OsiMaxNumIterationHotStart, saveLimit); + int targetIterations = CoinMax(500, numberIterationsAllowed / numberObjects); + if (saveLimit < targetIterations) + solver->setIntParam(OsiMaxNumIterationHotStart, targetIterations); + if ((solveType&2)==0) { // Mark hot start solver->markHotStart(); - // Sort - CoinSort_2(sort, sort + numberToDo, whichObject); - double * currentSolution = model->currentSolution(); - double objMin = 1.0e50; - double objMax = -1.0e50; - bool needResolve = false; - /* - Now calculate the cost forcing the variable up and down. - */ - int iDo; - for (iDo = 0; iDo < numberToDo; iDo++) { - CbcStrongInfo choice; - int iObject = whichObject[iDo]; - OsiObject * object = model->modifiableObject(iObject); - CbcSimpleIntegerDynamicPseudoCost * dynamicObject = - dynamic_cast (object) ; - if (!dynamicObject) - continue; - int iColumn = dynamicObject->columnNumber(); - int preferredWay; - /* - Update the information held in the object. - */ - object->infeasibility(&usefulInfo, preferredWay); - double value = currentSolution[iColumn]; - double nearest = floor(value + 0.5); - double lowerValue = floor(value); - bool satisfied = false; - if (fabs(value - nearest) <= integerTolerance || value < saveLower[iColumn] || value > saveUpper[iColumn]) { - satisfied = true; - double newValue; - if (nearest < saveUpper[iColumn]) { - newValue = nearest + 1.0001 * integerTolerance; - lowerValue = nearest; - } else { - newValue = nearest - 1.0001 * integerTolerance; - lowerValue = nearest - 1; - } - currentSolution[iColumn] = newValue; - } - double upperValue = lowerValue + 1.0; - //CbcSimpleInteger * obj = - //dynamic_cast (object) ; - //if (obj) { - //choice.possibleBranch=obj->createCbcBranch(solver,&usefulInfo,preferredWay); - //} else { - CbcObject * obj = - dynamic_cast (object) ; - assert (obj); - choice.possibleBranch = obj->createCbcBranch(solver, &usefulInfo, preferredWay); - //} - currentSolution[iColumn] = value; - // Save which object it was - choice.objectNumber = iObject; - choice.numIntInfeasUp = numberUnsatisfied_; - choice.numIntInfeasDown = numberUnsatisfied_; - choice.downMovement = 0.0; - choice.upMovement = 0.0; - choice.numItersDown = 0; - choice.numItersUp = 0; - choice.fix = 0; // say not fixed - double objectiveChange ; - double newObjectiveValue = 1.0e100; - int j; - // status is 0 finished, 1 infeasible and other - int iStatus; - /* - Try the down direction first. (Specify the initial branching alternative as - down with a call to way(-1). Each subsequent call to branch() performs the - specified branch and advances the branch object state to the next branch - alternative.) - */ - choice.possibleBranch->way(-1) ; - choice.possibleBranch->branch() ; - if (fabs(value - lowerValue) > integerTolerance) { - solver->solveFromHotStart() ; - /* - We now have an estimate of objective degradation that we can use for strong - branching. If we're over the cutoff, the variable is monotone up. - If we actually made it to optimality, check for a solution, and if we have - a good one, call setBestSolution to process it. Note that this may reduce the - cutoff, so we check again to see if we can declare this variable monotone. - */ - if (solver->isProvenOptimal()) - iStatus = 0; // optimal - else if (solver->isIterationLimitReached() - && !solver->isDualObjectiveLimitReached()) - iStatus = 2; // unknown - else - iStatus = 1; // infeasible - newObjectiveValue = solver->getObjSense() * solver->getObjValue(); - choice.numItersDown = solver->getIterationCount(); - numberIterationsAllowed -= choice.numItersDown; - objectiveChange = newObjectiveValue - objectiveValue_; - if (!iStatus) { - choice.finishedDown = true ; - if (newObjectiveValue >= cutoff) { - objectiveChange = 1.0e100; // say infeasible - } else { - // See if integer solution - if (model->feasibleSolution(choice.numIntInfeasDown, - choice.numObjInfeasDown) - && model->problemFeasibility()->feasible(model, -1) >= 0) { - model->setBestSolution(CBC_STRONGSOL, - newObjectiveValue, - solver->getColSolution()) ; - model->setLastHeuristic(NULL); - model->incrementUsed(solver->getColSolution()); - cutoff = model->getCutoff(); - if (newObjectiveValue >= cutoff) // *new* cutoff - objectiveChange = 1.0e100 ; - } - } - } else if (iStatus == 1) { - objectiveChange = 1.0e100 ; - } else { - // Can't say much as we did not finish - choice.finishedDown = false ; - } - choice.downMovement = objectiveChange ; - } - // restore bounds - for ( j = 0; j < numberColumns; j++) { - if (saveLower[j] != lower[j]) - solver->setColLower(j, saveLower[j]); - if (saveUpper[j] != upper[j]) - solver->setColUpper(j, saveUpper[j]); - } - // repeat the whole exercise, forcing the variable up - choice.possibleBranch->branch(); - if (fabs(value - upperValue) > integerTolerance) { - solver->solveFromHotStart() ; - /* - We now have an estimate of objective degradation that we can use for strong - branching. If we're over the cutoff, the variable is monotone up. - If we actually made it to optimality, check for a solution, and if we have - a good one, call setBestSolution to process it. Note that this may reduce the - cutoff, so we check again to see if we can declare this variable monotone. - */ - if (solver->isProvenOptimal()) - iStatus = 0; // optimal - else if (solver->isIterationLimitReached() - && !solver->isDualObjectiveLimitReached()) - iStatus = 2; // unknown - else - iStatus = 1; // infeasible - newObjectiveValue = solver->getObjSense() * solver->getObjValue(); - choice.numItersUp = solver->getIterationCount(); - numberIterationsAllowed -= choice.numItersUp; - objectiveChange = newObjectiveValue - objectiveValue_; - if (!iStatus) { - choice.finishedUp = true ; - if (newObjectiveValue >= cutoff) { - objectiveChange = 1.0e100; // say infeasible - } else { - // See if integer solution - if (model->feasibleSolution(choice.numIntInfeasUp, - choice.numObjInfeasUp) - && model->problemFeasibility()->feasible(model, -1) >= 0) { - model->setBestSolution(CBC_STRONGSOL, - newObjectiveValue, - solver->getColSolution()) ; - model->setLastHeuristic(NULL); - model->incrementUsed(solver->getColSolution()); - cutoff = model->getCutoff(); - if (newObjectiveValue >= cutoff) // *new* cutoff - objectiveChange = 1.0e100 ; - } - } - } else if (iStatus == 1) { - objectiveChange = 1.0e100 ; - } else { - // Can't say much as we did not finish - choice.finishedUp = false ; - } - choice.upMovement = objectiveChange ; - - // restore bounds - for ( j = 0; j < numberColumns; j++) { - if (saveLower[j] != lower[j]) - solver->setColLower(j, saveLower[j]); - if (saveUpper[j] != upper[j]) - solver->setColUpper(j, saveUpper[j]); - } - } - // If objective goes above certain amount we can set bound - int jInt = back[iColumn]; - newLower[jInt] = upperValue; - if (choice.finishedDown) - objLower[jInt] = choice.downMovement + objectiveValue_; - else - objLower[jInt] = objectiveValue_; - newUpper[jInt] = lowerValue; - if (choice.finishedUp) - objUpper[jInt] = choice.upMovement + objectiveValue_; - else - objUpper[jInt] = objectiveValue_; - objMin = CoinMin(CoinMin(objLower[jInt], objUpper[jInt]), objMin); - /* - End of evaluation for this candidate variable. Possibilities are: - * Both sides below cutoff; this variable is a candidate for branching. - * Both sides infeasible or above the objective cutoff: no further action - here. Break from the evaluation loop and assume the node will be purged - by the caller. - * One side below cutoff: Install the branch (i.e., fix the variable). Break - from the evaluation loop and assume the node will be reoptimised by the - caller. - */ - if (choice.upMovement < 1.0e100) { - if (choice.downMovement < 1.0e100) { - objMax = CoinMax(CoinMax(objLower[jInt], objUpper[jInt]), objMax); - // In case solution coming in was odd - choice.upMovement = CoinMax(0.0, choice.upMovement); - choice.downMovement = CoinMax(0.0, choice.downMovement); - // feasible - - model->messageHandler()->message(CBC_STRONG, *model->messagesPointer()) - << iObject << iColumn - << choice.downMovement << choice.numIntInfeasDown - << choice.upMovement << choice.numIntInfeasUp - << value - << CoinMessageEol; - } else { - // up feasible, down infeasible - if (!satisfied) - needResolve = true; - choice.fix = 1; - numberToFix++; - saveLower[iColumn] = upperValue; - solver->setColLower(iColumn, upperValue); - } - } else { - if (choice.downMovement < 1.0e100) { - // down feasible, up infeasible - if (!satisfied) - needResolve = true; - choice.fix = -1; - numberToFix++; - saveUpper[iColumn] = lowerValue; - solver->setColUpper(iColumn, lowerValue); - } else { - // neither side feasible - COIN_DETAIL_PRINT(printf("Both infeasible for choice %d sequence %d\n", i, - model->object(choice.objectNumber)->columnNumber())); - delete ws; - ws = NULL; - //solver->writeMps("bad"); - numberToFix = -1; - delete choice.possibleBranch; - choice.possibleBranch = NULL; - break; - } - } - delete choice.possibleBranch; - if (numberIterationsAllowed <= 0) - break; - //printf("obj %d, col %d, down %g up %g value %g\n",iObject,iColumn, - // choice.downMovement,choice.upMovement,value); + } + solver->setHintParam(OsiDoDualInResolve, true, OsiHintDo) ; + // Sort + CoinSort_2(sort, sort + numberToDo, whichObject); + double * currentSolution = model->currentSolution(); + double objMin = 1.0e50; + double objMax = -1.0e50; + bool needResolve = false; + int maxChoices=1; + int currentChoice=0; + int numberThreads=0; + bool doAtEnd=false; + if (model->parallelMode() && (solveType&4)!=0) { + numberThreads=model->getNumberThreads(); + sprintf(general,"Using %d threads in analysis\n",numberThreads); + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << general + << CoinMessageEol; + if (model->parallelMode()==1) { + maxChoices=numberThreads; + } else { + maxChoices = numberToDo; + if ((solveType&2)!=0) + maxChoices = numberColumns; + doAtEnd=true; + } + } + StrongInfo * choices = new StrongInfo[maxChoices]; + StrongStaticInfo staticInfo; + int numberBundles = CoinMax(1,numberThreads); + StrongBundle * bundles = new StrongBundle[numberBundles]; + /* + 0 - available - no need to look at results + 1 - not available + 2 - available - need to look at results + */ +#ifndef NUMBER_THREADS +#define NUMBER_THREADS 4 +#endif + int status[NUMBER_THREADS]; + memset(status,0,sizeof(status)); + memset(&staticInfo,0,sizeof(staticInfo)); + staticInfo.solveType = solveType; + staticInfo.originalSolution=saveSolution; + staticInfo.back=back; + staticInfo.ws=ws; + staticInfo.integerTolerance=integerTolerance; + double time1 = model->getCurrentSeconds(); +#define DO_STEEPEST_SERIAL 1 +# ifdef COIN_HAS_CLP + if (osiclp&&(solveType&2)!=0&&(!numberThreads||DO_STEEPEST_SERIAL)) { + ClpSimplex * simplex = osiclp->getModelPtr(); + simplex->setLogLevel(0); + simplex->dual(0,1); + ClpDualRowPivot * dualRowPivot=simplex->dualRowPivot(); + ClpDualRowSteepest * steep = dynamic_cast(dualRowPivot); + if (steep) { + staticInfo.dualRowPivot=new ClpDualRowSteepest (*steep); + staticInfo.dualRowPivot->setMode(1); // full steepest edge + simplex->spareIntArray_[0]=0; + simplex->spareIntArray_[1]=numberRows; + staticInfo.dualRowPivot->saveWeights(simplex,7); + } + } +#endif + for (int i=0;iclone(); + threadNeedsRefreshing[i]=0; + } +# ifdef COIN_HAS_CLP + int numberSteepThreads=0; + int step=numberThreads ? (numberRows+numberThreads-1)/numberThreads : 0; + int first=0; + for (int i=0;i(threadInfo.threadInfo_[i].extraInfo2); + OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver); + ClpSimplex * simplex = osiclp->getModelPtr(); + simplex->setLogLevel(0); + simplex->dual(0,1); + ClpDualRowPivot * dualRowPivot=simplex->dualRowPivot(); + ClpDualRowSteepest * steep = dynamic_cast(dualRowPivot); + if (steep) { + numberSteepThreads=numberThreads; + ClpDualRowSteepest * dualRowPivot=new ClpDualRowSteepest (*steep); + dualRowPivot->setMode(1); // full steepest edge + simplex->spareIntArray_[0]=0; + simplex->spareIntArray_[1]=numberRows; + simplex->spareIntArray_[0]=first; + simplex->spareIntArray_[1]=CoinMin(first+step,numberRows); + first += step; + if (i==0) + staticInfo.dualRowPivot=dualRowPivot; + choices[i].steepest=dualRowPivot; + dualRowPivot->saveWeights(simplex,7); + } + } + } + if (numberSteepThreads&&false) { + int numberDone=0; + int iDo=0; + staticInfo.solveType = 200; + while (numberDone(threadInfo.threadInfo_[iThread].extraInfo2); + threadStatus=0; +#ifdef DETAIL_THREAD + printf("Starting steep task on thread %d\n", + choice.iThread); +#endif + threadInfo.startParallelTask(1,iThread,&bundle); + } + if (!threadStatus) { +#ifdef _MSC_VER + Sleep(1); +#else + usleep(1000); +#endif + continue; + } + if (threadStatus) { + numberDone++; + // say available + threadInfo.sayIdle(iThread); + } + staticInfo.solveType = solveType; + } + OsiSolverInterface * solver0= + reinterpret_cast(threadInfo.threadInfo_[0].extraInfo2); + CoinIndexedVector * savedWeights0 = staticInfo.dualRowPivot->savedWeights(); + int * index0 = savedWeights0->getIndices(); + double * weight0 = savedWeights0->denseVector(); + int step=(numberRows+numberSteepThreads-1)/numberSteepThreads; + int first=step; + //memset(weight0+first,0,(numberRows-first)*sizeof(double)); + for (int i=1;isavedWeights(); + int * index = savedWeights->getIndices(); + double * weight = savedWeights->denseVector(); + memcpy(index0+first,index+first,n*sizeof(int)); + memcpy(weight0+first,weight+first,n*sizeof(double)); + first += step; + delete choices[i].steepest; + choices[i].steepest=NULL; + } + //for (int j=0;jgetMinimizationObjValue(); + double * bestSolution = NULL; + double cutoff; + solver->getDblParam(OsiDualObjectiveLimit,cutoff); + double maxMovement = 2.0*(cutoff-objectiveValue_)+1.0e-6; + /* + Now calculate the cost forcing the variable up and down. + */ + int iDo=0; + int iDone=-1; + int numberDone=0; + int iThread=0; + int threadStatus=0; + int whenPrint = (numberToDo+9)/10; + while (numberDonegetCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed); + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << general + << CoinMessageEol; + } +#ifdef USE_STRONG_THREADS + if (numberThreads) { + threadInfo.waitParallelTask(1,iThread,iDo(threadInfo.threadInfo_[iThread].extraInfo2); + if ((threadNeedsRefreshing[iThread]&1)!=0) + solver->setColLower(saveLower); + if ((threadNeedsRefreshing[iThread]&2)!=0) + solver->setColUpper(saveUpper); + threadNeedsRefreshing[iThread]=0; + } + } +#endif + if (threadStatus==0&&iDomodifiableObject(iObject); + CbcSimpleIntegerDynamicPseudoCost * dynamicObject = + dynamic_cast (object) ; + int iColumn = dynamicObject->columnNumber(); + double value = currentSolution[iColumn]; + double nearest = floor(value + 0.5); + double lowerValue = floor(value); + bool satisfied = false; + if (fabs(value - nearest) <= integerTolerance || + value < saveLower[iColumn] || value > saveUpper[iColumn]) { + satisfied = true; + if (nearest < saveUpper[iColumn]) { + lowerValue = nearest; + } else { + lowerValue = nearest - 1; + } + } + double upperValue = lowerValue + 1.0; + // Save which object it was + choice.columnNumber = iColumn; + choice.initialValue=value; + choice.upLowerBound=upperValue; + choice.downUpperBound=lowerValue; + choice.numIntInfeas[1] = numberUnsatisfied_; + choice.numIntInfeas[0] = numberUnsatisfied_; + choice.movement[0] = 0.0; + choice.movement[1] = 0.0; + choice.numIters[0] = 0; + choice.numIters[1] = 0; + if (fabs(value - lowerValue) <= integerTolerance) + choice.numIters[0]=-1; // mark as not done + if (fabs(value - upperValue) <= integerTolerance) + choice.numIters[1]=-1; // mark as not done + bundle.choice=&choice; + bundle.solver = solver; +#ifdef USE_STRONG_THREADS + if (numberThreads) { + bundle.solver=reinterpret_cast(threadInfo.threadInfo_[iThread].extraInfo2); + threadStatus=0; +#ifdef DETAIL_THREAD + printf("Starting task for column %d on thread %d\n", + choice.columnNumber,iThread); +#endif + threadInfo.startParallelTask(1,iThread,&bundle); + } else { +#endif + threadStatus=2; + solveAnalyze(&bundle); +#ifdef USE_STRONG_THREADS + } +#endif + } + if (!threadStatus) { +#ifdef _MSC_VER + Sleep(1); +#else + usleep(1000); +#endif + continue; + } + if (threadStatus) { + int whichChoice = bundles[iThread].whichChoice; + StrongInfo & choice = choices[whichChoice]; + int iColumn=choice.columnNumber; + if (choice.integerSolution) { + double * foundSolution = choice.integerSolution; + solver->setColSolution(foundSolution); + // See if integer solution + int numberInfeas=0; + int numberOddInfeas=0; + if (model->feasibleSolution(numberInfeas,numberOddInfeas) + && model->problemFeasibility()->feasible(model, -1) >= 0) { + double newObjectiveValue; + solver->getDblParam(OsiObjOffset,newObjectiveValue); + newObjectiveValue=-newObjectiveValue; + const double * cost = solver->getObjCoefficients(); + for ( int i = 0 ; i < numberColumns ; i++ ) + newObjectiveValue += cost[i] * foundSolution[i]; + if (newObjectiveValuesetBestSolution(CBC_STRONGSOL, + newObjectiveValue, + foundSolution) ; + model->setLastHeuristic(NULL); + model->incrementUsed(solver->getColSolution()); + bestSolutionValue = model->getMinimizationObjValue(); + } + } + } + delete [] foundSolution; + } + for (int iWay=0;iWay<2;iWay++) { + numberIterationsAllowed -= choice.numIters[iWay]; + choice.movement[iWay] -= objectiveValue_; + } + // If objective goes above certain amount we can set bound + int jInt = back[iColumn]; + OsiObject * object = model->modifiableObject(jInt); + CbcSimpleIntegerDynamicPseudoCost * dynamicObject = + dynamic_cast (object) ; + if (dynamicObject) { + if (choice.numIters[0]>=0) { + dynamicObject->addToSumDownCost(CoinMin(choice.movement[0],maxMovement)); + dynamicObject->addToSumDownChange(choice.initialValue-choice.downUpperBound); + } + if (choice.numIters[1]>=0) { + dynamicObject->addToSumUpCost(CoinMin(choice.movement[1],maxMovement)); + dynamicObject->addToSumUpChange(choice.upLowerBound-choice.initialValue); + } + } + newLower[jInt] = choice.upLowerBound; + if (choice.finished[0]) + objLower[jInt] = choice.movement[0] + objectiveValue_; + else + objLower[jInt] = objectiveValue_; + newUpper[jInt] = choice.downUpperBound; + if (choice.finished[1]) + objUpper[jInt] = choice.movement[1] + objectiveValue_; + else + objUpper[jInt] = objectiveValue_; + objMin = CoinMin(CoinMin(objLower[jInt], objUpper[jInt]), objMin); + objMovement[2*jInt]=choice.movement[0]; + objMovement[2*jInt+1]=choice.movement[1]; + double sumModified = choice.modified[0] + choice.modified[1] + + 1.0e-15*(choice.sumModified[0]+choice.sumModified[1]); + if (choice.numIters[0]>=0&&choice.numIters[1]>=0) + sumModified *= 0.6; + interAction[jInt] = sumModified; + /* + End of evaluation for this candidate variable. Possibilities are: + * Both sides below cutoff; this variable is a candidate for branching. + * Both sides infeasible or above the objective cutoff: no further action + here. Break from the evaluation loop and assume the node will be purged + by the caller. + * One side below cutoff: Install the branch (i.e., fix the variable). Break + from the evaluation loop and assume the node will be reoptimised by the + caller. + */ + threadStatus=0; + currentChoice++; + numberDone++; +#ifdef USE_STRONG_THREADS + // say available + if (numberThreads) { + threadInfo.sayIdle(iThread); + } +#endif + if (doAtEnd) + continue; + if (choice.movement[1] < 1.0e100) { + if (choice.movement[0] < 1.0e100) { + objMax = CoinMax(CoinMax(objLower[jInt], objUpper[jInt]), objMax); + // In case solution coming in was odd + choice.movement[1] = CoinMax(0.0, choice.movement[1]); + choice.movement[0] = CoinMax(0.0, choice.movement[0]); + // feasible - + model->messageHandler()->message(CBC_STRONG, *model->messagesPointer()) + << iColumn << iColumn + << choice.movement[0] << choice.numIntInfeas[0] + << choice.movement[1] << choice.numIntInfeas[1] + << choice.initialValue + << CoinMessageEol; + } else { + // up feasible, down infeasible + needResolve = true; + numberToFix++; + saveLower[iColumn] = choice.upLowerBound; + solver->setColLower(iColumn, choice.upLowerBound); +#ifdef USE_STRONG_THREADS + for (int i=0;isetColUpper(iColumn, choice.downUpperBound); +#ifdef USE_STRONG_THREADS + for (int i=0;iobject(choice.objectNumber)->columnNumber())); + //solver->writeMps("bad"); + numberToFix = -1; + break; + } + } + if (numberIterationsAllowed <= 0) + break; + if (currentChoice==maxChoices) + currentChoice=0; + } + //printf("obj %d, col %d, down %g up %g value %g\n",iObject,iColumn, + // choice.downMovement,choice.upMovement,value); + } + // Do at end if deterministic + if (doAtEnd) { + if (bestSolution) { + model->setBestSolution(CBC_STRONGSOL, + bestSolutionValue, + bestSolution) ; + model->setLastHeuristic(NULL); + model->incrementUsed(solver->getColSolution()); + delete [] bestSolution; + } + for (int iDo = 0; iDo < numberLookIntegers; iDo++) { + StrongInfo & choice = choices[iDo]; + int iColumn = choice.columnNumber; + int iObject = iColumn; + int jInt = back[iColumn]; + double value = choice.initialValue; + double lowerValue = choice.downUpperBound; + double upperValue = choice.upLowerBound; + if (choice.movement[1] < 1.0e100) { + if (choice.movement[0] < 1.0e100) { + objMax = CoinMax(CoinMax(objLower[jInt], objUpper[jInt]), objMax); + // In case solution coming in was odd + choice.movement[1] = CoinMax(0.0, choice.movement[1]); + choice.movement[0] = CoinMax(0.0, choice.movement[0]); + // feasible - + model->messageHandler()->message(CBC_STRONG, *model->messagesPointer()) + << iObject << iColumn + << choice.movement[0] << choice.numIntInfeas[0] + << choice.movement[1] << choice.numIntInfeas[1] + << value + << CoinMessageEol; + } else { + // up feasible, down infeasible + numberToFix++; + saveLower[iColumn] = upperValue; + solver->setColLower(iColumn, upperValue); + } + } else { + if (choice.movement[0] < 1.0e100) { + // down feasible, up infeasible + needResolve = true; + numberToFix++; + saveUpper[iColumn] = lowerValue; + solver->setColUpper(iColumn, lowerValue); + } else { + // neither side feasible + COIN_DETAIL_PRINT(printf("Both infeasible for choice %d sequence %d\n", i, + model->object(choice.objectNumber)->columnNumber())); + //solver->writeMps("bad"); + numberToFix = -1; + break; + } + } + } + } + if (false) { + const double * lower = solver->getColLower(); + const double * upper = solver->getColUpper(); + for (int i=0;inumberAnalyzeIterations() - numberIterationsAllowed)); + model->setNumberAnalyzeIterations(numberIterationsAllowed); + if (numberToFix>0) { + sprintf(general,"%d variable bounds modified by initial strong branching (%.2f seconds - %d iterations)",numberToFix,model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed); + } else if (numberToFix<0) { + sprintf(general,"initial strong branching found to be infeasible (%.2f seconds - %d iterations)",model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed); + } else if ((solveType&32)!=0) { + sprintf(general,"No variables fixed by initial strong branching (%.2f seconds - %d iterations)",model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed); + } else { + general[0]='\0'; + } + if (general[0]!='\0') + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << general + << CoinMessageEol; + double smallestEffect=COIN_DBL_MAX; + double largestEffect=0.0; + for (i = 0; i < numberIntegers; i++) { + int iColumn=integerVariable[i]; + if (back[iColumn]>=numberColumns) + continue; + smallestEffect = CoinMin(smallestEffect,interAction[i]); + largestEffect = CoinMax(largestEffect,interAction[i]); + } + double groupValue[11]; + int groupCounts[11]={0,0,0,0,0,0,0,0,0,0,0}; + groupValue[10]=largestEffect; + for (int i=0;i<10;i++) + groupValue[i]=smallestEffect+i*0.1*(largestEffect-smallestEffect); + sprintf(general,"Looked at %d integer variables - smallest interaction %g", + numberLookIntegers,smallestEffect); + model->messageHandler()->message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1, + *model->messagesPointer()) + << general + << CoinMessageEol; + for (int i = 0; i < numberIntegers; i++) { + int iColumn=integerVariable[i]; + if (back[iColumn]>=numberColumns) + continue; + double value = interAction[i]; + int j; + for (j=0;j<11;j++) { + if (value<=groupValue[j]||j==10) + break; + } + groupCounts[j]++; + } + general[0]='\0'; + for (int i=0;i<11;i++) + sprintf(general+strlen(general),"%d <= %g ",groupCounts[i],groupValue[i]); + model->messageHandler()->message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1, + *model->messagesPointer()) + << general + << CoinMessageEol; + smallestEffect=COIN_DBL_MAX; + largestEffect=0.0; + int numberChanged=0; + int numberZeroMoved=0; + for (i = 0; i < numberIntegers; i++) { + int iColumn=integerVariable[i]; + if (back[iColumn]>=numberColumns) + continue; + for (int iWay=0;iWay<2;iWay++) { + double value=objMovement[2*i+iWay]; + if (value<1.0e-7) { + numberZeroMoved++; + } else if (value<1.0e50) { + smallestEffect = CoinMin(smallestEffect,value); + largestEffect = CoinMax(largestEffect,value); + } else { + numberChanged++; + } + } + } + memset(groupCounts,0,sizeof(groupCounts)); + groupValue[10]=largestEffect; + for (int i=0;i<10;i++) + groupValue[i]=smallestEffect+i*0.1*(largestEffect-smallestEffect); + sprintf(general,"Strong branching - %d bounds changed, %d zero objective changes and %d nonzero (smallest %g)", + numberChanged,numberZeroMoved, + 2*numberLookIntegers-numberChanged-numberZeroMoved,smallestEffect); + model->messageHandler()->message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1, + *model->messagesPointer()) + << general + << CoinMessageEol; + sprintf(general,"Breakdown "); + for (i = 0; i < numberIntegers; i++) { + int iColumn=integerVariable[i]; + if (back[iColumn]>=numberColumns) + continue; + for (int iWay=0;iWay<2;iWay++) { + double value = objMovement[2*i+iWay]; + int j; + for (j=0;j<11;j++) { + if (value<=groupValue[j]||j==10) + break; + } + groupCounts[j]++; } - COIN_DETAIL_PRINT(printf("Best possible solution %g, can fix more if solution of %g found - looked at %d variables in %d iterations\n", - objMin, objMax, iDo, model->numberAnalyzeIterations() - numberIterationsAllowed)); - model->setNumberAnalyzeIterations(numberIterationsAllowed); + } + for (int i=0;i<11;i++) + sprintf(general+strlen(general),"%d <= %g ",groupCounts[i],groupValue[i]); + model->messageHandler()->message((solveType&32)==0 ? CBC_FPUMP2 : CBC_FPUMP1, + *model->messagesPointer()) + << general + << CoinMessageEol; + delete [] objMovement; + if ((solveType&2)==0) { // Delete the snapshot solver->unmarkHotStart(); - // back to normal - solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ; - solver->setIntParam(OsiMaxNumIterationHotStart, saveLimit); - // restore basis - solver->setWarmStart(ws); + } + // back to normal + solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ; + solver->setIntParam(OsiMaxNumIterationHotStart, saveLimit); + // restore basis + solver->setWarmStart(ws); + // skip if infeasible + if (numberToFix<0) + solveType=0; + int numberBoundsChanged=0; + if ((solveType&16)==0) { + double size=numberRows; + size*=numberColumns; + if (size>1000000) { + if ((solveType&32)!=0) + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << "Skipping analyze on other columns as problem too large" + << CoinMessageEol; + solveType &= ~2; + } + } + if ((solveType&2)!=0) { +# ifdef COIN_HAS_CLP + int saveOptions = osiclp ? osiclp->specialOptions() : 0; + if (osiclp) { + //ClpPrimalColumnPivot * primalColumnPivot=NULL; + osiclp->setSpecialOptions(saveOptions|2048); // off crunch + } +#endif + double * newLower = new double [2*numberColumns]; + double * newUpper = newLower + numberColumns; + // look at ints/all - should be parametrics - for now primal + OsiSolverInterface * temp = solver->clone(); + // add constraint + int * indices = reinterpret_cast(newUpper); + double * obj = newLower; + memcpy(obj,solver->getObjCoefficients(),numberColumns*sizeof(double)); + int n=0; + for (int i=0;igetCutoff(); + // relax a little bit + cutoff += 1.0e-4; + double offset; + temp->getDblParam(OsiObjOffset, offset); + temp->addRow(n,indices,obj,-COIN_DBL_MAX,CoinMin(cutoff,1.0e25)+offset); + temp->setDblParam(OsiObjOffset, 0.0); +#if defined (THREADS_IN_ANALYZE) && defined (COIN_HAS_CLP) + for (int iThread=0;iThread(threadInfo.threadInfo_[iThread].extraInfo2); + solver->addRow(n,indices,obj,-COIN_DBL_MAX,CoinMin(cutoff,1.0e25)+offset); + } +#endif + } + //temp->setHintParam(OsiDoDualInResolve, false, OsiHintDo) ; + temp->setHintParam(OsiDoReducePrint, true, OsiHintTry); + temp->setDblParam(OsiDualObjectiveLimit, COIN_DBL_MAX); + temp->resolve(); + { + const double * lower =temp->getColLower(); + const double * upper =temp->getColUpper(); + for (int i=0;isetColSolution(saveSolution); + ws = temp->getWarmStart(); + staticInfo.ws=ws; + staticInfo.newObjective = new double[2*numberColumns]; + memcpy(staticInfo.newObjective,solver->getObjCoefficients(),numberColumns*sizeof(double)); + memset(staticInfo.newObjective+numberColumns,0,numberColumns*sizeof(double)); +#if defined (THREADS_IN_ANALYZE) && defined (COIN_HAS_CLP) + for (int iThread=0;iThread(threadInfo.threadInfo_[iThread].extraInfo2); + solver->setObjective(newLower); + solver->setDblParam(OsiDualObjectiveLimit, COIN_DBL_MAX); + threadNeedsRefreshing[iThread]=3; + } +#endif + for (int i = 0; i < numberColumns; i++) { + newLower[i]=lower[i]; + newUpper[i]=upper[i]; + } + double * thisSolution = CoinCopyOfArray(temp->getColSolution(),numberColumns); + double primalTolerance; + solver->getDblParam(OsiPrimalTolerance,primalTolerance); + iDo=0; + iDone=-1; + numberDone=0; + int iThread=0; + threadStatus=0; + currentChoice=0; + staticInfo.solveType=100; //mark for analyze + staticInfo.originalSolution=thisSolution; + whenPrint=(numberColumns+9)/10; + while (numberDonegetCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed); + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << general + << CoinMessageEol; + } +#ifdef USE_STRONG_THREADS + if (numberThreads) { + threadInfo.waitParallelTask(1,iThread,iDo(threadInfo.threadInfo_[iThread].extraInfo2); + if ((threadNeedsRefreshing[iThread]&1)!=0) + solver->setColLower(saveLower); + if ((threadNeedsRefreshing[iThread]&2)!=0) + solver->setColUpper(saveUpper); + threadNeedsRefreshing[iThread]=0; + } + } +#endif + if (threadStatus==0&&iDonewLower[iColumn]+integerTolerance) + typeSolve=1; + if (thisSolution[iColumn]=0) { + if (thisSolution[iColumn]newUpper[iColumn]-0.9999) + typeSolve &= ~2; + if (temp->isBinary(iColumn)) + typeSolve=0; // already done + } + if (typeSolve==0 || newUpper[iColumn]==newLower[iColumn]) { +#ifdef USE_STRONG_THREADS + // say available + if (numberThreads) { + threadInfo.sayIdle(iThread); + } +#endif + numberDone++; + continue; + } + // Save which object it was + choice.columnNumber = iColumn; + choice.initialValue=thisSolution[iColumn]; + choice.movement[0]=COIN_DBL_MAX; + choice.movement[1]=-COIN_DBL_MAX; + choice.upLowerBound=newUpper[iColumn]; + choice.downUpperBound=newLower[iColumn]; + if ((typeSolve&1)==0) + choice.numIters[0]=-1; // mark as not done + if ((typeSolve&2)==0) + choice.numIters[1]=-1; // mark as not done + bundle.choice=&choice; + bundle.solver = temp; +#ifdef USE_STRONG_THREADS + if (numberThreads) { + bundle.solver=reinterpret_cast(threadInfo.threadInfo_[iThread].extraInfo2); + threadStatus=0; +#ifdef DETAIL_THREAD + printf("Starting task for column %d on thread %d\n", + choice.columnNumber,iThread); +#endif + threadInfo.startParallelTask(1,iThread,&bundle); + } else { +#endif + threadStatus=2; + solveAnalyze(&bundle); +#ifdef USE_STRONG_THREADS + } +#endif + } + if (threadStatus) { + int whichChoice = bundles[iThread].whichChoice; + StrongInfo & choice = choices[whichChoice]; + int iColumn=choice.columnNumber; + if(choice.modified[0]) { + numberToFix = -numberColumns-1; + } + double gotLower=COIN_DBL_MAX; + double gotUpper=-COIN_DBL_MAX; + if (choice.numIters[0]>=0) { + // go down + double value = choice.movement[0]; + if (value>newLower[iColumn]+100.0*integerTolerance) { + if (back[iColumn]>=0) + value = ceil(value-integerTolerance); + else + value = CoinMax(newLower[iColumn],value-1.0e-5-1.0e-8*fabs(value)); + if (value>newLower[iColumn]+1.0e-8*(1.0+fabs(value))) { + sprintf(general,"Secondary analysis solve increases lower bound on %d from %g to %g%s", + iColumn,newUpper[iColumn],value,(back[iColumn]>=0) ? "(integer)" : ""); + model->messageHandler()->message(CBC_FPUMP2, *model->messagesPointer()) + << general + << CoinMessageEol; + numberBoundsChanged++; + if (value>newUpper[iColumn]-primalTolerance) { + value=newUpper[iColumn]; + if (value>newUpper[iColumn]+10.0*primalTolerance) { + // infeasible + numberToFix=-numberColumns-1; + } + } + gotLower = value; + } + } + } + if (choice.numIters[1]>=0) { + // go up + double value=choice.movement[1]; + if (value=0) + value = floor(value+integerTolerance); + else + value = CoinMin(newUpper[iColumn],value+1.0e-5+1.0e-8*fabs(value)); + if (value=0) ? "(integer)" : ""); + model->messageHandler()->message(CBC_FPUMP2, *model->messagesPointer()) + << general + << CoinMessageEol; + numberBoundsChanged++; + if (valuesetColLower(iColumn,gotLower); + if (!doAtEnd) + solver->setColLower(iColumn,gotLower); + } + if (gotUpper!=-COIN_DBL_MAX) { + gotUpper=CoinMax(gotUpper,newLower[iColumn]); + newUpper[iColumn]=gotUpper; + temp->setColUpper(iColumn,gotUpper); + if (!doAtEnd) + solver->setColUpper(iColumn,gotUpper); + } +#if 0 + if ((model->specialOptions()&1) != 0) { + const OsiRowCutDebugger *debugger = solver->getRowCutDebugger() ; + if (!debugger) { + abort(); + } else { + printf("still ok\n"); + } + } +#endif + threadStatus=0; + currentChoice++; + numberDone++; + for (int iWay=0;iWay<2;iWay++) { + if (choice.numIters[iWay]>0) + numberIterationsAllowed -= choice.numIters[iWay]; + } + if (currentChoice==maxChoices) + currentChoice=0; +#ifdef USE_STRONG_THREADS + // say available + if (numberThreads) { + threadInfo.sayIdle(iThread); + } +#endif + } + } + delete [] thisSolution; + delete temp; + delete [] newLower; # ifdef COIN_HAS_CLP - if (osiclp) - osiclp->setSpecialOptions(saveClpOptions); + if (osiclp) { + //ClpPrimalColumnPivot * primalColumnPivot=NULL; + osiclp->setSpecialOptions(saveOptions); + } +#endif + } + delete [] staticInfo.newObjective; +# ifdef COIN_HAS_CLP + if (osiclp) { + delete staticInfo.dualRowPivot; + delete staticInfo.primalColumnPivot; + ClpSimplex * simplex = osiclp->getModelPtr(); + ClpDualRowPivot * dualRowPivot=simplex->dualRowPivot(); + ClpDualRowSteepest * steep = dynamic_cast(dualRowPivot); + if (steep) + steep->setMode(3); + } +#endif + if ((solveType&64)!=0) { + OsiSolverInterface * temp = solver->clone(); + int numberRows=solver->getNumRows(); + int numberContinuousRows=model->numberRowsAtContinuous(); + int * del = new int[numberRows-numberContinuousRows]; + for (int i=numberContinuousRows;ideleteRows(numberRows-numberContinuousRows,del); + delete [] del; +# ifdef COIN_HAS_CLP + if (!osiclp) { +#endif + solver->writeMps("analyzed"); + temp->writeMps("analyzed2"); +# ifdef COIN_HAS_CLP + } else { + OsiClpSolverInterface * osiclp2 = dynamic_cast< OsiClpSolverInterface*> (temp); + osiclp->getModelPtr()->writeMps("analyzed.mps",2,1); + osiclp2->getModelPtr()->writeMps("analyzed2.mps",2,1); + } +#endif + delete temp; + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << "Models saved on 'analyzed' and 'analyzed2'" + << CoinMessageEol; + } + delete [] choices; + for (int i=0;i(threadInfo.threadInfo_[i].extraInfo2); + } + } +#endif + delete ws; + + delete [] sort; + delete [] whichObject; + delete [] saveLower; + delete [] saveUpper; + delete [] back; + // restore solution + solver->setColSolution(saveSolution); +# ifdef COIN_HAS_CLP + if (osiclp) + osiclp->setSpecialOptions(saveClpOptions); # endif - model->reserveCurrentSolution(saveSolution); - delete [] saveSolution; - if (needResolve) - solver->resolve(); + delete [] saveSolution; + solver->resolve(); + if (numberToFix<0&&!solver->isProvenOptimal()) { + // infeasible + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << "Analysis shows problem to be infeasible" + << CoinMessageEol; return numberToFix; + } + if (numberBoundsChanged) { + sprintf(general,"%d bounds changed by secondary solves (%.2f seconds - %d iterations)", + numberBoundsChanged,model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed); + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << general + << CoinMessageEol; + } else if ((solveType&32)!=0) { + sprintf(general,"No bounds changed by secondary solves (%.2f seconds - %d iterations)", + model->getCurrentSeconds()-time1,saveAllowed-numberIterationsAllowed); + model->messageHandler()->message(CBC_GENERAL, *model->messagesPointer()) + << general + << CoinMessageEol; + } + model->reserveCurrentSolution(solver->getColSolution()); + if ((solveType&1)!=0) { + if (groupCounts[0]*4>numberIntegers) { + // change priority on this group + int generalPriority=-10000000; + for (int i = 0; i < numberIntegers; i++) { + OsiObject * object = model->modifiableObject(i); + CbcSimpleInteger * integerObject = + dynamic_cast (object) ; + if (!integerObject) + continue; + generalPriority = CoinMax(generalPriority,integerObject->priority()); + } + for (int i = 0; i < numberIntegers; i++) { + OsiObject * object = model->modifiableObject(i); + CbcSimpleInteger * integerObject = + dynamic_cast (object) ; + if (!integerObject) + continue; + if (!interAction[i]&&integerObject->priority()==generalPriority) + integerObject->setPriority(generalPriority+1); + } + } + } + return numberToFix; } @@ -4141,7 +5624,7 @@ : CoinTreeNode(rhs) { #ifdef CHECK_NODE - printf("CbcNode %x Constructor from rhs %x\n", this, &rhs); + printf("CbcNode %p Constructor from rhs %p\n", this, &rhs); #endif if (rhs.nodeInfo_) nodeInfo_ = rhs.nodeInfo_->clone(); @@ -4195,11 +5678,11 @@ { #ifdef CHECK_NODE if (nodeInfo_) { - printf("CbcNode %x Destructor nodeInfo %x (%d)\n", + printf("CbcNode %p Destructor nodeInfo %p (%d)\n", this, nodeInfo_, nodeInfo_->numberPointingToThis()); //assert(nodeInfo_->numberPointingToThis()>=0); } else { - printf("CbcNode %x Destructor nodeInfo %x (?)\n", + printf("CbcNode %p Destructor nodeInfo %p (?)\n", this, nodeInfo_); } #endif @@ -4214,7 +5697,7 @@ nodeInfo_->nullParent(); delete nodeInfo_; } else { - //printf("node %x nodeinfo %x parent %x\n",this,nodeInfo_,nodeInfo_->parent()); + //printf("node %p nodeinfo %p parent %p\n",this,nodeInfo_,nodeInfo_->parent()); // anyway decrement parent //if (parent) ///parent->decrement(1); diff -Nru coinor-cbc-2.8.12/src/CbcNode.hpp coinor-cbc-2.9.9+repack1/src/CbcNode.hpp --- coinor-cbc-2.8.12/src/CbcNode.hpp 2011-01-05 01:12:36.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcNode.hpp 2013-08-27 15:19:55.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcNode.hpp 1573 2011-01-05 01:12:36Z lou $ */ +/* $Id: CbcNode.hpp 1957 2013-08-27 15:19:55Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -307,6 +307,12 @@ if (yesNo) state_ |= 2; else state_ &= ~2; } + /// Get state (really for debug) + inline int getState() const + { return state_;} + /// Set state (really for debug) + inline void setState(int value) + { state_ = value;} /// Print void print() const; /// Debug diff -Nru coinor-cbc-2.8.12/src/CbcNodeInfo.cpp coinor-cbc-2.9.9+repack1/src/CbcNodeInfo.cpp --- coinor-cbc-2.8.12/src/CbcNodeInfo.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcNodeInfo.cpp 2014-11-21 10:57:22.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcNodeInfo.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcNodeInfo.cpp 2097 2014-11-21 10:57:22Z forrest $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -61,7 +61,7 @@ active_(7) { #ifdef CHECK_NODE - printf("CbcNodeInfo %x Constructor\n", this); + printf("CbcNodeInfo %p Constructor\n", this); #endif } @@ -107,7 +107,7 @@ active_(7) { #ifdef CHECK_NODE - printf("CbcNodeInfo %x Constructor from parent %x\n", this, parent_); + printf("CbcNodeInfo %p Constructor from parent %p\n", this, parent_); #endif //setParentBasedData(); } @@ -128,7 +128,7 @@ active_(rhs.active_) { #ifdef CHECK_NODE - printf("CbcNodeInfo %x Copy constructor\n", this); + printf("CbcNodeInfo %p Copy constructor\n", this); #endif if (numberCuts_) { cuts_ = new CbcCountRowCut * [numberCuts_]; @@ -163,7 +163,7 @@ active_(7) { #ifdef CHECK_NODE - printf("CbcNodeInfo %x Constructor from parent %x\n", this, parent_); + printf("CbcNodeInfo %p Constructor from parent %p\n", this, parent_); #endif //setParentBasedData(); } @@ -176,7 +176,8 @@ CbcNodeInfo::~CbcNodeInfo() { #ifdef CHECK_NODE - printf("CbcNodeInfo %x Destructor parent %x\n", this, parent_); + printf("CbcNodeInfo %p Destructor parent %p\n", this, parent_); + printf("cuts %p - number %d\n",cuts_,numberCuts_); #endif assert(!numberPointingToThis_); @@ -218,7 +219,7 @@ if (cuts_[i]) { int number = cuts_[i]->decrement(changeThis); if (!number) { - //printf("info %x del cut %d %x\n",this,i,cuts_[i]); + //printf("info %p del cut %d %p\n",this,i,cuts_[i]); #ifndef GLOBAL_CUTS_JUST_POINTERS delete cuts_[i]; #else @@ -397,7 +398,7 @@ for (i = 0; i < numberCuts; i++) { CbcCountRowCut * thisCut = cut[i]; thisCut->setInfo(this, numberCuts_); - //printf("info %x cut %d %x\n",this,i,thisCut); + //printf("info %p cut %d %p\n",this,i,thisCut); thisCut->increment(numberToBranchOn); cuts_[numberCuts_++] = thisCut; #ifdef CBC_DEBUG @@ -506,5 +507,14 @@ CbcNodeInfo::deactivate(int mode) { active_ &= (~mode); + if (mode==7) { + for (int i = 0; i < numberCuts_; i++) { + delete cuts_[i]; + cuts_[i] = NULL; + } + delete [] cuts_; + cuts_=NULL; + numberCuts_=0; + } } diff -Nru coinor-cbc-2.8.12/src/CbcNodeInfo.hpp coinor-cbc-2.9.9+repack1/src/CbcNodeInfo.hpp --- coinor-cbc-2.8.12/src/CbcNodeInfo.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcNodeInfo.hpp 2014-07-16 09:29:16.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcNodeInfo.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcNodeInfo.hpp 2048 2014-07-16 09:29:16Z forrest $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -256,11 +256,13 @@ 1 - bounds 2 - cuts 4 - basis! + 8 - just marked + 16 - symmetry branching worked */ void deactivate(int mode = 3); /// Say if normal inline bool allActivated() const { - return (active_ == 7); + return ((active_&7) == 7); } /// Say if marked inline bool marked() const { @@ -274,6 +276,12 @@ inline void unmark() { active_ &= ~8; } + /// Get symmetry value (true worked at this node) + inline bool symmetryWorked() const + { return (active_&16) !=0;} + /// Say symmetry worked at this node) + inline void setSymmetryWorked() + { active_ |= 16;} /// Branching object for the parent inline const OsiBranchingObject * parentBranch() const { diff -Nru coinor-cbc-2.8.12/src/CbcNWay.cpp coinor-cbc-2.9.9+repack1/src/CbcNWay.cpp --- coinor-cbc-2.8.12/src/CbcNWay.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcNWay.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcNWay.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcNWay.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcNWay.hpp coinor-cbc-2.9.9+repack1/src/CbcNWay.hpp --- coinor-cbc-2.8.12/src/CbcNWay.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcNWay.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcNWay.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcNWay.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcObject.cpp coinor-cbc-2.9.9+repack1/src/CbcObject.cpp --- coinor-cbc-2.8.12/src/CbcObject.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcObject.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcObject.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcObject.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcObject.hpp coinor-cbc-2.9.9+repack1/src/CbcObject.hpp --- coinor-cbc-2.8.12/src/CbcObject.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcObject.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcObject.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcObject.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcObjectUpdateData.cpp coinor-cbc-2.9.9+repack1/src/CbcObjectUpdateData.cpp --- coinor-cbc-2.8.12/src/CbcObjectUpdateData.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcObjectUpdateData.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcObjectUpdateData.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcObjectUpdateData.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcObjectUpdateData.hpp coinor-cbc-2.9.9+repack1/src/CbcObjectUpdateData.hpp --- coinor-cbc-2.8.12/src/CbcObjectUpdateData.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcObjectUpdateData.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcObjectUpdateData.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcObjectUpdateData.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcPartialNodeInfo.cpp coinor-cbc-2.9.9+repack1/src/CbcPartialNodeInfo.cpp --- coinor-cbc-2.8.12/src/CbcPartialNodeInfo.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcPartialNodeInfo.cpp 2013-08-02 14:26:23.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcPartialNodeInfo.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcPartialNodeInfo.cpp 1951 2013-08-02 14:26:23Z forrest $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -128,7 +128,7 @@ { OsiSolverInterface *solver = model->solver(); - if ((active_&4) != 0) { + if ((active_&4) != 0 && basis) { basis->applyDiff(basisDiff_) ; #ifdef CBC_CHECK_BASIS std::cout << "Basis (after applying " << this << ") " << std::endl ; diff -Nru coinor-cbc-2.8.12/src/CbcPartialNodeInfo.hpp coinor-cbc-2.9.9+repack1/src/CbcPartialNodeInfo.hpp --- coinor-cbc-2.8.12/src/CbcPartialNodeInfo.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcPartialNodeInfo.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcPartialNodeInfo.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcPartialNodeInfo.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcSimpleInteger.cpp coinor-cbc-2.9.9+repack1/src/CbcSimpleInteger.cpp --- coinor-cbc-2.8.12/src/CbcSimpleInteger.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSimpleInteger.cpp 2013-07-21 09:05:45.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcSimpleInteger.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcSimpleInteger.cpp 1943 2013-07-21 09:05:45Z forrest $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -21,6 +21,7 @@ #include "CbcModel.hpp" #include "CbcMessage.hpp" #include "CbcSimpleInteger.hpp" +#include "CbcSimpleIntegerDynamicPseudoCost.hpp" #include "CbcBranchActual.hpp" #include "CoinSort.hpp" #include "CoinError.hpp" @@ -144,6 +145,11 @@ newValue = floor(newValue + 0.5); solver->setColLower(columnNumber_, newValue); solver->setColUpper(columnNumber_, newValue); +#ifdef SWITCH_VARIABLES + const CbcSwitchingBinary * sObject = dynamic_cast (this); + if (sObject) + sObject->setAssociatedBounds(solver,1); +#endif return fabs(value - newValue); } @@ -308,6 +314,11 @@ down_[1] = floor(value_); up_[0] = ceil(value_); up_[1] = model_->getColUpper()[iColumn]; + // fix extreme cases + if (up_[0]==1.0) + down_[1]=0.0; + if (down_[1]==0.0) + up_[0]=1.0; } // Useful constructor for fixing CbcIntegerBranchingObject::CbcIntegerBranchingObject (CbcModel * model, @@ -555,6 +566,15 @@ if (nlb < olb + 1.0e-8 && nub > oub - 1.0e-8 && false) printf("bad null change for column %d - bounds %g,%g\n", iColumn, olb, oub); #endif +#ifdef SWITCH_VARIABLES + if (model_->logLevel()>2) + printf("for column %d - old bounds %g,%g - new %g,%g\n", iColumn, olb, oub, + nlb,nub); + CbcSwitchingBinary * sObject = dynamic_cast (originalCbcObject_); + if (sObject) + sObject->setAssociatedBounds(); + //(dynamic_cast(originalCbcObject_))->setAssociatedBounds(); +#endif return 0.0; } /* Update bounds in solver as in 'branch' and update given bounds. diff -Nru coinor-cbc-2.8.12/src/CbcSimpleIntegerDynamicPseudoCost.cpp coinor-cbc-2.9.9+repack1/src/CbcSimpleIntegerDynamicPseudoCost.cpp --- coinor-cbc-2.8.12/src/CbcSimpleIntegerDynamicPseudoCost.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSimpleIntegerDynamicPseudoCost.cpp 2013-07-21 09:05:45.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcSimpleIntegerDynamicPseudoCost.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcSimpleIntegerDynamicPseudoCost.cpp 1943 2013-07-21 09:05:45Z forrest $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -23,6 +23,9 @@ #include "CoinSort.hpp" #include "CoinError.hpp" #include "CbcSimpleIntegerDynamicPseudoCost.hpp" +#ifdef COIN_HAS_CLP +#include "OsiClpSolverInterface.hpp" +#endif #ifdef COIN_DEVELOP typedef struct { double sumUp_; @@ -839,9 +842,11 @@ assert (info->upper_[columnNumber_] > info->lower_[columnNumber_]); if (!info->hotstartSolution_ && priority_ != -999) { #ifndef NDEBUG +#ifndef SWITCH_VARIABLES double nearest = floor(value + 0.5); assert (fabs(value - nearest) > info->integerTolerance_); #endif +#endif } else if (info->hotstartSolution_) { double targetValue = info->hotstartSolution_[columnNumber_]; if (way > 0) @@ -1015,6 +1020,15 @@ double nearest = floor(value + 0.5); if (fabs(value - nearest) > integerTolerance) unsatisfied++; +#ifdef SWITCH_VARIABLES + const CbcSwitchingBinary * sObject = dynamic_cast (this); + if (sObject) { + int state[3],nBadFixed; + unsatisfied += + sObject->checkAssociatedBounds(solver,solution,0, + state,nBadFixed); + } +#endif } } int way = branchingObject->way(); @@ -1397,4 +1411,443 @@ const double* otherBd = br->way_ < 0 ? br->down_ : br->up_; return CbcCompareRanges(thisBd, otherBd, replaceIfOverlap); } +#ifdef SWITCH_VARIABLES +/** Default Constructor + + Equivalent to an unspecified binary variable. +*/ +CbcSwitchingBinary::CbcSwitchingBinary () + : CbcSimpleIntegerDynamicPseudoCost(), + zeroLowerBound_(NULL), + oneLowerBound_(NULL), + zeroUpperBound_(NULL), + oneUpperBound_(NULL), + otherVariable_(NULL), + numberOther_(0), + type_(0) +{ +} + +/** Useful constructor +*/ +CbcSwitchingBinary::CbcSwitchingBinary (CbcSimpleIntegerDynamicPseudoCost * oldObject, + int nOdd,const int * other, const int * otherRow) + : CbcSimpleIntegerDynamicPseudoCost(*oldObject), + zeroLowerBound_(NULL), + oneLowerBound_(NULL), + zeroUpperBound_(NULL), + oneUpperBound_(NULL), + otherVariable_(NULL), + numberOther_(0), + type_(0) +{ + if (nOdd) + type_=2; + const CoinPackedMatrix * rowCopy = model_->solver()->getMatrixByRow(); + const int * column = rowCopy->getIndices(); + //const int * rowLength = rowCopy->getVectorLengths(); + const CoinBigIndex * rowStart = rowCopy->getVectorStarts(); + //const double * rowLower = model_->solver()->getRowLower(); + const double * rowUpper = model_->solver()->getRowUpper(); + const double * columnLower = model_->solver()->getColLower(); + const double * columnUpper = model_->solver()->getColUpper(); + const double * element = rowCopy->getElements(); + int last = other[0]; + int nPair=0; + int nInGroup=1; + for (int i=1;i<=nOdd;i++) { + if (other[i]==last) { + nInGroup++; + } else { + if (nInGroup>2 && model_->logLevel()>2) + printf("%d in group for column %d - some redundancy\n", + nInGroup,columnNumber_); + nPair++; + last=other[i]; + nInGroup=1; + } + } + zeroLowerBound_ = new double [4*nPair]; + oneLowerBound_ = zeroLowerBound_+nPair; + zeroUpperBound_ = oneLowerBound_+nPair; + oneUpperBound_ = zeroUpperBound_+nPair; + otherVariable_ = new int [nPair]; + numberOther_ = nPair; + if (nPair>1&&model_->logLevel()>2) + printf("%d pairs for column %d\n", + nPair,columnNumber_); + // Now fill + last = other[0]; + nPair=0; + int rows[20]; + rows[0]= otherRow[0]; + nInGroup=1; + for (int i=1;i<=nOdd;i++) { + if (other[i]==last) { + rows[nInGroup++]=otherRow[i]; + } else { + double newLowerZero=0.0; + double newUpperZero=COIN_DBL_MAX; + double newLowerOne=0.0; + double newUpperOne=COIN_DBL_MAX; + int cColumn=-1; + for (int j=0;j0.0) { + // binary*abs(bValue) <= continuous*abs(cValue); + newLowerOne = -bValue/cValue; + } else { + // binary*abs(bValue) >= continuous*abs(cValue); + newUpperOne = -bValue/cValue; + newUpperZero = 0.0; + } + } + zeroLowerBound_[nPair]=newLowerZero; + oneLowerBound_[nPair]=newLowerOne; + zeroUpperBound_[nPair]=newUpperZero; + oneUpperBound_[nPair]=newUpperOne; + // make current bounds tight + double newLower = CoinMin(newLowerZero,newLowerOne); + if (newLower>columnLower[cColumn]) + model_->solver()->setColLower(cColumn,newLower); + double newUpper = CoinMax(newUpperZero,newUpperOne); + if (newUppersolver()->setColUpper(cColumn,newUpper); + otherVariable_[nPair++]=cColumn; + last=other[i]; + rows[0] = otherRow[i]; + nInGroup=1; + } + } +} +// Copy constructor +CbcSwitchingBinary::CbcSwitchingBinary ( const CbcSwitchingBinary & rhs) + : CbcSimpleIntegerDynamicPseudoCost(rhs), + numberOther_(rhs.numberOther_), + type_(rhs.type_) +{ + zeroLowerBound_ = CoinCopyOfArray(rhs.zeroLowerBound_,4*numberOther_); + oneLowerBound_ = zeroLowerBound_+numberOther_; + zeroUpperBound_ = oneLowerBound_+numberOther_; + oneUpperBound_ = zeroUpperBound_+numberOther_; + otherVariable_ = CoinCopyOfArray(rhs.otherVariable_,numberOther_); +} + +// Clone +CbcObject * +CbcSwitchingBinary::clone() const +{ + return new CbcSwitchingBinary(*this); +} + +// Assignment operator +CbcSwitchingBinary & +CbcSwitchingBinary::operator=( const CbcSwitchingBinary & rhs) +{ + if (this != &rhs) { + CbcSimpleIntegerDynamicPseudoCost::operator=(rhs); + numberOther_=rhs.numberOther_; + type_ = rhs.type_; + delete [] zeroLowerBound_; + delete [] otherVariable_; + zeroLowerBound_ = CoinCopyOfArray(rhs.zeroLowerBound_,4*numberOther_); + oneLowerBound_ = zeroLowerBound_+numberOther_; + zeroUpperBound_ = oneLowerBound_+numberOther_; + oneUpperBound_ = zeroUpperBound_+numberOther_; + otherVariable_ = CoinCopyOfArray(rhs.otherVariable_,numberOther_); + } + return *this; +} +// Destructor +CbcSwitchingBinary::~CbcSwitchingBinary () +{ + delete [] zeroLowerBound_; + delete [] otherVariable_; +} +// Add in zero switches +void +CbcSwitchingBinary::addZeroSwitches(int nAdd,const int * columns) +{ + type_ |= 1; + int nNew = numberOther_+nAdd; + double * bounds = new double[4*nNew]; + int * other = new int [nNew]; + memcpy(other,otherVariable_,numberOther_*sizeof(int)); + delete [] otherVariable_; + otherVariable_=other; + memcpy(bounds,zeroLowerBound_,numberOther_*sizeof(double)); + memcpy(bounds+nNew,oneLowerBound_,numberOther_*sizeof(double)); + memcpy(bounds+2*nNew,zeroUpperBound_,numberOther_*sizeof(double)); + memcpy(bounds+3*nNew,oneUpperBound_,numberOther_*sizeof(double)); + delete [] zeroLowerBound_; + zeroLowerBound_ = bounds; + oneLowerBound_ = zeroLowerBound_+nNew; + zeroUpperBound_ = oneLowerBound_+nNew; + oneUpperBound_ = zeroUpperBound_+nNew; + for (int i=0;i 1.0e-40 && upDynamicPseudoCost_ > 1.0e-40); + double * solution = const_cast(model_->testSolution()); + const double * lower = model_->getCbcColLower(); + const double * upper = model_->getCbcColUpper(); + double saveValue = solution[columnNumber_]; + if (!lower[columnNumber_]&&upper[columnNumber_]==1.0) { + double integerTolerance = + model_->getDblParam(CbcModel::CbcIntegerTolerance); + if (saveValuesolver()->getDblParam(OsiPrimalTolerance, tolerance) ; + for (int i=0;izeroUpperBound_[i]+tolerance) + allGood=false; + } + if (!allGood) + solution[columnNumber_]=2.0*integerTolerance; + } else if (saveValue>1.0-integerTolerance) { + // check others OK + bool allGood=true; + double tolerance; + model_->solver()->getDblParam(OsiPrimalTolerance, tolerance) ; + for (int i=0;ioneUpperBound_[i]+tolerance) + allGood=false; + } + if (!allGood) + solution[columnNumber_]=1.0-2.0*integerTolerance; + } + } + double inf = CbcSimpleIntegerDynamicPseudoCost::infeasibility(info,preferredWay); + solution[columnNumber_]=saveValue; + return inf; +} +// Set associated bounds +int +CbcSwitchingBinary::setAssociatedBounds(OsiSolverInterface * solver, + int cleanBasis) const +{ + if (!solver) + solver = model_->solver(); +#ifdef COIN_HAS_CLP + OsiClpSolverInterface * clpSolver + = dynamic_cast (solver); + if (cleanBasis!=1) + clpSolver=NULL; +#endif + const double * columnLower = solver->getColLower(); + const double * columnUpper = solver->getColUpper(); + int nChanged=0; + if (!columnUpper[columnNumber_]) { +#ifdef COIN_HAS_CLP + if (clpSolver) + clpSolver->setColumnStatus(columnNumber_,ClpSimplex::isFixed); +#endif + for (int i=0;icolumnLower[otherColumn]) { + solver->setColLower(otherColumn,zeroLowerBound_[i]); + nChanged++; + } + if (zeroUpperBound_[i]setColUpper(otherColumn,zeroUpperBound_[i]); +#ifdef COIN_DEVELOP + const double * solution = solver->getColSolution(); + double value = solution[otherColumn]; + if (value - zeroUpperBound_[i] > 1.0e-5 && model_->logLevel()>1) + printf("value for continuous %d %g - above %g - switch %d is %.12g (ub 0)\n", + otherColumn, value, zeroUpperBound_[i],columnNumber_,solution[columnNumber_]); +#endif + nChanged++; + } + } + } else if (columnLower[columnNumber_]==1.0) { +#ifdef COIN_HAS_CLP + if (clpSolver) + clpSolver->setColumnStatus(columnNumber_,ClpSimplex::isFixed); +#endif + for (int i=0;icolumnLower[otherColumn]) { + solver->setColLower(otherColumn,oneLowerBound_[i]); + nChanged++; + } + if (oneUpperBound_[i]setColUpper(otherColumn,oneUpperBound_[i]); + nChanged++; + } + } + } else if (cleanBasis>=2) { + // if all OK then can fix + int state[3]; + int nBadFixed; + const double * solution = solver->getColSolution(); + if (!checkAssociatedBounds(solver,solution, + 0,state,nBadFixed)) { + const double *reducedCost = solver->getReducedCost() ; + double good=true; + double integerTolerance = + model_->getDblParam(CbcModel::CbcIntegerTolerance); + if (solution[columnNumber_]1.0e-6) + solver->setColUpper(columnNumber_,0.0); + else + good=false; + } else if (solution[columnNumber_]>1.0-integerTolerance) { + if (cleanBasis==2||reducedCost[columnNumber_]<-1.0e-6) + solver->setColLower(columnNumber_,1.0); + else + good=false; + } + if (good) + nChanged=setAssociatedBounds(solver,0); + } + } else { + // see if any continuous bounds force binary + for (int i=0;izeroUpperBound_[i]) { + // can't be zero + solver->setColLower(columnNumber_,1.0); + nChanged++; + } else if (columnLower[otherColumn]>oneUpperBound_[i]) { + // can't be one + solver->setColUpper(columnNumber_,0.0); + nChanged++; + } + if (columnUpper[otherColumn]setColLower(columnNumber_,1.0); + nChanged++; + } else if (columnUpper[otherColumn]setColUpper(columnNumber_,0.0); + nChanged++; + } + } + } + return nChanged; +} +// Check associated bounds +int +CbcSwitchingBinary::checkAssociatedBounds(const OsiSolverInterface * solver, + const double * solution, int printLevel, + int state[3], int & nBadFixed) const +{ + state[0] = 0; + int nBad=0; + if (!solver) + solver = model_->solver(); + double tolerance; + solver->getDblParam(OsiPrimalTolerance, tolerance) ; + const double * columnLower = solver->getColLower(); + const double * columnUpper = solver->getColUpper(); + double integerTolerance = + model_->getDblParam(CbcModel::CbcIntegerTolerance); + bool printIt = printLevel>2 && model_->logLevel()>1; + if (solution[columnNumber_]solution[otherColumn]+tolerance*5.0) { + nBad++; + if (columnUpper[columnNumber_]==0.0) { + nBadFixed++; + //printIt=true; + } + if (printIt) + printf("switch %d at zero, other %d at %.12g below bound of %.12g\n", + columnNumber_,otherColumn,solution[otherColumn],zeroLowerBound_[i]); + } + if (zeroUpperBound_[i]1.0-integerTolerance) { + state[0] = 1; + for (int i=0;isolution[otherColumn]+tolerance*5.0) { + nBad++; + if (columnLower[columnNumber_]==1.0) { + nBadFixed++; + //printIt=true; + } + if (printIt) + printf("switch %d at one, other %d at %.12g below bound of %.12g\n", + columnNumber_,otherColumn,solution[otherColumn],oneLowerBound_[i]); + } + if (oneUpperBound_[i]columnLower[otherColumn]+tolerance&& + otherValue999 + if (value>999) { + int switchValue=value/1000; + const char * message = NULL; + value -= 1000*switchValue; + parameters_[whichParam(CBC_PARAM_INT_EXPERIMENT, numberParameters_, parameters_)].setIntValue(0/*value*/); + switch (switchValue) { + default: + case 4: + // hotstart 500, -200 cut passes + message=parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].setIntValueWithMessage(500); + if (!noPrinting_&&message) + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << message << CoinMessageEol; + message=parameters_[whichParam(CBC_PARAM_INT_CUTPASS, numberParameters_, parameters_)].setIntValueWithMessage(-200); + if (!noPrinting_&&message) + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << message << CoinMessageEol; + case 3: + // multiple 4 + message=parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].setIntValueWithMessage(4); + if (!noPrinting_&&message) + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << message << CoinMessageEol; + case 2: + // rens plus all diving at root + message=parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_)].setIntValueWithMessage(16); + if (!noPrinting_&&message) + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << message << CoinMessageEol; + model_.setNumberAnalyzeIterations(-value); + // -tune 7 zero,lagomory,gmi at root - probing on + case 1: + tunePreProcess=7; + message=parameters_[whichParam(CLP_PARAM_INT_PROCESSTUNE, numberParameters_, parameters_)].setIntValueWithMessage(7); + if (!noPrinting_&&message) + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << message << CoinMessageEol; + //message = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].setIntValueWithMessage(1025); + //if (!noPrinting_&&message) + // generalMessageHandler->message(CLP_GENERAL, generalMessages) + // << message << CoinMessageEol; + message=parameters_[whichParam(CBC_PARAM_STR_PROBINGCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("on"); + probingAction = 1; + if (!noPrinting_&&message) + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << message << CoinMessageEol; + message=parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root"); + if (!noPrinting_&&message) + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << message << CoinMessageEol; + message=parameters_[whichParam(CBC_PARAM_STR_LAGOMORYCUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root"); + if (!noPrinting_&&message) + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << message << CoinMessageEol; +#ifdef SWAP_GOMORY + GMIAction = 3; + message=parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("ifmove"); +#else + GMIAction = 2; + message=parameters_[whichParam(CBC_PARAM_STR_GMICUTS, numberParameters_, parameters_)].setCurrentOptionWithMessage("root"); +#endif + if (!noPrinting_&&message) + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << message << CoinMessageEol; + } + value = 0; + } if (value>=10) { addFlags = 1048576*(value/10); value = value % 10; @@ -2562,7 +2645,6 @@ gomoryAction = action; probingAction = action; knapsackAction = action; - zerohalfAction = action; cliqueAction = action; flowAction = action; mixedAction = action; @@ -2575,8 +2657,9 @@ parameters_[whichParam(CBC_PARAM_STR_FLOWCUTS, numberParameters_, parameters_)].setCurrentOption(action); parameters_[whichParam(CBC_PARAM_STR_MIXEDCUTS, numberParameters_, parameters_)].setCurrentOption(action); parameters_[whichParam(CBC_PARAM_STR_TWOMIRCUTS, numberParameters_, parameters_)].setCurrentOption(action); - parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption(action); if (!action) { + zerohalfAction = action; + parameters_[whichParam(CBC_PARAM_STR_ZEROHALFCUTS, numberParameters_, parameters_)].setCurrentOption(action); redsplitAction = action; parameters_[whichParam(CBC_PARAM_STR_REDSPLITCUTS, numberParameters_, parameters_)].setCurrentOption(action); redsplit2Action = action; @@ -2981,7 +3064,7 @@ } #ifdef COIN_HAS_ASL if (statusUserFunction_[0]) { - double value = model2->getObjValue() * model2->getObjSense(); + double value = model2->getObjValue(); char buf[300]; int pos = 0; int iStat = model2->status(); @@ -3045,9 +3128,8 @@ } #endif } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CLP_PARAM_ACTION_STATISTICS: @@ -3083,20 +3165,20 @@ if (deleteModel2) delete model2; } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CLP_PARAM_ACTION_TIGHTEN: if (goodModel) { int numberInfeasibilities = lpSolver->tightenPrimalBounds(); - if (numberInfeasibilities) - std::cout << "** Analysis indicates model infeasible" << std::endl; + if (numberInfeasibilities) { + sprintf(generalPrint,"** Analysis indicates model infeasible"); + printGeneralMessage(model_,generalPrint); + } } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CLP_PARAM_ACTION_PLUSMINUS: @@ -3109,17 +3191,19 @@ if (newMatrix->getIndices()) { lpSolver->replaceMatrix(newMatrix); delete saveMatrix; - std::cout << "Matrix converted to +- one matrix" << std::endl; + sprintf(generalPrint, "Matrix converted to +- one matrix"); + printGeneralMessage(model_,generalPrint); } else { - std::cout << "Matrix can not be converted to +- 1 matrix" << std::endl; + sprintf(generalPrint, "Matrix can not be converted to +- 1 matrix"); + printGeneralMessage(model_,generalPrint); } } else { - std::cout << "Matrix not a ClpPackedMatrix" << std::endl; + sprintf(generalPrint, "Matrix not a ClpPackedMatrix"); + printGeneralMessage(model_,generalPrint); } } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CLP_PARAM_ACTION_OUTDUPROWS: @@ -3137,9 +3221,8 @@ << generalPrint << CoinMessageEol; } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } #endif break; @@ -3153,21 +3236,29 @@ if (newMatrix->getIndices()) { lpSolver->replaceMatrix(newMatrix); delete saveMatrix; - std::cout << "Matrix converted to network matrix" << std::endl; + sprintf(generalPrint, "Matrix converted to network matrix"); + printGeneralMessage(model_,generalPrint); } else { - std::cout << "Matrix can not be converted to network matrix" << std::endl; + sprintf(generalPrint, "Matrix can not be converted to network matrix"); + printGeneralMessage(model_,generalPrint); } } else { - std::cout << "Matrix not a ClpPackedMatrix" << std::endl; + sprintf(generalPrint, "Matrix not a ClpPackedMatrix"); + printGeneralMessage(model_,generalPrint); } } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CBC_PARAM_ACTION_DOHEURISTIC: if (goodModel) { +#ifndef CBC_USE_INITIAL_TIME + if (model_.useElapsedTime()) + model_.setDblParam(CbcModel::CbcStartSeconds, CoinGetTimeOfDay()); + else + model_.setDblParam(CbcModel::CbcStartSeconds, CoinCpuTime()); +#endif int vubAction = parameters_[whichParam(CBC_PARAM_INT_VUBTRY, numberParameters_, parameters_)].intValue(); if (vubAction != -1) { // look at vubs @@ -3198,8 +3289,52 @@ //assert (!newSolver); } // Actually do heuristics + // may need to flip objective + bool needFlip = model_.solver()->getObjSense()<0.0; + if (needFlip) + model_.flipModel(); + //if we do then - fix priorities in clonebutmodel_.convertToDynamic(); + bool objectsExist = model_.objects() != NULL; + if (!objectsExist) { + model_.findIntegers(false); + model_.convertToDynamic(); + } + // set priorities etc + if (priorities) { + OsiObject ** objects = model_.objects(); + int numberObjects = model_.numberObjects(); + for (int iObj = 0; iObj < numberObjects; iObj++) { + CbcSimpleInteger * obj = + dynamic_cast (objects[iObj]) ; + if (!obj) + continue; + int iColumn = obj->columnNumber(); + if (branchDirection) { + obj->setPreferredWay(branchDirection[iColumn]); + } + if (priorities) { + int iPriority = priorities[iColumn]; + if (iPriority > 0) + obj->setPriority(iPriority); + } + if (pseudoUp && pseudoUp[iColumn]) { + CbcSimpleIntegerPseudoCost * obj1a = + dynamic_cast (objects[iObj]) ; + assert (obj1a); + if (pseudoDown[iColumn] > 0.0) + obj1a->setDownPseudoCost(pseudoDown[iColumn]); + if (pseudoUp[iColumn] > 0.0) + obj1a->setUpPseudoCost(pseudoUp[iColumn]); + } + } + } doHeuristics(&model_, 2, parameters_, numberParameters_, noPrinting_, initialPumpTune); + if (!objectsExist) { + model_.deleteObjects(false); + } + if (needFlip) + model_.flipModel(); if (model_.bestSolution()) { model_.setProblemStatus(1); model_.setSecondaryStatus(6); @@ -3256,6 +3391,7 @@ case CBC_PARAM_ACTION_MIPLIB: // User can set options - main difference is lack of model and CglPreProcess goodModel = true; + parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].setIntValue(0); /* Run branch-and-cut. First set a few options -- node comparison, scaling. Print elapsed time at the end. @@ -3266,6 +3402,10 @@ bool miplib = type == CBC_PARAM_ACTION_MIPLIB; int logLevel = parameters_[slog].intValue(); int truncateColumns=COIN_INT_MAX; + int truncateRows=-1; + bool redoSOS=false; + double * truncatedRhsLower=NULL; + double * truncatedRhsUpper=NULL; int * newPriorities=NULL; // Reduce printout if (logLevel <= 1) { @@ -3450,9 +3590,8 @@ cbcModel->initialSolve(); if (clpModel->tightenPrimalBounds() != 0) { -#ifndef DISALLOW_PRINTING - std::cout << "Problem is infeasible - tightenPrimalBounds!" << std::endl; -#endif + sprintf(generalPrint, "Problem is infeasible - tightenPrimalBounds!"); + printGeneralMessage(model_,generalPrint); break; } clpModel->dual(); // clean up @@ -3622,11 +3761,12 @@ } #ifndef CBC_OTHER_SOLVER if (!complicatedInteger && preProcess == 0 && clpSolver->tightenPrimalBounds(0.0, 0, true) != 0) { -#ifndef DISALLOW_PRINTING - std::cout << "Problem is infeasible - tightenPrimalBounds!" << std::endl; -#endif + sprintf(generalPrint, "Problem is infeasible - tightenPrimalBounds!"); + printGeneralMessage(model_,generalPrint); model_.setProblemStatus(0); model_.setSecondaryStatus(1); + // say infeasible for solution + integerStatus = 6; // and in babModel if exists if (babModel_) { babModel_->setProblemStatus(0); @@ -3727,9 +3867,8 @@ // bounds based on continuous if (tightenFactor && !complicatedInteger) { if (modelC->tightenPrimalBounds(tightenFactor) != 0) { -#ifndef DISALLOW_PRINTING - std::cout << "Problem is infeasible!" << std::endl; -#endif + sprintf(generalPrint, "Problem is infeasible!"); + printGeneralMessage(model_,generalPrint); model_.setProblemStatus(0); model_.setSecondaryStatus(1); // and in babModel if exists @@ -3828,15 +3967,23 @@ if (mipStartBefore.size()) { CbcModel tempModel=*babModel_; + assert (babModel_->getNumCols()==model_.getNumCols()); std::vector< std::string > colNames; - for ( int i=0 ; (isolver()->getNumCols()) ; ++i ) + for ( int i=0 ; (igetNumCols()) ; ++i ) colNames.push_back( model_.solver()->getColName(i) ); - std::vector< double > x( babModel_->getNumCols(), 0.0 ); + std::vector< double > x( model_.getNumCols(), 0.0 ); double obj; int status = computeCompleteSolution( &tempModel, colNames, mipStartBefore, &x[0], obj ); - // set cutoff - if (!status) - babModel_->setCutoff(CoinMin(babModel_->getCutoff(),obj+1.0e-4)); + // set cutoff ( a trifle high) + if (!status) { + double newCutoff = CoinMin(babModel_->getCutoff(),obj+1.0e-4); + babModel_->setBestSolution( &x[0], static_cast(x.size()), obj, false ); + babModel_->setCutoff(newCutoff); + babModel_->setSolutionCount(1); + model_.setBestSolution( &x[0], static_cast(x.size()), obj, false ); + model_.setCutoff(newCutoff); + model_.setSolutionCount(1); + } } if (preProcess && type == CBC_PARAM_ACTION_BAB) { #ifndef CBC_OTHER_SOLVER @@ -3894,8 +4041,9 @@ if ((tunePreProcess&1) != 0) { // heavy probing generator1.setMaxPassRoot(2); - generator1.setMaxElements(300); + generator1.setMaxElements(1000); generator1.setMaxProbeRoot(saveSolver->getNumCols()); + generator1.setMaxLookRoot(saveSolver->getNumCols()); } if ((babModel_->specialOptions()&65536) != 0) process.setOptions(1); @@ -3957,6 +4105,10 @@ if (model_.numberObjects()) { OsiObject ** oldObjects = babModel_->objects(); int numberOldObjects = babModel_->numberObjects(); + if (!numberOldObjects) { + oldObjects = model_.objects(); + numberOldObjects = model_.numberObjects(); + } // SOS int numberColumns = saveSolver->getNumCols(); char * prohibited = new char[numberColumns]; @@ -3987,13 +4139,6 @@ delete [] prohibited; } int numberPasses = 10; - if (tunePreProcess >= 1000000) { - numberPasses = (tunePreProcess / 1000000) - 1; - tunePreProcess = tunePreProcess % 1000000; - } else if (tunePreProcess >= 10000) { - numberPasses = (tunePreProcess / 10000) - 1; - tunePreProcess = tunePreProcess % 10000; - } #ifndef CBC_OTHER_SOLVER if (doSprint > 0) { // Sprint for primal solves @@ -4029,14 +4174,23 @@ if ((model_.moreSpecialOptions()&65536)!=0) process.setOptions(2+4+8); // no cuts cbcPreProcessPointer = & process; - solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses, + int saveOptions = osiclp->getModelPtr()->moreSpecialOptions(); + if ((model_.specialOptions()&16777216)!=0&& + model_.getCutoff()>1.0e30) { + osiclp->getModelPtr()->setMoreSpecialOptions(saveOptions|262144); + } + redoSOS=true; + solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses, tunePreProcess); - /*solver2->writeMps("after"); - saveSolver->writeMps("before");*/ - osiclp->getModelPtr()->setPerturbation(savePerturbation); + if (solver2) { + model_.setOriginalColumns( process.originalColumns(), solver2->getNumCols() ); + osiclp->getModelPtr()->setPerturbation(savePerturbation); + osiclp->getModelPtr()->setMoreSpecialOptions(saveOptions); + } } #elif CBC_OTHER_SOLVER==1 cbcPreProcessPointer = & process; + redoSOS=true; solver2 = process.preProcessNonDefault(*saveSolver, translate[preProcess], numberPasses, tunePreProcess); #endif @@ -4071,6 +4225,8 @@ if (!solver2) { // say infeasible for solution integerStatus = 6; + delete saveSolver; + saveSolver=NULL; model_.setProblemStatus(0); model_.setSecondaryStatus(1); babModel_->setProblemStatus(0); @@ -4105,24 +4261,8 @@ //solver2->resolve(); if (preProcess == 2) { OsiClpSolverInterface * clpSolver2 = dynamic_cast< OsiClpSolverInterface*> (solver2); -#if 1 - ClpSimplex * lpSolver = - clpSolver2->getModelPtr(); - lpSolver->writeMps("presolved.mps", 0, 1, lpSolver->optimizationDirection()); -#else - // put back names - ClpSimplex lpSolver(*clpSolver2->getModelPtr()); - //OsiClpSolverInterface * originalSolver = dynamic_cast< OsiClpSolverInterface*> (olver); - ClpSimplex * originalLp = clpSolver->getModelPtr(); - const int * originalColumns = process.originalColumns(); - int numberColumns = lpSolver.getNumCols(); - for (int i = 0; i < numberColumns; i++) { - int jColumn = originalColumns[i]; - std::string name = originalLp->getColumnName(jColumn); - lpSolver.setColumnName(i,name); - } - lpSolver.writeMps("presolved.mps", 0, 1, lpSolver.optimizationDirection()); -#endif + ClpSimplex * lpSolver = clpSolver2->getModelPtr(); + lpSolver->writeMps("presolved.mps", 2, 1, lpSolver->optimizationDirection()); printf("Preprocessed model (minimization) on presolved.mps\n"); } { @@ -4140,14 +4280,44 @@ osiclp2->setOptionalInteger(i); // say optional } } + // redo existing SOS + if (osiclp->numberSOS()) { + redoSOS=false; + int * back = new int[numberOriginalColumns]; + for (int i = 0; i < numberOriginalColumns; i++) + back[i]=-1; + for (int i = 0; i < numberColumns; i++) { + int iColumn = originalColumns[i]; + back[iColumn]=i; + } + int numberSOSOld=osiclp->numberSOS(); + int numberSOS=osiclp2->numberSOS(); + assert (numberSOS==numberSOSOld); + CoinSet * setInfo = const_cast(osiclp2->setInfo()); + for (int i = 0; i < numberSOS; i++) { + //int type = setInfo[i].setType(); + int n = setInfo[i].numberEntries(); + int * which = const_cast(setInfo[i].which()); + for (int j=0;j=0); + which[j]=iColumn; + } + } + delete [] back; + } } // we have to keep solver2 so pass clone solver2 = solver2->clone(); // see if extra variables wanted int threshold = parameters_[whichParam(CBC_PARAM_INT_EXTRA_VARIABLES, numberParameters_, parameters_)].intValue(); - if (threshold) { + int more2 = parameters_[whichParam(CBC_PARAM_INT_MOREMOREMIPOPTIONS, numberParameters_, parameters_)].intValue(); + if (threshold || (more2&(512|1024)) != 0) { int numberColumns = solver2->getNumCols(); + truncateRows = solver2->getNumRows(); + bool modifiedModel=false; int highPriority=0; /* normal - no priorities @@ -4351,10 +4521,7 @@ rowAdd,columnAdd,elementAdd, lowerNew, upperNew); sprintf(generalPrint,"Replacing model - %d new variables",numberDifferentObj); - generalMessageHandler->message(CLP_GENERAL, generalMessages) - << generalPrint - << CoinMessageEol; - truncateColumns=numberColumns; + modifiedModel=true; } delete [] columnAdd; delete [] elementAdd; @@ -4363,6 +4530,204 @@ } delete [] which; delete [] obj; + if ((more2&(512|1024)) != 0) { + // try for row slacks etc + // later do row branching + int iRow, iColumn; + int numberColumns = solver2->getNumCols(); + int numberRows = solver2->getNumRows(); + int fudgeObjective = more2&512; + int addSlacks = more2&1024; + if (fudgeObjective) { + bool moveObj = false; + fudgeObjective = 0; + const double * objective = solver2->getObjCoefficients(); + const double * columnLower = solver2->getColLower(); + const double * columnUpper = solver2->getColUpper(); + double * newValues = new double [numberColumns+1]; + int * newColumn = new int [numberColumns+1]; + bool allInteger=true; + int n=0; + double newLower = 0.0; + double newUpper = 0.0; + for (iColumn=0;iColumnisInteger(iColumn)) { + allInteger=false; + break; + } else { + double value = objective[iColumn]; + double nearest = floor(value+0.5); + if (fabs(value-nearest)>1.0e-8) { + allInteger=false; + break; + } else { + newValues[n]=nearest; + newColumn[n++]=iColumn; + if (nearest>0.0) { + newLower += CoinMax(columnLower[iColumn],-1.0e20)*nearest; + newUpper += CoinMin(columnUpper[iColumn],1.0e20)*nearest; + } else { + newUpper += CoinMax(columnLower[iColumn],-1.0e20)*nearest; + newLower += CoinMin(columnUpper[iColumn],1.0e20)*nearest; + } + } + } + } + } + if (allInteger && n) { + fudgeObjective = n; + solver2->addCol(0,NULL,NULL,newLower,newUpper,0.0,"obj_col"); + solver2->setInteger(numberColumns); + newValues[n]=-1.0; + newColumn[n++]=numberColumns; + solver2->addRow(n,newColumn,newValues,0.0,0.0); + if (moveObj) { + memset(newValues,0,numberColumns*sizeof(double)); + newValues[numberColumns]=1.0; + solver2->setObjective(newValues); + } + numberRows++; + numberColumns++; + } + delete [] newValues; + delete [] newColumn; + } + if (addSlacks) { + bool moveObj = false; + addSlacks=0; + // get row copy + const CoinPackedMatrix * matrix = solver2->getMatrixByRow(); + const double * element = matrix->getElements(); + const int * column = matrix->getIndices(); + const CoinBigIndex * rowStart = matrix->getVectorStarts(); + const int * rowLength = matrix->getVectorLengths(); + const double * rowLower = solver2->getRowLower(); + const double * rowUpper = solver2->getRowUpper(); + const double * columnLower = solver2->getColLower(); + const double * columnUpper = solver2->getColUpper(); + + // maximum space for additional columns + CoinBigIndex * newColumnStart = new CoinBigIndex[numberRows+1]; + newColumnStart[0]=0; + int * newRow = new int [numberRows]; + double * newElement = new double [numberRows]; + double * newObjective = new double [numberRows]; + double * newColumnLower = new double [numberRows]; + double * newColumnUpper = new double [numberRows]; + double * oldObjective = CoinCopyOfArray(solver2->getObjCoefficients(), + numberColumns); + for (iRow=0;iRowisInteger(iColumn)) { + allInteger=false; + break; + } else { + double value = element[j]; + double nearest = floor(value+0.5); + if (fabs(value-nearest)>1.0e-8) { + allInteger=false; + break; + } else { + if (!oldObjective[iColumn]) + constantObjective=COIN_DBL_MAX; + if (!constantObjective) { + constantObjective=oldObjective[iColumn]/nearest; + } else if (constantObjective!=COIN_DBL_MAX) { + double newConstant=oldObjective[iColumn]/nearest; + if (constantObjective>0.0) { + if (newConstant<=0.0) + constantObjective=COIN_DBL_MAX; + else + constantObjective=CoinMin(constantObjective,newConstant); + } else { + if (newConstant>=0.0) + constantObjective=COIN_DBL_MAX; + else + constantObjective=CoinMax(constantObjective,newConstant); + } + } + if (nearest>0.0) { + newLower += CoinMax(columnLower[iColumn],-1.0e20)*nearest; + newUpper += CoinMin(columnUpper[iColumn],1.0e20)*nearest; + } else { + newUpper += CoinMax(columnLower[iColumn],-1.0e20)*nearest; + newLower += CoinMin(columnUpper[iColumn],1.0e20)*nearest; + } + } + } + } + if (allInteger) { + newColumnStart[addSlacks+1]=addSlacks+1; + newRow[addSlacks]=iRow; + newElement[addSlacks]=-1.0; + newObjective[addSlacks] = 0.0; + if (moveObj && constantObjective != COIN_DBL_MAX) { + // move some of objective here if looks constant + newObjective[addSlacks]=constantObjective; + for (int j=rowStart[iRow];jsetObjective(oldObjective); + solver2->addCols(addSlacks,newColumnStart,newRow,newElement, + newColumnLower,newColumnUpper,newObjective); + truncatedRhsLower = CoinCopyOfArray(solver2->getRowLower(),numberRows); + truncatedRhsUpper = CoinCopyOfArray(solver2->getRowUpper(),numberRows); + for (int j=0;jsetRowLower(iRow,0.0); + solver2->setRowUpper(iRow,0.0); + int iColumn = j+numberColumns; + solver2->setInteger(iColumn); + std::string name = solver2->getRowName(iRow); + name += "_int"; + solver2->setColName(iColumn,name); + } + } + } + if (fudgeObjective||addSlacks) { + modifiedModel=true; + if (fudgeObjective && addSlacks) { + sprintf(generalPrint,"Objective integer added with %d elements and %d Integer slacks added", + fudgeObjective,addSlacks); + } else if (fudgeObjective) { + // just objective + sprintf(generalPrint,"Objective integer added with %d elements", + fudgeObjective); + more2 &= ~1024; + } else { + // just slacks + sprintf(generalPrint,"%d Integer slacks added",addSlacks); + more2 &= ~512; + } + } else { + more2 &= ~(512|1024); + } + parameters_[whichParam(CBC_PARAM_INT_MOREMOREMIPOPTIONS, numberParameters_, parameters_)].setIntValue(more2); + } + if (modifiedModel) { + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << generalPrint + << CoinMessageEol; + truncateColumns=numberColumns; + } } babModel_->assignSolver(solver2); babModel_->setOriginalColumns(process.originalColumns(), @@ -4381,13 +4746,14 @@ //if (noPrinting_) //modelC->setLogLevel(0); if (!complicatedInteger && modelC->tightenPrimalBounds() != 0) { -#ifndef DISALLOW_PRINTING - std::cout << "Problem is infeasible!" << std::endl; -#endif + sprintf(generalPrint, "Problem is infeasible!"); + printGeneralMessage(model_,generalPrint); model_.setProblemStatus(0); model_.setSecondaryStatus(1); // say infeasible for solution integerStatus = 6; + delete saveSolver; + saveSolver=NULL; // and in babModel_ if exists if (babModel_) { babModel_->setProblemStatus(0); @@ -4540,10 +4906,9 @@ parameters_)].intValue(); int bothFlags = CoinMax(CoinMin(experimentFlag, 1), strategyFlag); // add cut generators if wanted - int switches[30]; - int accuracyFlag[30]; - char doAtEnd[30]; - memset(doAtEnd,0,30); + int switches[30]={}; + int accuracyFlag[30]={}; + char doAtEnd[30]={}; int numberGenerators = 0; int translate[] = { -100, -1, -99, -98, 1, -1098, -999, 1, 1, 1, -1}; int maximumSlowPasses = @@ -4572,7 +4937,7 @@ if (probingAction == 10) { probingGen.setMaxPassRoot(2); probingGen.setMaxProbeRoot(numberColumns); - probingGen.setMaxLookRoot(100); + probingGen.setMaxLookRoot(numberColumns); } // If 5 then force on int iAction = translate[probingAction]; @@ -4745,7 +5110,7 @@ if (flowAction) { babModel_->addCutGenerator(&flowGen, translate[flowAction], "FlowCover"); accuracyFlag[numberGenerators] = 2; - switches[numberGenerators++] = 1; + switches[numberGenerators++] = 0; } if (twomirAction && (complicatedInteger != 1 || (twomirAction == 1 || twomirAction >= 4))) { @@ -4826,6 +5191,8 @@ } babModel_->addCutGenerator(&zerohalfGen, translate[zerohalfAction], "ZeroHalf"); accuracyFlag[numberGenerators] = 5; + babModel_->cutGenerator(numberGenerators)-> + setNeedsRefresh(true); switches[numberGenerators++] = 2; } if (dominatedCuts) @@ -4976,7 +5343,7 @@ // Turn this off if you get problems // Used to be automatically set int mipOptions = parameters_[whichParam(CBC_PARAM_INT_MIPOPTIONS, numberParameters_, parameters_)].intValue() % 10000; - if (mipOptions != (1057)) { + if (mipOptions != (1057) && mipOptions != 1025 ) { sprintf(generalPrint, "mip options %d", mipOptions); generalMessageHandler->message(CLP_GENERAL, generalMessages) << generalPrint @@ -5097,38 +5464,53 @@ } #endif const int * originalColumns = preProcess ? process.originalColumns() : NULL; - if (mipStart.size() && !mipStartBefore.size()) + + if (model.getMIPStart().size()) + mipStart = model.getMIPStart(); + + if (mipStart.size() && !mipStartBefore.size() && babModel_->getNumCols()) { - std::vector< std::string > colNames; - if (preProcess) - { - std::vector< std::pair< std::string, double > > mipStart2; - for ( int i=0 ; (isolver()->getNumCols()) ; ++i ) { - int iColumn = babModel_->originalColumns()[i]; - if (iColumn>=0) { - colNames.push_back( model_.solver()->getColName( iColumn ) ); - babModel_->solver()->setColName(i,model_.solver()->getColName(iColumn)); - mipStart2.push_back(mipStart[iColumn]); - } else { - // created variable - char newName[15]; - sprintf(newName,"C%7.7d",i); - colNames.push_back( newName ); - } - } - mipStart = mipStart2; - } else { - for ( int i=0 ; (isolver()->getNumCols()) ; ++i ) - colNames.push_back( model_.solver()->getColName(i) ); - } - //printf("--- %s %d\n", babModel_->solver()->getColName(0).c_str(), babModel_->solver()->getColNames().size() ); - //printf("-- SIZES of models %d %d %d\n", model_.getNumCols(), babModel_->solver()->getNumCols(), babModel_->solver()->getColNames().size() ); - std::vector< double > x( babModel_->getNumCols(), 0.0 ); - double obj; - int status = computeCompleteSolution( babModel_, colNames, mipStart, &x[0], obj ); - if (!status) - babModel_->setBestSolution( &x[0], static_cast(x.size()), obj, false ); - } + std::vector< std::string > colNames; + if (preProcess) + { + /* translating mipstart solution */ + std::map< std::string, double > mipStartV; + for ( size_t i=0 ; (i > mipStart2; + for ( int i=0 ; (isolver()->getNumCols()) ; ++i ) { + int iColumn = babModel_->originalColumns()[i]; + if (iColumn>=0) { + std::string cname = model_.solver()->getColName( iColumn ); + colNames.push_back( cname ); + babModel_->solver()->setColName( i, cname ); + std::map< std::string, double >::const_iterator msIt = mipStartV.find( cname ); + if ( msIt != mipStartV.end() ) + mipStart2.push_back( std::pair< std::string, double>( cname, msIt->second ) ); + } else { + // created variable + char newName[15]; + sprintf(newName,"C%7.7d",i); + colNames.push_back( newName ); + } + } + mipStart = mipStart2; + } else { + for ( int i=0 ; (isolver()->getNumCols()) ; ++i ) + colNames.push_back( model_.solver()->getColName(i) ); + } + //printf("--- %s %d\n", babModel_->solver()->getColName(0).c_str(), babModel_->solver()->getColNames().size() ); + //printf("-- SIZES of models %d %d %d\n", model_.getNumCols(), babModel_->solver()->getNumCols(), babModel_->solver()->getColNames().size() ); + std::vector< double > x( babModel_->getNumCols(), 0.0 ); + double obj; + int status = computeCompleteSolution( babModel_, colNames, mipStart, &x[0], obj ); + if (!status) { + babModel_->setBestSolution( &x[0], static_cast(x.size()), obj, false ); + babModel_->setSolutionCount(1); + } + } + if (solutionIn && useSolution >= 0) { if (!prioritiesIn) { @@ -5214,7 +5596,8 @@ // extend arrays in case SOS assert (originalColumns); int n = CoinMin(truncateColumns,numberColumns); - n = originalColumns[n-1] + 1; + // allow for empty problem + n = (n) ? originalColumns[n-1] + 1 : 0; n = CoinMax(n, CoinMax(numberColumns, numberOriginalColumns)); int * newColumn = new int[n]; int i; @@ -5259,6 +5642,7 @@ oldObjects[iObj]->setPriority(numberColumns + 1); int iColumn = oldObjects[iObj]->columnNumber(); if (iColumn < 0 || iColumn >= numberOriginalColumns) { + if (redoSOS) { // now done earlier?? CbcSOS * obj = dynamic_cast (oldObjects[iObj]) ; if (obj) { @@ -5278,7 +5662,8 @@ } obj->setNumberMembers(nn); } - continue; + } + continue; } if (originalColumns) iColumn = originalColumns[iColumn]; @@ -5319,8 +5704,15 @@ for (iSOS = 0; iSOS < numberSOS; iSOS++) { int iStart = starts[iSOS]; int n = starts[iSOS+1] - iStart; + //#define MAKE_SOS_CLIQUES +#ifndef MAKE_SOS_CLIQUES objects[iSOS] = new CbcSOS(babModel_, n, which + iStart, weight + iStart, iSOS, type[iSOS]); +#else + objects[iSOS] = + new CbcClique(babModel_, 1, n, which + iStart, + NULL,-iSOS-1); +#endif // branch on long sets first objects[iSOS]->setPriority(numberColumns - n); } @@ -5413,6 +5805,13 @@ dynamic_cast (objects[iObj]) ; if (objSOS) continue; +#ifdef MAKE_SOS_CLIQUES + // skip cliques + CbcClique * objClique = + dynamic_cast (objects[iObj]) ; + if (objClique) + continue; +#endif int iColumn = objects[iObj]->columnNumber(); assert (iColumn >= 0); if (originalColumns) @@ -6058,6 +6457,13 @@ #ifndef CBC_OTHER_SOLVER osiclp = dynamic_cast< OsiClpSolverInterface*> (babModel_->solver()); lpSolver = osiclp->getModelPtr(); + int hotits = parameters_[whichParam(CBC_PARAM_INT_MAXHOTITS, numberParameters_, parameters_)].intValue(); + if (hotits>100) { + osiclp->setSpecialOptions(osiclp->specialOptions()&~32); + osiclp->setIntParam(OsiMaxNumIterationHotStart, hotits); + } else { + osiclp->setIntParam(OsiMaxNumIterationHotStart, hotits); + } #elif CBC_OTHER_SOLVER==1 #endif if ((experimentFlag >= 1 || strategyFlag >= 1) && babModel_->fastNodeDepth() == -1) { @@ -6225,12 +6631,93 @@ donor.setStoredRowCuts(NULL); } // We may have priorities from extra variables + int more2 = parameters_[whichParam(CBC_PARAM_INT_MOREMOREMIPOPTIONS, numberParameters_, parameters_)].intValue(); if(newPriorities ) { if (truncateColumnsgetNumCols()) { // set new ones as high prority babModel_->passInPriorities(newPriorities,false); } delete [] newPriorities; + } else if ((more2&(512|1024)) != 0) { + babModel_->findIntegers(true); + int numberIntegers = babModel_->numberIntegers(); + int * newPriorities = new int [numberIntegers]; + int n = numberIntegers - (babModel_->getNumCols()-truncateColumns); + for (int i=0;ipriority(i); +#if 1 + int ixxxxxx = + parameters_[whichParam(CBC_PARAM_INT_MAXNODES, numberParameters_, parameters_)].intValue(); + int obj_priority=1000; + int slack_priority=1000; + if (ixxxxxx>=1000000&&ixxxxxx<1010000) { + ixxxxxx -= 1000000; + if (ixxxxxx == 0) { + obj_priority=1000; + slack_priority=1000; + } else if(ixxxxxx == 1) { + obj_priority=10000; + slack_priority=10000; + } else if(ixxxxxx == 2) { + obj_priority=100; + slack_priority=100; + } else if(ixxxxxx == 3) { + obj_priority=100; + slack_priority=10000; + } else if(ixxxxxx == 4) { + obj_priority=10000; + slack_priority=100; + } else if(ixxxxxx == 5) { + obj_priority=100; + slack_priority=200; + } else if(ixxxxxx == 6) { + obj_priority=200; + slack_priority=100; + } else { + abort(); + } + } + if ((more2&512)!=0) { + newPriorities[n++]=obj_priority; + } + if ((more2&1024)!=0) { + for (int i=n;ipassInPriorities(newPriorities,false); + delete [] newPriorities; } #ifdef JJF_ZERO int extra5 = parameters_[whichParam(EXTRA5, numberParameters_, parameters_)].intValue(); @@ -6254,8 +6741,12 @@ babModel_->setStrongStrategy(specialOptions); int jParam = whichParam(CBC_PARAM_STR_CUTOFF_CONSTRAINT, numberParameters_, parameters_); - if(parameters_[jParam].currentOptionAsInteger()) + if(parameters_[jParam].currentOptionAsInteger()) { babModel_->setCutoffAsConstraint(true); + int moreOptions=babModel_->moreSpecialOptions(); + if(parameters_[jParam].currentOptionAsInteger()==4) + babModel_->setMoreSpecialOptions(moreOptions|4194304); + } int multipleRoot = parameters_[whichParam(CBC_PARAM_INT_MULTIPLEROOTS, numberParameters_, parameters_)].intValue(); if (multipleRoot<10000) { babModel_->setMultipleRootTries(multipleRoot); @@ -6344,6 +6835,17 @@ } if (biLinearProblem) babModel_->setSpecialOptions(babModel_->specialOptions() &(~(512|32768))); + babModel_->setMoreSpecialOptions2(parameters_[whichParam(CBC_PARAM_INT_MOREMOREMIPOPTIONS, numberParameters_, parameters_)].intValue()); +#ifdef COIN_HAS_NTY + { + int jParam = whichParam(CBC_PARAM_STR_ORBITAL, + numberParameters_, parameters_); + if(parameters_[jParam].currentOptionAsInteger()) { + int k = parameters_[jParam].currentOptionAsInteger(); + babModel_->setMoreSpecialOptions2(babModel_->moreSpecialOptions2() | (k*128)); + } + } +#endif babModel_->branchAndBound(statistics); if (truncateColumnssolver()->getNumCols()) { OsiSolverInterface * solverX = babModel_->solver(); @@ -6354,10 +6856,20 @@ for (int i=0;ideleteCols(numberDelete,delStuff); + numberDelete = numberRows-truncateRows; for (int i=0;ideleteRows(numberDelete,delStuff); delete [] delStuff; + if (truncatedRhsLower) { + numberRows=solverX->getNumRows(); + for (int i=0;isetRowLower(i,truncatedRhsLower[i]); + solverX->setRowUpper(i,truncatedRhsUpper[i]); + } + delete [] truncatedRhsLower; + delete [] truncatedRhsUpper; + } } //#define CLP_FACTORIZATION_INSTRUMENT #ifdef CLP_FACTORIZATION_INSTRUMENT @@ -6566,7 +7078,7 @@ continue; #ifndef CLP_INVESTIGATE CglImplication * implication = dynamic_cast(generator->generator()); - if (implication) + if (implication && !generator->numberCutsInTotal()) continue; #endif generalMessageHandler->message(CLP_GENERAL, generalMessages) @@ -6605,9 +7117,11 @@ } else { if (babModel_->isProvenOptimal()) { integerStatus = 0; - } else { + } else if (!babModel_->bestSolution()) { // infeasible integerStatus = 6; + delete saveSolver; + saveSolver=NULL; } } if (babModel_->getMinimizationObjValue() < 1.0e50 && type == CBC_PARAM_ACTION_BAB) { @@ -6766,7 +7280,13 @@ if (osiclp) osiclp->getModelPtr()->checkUnscaledSolution(); } - assert (saveSolver->isProvenOptimal()); + + if (!saveSolver->isProvenOptimal()) { + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << "Accuracy problem on post-processing - maybe try without pre-processing" + << CoinMessageEol; + } + //assert (saveSolver->isProvenOptimal()); #ifndef CBC_OTHER_SOLVER // and original solver originalSolver->setDblParam(OsiDualObjectiveLimit, COIN_DBL_MAX); @@ -6965,7 +7485,8 @@ if (babModel_->bestSolution()){ sprintf(generalPrint + strlen(generalPrint), "Gap: %.2f\n", - (babModel_->getObjValue()-babModel_->getBestPossibleObjValue())/babModel_->getBestPossibleObjValue()); + (babModel_->getObjValue()-babModel_->getBestPossibleObjValue())/ + fabs(babModel_->getBestPossibleObjValue())); } } sprintf(generalPrint + strlen(generalPrint), @@ -7067,8 +7588,9 @@ } #endif } else { - std::cout << "Model strengthened - now has " << clpSolver->getNumRows() - << " rows" << std::endl; + sprintf(generalPrint, "Model strengthened - now has %d rows", + clpSolver->getNumRows()); + printGeneralMessage(model_,generalPrint); } time1 = time2; #ifdef COIN_HAS_ASL @@ -7084,9 +7606,8 @@ //delete babModel_; //babModel_=NULL; } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl ; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break ; case CLP_PARAM_ACTION_IMPORT: { @@ -7213,11 +7734,13 @@ fclose(fp); } else { canOpen = false; - std::cout << "Unable to open file " << gmplData << std::endl; + sprintf(generalPrint, "Unable to open file %s",gmplData.c_str()); + printGeneralMessage(model_,generalPrint); } } } else { - std::cout << "Unable to open file " << fileName << std::endl; + sprintf(generalPrint, "Unable to open file %s",fileName.c_str()); + printGeneralMessage(model_,generalPrint); } } if (canOpen) { @@ -7234,9 +7757,9 @@ keepImportNames != 0); } else { #ifdef KILL_ZERO_READLP - status = lpSolver->readLp(fileName.c_str(), lpSolver->getSmallElementValue()); + status = clpSolver->readLp(fileName.c_str(), lpSolver->getSmallElementValue()); #else - status = lpSolver->readLp(fileName.c_str(), 1.0e-12); + status = clpSolver->readLp(fileName.c_str(), 1.0e-12); #endif } #else @@ -7284,8 +7807,8 @@ } } else { // errors - std::cout << "There were " << status << - " errors on input" << std::endl; + sprintf(generalPrint, "There were %d errors on input",status); + printGeneralMessage(model_,generalPrint); } } } @@ -7342,7 +7865,8 @@ fclose(fp); canOpen = true; } else { - std::cout << "Unable to open file " << fileName << std::endl; + sprintf(generalPrint, "Unable to open file %s",fileName.c_str()); + printGeneralMessage(model_,generalPrint); } } if (canOpen) { @@ -7411,7 +7935,8 @@ fclose(fp); canOpen = true; } else { - std::cout << "Unable to open file " << fileName << std::endl; + sprintf(generalPrint, "Unable to open file %s",fileName.c_str()); + printGeneralMessage(model_,generalPrint); } if (canOpen) { // If presolve on then save presolved @@ -7434,10 +7959,12 @@ sosStart = info.sosStart; sosIndices = info.sosIndices; sosReference = info.sosReference; - preSolve = false; clpSolver->setSOSData(numberSOS, info.sosType, sosStart, sosIndices, sosReference); } #endif + numberSOS = clpSolver->numberSOS(); + if (numberSOS) + preSolve = false; #endif if (preSolve) { ClpPresolve pinfo; @@ -7490,8 +8017,22 @@ CoinStrdup(model2->columnName(iColumn).c_str()); } } - clpSolver->writeMpsNative(fileName.c_str(), const_cast (rowNames), const_cast (columnNames), - (outputFormat - 1) / 2, 1 + ((outputFormat - 1)&1)); + // see if extension lp + bool writeLp=false; + { + int lengthName = strlen(fileName.c_str()); + if (lengthName>3&&!strcmp(fileName.c_str()+lengthName-3,".lp")) + writeLp=true; + } + if (!writeLp) { + remove(fileName.c_str()); + clpSolver->writeMpsNative(fileName.c_str(), const_cast (rowNames), const_cast (columnNames), + (outputFormat - 1) / 2, 1 + ((outputFormat - 1)&1)); + } else { + FILE *fp = fopen(fileName.c_str(), "w"); + assert (fp); + clpSolver->writeLp(fp,1.0e-12); + } if (rowNames) { for (iRow = 0; iRow < numberRows; iRow++) { free(rowNames[iRow]); @@ -7517,9 +8058,8 @@ time1 = time2; } } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CLP_PARAM_ACTION_BASISIN: @@ -7561,7 +8101,8 @@ fclose(fp); canOpen = true; } else { - std::cout << "Unable to open file " << fileName << std::endl; + sprintf(generalPrint, "Unable to open file %s",fileName.c_str()); + printGeneralMessage(model_,generalPrint); } } if (canOpen) { @@ -7576,9 +8117,8 @@ #endif } } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CBC_PARAM_ACTION_PRIORITYIN: @@ -7616,6 +8156,19 @@ }; int got[] = { -1, -1, -1, -1, -1, -1, -1, -1}; int order[8]; + bool useMasks = false; + if (strstr(fileName.c_str(),"mask_")) { + // look more closely + const char * name = fileName.c_str(); + int length = strlen(name); + for (int i=length-1;i>=0;i--) { + if (name[i]==dirsep) { + name += i+1; + break; + } + } + useMasks = !strncmp(name,"mask_",5); + } assert(sizeof(got) == sizeof(order)); int nAcross = 0; char line[1000]; @@ -7682,9 +8235,15 @@ } if (good) { char ** columnNames = new char * [numberColumns]; - pseudoDown = reinterpret_cast (malloc(numberColumns * sizeof(double))); - pseudoUp = reinterpret_cast (malloc(numberColumns * sizeof(double))); - branchDirection = reinterpret_cast (malloc(numberColumns * sizeof(int))); + //pseudoDown = NULL; + //pseudoUp = NULL; + //branchDirection = NULL; + //if (got[5]!=-1) + pseudoDown = reinterpret_cast (malloc(numberColumns * sizeof(double))); + //if (got[4]!=-1) + pseudoUp = reinterpret_cast (malloc(numberColumns * sizeof(double))); + //if (got[2]!=-1) + branchDirection = reinterpret_cast (malloc(numberColumns * sizeof(int))); priorities = reinterpret_cast (malloc(numberColumns * sizeof(int))); free(solutionIn); solutionIn = NULL; @@ -7704,10 +8263,13 @@ for (iColumn = 0; iColumn < numberColumns; iColumn++) { columnNames[iColumn] = CoinStrdup(lpSolver->columnName(iColumn).c_str()); - pseudoDown[iColumn] = 0.0; - pseudoUp[iColumn] = 0.0; - branchDirection[iColumn] = 0; - priorities[iColumn] = 0; + //if (got[5]!=-1) + pseudoDown[iColumn] = 0.0; + //if (got[4]!=-1) + pseudoUp[iColumn] = 0.0; + //if (got[2]!=-1) + branchDirection[iColumn] = 0; + priorities[iColumn] = useMasks ? -123456789 : 0; } int nBadPseudo = 0; int nBadDir = 0; @@ -7715,11 +8277,18 @@ int nBadName = 0; int nBadLine = 0; int nLine = 0; - while (fgets(line, 1000, fp)) { - if (!strncmp(line, "ENDATA", 6)) + iColumn = -1; + int lowestPriority=-COIN_INT_MAX; + bool needCard = true; + while (!needCard || fgets(line, 1000, fp)) { + if (!strncmp(line, "ENDATA", 6)|| + !strncmp(line, "endata", 6)) break; nLine++; - iColumn = -1; + if (!useMasks) + iColumn = -1; + else + needCard=false; double up = 0.0; double down = 0.0; int pri = 0; @@ -7757,12 +8326,34 @@ switch (order[i]) { // name case 0: - for (iColumn = 0; iColumn < numberColumns; iColumn++) { + iColumn++; + for (; iColumn < numberColumns; iColumn++) { + if (priorities[iColumn]!=-123456789) { if (!strcmp(columnNames[iColumn], pos)) break; + } else { + // mask (at present ? and trailing *) + const char * name = columnNames[iColumn]; + int length=strlen(name); + int lengthMask=strlen(pos); + bool asterisk = pos[lengthMask-1]=='*'; + if (asterisk) + length=lengthMask-1; + int i; + for (i=0;imessage(CLP_GENERAL, generalMessages) - << generalPrint - << CoinMessageEol; + sprintf(generalPrint,"opening mipstart file %s.",fileName.c_str() ); + generalMessageHandler->message(CLP_GENERAL, generalMessages) << generalPrint << CoinMessageEol; double msObj; readMIPStart( &model_, fileName.c_str(), mipStart, msObj ); - // copy to before preprocess if has .before. - if (strstr(fileName.c_str(),".before.")) { - mipStartBefore = mipStart; - sprintf(generalPrint,"file %s will be used before preprocessing.",fileName.c_str() ); - generalMessageHandler->message(CLP_GENERAL, generalMessages) - << generalPrint - << CoinMessageEol; - } + // copy to before preprocess if has .before. + if (strstr(fileName.c_str(),".before.")) { + mipStartBefore = mipStart; + sprintf(generalPrint,"file %s will be used before preprocessing.",fileName.c_str() ); + generalMessageHandler->message(CLP_GENERAL, generalMessages) + << generalPrint + << CoinMessageEol; + } } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CLP_PARAM_ACTION_DEBUG: @@ -8000,12 +8596,12 @@ } fclose(fp); } else { - std::cout << "Unable to open file " << fileName << std::endl; + sprintf(generalPrint, "Unable to open file %s",fileName.c_str()); + printGeneralMessage(model_,generalPrint); } } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CLP_PARAM_ACTION_PRINTMASK: @@ -8054,7 +8650,8 @@ fclose(fp); canOpen = true; } else { - std::cout << "Unable to open file " << fileName << std::endl; + sprintf(generalPrint, "Unable to open file %s",fileName.c_str()); + printGeneralMessage(model_,generalPrint); } if (canOpen) { ClpSimplex * model2 = lpSolver; @@ -8064,9 +8661,8 @@ time1 = time2; } } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CLP_PARAM_ACTION_SAVE: { @@ -8102,7 +8698,8 @@ fclose(fp); canOpen = true; } else { - std::cout << "Unable to open file " << fileName << std::endl; + sprintf(generalPrint, "Unable to open file %s",fileName.c_str()); + printGeneralMessage(model_,generalPrint); } if (canOpen) { int status; @@ -8141,7 +8738,8 @@ time1 = time2; } else { // errors - std::cout << "There were errors on output" << std::endl; + sprintf(generalPrint, "There were errors on output"); + printGeneralMessage(model_,generalPrint); } } } @@ -8179,7 +8777,8 @@ fclose(fp); canOpen = true; } else { - std::cout << "Unable to open file " << fileName << std::endl; + sprintf(generalPrint, "Unable to open file %s",fileName.c_str()); + printGeneralMessage(model_,generalPrint); } if (canOpen) { int status = lpSolver->restoreModel(fileName.c_str()); @@ -8190,7 +8789,8 @@ time1 = time2; } else { // errors - std::cout << "There were errors on input" << std::endl; + sprintf(generalPrint, "There were errors on input"); + printGeneralMessage(model_,generalPrint); } } } @@ -8307,8 +8907,8 @@ // get bound double value = CoinReadGetDoubleField(argc, argv, &valid); if (!valid) { - std::cout << "Setting " << parameters_[iParam].name() << - " to DEBUG " << value << std::endl; + sprintf(generalPrint, "Setting %s to DEBUG %g",parameters_[iParam].name().c_str(),value); + printGeneralMessage(model_,generalPrint); int iRow; int numberRows = lpSolver->numberRows(); double * rowLower = lpSolver->rowLower(); @@ -8545,7 +9145,8 @@ fprintf(fp, "\n"); fclose(fp); } else { - std::cout << "Unable to open file " << fileName << std::endl; + sprintf(generalPrint, "Unable to open file %s",fileName.c_str()); + printGeneralMessage(model_,generalPrint); } } break; @@ -8922,6 +9523,10 @@ int numberColumns = solver->numberColumns(); // column length unless rhs ranging int number = numberColumns; + if (lpSolver->status()) { + fprintf(fp,"**** Results not valid when LP not optimal\n"); + number=0; + } switch (printMode) { // bound ranging case 6: @@ -8930,18 +9535,17 @@ // rhs ranging case 7: fprintf(fp,"Rhs ranging"); - number = numberRows; + if (!lpSolver->status()) + number = numberRows; break; // objective ranging case 8: fprintf(fp,"Objective ranging"); break; } - if (printMode<9) { - if (lengthName) + if (lengthName) fprintf(fp,",name"); - fprintf(fp,",increase,variable,decrease,variable\n"); - } + fprintf(fp,",increase,variable,decrease,variable\n"); int * which = new int [ number]; if (printMode != 7) { if (!doMask) { @@ -9059,6 +9663,10 @@ } break; } + char printFormat[50]; + sprintf(printFormat," %s %s\n", + CLP_QUOTE(CLP_OUTPUT_FORMAT), + CLP_QUOTE(CLP_OUTPUT_FORMAT)); if (printMode > 2 && printMode < 5) { for (iRow = 0; iRow < numberRows; iRow++) { int type = printMode - 3; @@ -9084,7 +9692,7 @@ for (; i < lengthPrint; i++) fprintf(fp, " "); } - fprintf(fp, " %15.8g %15.8g\n", primalRowSolution[iRow], + fprintf(fp, printFormat, primalRowSolution[iRow], dualRowSolution[iRow]); } } @@ -9135,7 +9743,7 @@ for (; i < lengthPrint; i++) fprintf(fp, " "); } - fprintf(fp, " %15.8g %15.8g\n", + fprintf(fp, printFormat, primalColumnSolution[iColumn], dualColumnSolution[iColumn]); } else { @@ -9223,12 +9831,12 @@ delete [] masks; } } else { - std::cout << "Unable to open file " << fileName << std::endl; + sprintf(generalPrint, "Unable to open file %s",fileName.c_str()); + printGeneralMessage(model_,generalPrint); } } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CLP_PARAM_ACTION_SAVESOL: @@ -9260,9 +9868,8 @@ } saveSolution(lpSolver, fileName); } else { -#ifndef DISALLOW_PRINTING - std::cout << "** Current model not valid" << std::endl; -#endif + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; case CLP_PARAM_ACTION_DUMMY: @@ -9303,7 +9910,8 @@ totalTime += time2 - time1; time1 = time2; } else { - std::cout << "** Current model not valid" << std::endl; + sprintf(generalPrint, "** Current model not valid"); + printGeneralMessage(model_,generalPrint); } break; default: @@ -9553,7 +10161,7 @@ parameters[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters, parameters)].setCurrentOption("on"); parameters[whichParam(CBC_PARAM_STR_FPUMP, numberParameters, parameters)].setCurrentOption("on"); parameters[whichParam(CBC_PARAM_STR_GREEDY, numberParameters, parameters)].setCurrentOption("on"); - parameters[whichParam(CBC_PARAM_STR_COMBINE, numberParameters, parameters)].setCurrentOption("on"); + parameters[whichParam(CBC_PARAM_STR_COMBINE, numberParameters, parameters)].setCurrentOption("off"); parameters[whichParam(CBC_PARAM_STR_CROSSOVER2, numberParameters, parameters)].setCurrentOption("off"); parameters[whichParam(CBC_PARAM_STR_PIVOTANDCOMPLEMENT, numberParameters, parameters)].setCurrentOption("off"); parameters[whichParam(CBC_PARAM_STR_PIVOTANDFIX, numberParameters, parameters)].setCurrentOption("off"); @@ -9615,263 +10223,1426 @@ delete [] number; delete [] numberExact; } +static void sortOnOther(int * column, + const CoinBigIndex * rowStart, + int * order, + int * other, + int nRow, + int nInRow, + int where) +{ + if (nRow < 2 || where >= nInRow) + return; + // do initial sort + int kRow; + int iRow; + for ( kRow = 0; kRow < nRow; kRow++) { + iRow = order[kRow]; + other[kRow] = column[rowStart[iRow] + where]; + } + CoinSort_2(other, other + nRow, order); + int first = 0; + iRow = order[0]; + int firstC = column[rowStart[iRow] + where]; + kRow = 1; + while (kRow < nRow) { + int lastC = 9999999;; + for (; kRow < nRow + 1; kRow++) { + if (kRow < nRow) { + iRow = order[kRow]; + lastC = column[rowStart[iRow] + where]; + } else { + lastC = 9999999; + } + if (lastC > firstC) + break; + } + // sort + sortOnOther(column, rowStart, order + first, other, kRow - first, + nInRow, where + 1); + firstC = lastC; + first = kRow; + } +} static void statistics(ClpSimplex * originalModel, ClpSimplex * model) { - int numberColumns = originalModel->numberColumns(); - const char * integerInformation = originalModel->integerInformation(); - const double * columnLower = originalModel->columnLower(); - const double * columnUpper = originalModel->columnUpper(); - int numberIntegers = 0; - int numberBinary = 0; - int iRow, iColumn; - if (integerInformation) { - for (iColumn = 0; iColumn < numberColumns; iColumn++) { - if (integerInformation[iColumn]) { - if (columnUpper[iColumn] > columnLower[iColumn]) { - numberIntegers++; - if (columnUpper[iColumn] == 0.0 && columnLower[iColumn] == 1) - numberBinary++; - } - } - } - } - numberColumns = model->numberColumns(); - int numberRows = model->numberRows(); - columnLower = model->columnLower(); - columnUpper = model->columnUpper(); - const double * rowLower = model->rowLower(); - const double * rowUpper = model->rowUpper(); - const double * objective = model->objective(); - CoinPackedMatrix * matrix = model->matrix(); - CoinBigIndex numberElements = matrix->getNumElements(); - const int * columnLength = matrix->getVectorLengths(); - //const CoinBigIndex * columnStart = matrix->getVectorStarts(); - const double * elementByColumn = matrix->getElements(); - int * number = new int[numberRows+1]; - memset(number, 0, (numberRows + 1)*sizeof(int)); - int numberObjSingletons = 0; - /* cType - 0 0/inf, 1 0/up, 2 lo/inf, 3 lo/up, 4 free, 5 fix, 6 -inf/0, 7 -inf/up, - 8 0/1 - */ - int cType[9]; - std::string cName[] = {"0.0->inf,", "0.0->up,", "lo->inf,", "lo->up,", "free,", "fixed,", "-inf->0.0,", - "-inf->up,", "0.0->1.0" - }; - int nObjective = 0; - memset(cType, 0, sizeof(cType)); - for (iColumn = 0; iColumn < numberColumns; iColumn++) { - int length = columnLength[iColumn]; - if (length == 1 && objective[iColumn]) - numberObjSingletons++; - number[length]++; - if (objective[iColumn]) - nObjective++; - if (columnLower[iColumn] > -1.0e20) { - if (columnLower[iColumn] == 0.0) { - if (columnUpper[iColumn] > 1.0e20) - cType[0]++; - else if (columnUpper[iColumn] == 1.0) - cType[8]++; - else if (columnUpper[iColumn] == 0.0) - cType[5]++; - else - cType[1]++; - } else { - if (columnUpper[iColumn] > 1.0e20) - cType[2]++; - else if (columnUpper[iColumn] == columnLower[iColumn]) - cType[5]++; - else - cType[3]++; - } - } else { - if (columnUpper[iColumn] > 1.0e20) - cType[4]++; - else if (columnUpper[iColumn] == 0.0) - cType[6]++; - else - cType[7]++; - } - } - /* rType - 0 E 0, 1 E 1, 2 E -1, 3 E other, 4 G 0, 5 G 1, 6 G other, - 7 L 0, 8 L 1, 9 L other, 10 Range 0/1, 11 Range other, 12 free - */ - int rType[13]; - std::string rName[] = {"E 0.0,", "E 1.0,", "E -1.0,", "E other,", "G 0.0,", "G 1.0,", "G other,", - "L 0.0,", "L 1.0,", "L other,", "Range 0.0->1.0,", "Range other,", "Free" - }; - memset(rType, 0, sizeof(rType)); - for (iRow = 0; iRow < numberRows; iRow++) { - if (rowLower[iRow] > -1.0e20) { - if (rowLower[iRow] == 0.0) { - if (rowUpper[iRow] > 1.0e20) - rType[4]++; - else if (rowUpper[iRow] == 1.0) - rType[10]++; - else if (rowUpper[iRow] == 0.0) - rType[0]++; - else - rType[11]++; - } else if (rowLower[iRow] == 1.0) { - if (rowUpper[iRow] > 1.0e20) - rType[5]++; - else if (rowUpper[iRow] == rowLower[iRow]) - rType[1]++; - else - rType[11]++; - } else if (rowLower[iRow] == -1.0) { - if (rowUpper[iRow] > 1.0e20) - rType[6]++; - else if (rowUpper[iRow] == rowLower[iRow]) - rType[2]++; - else - rType[11]++; - } else { - if (rowUpper[iRow] > 1.0e20) - rType[6]++; - else if (rowUpper[iRow] == rowLower[iRow]) - rType[3]++; - else - rType[11]++; - } - } else { - if (rowUpper[iRow] > 1.0e20) - rType[12]++; - else if (rowUpper[iRow] == 0.0) - rType[7]++; - else if (rowUpper[iRow] == 1.0) - rType[8]++; - else - rType[9]++; - } - } - // Basic statistics - printf("\n\nProblem has %d rows, %d columns (%d with objective) and %d elements\n", - numberRows, numberColumns, nObjective, numberElements); - if (number[0] + number[1]) { - printf("There are "); - if (numberObjSingletons) - printf("%d singletons with objective ", numberObjSingletons); - int numberNoObj = number[1] - numberObjSingletons; - if (numberNoObj) - printf("%d singletons with no objective ", numberNoObj); - if (number[0]) - printf("** %d columns have no entries", number[0]); - printf("\n"); - } - printf("Column breakdown:\n"); - int k; - for (k = 0; k < static_cast (sizeof(cType) / sizeof(int)); k++) { - printf("%d of type %s ", cType[k], cName[k].c_str()); - if (((k + 1) % 3) == 0) - printf("\n"); - } - if ((k % 3) != 0) - printf("\n"); - printf("Row breakdown:\n"); - for (k = 0; k < static_cast (sizeof(rType) / sizeof(int)); k++) { - printf("%d of type %s ", rType[k], rName[k].c_str()); - if (((k + 1) % 3) == 0) - printf("\n"); - } - if ((k % 3) != 0) - printf("\n"); - if (model->logLevel() < 2) - return ; - int kMax = model->logLevel() > 3 ? 1000000 : 10; - k = 0; - for (iRow = 1; iRow <= numberRows; iRow++) { - if (number[iRow]) { - k++; - printf("%d columns have %d entries\n", number[iRow], iRow); - if (k == kMax) - break; - } - } - if (k < numberRows) { - int kk = k; - k = 0; - for (iRow = numberRows; iRow >= 1; iRow--) { - if (number[iRow]) { - k++; - if (k == kMax) + int numberColumns = originalModel->numberColumns(); + const char * integerInformation = originalModel->integerInformation(); + const double * columnLower = originalModel->columnLower(); + const double * columnUpper = originalModel->columnUpper(); + int numberIntegers = 0; + int numberBinary = 0; + int iRow, iColumn; + if (integerInformation) { + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + if (integerInformation[iColumn]) { + if (columnUpper[iColumn] > columnLower[iColumn]) { + numberIntegers++; + if (columnLower[iColumn] == 0.0 && columnUpper[iColumn] == 1) + numberBinary++; + } + } + } + printf("Original problem has %d integers (%d of which binary)\n", + numberIntegers,numberBinary); + } + numberColumns = model->numberColumns(); + int numberRows = model->numberRows(); + columnLower = model->columnLower(); + columnUpper = model->columnUpper(); + const double * rowLower = model->rowLower(); + const double * rowUpper = model->rowUpper(); + const double * objective = model->objective(); + if (model->integerInformation()) { + const char * integerInformation = model->integerInformation(); + int numberIntegers = 0; + int numberBinary = 0; + double * obj = new double [numberColumns]; + int * which = new int [numberColumns]; + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + if (columnUpper[iColumn] > columnLower[iColumn]) { + if (integerInformation[iColumn]) { + numberIntegers++; + if (columnLower[iColumn] == 0.0 && columnUpper[iColumn] == 1) + numberBinary++; + } + } + } + if(numberColumns != originalModel->numberColumns()) + printf("Presolved problem has %d integers (%d of which binary)\n", + numberIntegers,numberBinary); + for (int ifInt=0;ifInt<2;ifInt++) { + for (int ifAbs=0;ifAbs<2;ifAbs++) { + int numberSort=0; + int numberZero=0; + int numberDifferentObj=0; + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + if (columnUpper[iColumn] > columnLower[iColumn]) { + if (!ifInt||integerInformation[iColumn]) { + obj[numberSort]=(ifAbs) ? fabs(objective[iColumn]) : + objective[iColumn]; + which[numberSort++]=iColumn; + if (!objective[iColumn]) + numberZero++; + } + } + } + CoinSort_2(obj,obj+numberSort,which); + double last=obj[0]; + for (int jColumn = 1; jColumn < numberSort; jColumn++) { + if (fabs(obj[jColumn]-last)>1.0e-12) { + numberDifferentObj++; + last=obj[jColumn]; + } + } + numberDifferentObj++; + printf("==== "); + if (ifInt) + printf("for integers "); + if (!ifAbs) + printf("%d zero objective ",numberZero); + else + printf("absolute objective values "); + printf("%d different\n",numberDifferentObj); + bool saveModel=false; + int target=model->logLevel(); + if (target>10000) { + if (ifInt&&!ifAbs) + saveModel=true; + target-=10000; + } + + if (target<=100) + target=12; + else + target-=100; + if (numberDifferentObj1.0e-12) { + printf("%d variables have objective of %g\n", + jColumn-iLast,last); + iLast=jColumn; + last=obj[jColumn]; + } + } + printf("%d variables have objective of %g\n", + numberSort-iLast,last); + if (saveModel) { + int spaceNeeded=numberSort+numberDifferentObj; + int * columnAdd = new int[spaceNeeded+numberDifferentObj+1]; + double * elementAdd = new double[spaceNeeded]; + int * rowAdd = new int[2*numberDifferentObj+1]; + int * newIsInteger = rowAdd+numberDifferentObj+1; + double * objectiveNew = new double[3*numberDifferentObj]; + double * lowerNew = objectiveNew+numberDifferentObj; + double * upperNew = lowerNew+numberDifferentObj; + memset(columnAdd+spaceNeeded,0, + (numberDifferentObj+1)*sizeof(int)); + ClpSimplex tempModel=*model; + int iLast=0; + double last=obj[0]; + numberDifferentObj=0; + int numberElements=0; + rowAdd[0]=0; + double * objective = tempModel.objective(); + for (int jColumn = 1; jColumn < numberSort+1; jColumn++) { + if (jColumn==numberSort||fabs(obj[jColumn]-last)>1.0e-12) { + // not if just one + if (jColumn-iLast>1) { + bool allInteger=integerInformation!=NULL; + int iColumn=which[iLast]; + objectiveNew[numberDifferentObj]=objective[iColumn]; + double lower=0.0; + double upper=0.0; + for (int kColumn=iLast;kColumnproblemName(); + if (ifInt) + tempName += "_int"; + if (ifAbs) + tempName += "_abs"; + tempName += ".mps"; + tempModel.writeMps(tempName.c_str()); + } + } + } + } + delete [] which; + delete [] obj; + printf("===== end objective counts\n"); + } + CoinPackedMatrix * matrix = model->matrix(); + CoinBigIndex numberElements = matrix->getNumElements(); + const int * columnLength = matrix->getVectorLengths(); + //const CoinBigIndex * columnStart = matrix->getVectorStarts(); + const double * elementByColumn = matrix->getElements(); + int * number = new int[numberRows+1]; + memset(number, 0, (numberRows + 1)*sizeof(int)); + int numberObjSingletons = 0; + /* cType + 0 0/inf, 1 0/up, 2 lo/inf, 3 lo/up, 4 free, 5 fix, 6 -inf/0, 7 -inf/up, + 8 0/1 + */ + int cType[9]; + std::string cName[] = {"0.0->inf,", "0.0->up,", "lo->inf,", "lo->up,", "free,", "fixed,", "-inf->0.0,", + "-inf->up,", "0.0->1.0" + }; + int nObjective = 0; + memset(cType, 0, sizeof(cType)); + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + int length = columnLength[iColumn]; + if (length == 1 && objective[iColumn]) + numberObjSingletons++; + number[length]++; + if (objective[iColumn]) + nObjective++; + if (columnLower[iColumn] > -1.0e20) { + if (columnLower[iColumn] == 0.0) { + if (columnUpper[iColumn] > 1.0e20) + cType[0]++; + else if (columnUpper[iColumn] == 1.0) + cType[8]++; + else if (columnUpper[iColumn] == 0.0) + cType[5]++; + else + cType[1]++; + } else { + if (columnUpper[iColumn] > 1.0e20) + cType[2]++; + else if (columnUpper[iColumn] == columnLower[iColumn]) + cType[5]++; + else + cType[3]++; + } + } else { + if (columnUpper[iColumn] > 1.0e20) + cType[4]++; + else if (columnUpper[iColumn] == 0.0) + cType[6]++; + else + cType[7]++; + } + } + /* rType + 0 E 0, 1 E 1, 2 E -1, 3 E other, 4 G 0, 5 G 1, 6 G other, + 7 L 0, 8 L 1, 9 L other, 10 Range 0/1, 11 Range other, 12 free + */ + int rType[13]; + std::string rName[] = {"E 0.0,", "E 1.0,", "E -1.0,", "E other,", "G 0.0,", "G 1.0,", "G other,", + "L 0.0,", "L 1.0,", "L other,", "Range 0.0->1.0,", "Range other,", "Free" + }; + memset(rType, 0, sizeof(rType)); + for (iRow = 0; iRow < numberRows; iRow++) { + if (rowLower[iRow] > -1.0e20) { + if (rowLower[iRow] == 0.0) { + if (rowUpper[iRow] > 1.0e20) + rType[4]++; + else if (rowUpper[iRow] == 1.0) + rType[10]++; + else if (rowUpper[iRow] == 0.0) + rType[0]++; + else + rType[11]++; + } else if (rowLower[iRow] == 1.0) { + if (rowUpper[iRow] > 1.0e20) + rType[5]++; + else if (rowUpper[iRow] == rowLower[iRow]) + rType[1]++; + else + rType[11]++; + } else if (rowLower[iRow] == -1.0) { + if (rowUpper[iRow] > 1.0e20) + rType[6]++; + else if (rowUpper[iRow] == rowLower[iRow]) + rType[2]++; + else + rType[11]++; + } else { + if (rowUpper[iRow] > 1.0e20) + rType[6]++; + else if (rowUpper[iRow] == rowLower[iRow]) + rType[3]++; + else + rType[11]++; + } + } else { + if (rowUpper[iRow] > 1.0e20) + rType[12]++; + else if (rowUpper[iRow] == 0.0) + rType[7]++; + else if (rowUpper[iRow] == 1.0) + rType[8]++; + else + rType[9]++; + } + } + // Basic statistics + printf("\n\nProblem has %d rows, %d columns (%d with objective) and %d elements\n", + numberRows, numberColumns, nObjective, numberElements); + if (number[0] + number[1]) { + printf("There are "); + if (numberObjSingletons) + printf("%d singletons with objective ", numberObjSingletons); + int numberNoObj = number[1] - numberObjSingletons; + if (numberNoObj) + printf("%d singletons with no objective ", numberNoObj); + if (number[0]) + printf("** %d columns have no entries", number[0]); + printf("\n"); + } + printf("Column breakdown:\n"); + int k; + for (k = 0; k < static_cast (sizeof(cType) / sizeof(int)); k++) { + printf("%d of type %s ", cType[k], cName[k].c_str()); + if (((k + 1) % 3) == 0) + printf("\n"); + } + if ((k % 3) != 0) + printf("\n"); + printf("Row breakdown:\n"); + for (k = 0; k < static_cast (sizeof(rType) / sizeof(int)); k++) { + printf("%d of type %s ", rType[k], rName[k].c_str()); + if (((k + 1) % 3) == 0) + printf("\n"); + } + if ((k % 3) != 0) + printf("\n"); + //#define SYM +#ifndef SYM + if (model->logLevel() < 2) + return ; +#endif + int kMax = model->logLevel() > 3 ? 1000000 : 10; + k = 0; + for (iRow = 1; iRow <= numberRows; iRow++) { + if (number[iRow]) { + k++; + printf("%d columns have %d entries\n", number[iRow], iRow); + if (k == kMax) break; - } - } - if (k > kk) { - printf("\n .........\n\n"); - iRow = k; - k = 0; - for (; iRow < numberRows; iRow++) { - if (number[iRow]) { + } + } + if (k < numberRows) { + int kk = k; + k = 0; + for (iRow = numberRows; iRow >= 1; iRow--) { + if (number[iRow]) { k++; - printf("%d columns have %d entries\n", number[iRow], iRow); if (k == kMax) - break; - } - } - } - } - delete [] number; - printf("\n\n"); - // get row copy - CoinPackedMatrix rowCopy = *matrix; - rowCopy.reverseOrdering(); - //const int * column = rowCopy.getIndices(); - const int * rowLength = rowCopy.getVectorLengths(); - //const CoinBigIndex * rowStart = rowCopy.getVectorStarts(); - //const double * element = rowCopy.getElements(); - number = new int[numberColumns+1]; - memset(number, 0, (numberColumns + 1)*sizeof(int)); - for (iRow = 0; iRow < numberRows; iRow++) { - int length = rowLength[iRow]; - number[length]++; - } - if (number[0]) - printf("** %d rows have no entries\n", number[0]); - k = 0; - for (iColumn = 1; iColumn <= numberColumns; iColumn++) { - if (number[iColumn]) { - k++; - printf("%d rows have %d entries\n", number[iColumn], iColumn); - if (k == kMax) - break; - } - } - if (k < numberColumns) { - int kk = k; - k = 0; - for (iColumn = numberColumns; iColumn >= 1; iColumn--) { - if (number[iColumn]) { - k++; - if (k == kMax) + break; + } + } + if (k > kk) { + printf("\n .........\n\n"); + iRow = k; + k = 0; + for (; iRow < numberRows; iRow++) { + if (number[iRow]) { + k++; + printf("%d columns have %d entries\n", number[iRow], iRow); + if (k == kMax) + break; + } + } + } + } + delete [] number; + printf("\n\n"); + if (model->logLevel() == 63 +#ifdef SYM + || true +#endif + ) { + // get column copy + CoinPackedMatrix columnCopy = *matrix; + const int * columnLength = columnCopy.getVectorLengths(); + number = new int[numberRows+1]; + memset(number, 0, (numberRows + 1)*sizeof(int)); + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + int length = columnLength[iColumn]; + number[length]++; + } + k = 0; + for (iRow = 1; iRow <= numberRows; iRow++) { + if (number[iRow]) { + k++; + } + } + int * row = columnCopy.getMutableIndices(); + const CoinBigIndex * columnStart = columnCopy.getVectorStarts(); + double * element = columnCopy.getMutableElements(); + int * order = new int[numberColumns]; + int * other = new int[numberColumns]; + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + int length = columnLength[iColumn]; + order[iColumn] = iColumn; + other[iColumn] = length; + CoinBigIndex start = columnStart[iColumn]; + CoinSort_2(row + start, row + start + length, element + start); + } + CoinSort_2(other, other + numberColumns, order); + int jColumn = number[0] + number[1]; + for (iRow = 2; iRow <= numberRows; iRow++) { + if (number[iRow]) { + printf("XX %d columns have %d entries\n", number[iRow], iRow); + int kColumn = jColumn + number[iRow]; + sortOnOther(row, columnStart, + order + jColumn, other, number[iRow], iRow, 0); + // Now print etc + if (iRow < 500000) { + for (int lColumn = jColumn; lColumn < kColumn; lColumn++) { + iColumn = order[lColumn]; + CoinBigIndex start = columnStart[iColumn]; + if (model->logLevel() == 63) { + printf("column %d %g <= ", iColumn, columnLower[iColumn]); + for (CoinBigIndex i = start; i < start + iRow; i++) + printf("( %d, %g) ", row[i], element[i]); + printf("<= %g\n", columnUpper[iColumn]); + } + } + } + jColumn = kColumn; + } + } + delete [] order; + delete [] other; + delete [] number; + } + // get row copy + CoinPackedMatrix rowCopy = *matrix; + rowCopy.reverseOrdering(); + const int * rowLength = rowCopy.getVectorLengths(); + number = new int[numberColumns+1]; + memset(number, 0, (numberColumns + 1)*sizeof(int)); + if (model->logLevel() > 3) { + // get column copy + CoinPackedMatrix columnCopy = *matrix; + const int * columnLength = columnCopy.getVectorLengths(); + const int * row = columnCopy.getIndices(); + const CoinBigIndex * columnStart = columnCopy.getVectorStarts(); + const double * element = columnCopy.getElements(); + const double * elementByRow = rowCopy.getElements(); + const int * rowStart = rowCopy.getVectorStarts(); + const int * column = rowCopy.getIndices(); + int nPossibleZeroCost=0; + int nPossibleNonzeroCost=0; + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + int length = columnLength[iColumn]; + if (columnLower[iColumn]<-1.0e30&&columnUpper[iColumn]>1.0e30) { + if (length==1) { + printf("Singleton free %d - cost %g\n",iColumn,objective[iColumn]); + } else if (length==2) { + int iRow0=row[columnStart[iColumn]]; + int iRow1=row[columnStart[iColumn]+1]; + double element0=element[columnStart[iColumn]]; + double element1=element[columnStart[iColumn]+1]; + int n0=rowLength[iRow0]; + int n1=rowLength[iRow1]; + printf("Doubleton free %d - cost %g - %g in %srow with %d entries and %g in %srow with %d entries\n", + iColumn,objective[iColumn],element0,(rowLower[iRow0]==rowUpper[iRow0]) ? "==" : "",n0, + element1,(rowLower[iRow1]==rowUpper[iRow1]) ? "==" : "",n1); + + } + } + if (length==1) { + int iRow=row[columnStart[iColumn]]; + double value=COIN_DBL_MAX; + for (int i=rowStart[iRow];ilogLevel() > 4) + printf("Singleton %d with no objective in row with %d elements - rhs %g,%g\n",iColumn,rowLength[iRow],rowLower[iRow],rowUpper[iRow]); + nPossibleZeroCost++; + } else if (value!=-COIN_DBL_MAX) { + if (model->logLevel() > 4) + printf("Singleton %d (%s) with objective in row %d (%s) with %d equal elements - rhs %g,%g\n",iColumn,model->getColumnName(iColumn).c_str(), + iRow,model->getRowName(iRow).c_str(), + rowLength[iRow],rowLower[iRow],rowUpper[iRow]); + nPossibleNonzeroCost++; + } + } + } + if (nPossibleZeroCost||nPossibleNonzeroCost) + printf("%d singletons with zero cost, %d with valid cost\n", + nPossibleZeroCost,nPossibleNonzeroCost); + // look for DW + int * blockStart = new int [2*(numberRows+numberColumns)+1+numberRows]; + int * columnBlock = blockStart+numberRows; + int * nextColumn = columnBlock+numberColumns; + int * blockCount = nextColumn+numberColumns; + int * blockEls = blockCount+numberRows+1; + int direction[2]={-1,1}; + int bestBreak=-1; + double bestValue=0.0; + int iPass=0; + int halfway=(numberRows+1)/2; + int firstMaster=-1; + int lastMaster=-2; + while (iPass<2) { + int increment=direction[iPass]; + int start= increment>0 ? 0 : numberRows-1; + int stop=increment>0 ? numberRows : -1; + int numberBlocks=0; + int thisBestBreak=-1; + double thisBestValue=COIN_DBL_MAX; + int numberRowsDone=0; + int numberMarkedColumns=0; + int maximumBlockSize=0; + for (int i=0;i=0) { + // column marked + if (iBlock<0) { + // put row in that block + iBlock=whichColumnBlock; + } else if (iBlock!=whichColumnBlock) { + // merge + blockCount[iBlock]+=blockCount[whichColumnBlock]; + blockCount[whichColumnBlock]=0; + int jColumn=blockStart[whichColumnBlock]; + while (jColumn>=0) { + columnBlock[jColumn]=iBlock; + iColumn=jColumn; + jColumn=nextColumn[jColumn]; + } + nextColumn[iColumn]=blockStart[iBlock]; + blockStart[iBlock]=blockStart[whichColumnBlock]; + blockStart[whichColumnBlock]=-1; + } + } + } + int n=numberMarkedColumns; + if (iBlock<0) { + //new block + if (rowLength[iRow]) { + numberBlocks++; + iBlock=numberBlocks; + int jColumn=column[rowStart[iRow]]; + columnBlock[jColumn]=iBlock; + blockStart[iBlock]=jColumn; + numberMarkedColumns++; + for (CoinBigIndex j=rowStart[iRow]+1;j maximumBlockSize&&numberRowsDone>halfway) { + thisBestBreak=iRow; + thisBestValue=static_cast(maximumBlockSize)/ + static_cast(numberRowsDone); + } + } + if (thisBestBreak==stop) + thisBestValue=COIN_DBL_MAX; + iPass++; + if (iPass==1) { + bestBreak=thisBestBreak; + bestValue=thisBestValue; + } else { + if (bestValue=0) { + blockCount[iBlock]++; + blockEls[iBlock]+=rowLength[iRow]; + } else { + if (iBlock==-2) + numberMaster++; + else + numberEmpty++; + } + } + int numberEmptyColumns=0; + int numberMasterColumns=0; + for (int iColumn = 0; iColumn < numberColumns; iColumn++) { + int iBlock=columnBlock[iColumn]; + if (iBlock>=0) { + nextColumn[iBlock]++; + } else { + if (columnLength[iColumn]) + numberMasterColumns++; + else + numberEmptyColumns++; + } + } + int largestRows=0; + int largestColumns=0; + for (int i=0;ilargestRows+largestColumns) { + largestRows=blockCount[i]; + largestColumns=nextColumn[i]; + } + } + bool useful=true; + if (numberMaster>halfway||largestRows*3>numberRows) + useful=false; + printf("%s %d blocks (largest %d,%d), %d master rows (%d empty) out of %d, %d master columns (%d empty) out of %d\n", + useful ? "**Useful" : "NoGood", + numberBlocks,largestRows,largestColumns,numberMaster,numberEmpty,numberRows, + numberMasterColumns,numberEmptyColumns,numberColumns); + FILE * fp=NULL; + bool justIntegers=true; + bool oneFile=true; + int logLevel = model->logLevel(); + if (logLevel>19) { + logLevel-=2; + oneFile=true; + fp = fopen("fake.bnd","w"); + } + if (logLevel==19) + justIntegers=false; + for (int i=0;i= 17 && logLevel <= 21) { + int * whichRows=new int[numberRows+numberColumns]; + int * whichColumns=whichRows+numberRows; + char name[20]; + for (int iBlock=0;iBlockgetRowName(iRow); + subset.setRowName(jRow,name); + } + int nInteger=0; + for (int jColumn=0;jColumnisInteger(iColumn)) { + subset.setInteger(jColumn); + nInteger++; + } + std::string name = model->getColumnName(iColumn); + subset.setColumnName(jColumn,name); + } + if (logLevel == 17) { + subset.writeMps(name,0,1); + } else if (nInteger) { + OsiClpSolverInterface subset2(&subset); + CbcModel smallModel(subset2); + smallModel.branchAndBound(); + const double * solution = smallModel.bestSolution(); + if (solution) { + if (!oneFile) { + sprintf(name,"block%d.bnd",iBlock); + fp = fopen(name,"w"); + assert (fp); + } + fprintf(fp,"BBB objective %g for block %d\n", + smallModel.getObjValue(),iBlock); + for (int jColumn=0;jColumn kk) { - printf("\n .........\n\n"); - iColumn = k; - k = 0; - for (; iColumn < numberColumns; iColumn++) { - if (number[iColumn]) { + } + } + if (k < numberColumns) { + int kk = k; + k = 0; + for (iColumn = numberColumns; iColumn >= 1; iColumn--) { + if (number[iColumn]) { k++; - printf("%d rows have %d entries\n", number[iColumn], iColumn); if (k == kMax) - break; - } - } - } - } - delete [] number; - // Now do breakdown of ranges - breakdown("Elements", numberElements, elementByColumn); - breakdown("RowLower", numberRows, rowLower); - breakdown("RowUpper", numberRows, rowUpper); - breakdown("ColumnLower", numberColumns, columnLower); - breakdown("ColumnUpper", numberColumns, columnUpper); - breakdown("Objective", numberColumns, objective); + break; + } + } + if (k > kk) { + printf("\n .........\n\n"); + iColumn = k; + k = 0; + for (; iColumn < numberColumns; iColumn++) { + if (number[iColumn]) { + k++; + printf("%d rows have %d entries\n", number[iColumn], iColumn); + if (k == kMax) + break; + } + } + } + } + if (model->logLevel() == 63 +#ifdef SYM + || true +#endif + ) { + int * column = rowCopy.getMutableIndices(); + const CoinBigIndex * rowStart = rowCopy.getVectorStarts(); + double * element = rowCopy.getMutableElements(); + int * order = new int[numberRows]; + int * other = new int[numberRows]; + for (iRow = 0; iRow < numberRows; iRow++) { + int length = rowLength[iRow]; + order[iRow] = iRow; + other[iRow] = length; + CoinBigIndex start = rowStart[iRow]; + CoinSort_2(column + start, column + start + length, element + start); + } + CoinSort_2(other, other + numberRows, order); + int jRow = number[0] + number[1]; + double * weight = new double[numberRows]; + double * randomColumn = new double[numberColumns+1]; + double * randomRow = new double [numberRows+1]; + int * sortRow = new int [numberRows]; + int * possibleRow = new int [numberRows]; + int * backRow = new int [numberRows]; + int * stackRow = new int [numberRows]; + int * sortColumn = new int [numberColumns]; + int * possibleColumn = new int [numberColumns]; + int * backColumn = new int [numberColumns]; + int * backColumn2 = new int [numberColumns]; + int * mapRow = new int [numberRows]; + int * mapColumn = new int [numberColumns]; + int * stackColumn = new int [numberColumns]; + double randomLower = CoinDrand48(); + double randomUpper = CoinDrand48(); + double randomInteger = CoinDrand48(); + int * startAdd = new int[numberRows+1]; + int * columnAdd = new int [2*numberElements]; + double * elementAdd = new double[2*numberElements]; + int nAddRows = 0; + startAdd[0] = 0; + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + randomColumn[iColumn] = CoinDrand48(); + backColumn2[iColumn] = -1; + } + for (iColumn = 2; iColumn <= numberColumns; iColumn++) { + if (number[iColumn]) { + printf("XX %d rows have %d entries\n", number[iColumn], iColumn); + int kRow = jRow + number[iColumn]; + sortOnOther(column, rowStart, + order + jRow, other, number[iColumn], iColumn, 0); + // Now print etc + if (iColumn < 500000) { + int nLook = 0; + for (int lRow = jRow; lRow < kRow; lRow++) { + iRow = order[lRow]; + CoinBigIndex start = rowStart[iRow]; + if (model->logLevel() == 63) { + printf("row %d %g <= ", iRow, rowLower[iRow]); + for (CoinBigIndex i = start; i < start + iColumn; i++) + printf("( %d, %g) ", column[i], element[i]); + printf("<= %g\n", rowUpper[iRow]); + } + int first = column[start]; + double sum = 0.0; + for (CoinBigIndex i = start; i < start + iColumn; i++) { + int jColumn = column[i]; + double value = element[i]; + jColumn -= first; + assert (jColumn >= 0); + sum += value * randomColumn[jColumn]; + } + if (rowLower[iRow] > -1.0e30 && rowLower[iRow]) + sum += rowLower[iRow] * randomLower; + else if (!rowLower[iRow]) + sum += 1.234567e-7 * randomLower; + if (rowUpper[iRow] < 1.0e30 && rowUpper[iRow]) + sum += rowUpper[iRow] * randomUpper; + else if (!rowUpper[iRow]) + sum += 1.234567e-7 * randomUpper; + sortRow[nLook] = iRow; + randomRow[nLook++] = sum; + // best way is to number unique elements and bounds and use + if (fabs(sum) > 1.0e4) + sum *= 1.0e-6; + weight[iRow] = sum; + } + assert (nLook <= numberRows); + CoinSort_2(randomRow, randomRow + nLook, sortRow); + randomRow[nLook] = COIN_DBL_MAX; + double last = -COIN_DBL_MAX; + int iLast = -1; + for (int iLook = 0; iLook < nLook + 1; iLook++) { + if (randomRow[iLook] > last) { + if (iLast >= 0) { + int n = iLook - iLast; + if (n > 1) { + //printf("%d rows possible?\n",n); + } + } + iLast = iLook; + last = randomRow[iLook]; + } + } + } + jRow = kRow; + } + } + CoinPackedMatrix columnCopy = *matrix; + const int * columnLength = columnCopy.getVectorLengths(); + const int * row = columnCopy.getIndices(); + const CoinBigIndex * columnStart = columnCopy.getVectorStarts(); + const double * elementByColumn = columnCopy.getElements(); + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + int length = columnLength[iColumn]; + CoinBigIndex start = columnStart[iColumn]; + double sum = objective[iColumn]; + if (columnLower[iColumn] > -1.0e30 && columnLower[iColumn]) + sum += columnLower[iColumn] * randomLower; + else if (!columnLower[iColumn]) + sum += 1.234567e-7 * randomLower; + if (columnUpper[iColumn] < 1.0e30 && columnUpper[iColumn]) + sum += columnUpper[iColumn] * randomUpper; + else if (!columnUpper[iColumn]) + sum += 1.234567e-7 * randomUpper; + if (model->isInteger(iColumn)) + sum += 9.87654321e-6 * randomInteger; + for (CoinBigIndex i = start; i < start + length; i++) { + int iRow = row[i]; + sum += elementByColumn[i] * weight[iRow]; + } + sortColumn[iColumn] = iColumn; + randomColumn[iColumn] = sum; + } + { + CoinSort_2(randomColumn, randomColumn + numberColumns, sortColumn); + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + int i = sortColumn[iColumn]; + backColumn[i] = iColumn; + } + randomColumn[numberColumns] = COIN_DBL_MAX; + double last = -COIN_DBL_MAX; + int iLast = -1; + for (int iLook = 0; iLook < numberColumns + 1; iLook++) { + if (randomColumn[iLook] > last) { + if (iLast >= 0) { + int n = iLook - iLast; + if (n > 1) { + //printf("%d columns possible?\n",n); + } + for (int i = iLast; i < iLook; i++) { + possibleColumn[sortColumn[i]] = n; + } + } + iLast = iLook; + last = randomColumn[iLook]; + } + } + for (iRow = 0; iRow < numberRows; iRow++) { + CoinBigIndex start = rowStart[iRow]; + double sum = 0.0; + int length = rowLength[iRow]; + for (CoinBigIndex i = start; i < start + length; i++) { + int jColumn = column[i]; + double value = element[i]; + jColumn = backColumn[jColumn]; + sum += value * randomColumn[jColumn]; + //if (iColumn==23089||iRow==23729) + //printf("row %d cola %d colb %d value %g rand %g sum %g\n", + // iRow,jColumn,column[i],value,randomColumn[jColumn],sum); + } + sortRow[iRow] = iRow; + randomRow[iRow] = weight[iRow]; + randomRow[iRow] = sum; + } + CoinSort_2(randomRow, randomRow + numberRows, sortRow); + for (iRow = 0; iRow < numberRows; iRow++) { + int i = sortRow[iRow]; + backRow[i] = iRow; + } + randomRow[numberRows] = COIN_DBL_MAX; + last = -COIN_DBL_MAX; + iLast = -1; + // Do backward indices from order + for (iRow = 0; iRow < numberRows; iRow++) { + other[order[iRow]] = iRow; + } + for (int iLook = 0; iLook < numberRows + 1; iLook++) { + if (randomRow[iLook] > last) { + if (iLast >= 0) { + int n = iLook - iLast; + if (n > 1) { + //printf("%d rows possible?\n",n); + // Within group sort as for original "order" + for (int i = iLast; i < iLook; i++) { + int jRow = sortRow[i]; + order[i] = other[jRow]; + } + CoinSort_2(order + iLast, order + iLook, sortRow + iLast); + } + for (int i = iLast; i < iLook; i++) { + possibleRow[sortRow[i]] = n; + } + } + iLast = iLook; + last = randomRow[iLook]; + } + } + // Temp out + for (int iLook = 0; iLook < numberRows - 1000000; iLook++) { + iRow = sortRow[iLook]; + CoinBigIndex start = rowStart[iRow]; + int length = rowLength[iRow]; + int numberPossible = possibleRow[iRow]; + for (CoinBigIndex i = start; i < start + length; i++) { + int jColumn = column[i]; + if (possibleColumn[jColumn] != numberPossible) + numberPossible = -1; + } + int n = numberPossible; + if (numberPossible > 1) { + //printf("pppppossible %d\n",numberPossible); + for (int jLook = iLook + 1; jLook < iLook + numberPossible; jLook++) { + int jRow = sortRow[jLook]; + CoinBigIndex start2 = rowStart[jRow]; + assert (numberPossible == possibleRow[jRow]); + assert(length == rowLength[jRow]); + for (CoinBigIndex i = start2; i < start2 + length; i++) { + int jColumn = column[i]; + if (possibleColumn[jColumn] != numberPossible) + numberPossible = -1; + } + } + if (numberPossible < 2) { + // switch off + for (int jLook = iLook; jLook < iLook + n; jLook++) + possibleRow[sortRow[jLook]] = -1; + } + // skip rest + iLook += n - 1; + } else { + possibleRow[iRow] = -1; + } + } + for (int iLook = 0; iLook < numberRows; iLook++) { + iRow = sortRow[iLook]; + int numberPossible = possibleRow[iRow]; + // Only if any integers + int numberIntegers = 0; + CoinBigIndex start = rowStart[iRow]; + int length = rowLength[iRow]; + for (CoinBigIndex i = start; i < start + length; i++) { + int jColumn = column[i]; + if (model->isInteger(jColumn)) + numberIntegers++; + } + if (numberPossible > 1 && !numberIntegers) { + //printf("possible %d - but no integers\n",numberPossible); + } + if (numberPossible > 1 && (numberIntegers || false)) { + // + printf("possible %d - %d integers\n", numberPossible, numberIntegers); + int lastLook = iLook; + int nMapRow = -1; + for (int jLook = iLook + 1; jLook < iLook + numberPossible; jLook++) { + // stop if too many failures + if (jLook > iLook + 10 && nMapRow < 0) + break; + // Create identity mapping + int i; + for (i = 0; i < numberRows; i++) + mapRow[i] = i; + for (i = 0; i < numberColumns; i++) + mapColumn[i] = i; + int offset = jLook - iLook; + int nStackC = 0; + // build up row and column mapping + int nStackR = 1; + stackRow[0] = iLook; + bool good = true; + while (nStackR) { + nStackR--; + int look1 = stackRow[nStackR]; + int look2 = look1 + offset; + assert (randomRow[look1] == randomRow[look2]); + int row1 = sortRow[look1]; + int row2 = sortRow[look2]; + assert (mapRow[row1] == row1); + assert (mapRow[row2] == row2); + mapRow[row1] = row2; + mapRow[row2] = row1; + CoinBigIndex start1 = rowStart[row1]; + CoinBigIndex offset2 = rowStart[row2] - start1; + int length = rowLength[row1]; + assert( length == rowLength[row2]); + for (CoinBigIndex i = start1; i < start1 + length; i++) { + int jColumn1 = column[i]; + int jColumn2 = column[i+offset2]; + if (randomColumn[backColumn[jColumn1]] != + randomColumn[backColumn[jColumn2]]) { + good = false; + break; + } + if (mapColumn[jColumn1] == jColumn1) { + // not touched + assert (mapColumn[jColumn2] == jColumn2); + if (jColumn1 != jColumn2) { + // Put on stack + mapColumn[jColumn1] = jColumn2; + mapColumn[jColumn2] = jColumn1; + stackColumn[nStackC++] = jColumn1; + } + } else { + if (mapColumn[jColumn1] != jColumn2 || + mapColumn[jColumn2] != jColumn1) { + // bad + good = false; + printf("bad col\n"); + break; + } + } + } + if (!good) + break; + while (nStackC) { + nStackC--; + int iColumn = stackColumn[nStackC]; + int iColumn2 = mapColumn[iColumn]; + assert (iColumn != iColumn2); + int length = columnLength[iColumn]; + assert (length == columnLength[iColumn2]); + CoinBigIndex start = columnStart[iColumn]; + CoinBigIndex offset2 = columnStart[iColumn2] - start; + for (CoinBigIndex i = start; i < start + length; i++) { + int iRow = row[i]; + int iRow2 = row[i+offset2]; + if (mapRow[iRow] == iRow) { + // First (but be careful) + if (iRow != iRow2) { + //mapRow[iRow]=iRow2; + //mapRow[iRow2]=iRow; + int iBack = backRow[iRow]; + int iBack2 = backRow[iRow2]; + if (randomRow[iBack] == randomRow[iBack2] && + iBack2 - iBack == offset) { + stackRow[nStackR++] = iBack; + } else { + //printf("randomRow diff - weights %g %g\n", + // weight[iRow],weight[iRow2]); + // bad + good = false; + break; + } + } + } else { + if (mapRow[iRow] != iRow2 || + mapRow[iRow2] != iRow) { + // bad + good = false; + printf("bad row\n"); + break; + } + } + } + if (!good) + break; + } + } + // then check OK + if (good) { + for (iRow = 0; iRow < numberRows; iRow++) { + CoinBigIndex start = rowStart[iRow]; + int length = rowLength[iRow]; + if (mapRow[iRow] == iRow) { + for (CoinBigIndex i = start; i < start + length; i++) { + int jColumn = column[i]; + backColumn2[jColumn] = i - start; + } + for (CoinBigIndex i = start; i < start + length; i++) { + int jColumn = column[i]; + if (mapColumn[jColumn] != jColumn) { + int jColumn2 = mapColumn[jColumn]; + CoinBigIndex i2 = backColumn2[jColumn2]; + if (i2 < 0) { + good = false; + } else if (element[i] != element[i2+start]) { + good = false; + } + } + } + for (CoinBigIndex i = start; i < start + length; i++) { + int jColumn = column[i]; + backColumn2[jColumn] = -1; + } + } else { + int row2 = mapRow[iRow]; + assert (iRow = mapRow[row2]); + if (rowLower[iRow] != rowLower[row2] || + rowLower[row2] != rowLower[iRow]) + good = false; + CoinBigIndex offset2 = rowStart[row2] - start; + for (CoinBigIndex i = start; i < start + length; i++) { + int jColumn = column[i]; + double value = element[i]; + int jColumn2 = column[i+offset2]; + double value2 = element[i+offset2]; + if (value != value2 || mapColumn[jColumn] != jColumn2 || + mapColumn[jColumn2] != jColumn) + good = false; + } + } + } + if (good) { + // check rim + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + if (mapColumn[iColumn] != iColumn) { + int iColumn2 = mapColumn[iColumn]; + if (objective[iColumn] != objective[iColumn2]) + good = false; + if (columnLower[iColumn] != columnLower[iColumn2]) + good = false; + if (columnUpper[iColumn] != columnUpper[iColumn2]) + good = false; + if (model->isInteger(iColumn) != model->isInteger(iColumn2)) + good = false; + } + } + } + if (good) { + // temp + if (nMapRow < 0) { + //const double * solution = model->primalColumnSolution(); + // find mapped + int nMapColumn = 0; + for (int i = 0; i < numberColumns; i++) { + if (mapColumn[i] > i) + nMapColumn++; + } + nMapRow = 0; + int kRow = -1; + for (int i = 0; i < numberRows; i++) { + if (mapRow[i] > i) { + nMapRow++; + kRow = i; + } + } + printf("%d columns, %d rows\n", nMapColumn, nMapRow); + if (nMapRow == 1) { + CoinBigIndex start = rowStart[kRow]; + int length = rowLength[kRow]; + printf("%g <= ", rowLower[kRow]); + for (CoinBigIndex i = start; i < start + length; i++) { + int jColumn = column[i]; + if (mapColumn[jColumn] != jColumn) + printf("* "); + printf("%d,%g ", jColumn, element[i]); + } + printf("<= %g\n", rowUpper[kRow]); + } + } + // temp + int row1 = sortRow[lastLook]; + int row2 = sortRow[jLook]; + lastLook = jLook; + CoinBigIndex start1 = rowStart[row1]; + CoinBigIndex offset2 = rowStart[row2] - start1; + int length = rowLength[row1]; + assert( length == rowLength[row2]); + CoinBigIndex put = startAdd[nAddRows]; + double multiplier = length < 11 ? 2.0 : 1.125; + double value = 1.0; + for (CoinBigIndex i = start1; i < start1 + length; i++) { + int jColumn1 = column[i]; + int jColumn2 = column[i+offset2]; + columnAdd[put] = jColumn1; + elementAdd[put++] = value; + columnAdd[put] = jColumn2; + elementAdd[put++] = -value; + value *= multiplier; + } + nAddRows++; + startAdd[nAddRows] = put; + } else { + printf("ouch - did not check out as good\n"); + } + } + } + // skip rest + iLook += numberPossible - 1; + } + } + } + if (nAddRows) { + double * lower = new double [nAddRows]; + double * upper = new double[nAddRows]; + int i; + //const double * solution = model->primalColumnSolution(); + for (i = 0; i < nAddRows; i++) { + lower[i] = 0.0; + upper[i] = COIN_DBL_MAX; + } + printf("Adding %d rows with %d elements\n", nAddRows, + startAdd[nAddRows]); + //ClpSimplex newModel(*model); + //newModel.addRows(nAddRows,lower,upper,startAdd,columnAdd,elementAdd); + //newModel.writeMps("modified.mps"); + delete [] lower; + delete [] upper; + } + delete [] startAdd; + delete [] columnAdd; + delete [] elementAdd; + delete [] order; + delete [] other; + delete [] randomColumn; + delete [] weight; + delete [] randomRow; + delete [] sortRow; + delete [] backRow; + delete [] possibleRow; + delete [] sortColumn; + delete [] backColumn; + delete [] backColumn2; + delete [] possibleColumn; + delete [] mapRow; + delete [] mapColumn; + delete [] stackRow; + delete [] stackColumn; + } + delete [] number; + // Now do breakdown of ranges + breakdown("Elements", numberElements, elementByColumn); + breakdown("RowLower", numberRows, rowLower); + breakdown("RowUpper", numberRows, rowUpper); + breakdown("ColumnLower", numberColumns, columnLower); + breakdown("ColumnUpper", numberColumns, columnUpper); + breakdown("Objective", numberColumns, objective); } @@ -10097,6 +11868,15 @@ fclose(fp); printf("C++ file written to %s\n", fileName); } +// Print a general message +static void printGeneralMessage(CbcModel &model,const char * message) +{ +#ifndef DISALLOW_PRINTING + model.messageHandler()->message(CBC_FPUMP1, model.messages()) + << message + << CoinMessageEol; +#endif +} /* Version 1.00.00 November 16 2005. This is to stop me (JJF) messing about too much. diff -Nru coinor-cbc-2.8.12/src/CbcSolverExpandKnapsack.cpp coinor-cbc-2.9.9+repack1/src/CbcSolverExpandKnapsack.cpp --- coinor-cbc-2.8.12/src/CbcSolverExpandKnapsack.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSolverExpandKnapsack.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcSolverExpandKnapsack.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcSolverExpandKnapsack.cpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcSolverExpandKnapsack.hpp coinor-cbc-2.9.9+repack1/src/CbcSolverExpandKnapsack.hpp --- coinor-cbc-2.8.12/src/CbcSolverExpandKnapsack.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSolverExpandKnapsack.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcSolverExpandKnapsack.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcSolverExpandKnapsack.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcSolverHeuristics.cpp coinor-cbc-2.9.9+repack1/src/CbcSolverHeuristics.cpp --- coinor-cbc-2.8.12/src/CbcSolverHeuristics.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSolverHeuristics.cpp 2015-01-05 13:11:11.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcSolverHeuristics.cpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcSolverHeuristics.cpp 2105 2015-01-05 13:11:11Z forrest $ */ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -29,6 +29,8 @@ #include "CbcHeuristicGreedy.hpp" #include "CbcHeuristicFPump.hpp" #include "CbcHeuristicRINS.hpp" +#include "CbcHeuristicDW.hpp" +#include "CbcHeuristicVND.hpp" #include "CbcHeuristicDiveCoefficient.hpp" #include "CbcHeuristicDiveFractional.hpp" @@ -1164,9 +1166,11 @@ int useRand = parameters_[whichParam(CBC_PARAM_STR_RANDROUND, numberParameters_, parameters_)].currentOptionAsInteger(); int useRINS = parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].currentOptionAsInteger(); int useRENS = parameters_[whichParam(CBC_PARAM_STR_RENS, numberParameters_, parameters_)].currentOptionAsInteger(); + int useVND = parameters_[whichParam(CBC_PARAM_STR_VND, numberParameters_, parameters_)].currentOptionAsInteger(); int useDINS = parameters_[whichParam(CBC_PARAM_STR_DINS, numberParameters_, parameters_)].currentOptionAsInteger(); int useDIVING2 = parameters_[whichParam(CBC_PARAM_STR_DIVINGS, numberParameters_, parameters_)].currentOptionAsInteger(); int useNaive = parameters_[whichParam(CBC_PARAM_STR_NAIVE, numberParameters_, parameters_)].currentOptionAsInteger(); + int useDW = parameters_[whichParam(CBC_PARAM_STR_DW, numberParameters_, parameters_)].currentOptionAsInteger(); int kType = (type < 10) ? type : 1; assert (kType == 1 || kType == 2); // FPump done first as it only works if no solution @@ -1293,11 +1297,17 @@ double fakeIncrement = parameters_[whichParam(CBC_PARAM_DBL_FAKEINCREMENT, numberParameters_, parameters_)].doubleValue(); if (fakeIncrement) increment = fakeIncrement; - heuristic4.setAbsoluteIncrement(increment); + if (increment>=0.0) + heuristic4.setAbsoluteIncrement(increment); + else + heuristic4.setRelativeIncrement(-increment); heuristic4.setMaximumRetries(r + 1); if (printStuff) { if (increment) { - sprintf(generalPrint, "Increment of %g", increment); + if (increment>0.0) + sprintf(generalPrint, "Absolute increment of %g", increment); + else + sprintf(generalPrint, "Relative increment of %g", -increment); generalMessageHandler->message(CBC_GENERAL, generalMessages) << generalPrint << CoinMessageEol; @@ -1380,23 +1390,28 @@ heuristic6a.setRensType(2+16); model->addHeuristic(&heuristic6a) ; } - if (useRENS >= kType && useRENS <= kType + 1) { -#ifndef JJF_ONE + if ((useRENS >= kType && useRENS <= kType + 1)|| + useRENS>2) { CbcHeuristicRENS heuristic6(*model); heuristic6.setHeuristicName("RENS"); heuristic6.setFractionSmall(0.4); heuristic6.setFeasibilityPumpOptions(1008003); - int nodes [] = { -2, 50, 50, 50, 200, 1000, 10000}; + int nodes [] = { -2, 50, 50, 50, 200, 1000, 10000, -1, -1, 200}; heuristic6.setNumberNodes(nodes[useRENS]); -#else - CbcHeuristicVND heuristic6(*model); - heuristic6.setHeuristicName("VND"); - heuristic5.setFractionSmall(0.5); - heuristic5.setDecayFactor(5.0); -#endif + heuristic6.setRensType(useRENS!=9 ? 0 : 32); model->addHeuristic(&heuristic6) ; anyToDo = true; } + if (useVND >= kType && useVND <= kType + 1) { + CbcHeuristicVND heuristic6b(*model); + heuristic6b.setHeuristicName("VND"); + heuristic6b.setFractionSmall(0.4); + heuristic6b.setFeasibilityPumpOptions(1008003); + int nodes [] = { -2, 50, 50, 50, 200, 1000, 10000}; + heuristic6b.setNumberNodes(nodes[useVND]); + model->addHeuristic(&heuristic6b) ; + anyToDo = true; + } if (useNaive >= kType && useNaive <= kType + 1) { CbcHeuristicNaive heuristic5b(*model); heuristic5b.setHeuristicName("Naive"); @@ -1453,7 +1468,7 @@ } if (useDIVING > 0) { - int majorIterations=64; + int majorIterations=parameters_[whichParam(CBC_PARAM_INT_DIVEOPTSOLVES, numberParameters_, parameters_)].intValue(); int diveOptions2 = parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_)].intValue(); int diveOptions; if (diveOptions2 > 99) { @@ -1464,14 +1479,25 @@ diveOptions = diveOptions2; diveOptions2 = 0; } - if (diveOptions < 0 || diveOptions > 9) + if (diveOptions < 0 || diveOptions > 29) diveOptions = 2; + int diveOptionsNotC=diveOptions; + if (diveOptions>10) { + if (diveOptions>20) { + diveOptions-=20; + diveOptionsNotC-=20; + } else { + diveOptions -= 10; + diveOptionsNotC = 4; + } + useDIVING = 63; + } if ((useDIVING&1) != 0) { CbcHeuristicDiveVectorLength heuristicDV(*model); heuristicDV.setHeuristicName("DiveVectorLength"); - heuristicDV.setWhen(diveOptions); + heuristicDV.setWhen(diveOptionsNotC); + heuristicDV.setMaxIterations(majorIterations); if (diveOptions2) { - heuristicDV.setMaxIterations(majorIterations); heuristicDV.setPercentageToFix(0.0); heuristicDV.setMaxSimplexIterations(COIN_INT_MAX); heuristicDV.setMaxSimplexIterationsAtRoot(COIN_INT_MAX-(diveOptions2-1)); @@ -1481,9 +1507,9 @@ if ((useDIVING&2) != 0) { CbcHeuristicDiveGuided heuristicDG(*model); heuristicDG.setHeuristicName("DiveGuided"); - heuristicDG.setWhen(diveOptions); + heuristicDG.setWhen(diveOptionsNotC); + heuristicDG.setMaxIterations(majorIterations); if (diveOptions2) { - heuristicDG.setMaxIterations(majorIterations); heuristicDG.setPercentageToFix(0.0); heuristicDG.setMaxSimplexIterations(COIN_INT_MAX); heuristicDG.setMaxSimplexIterationsAtRoot(COIN_INT_MAX-(diveOptions2-1)); @@ -1493,9 +1519,9 @@ if ((useDIVING&4) != 0) { CbcHeuristicDiveFractional heuristicDF(*model); heuristicDF.setHeuristicName("DiveFractional"); - heuristicDF.setWhen(diveOptions); + heuristicDF.setWhen(diveOptionsNotC); + heuristicDF.setMaxIterations(majorIterations); if (diveOptions2) { - heuristicDF.setMaxIterations(majorIterations); heuristicDF.setPercentageToFix(0.0); heuristicDF.setMaxSimplexIterations(COIN_INT_MAX); heuristicDF.setMaxSimplexIterationsAtRoot(COIN_INT_MAX-(diveOptions2-1)); @@ -1506,8 +1532,8 @@ CbcHeuristicDiveCoefficient heuristicDC(*model); heuristicDC.setHeuristicName("DiveCoefficient"); heuristicDC.setWhen(diveOptions); + heuristicDC.setMaxIterations(majorIterations); if (diveOptions2) { - heuristicDC.setMaxIterations(majorIterations); heuristicDC.setPercentageToFix(0.0); heuristicDC.setMaxSimplexIterations(COIN_INT_MAX); heuristicDC.setMaxSimplexIterationsAtRoot(COIN_INT_MAX-(diveOptions2-1)); @@ -1517,9 +1543,9 @@ if ((useDIVING&16) != 0) { CbcHeuristicDiveLineSearch heuristicDL(*model); heuristicDL.setHeuristicName("DiveLineSearch"); - heuristicDL.setWhen(diveOptions); + heuristicDL.setWhen(diveOptionsNotC); + heuristicDL.setMaxIterations(majorIterations); if (diveOptions2) { - heuristicDL.setMaxIterations(majorIterations); heuristicDL.setPercentageToFix(0.0); heuristicDL.setMaxSimplexIterations(COIN_INT_MAX); heuristicDL.setMaxSimplexIterationsAtRoot(COIN_INT_MAX-(diveOptions2-1)); @@ -1529,9 +1555,9 @@ if ((useDIVING&32) != 0) { CbcHeuristicDivePseudoCost heuristicDP(*model); heuristicDP.setHeuristicName("DivePseudoCost"); - heuristicDP.setWhen(diveOptions /*+ diveOptions2*/); + heuristicDP.setWhen(diveOptionsNotC /*+ diveOptions2*/); + heuristicDP.setMaxIterations(majorIterations); if (diveOptions2) { - heuristicDP.setMaxIterations(majorIterations); heuristicDP.setPercentageToFix(0.0); heuristicDP.setMaxSimplexIterations(COIN_INT_MAX); heuristicDP.setMaxSimplexIterationsAtRoot(COIN_INT_MAX-(diveOptions2-1)); @@ -1588,16 +1614,35 @@ model->addHeuristic(&heuristic5) ; anyToDo = true; } - if (useCombine >= kType && useCombine <= kType + 1) { + if (useDW >= kType && useDW <= kType + 1) { + CbcHeuristicDW heuristic13(*model); + heuristic13.setHeuristicName("Dantzig-Wolfe"); + heuristic13.setNumberPasses(100); + heuristic13.setNumberBadPasses(10); + int numberIntegers=0; + const OsiSolverInterface * solver = model->solver(); + int numberColumns = solver->getNumCols(); + for (int i=0;iisInteger(i)) + numberIntegers++; + } + heuristic13.setNumberNeeded(CoinMin(200,numberIntegers/10)); + model->addHeuristic(&heuristic13); + anyToDo = true; + } + if (useCombine >= kType && (useCombine-1)%3 <= kType ) { CbcHeuristicLocal heuristic2(*model); heuristic2.setHeuristicName("combine solutions"); heuristic2.setFractionSmall(0.5); - heuristic2.setSearchType(1); + int searchType=1; + if (useCombine>3) + searchType += 10; // experiment + heuristic2.setSearchType(searchType); model->addHeuristic(&heuristic2); anyToDo = true; } - if ((useProximity >= kType && useProximity <= kType + 1)|| - (kType == 1 && useProximity >= 4)) { + if ((useProximity >= kType && useProximity <= kType + 1) || + (kType == 1 && useProximity > 3) ){ CbcHeuristicProximity heuristic2a(*model); heuristic2a.setHeuristicName("Proximity Search"); heuristic2a.setFractionSmall(9999999.0); @@ -1609,6 +1654,15 @@ // more print out and stronger feasibility pump if (useProximity==6) heuristic2a.setFeasibilityPumpOptions(-3); + } else { + int proximityNumber; + parameters_[whichParam(CBC_PARAM_STR_PROXIMITY, numberParameters_, parameters_)].currentOptionAsInteger(proximityNumber); + if (proximityNumber>0) { + heuristic2a.setNumberNodes(proximityNumber); + // more print out and stronger feasibility pump + if (proximityNumber>=300) + heuristic2a.setFeasibilityPumpOptions(-3); + } } model->addHeuristic(&heuristic2a); anyToDo = true; diff -Nru coinor-cbc-2.8.12/src/CbcSolverHeuristics.hpp coinor-cbc-2.9.9+repack1/src/CbcSolverHeuristics.hpp --- coinor-cbc-2.8.12/src/CbcSolverHeuristics.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSolverHeuristics.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcSolverHeuristics.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: CbcSolverHeuristics.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcSolver.hpp coinor-cbc-2.9.9+repack1/src/CbcSolver.hpp --- coinor-cbc-2.8.12/src/CbcSolver.hpp 2014-01-14 14:50:43.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSolver.hpp 2013-12-19 18:11:05.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcSolver.hpp 2004 2014-01-14 14:50:43Z forrest $ */ +/* $Id: CbcSolver.hpp 1998 2013-12-19 18:11:05Z forrest $ */ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -236,6 +236,24 @@ }; //############################################################################# +/// Structure to hold useful arrays +typedef struct { + // Priorities + int * priorities_; + // SOS priorities + int * sosPriority_; + // Direction to branch first + int * branchDirection_; + // Input solution + double * primalSolution_; + // Down pseudo costs + double * pseudoDown_; + // Up pseudo costs + double * pseudoUp_; +} CbcSolverUsefulData2; + +//############################################################################# + /** The CbcSolver class was taken out at a 9/12/09 meeting This is a feeble replacement. diff -Nru coinor-cbc-2.8.12/src/CbcSOS.cpp coinor-cbc-2.9.9+repack1/src/CbcSOS.cpp --- coinor-cbc-2.8.12/src/CbcSOS.cpp 2014-08-09 16:05:41.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSOS.cpp 2014-09-08 09:24:45.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcSOS.cpp 2055 2014-08-09 16:05:41Z forrest $ +// $Id: CbcSOS.cpp 2070 2014-09-08 09:24:45Z forrest $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -30,17 +30,18 @@ // Default Constructor CbcSOS::CbcSOS () : CbcObject(), - members_(NULL), - weights_(NULL), - shadowEstimateDown_(1.0), - shadowEstimateUp_(1.0), - downDynamicPseudoRatio_(0.0), - upDynamicPseudoRatio_(0.0), - numberTimesDown_(0), - numberTimesUp_(0), - numberMembers_(0), - sosType_(-1), - integerValued_(false) + members_(NULL), + weights_(NULL), + shadowEstimateDown_(1.0), + shadowEstimateUp_(1.0), + downDynamicPseudoRatio_(0.0), + upDynamicPseudoRatio_(0.0), + numberTimesDown_(0), + numberTimesUp_(0), + numberMembers_(0), + sosType_(-1), + integerValued_(false), + oddValues_(false) { } @@ -55,7 +56,8 @@ numberTimesDown_(0), numberTimesUp_(0), numberMembers_(numberMembers), - sosType_(type) + sosType_(type), + oddValues_(false) { id_ = identifier; integerValued_ = type == 1; @@ -73,6 +75,15 @@ } } if (numberMembers_) { + const OsiSolverInterface * solver = model_->solver(); + const double * lower = solver->getColLower(); + for (int i = 0; i < numberMembers_; i++) { + if (lower[which[i]]<0.0) { + oddValues_ = true; // mark as odd + } + } + + // check >= 0.0 members_ = new int[numberMembers_]; weights_ = new double[numberMembers_]; memcpy(members_, which, numberMembers_*sizeof(int)); @@ -116,6 +127,7 @@ numberMembers_ = rhs.numberMembers_; sosType_ = rhs.sosType_; integerValued_ = rhs.integerValued_; + oddValues_ = rhs.oddValues_; if (numberMembers_) { members_ = new int[numberMembers_]; weights_ = new double[numberMembers_]; @@ -151,6 +163,7 @@ numberMembers_ = rhs.numberMembers_; sosType_ = rhs.sosType_; integerValued_ = rhs.integerValued_; + oddValues_ = rhs.oddValues_; if (numberMembers_) { members_ = new int[numberMembers_]; weights_ = new double[numberMembers_]; @@ -187,13 +200,13 @@ int lastNonZero = -1; OsiSolverInterface * solver = model_->solver(); const double * solution = model_->testSolution(); - //const double * lower = solver->getColLower(); + const double * lower = solver->getColLower(); const double * upper = solver->getColUpper(); //double largestValue=0.0; double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance); double weight = 0.0; - double sum = 0.0; + double sum = 0.0; // check bounds etc double lastWeight = -1.0e100; @@ -206,7 +219,7 @@ if (lastWeight >= weights_[j] - 1.0e-7) throw CoinError("Weights too close together in SOS", "infeasibility", "CbcSOS"); - double value = CoinMax(0.0, solution[iColumn]); + double value = CoinMax(lower[iColumn], solution[iColumn]); sum += value; /* If we're not making assumptions about integrality, why check integerTolerance @@ -215,7 +228,8 @@ The calculation of weight looks to be a relic --- in the end, the value isn't used to calculate either the return value or preferredWay. */ - if (value > integerTolerance && upper[iColumn]) { + if (fabs(value) > integerTolerance && (upper[iColumn] > 0.0 || + oddValues_)) { // Possibly due to scaling a fixed variable might slip through if (value > upper[iColumn]) { value = upper[iColumn]; @@ -227,6 +241,16 @@ iColumn, j, value, upper[iColumn]); #endif } + if (value < lower[iColumn]) { + value = lower[iColumn]; + // Could change to #ifdef CBC_DEBUG +#ifndef NDEBUG + if (model_->messageHandler()->logLevel() > 2 && + value < lower[iColumn] - integerTolerance) + printf("** Variable %d (%d) has value %g and lower bound of %g\n", + iColumn, j, value, lower[iColumn]); +#endif + } weight += weights_[j] * value; if (firstNonZero < 0) firstNonZero = j; @@ -243,8 +267,10 @@ */ if (lastNonZero - firstNonZero >= sosType_) { // find where to branch - assert (sum > 0.0); - weight /= sum; + if (!oddValues_) + weight /= sum; + else + weight = 0.5*(weights_[firstNonZero]+weights_[lastNonZero]); if (info->defaultDual_ >= 0.0 && info->usefulRegion_ && info->columnStart_) { assert (sosType_ == 1); int iWhere; @@ -442,7 +468,7 @@ int lastNonZero = -1; OsiSolverInterface * solver = model_->solver(); const double * solution = model_->testSolution(); - //const double * lower = solver->getColLower(); + const double * lower = solver->getColLower(); const double * upper = solver->getColUpper(); double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance); @@ -451,9 +477,9 @@ for (j = 0; j < numberMembers_; j++) { int iColumn = members_[j]; - double value = CoinMax(0.0, solution[iColumn]); + double value = CoinMax(lower[iColumn], solution[iColumn]); sum += value; - if (value > integerTolerance && upper[iColumn]) { + if (fabs(value) > integerTolerance && (upper[iColumn] || oddValues_)) { weight += weights_[j] * value; if (firstNonZero < 0) firstNonZero = j; @@ -464,16 +490,18 @@ if (lastNonZero - firstNonZero < sosType_) { for (j = 0; j < firstNonZero; j++) { int iColumn = members_[j]; + solver->setColLower(iColumn, 0.0); solver->setColUpper(iColumn, 0.0); } for (j = lastNonZero + 1; j < numberMembers_; j++) { int iColumn = members_[j]; + solver->setColLower(iColumn, 0.0); solver->setColUpper(iColumn, 0.0); } } else { for (j = 0; j < numberMembers_; j++) { int iColumn = members_[j]; - solver->setColUpper(iColumn, 0.0); + solver->setColUpper(iColumn, 0.0); // make infeasible solver->setColLower(iColumn, 1.0); } } @@ -509,6 +537,7 @@ double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance); //OsiSolverInterface * solver = model_->solver(); + const double * lower = solver->getColLower(); const double * upper = solver->getColUpper(); int firstNonFixed = -1; int lastNonFixed = -1; @@ -518,13 +547,13 @@ double sum = 0.0; for (j = 0; j < numberMembers_; j++) { int iColumn = members_[j]; - if (upper[iColumn]) { - double value = CoinMax(0.0, solution[iColumn]); + if (upper[iColumn] || oddValues_) { + double value = CoinMax(lower[iColumn], solution[iColumn]); sum += value; if (firstNonFixed < 0) firstNonFixed = j; lastNonFixed = j; - if (value > integerTolerance) { + if (fabs(value) > integerTolerance) { weight += weights_[j] * value; if (firstNonZero < 0) firstNonZero = j; @@ -534,13 +563,16 @@ } assert (lastNonZero - firstNonZero >= sosType_) ; // find where to branch - assert (sum > 0.0); - weight /= sum; + if (!oddValues_) + weight /= sum; + else + weight = 0.5*(weights_[firstNonZero]+weights_[lastNonZero]); int iWhere; double separator = 0.0; for (iWhere = firstNonZero; iWhere < lastNonZero; iWhere++) if (weight < weights_[iWhere+1]) break; + assert (iWhere= sosType_) ; // find where to branch - assert (sum > 0.0); - weight /= sum; + if (!oddValues_) + weight /= sum; + else + weight = 0.5*(weights_[firstNonZero]+weights_[lastNonZero]); // down branch fixes ones above weight to 0 int iWhere; int iDownStart = 0; @@ -853,16 +887,20 @@ break; } assert (i < numberMembers); - for (; i < numberMembers; i++) + for (; i < numberMembers; i++) { + solver->setColLower(which[i], 0.0); solver->setColUpper(which[i], 0.0); + } way_ = 1; // Swap direction } else { int i; for ( i = 0; i < numberMembers; i++) { - if (weights[i] >= separator_) + if (weights[i] >= separator_) { break; - else + } else { + solver->setColLower(which[i], 0.0); solver->setColUpper(which[i], 0.0); + } } assert (i < numberMembers); way_ = -1; // Swap direction @@ -880,7 +918,7 @@ branchState is -1 for 'down' +1 for 'up' */ void CbcSOSBranchingObject::fix(OsiSolverInterface * solver, - double * /*lower*/, double * upper, + double * lower, double * upper, int branchState) const { int numberMembers = set_->numberMembers(); @@ -897,6 +935,8 @@ } assert (i < numberMembers); for (; i < numberMembers; i++) { + solver->setColLower(which[i], 0.0); + lower[which[i]] = 0.0; solver->setColUpper(which[i], 0.0); upper[which[i]] = 0.0; } @@ -906,6 +946,8 @@ if (weights[i] >= separator_) { break; } else { + solver->setColLower(which[i], 0.0); + lower[which[i]] = 0.0; solver->setColUpper(which[i], 0.0); upper[which[i]] = 0.0; } diff -Nru coinor-cbc-2.8.12/src/CbcSOS.hpp coinor-cbc-2.9.9+repack1/src/CbcSOS.hpp --- coinor-cbc-2.8.12/src/CbcSOS.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSOS.hpp 2014-09-08 09:24:45.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcSOS.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcSOS.hpp 2070 2014-09-08 09:24:45Z forrest $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -179,6 +179,8 @@ int sosType_; /// Whether integer valued bool integerValued_; + /// Whether odd values e.g. negative + bool oddValues_; }; /** Branching object for Special ordered sets diff -Nru coinor-cbc-2.8.12/src/CbcSubProblem.cpp coinor-cbc-2.9.9+repack1/src/CbcSubProblem.cpp --- coinor-cbc-2.8.12/src/CbcSubProblem.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSubProblem.cpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcSubProblem.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcSubProblem.cpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcSubProblem.hpp coinor-cbc-2.9.9+repack1/src/CbcSubProblem.hpp --- coinor-cbc-2.8.12/src/CbcSubProblem.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSubProblem.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: CbcSubProblem.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: CbcSubProblem.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcSymmetry.cpp coinor-cbc-2.9.9+repack1/src/CbcSymmetry.cpp --- coinor-cbc-2.8.12/src/CbcSymmetry.cpp 1970-01-01 00:00:00.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSymmetry.cpp 2015-07-07 21:16:56.000000000 +0000 @@ -0,0 +1,1427 @@ +/* $Id: CbcSymmetry.cpp 925 2012-11-27 19:11:04Z stefan $ + * + * hacked from CouenneSymmetry.cpp + * Name: CbcSymmetry.cpp + * Author: Jim Ostrowski (the good bits - rest JJHF) + * Purpose: methods for exploiting symmetry + * Date: October 13, 2010 + * + * This file is licensed under the Eclipse Public License (EPL) + */ +//#define PRINT_MORE 1 + +#include "CbcConfig.h" + +#ifdef COIN_HAS_NTY + +extern "C" { +#include "nauty.h" +#include "nausparse.h" +#ifdef NTY_TRACES +#include "traces.h" +#endif +} + +#include +#include +#include +#include +#include +#include + +#include "CbcSymmetry.hpp" +#include "CbcBranchingObject.hpp" +#include "CoinTime.hpp" +#define NAUTY_MAX_LEVEL 0 +#if NAUTY_MAX_LEVEL +extern int nauty_maxalllevel; +#endif +/* Deliberately not threadsafe to save effort + Just for statistics + and not worth gathering across threads + can redo later + */ +static int nautyBranchCalls_ = 0; +static int lastNautyBranchCalls_ = 0; +static int nautyBranchSucceeded_ = 0; +static int nautyFixCalls_ = 0; +static int lastNautyFixCalls_ = 0; +static int nautyFixSucceeded_ = 0; +static double nautyTime_ = 0.0; +static double nautyFixes_= 0.0; +static double nautyOtherBranches_ = 0.0; + +void CbcSymmetry::Node::node(int i, double c , double l, double u, int cod, int s){ + index = i; + coeff = c; + lb = l; + ub = u; + color = -1; + code = cod; + sign = s; +} + +inline bool CbcSymmetry::compare (register Node &a, register Node &b) const { + if(a.get_code() == b.get_code() ) + if(a.get_coeff() == b.get_coeff() ) + if(a.get_sign() == b.get_sign() ) + if( fabs ( a.get_lb() - b.get_lb() ) <= COUENNE_HACKED_EPS ) + if( fabs ( a.get_ub() - b.get_ub() ) <= COUENNE_HACKED_EPS ) + return 1; + return 0; +} + +void CbcSymmetry::Compute_Symmetry() const{ + + + std::sort(node_info_. begin (), node_info_. end (), node_sort); + + for (std::vector :: iterator i = node_info_. begin (); i != node_info_. end (); ++i) + (*i).color_vertex(-1); + + int color = 1; + for (std::vector :: iterator i = node_info_. begin (); i != node_info_. end (); ++i) { + if( (*i).get_color() == -1){ + (*i).color_vertex(color); +#ifdef PRINT_MORE + printf ("Graph vertex %d is given color %d\n", (*i).get_index(), color); +#endif + nauty_info_ -> color_node((*i).get_index(), color); + for (std::vector :: iterator j = i+1; j != node_info_. end (); ++j) + if( compare( (*i) , (*j) ) ==1){ + (*j).color_vertex(color); + nauty_info_ -> color_node((*j).get_index(),color); +#ifdef PRINT_MORE + printf ("Graph vertex %d is given color %d, the same as vertex %d\n", (*j).get_index(), color, (*i).get_index()); +#endif + } + // else + // j = node_info_. end(); + color++; + } + } + + //Print_Orbits (); + nauty_info_ -> computeAuto(); + //Print_Orbits (); +} + +int +CbcSymmetry::statsOrbits(CbcModel * model, int type) const +{ + char general[200]; + int returnCode=0; + bool printSomething=true; + if (type) { + double branchSuccess=0.0; + if (nautyBranchSucceeded_) + branchSuccess = nautyOtherBranches_/nautyBranchSucceeded_; + double fixSuccess=0.0; + if (nautyFixSucceeded_) + fixSuccess = nautyFixes_/nautyFixSucceeded_; + if (nautyBranchCalls_>lastNautyBranchCalls_|| + nautyFixCalls_>lastNautyFixCalls_) { + sprintf(general,"Orbital branching tried %d times, succeeded %d times - average extra %7.3f, fixing %d times (%d, %7.3f)", + nautyBranchCalls_,nautyBranchSucceeded_,branchSuccess, + nautyFixCalls_,nautyFixSucceeded_,fixSuccess); + lastNautyBranchCalls_=nautyBranchCalls_; + lastNautyFixCalls_=nautyFixCalls_; + } else { + printSomething=false; + } + } else { + returnCode = nauty_info_->getNumGenerators(); + if (!nauty_info_->errorStatus()) { + if (returnCode && numberUsefulOrbits_) { + sprintf (general,"Nauty: %d orbits (%d useful covering %d variables), %d generators, group size: %g - dense size %d, sparse %d - took %g seconds", + nauty_info_->getNumOrbits(),numberUsefulOrbits_,numberUsefulObjects_, + nauty_info_ -> getNumGenerators () , + nauty_info_ -> getGroupSize (), + whichOrbit_[0],whichOrbit_[1],nautyTime_); + } else { + if ((model->moreSpecialOptions2()&(128|256))!=(128|256)) + sprintf(general,"Nauty did not find any useful orbits in time %g",nautyTime_); + else + sprintf(general,"Nauty did not find any useful orbits - but keeping Nauty on"); + } + } else { + // error + sprintf(general,"Nauty failed with error code %d (%g seconds)", + nauty_info_->errorStatus(),nautyTime_); + model->setMoreSpecialOptions2(model->moreSpecialOptions2()&~(128|256)); + } + } + if (printSomething) + model->messageHandler()->message(CBC_GENERAL, + model->messages()) + << general << CoinMessageEol ; + return returnCode; +} + +void CbcSymmetry::Print_Orbits () const { + + //printf ("num gens = %d, num orbits = %d \n", nauty_info_ -> getNumGenerators(), nauty_info_ -> getNumOrbits() ); + + std::vector > *new_orbits = nauty_info_->getOrbits(); + + printf ("Nauty: %d generators, group size: %.0g", + // nauty_info_->getNumOrbits(), + nauty_info_ -> getNumGenerators () , + nauty_info_ -> getGroupSize ()); + + int nNonTrivialOrbits = 0; + + for (unsigned int i = 0; i < new_orbits -> size(); i++) { + if ((*new_orbits)[i].size() > 1) + nNonTrivialOrbits++; + else continue; + + // int orbsize = (*new_orbits)[i].size(); + // printf( "Orbit %d [size: %d] [", i, orbsize); + // copy ((*new_orbits)[i].begin(), (*new_orbits)[i].end(), + // std::ostream_iterator(std::cout, " ")); + // printf("] \n"); + } + + printf (" (%d non-trivial orbits).\n", nNonTrivialOrbits); + +#if 1 + if (nNonTrivialOrbits) { + + int orbCnt = 0; + + std::vector > *orbits = nauty_info_ -> getOrbits (); + + for (std::vector >::iterator i = orbits -> begin (); i != orbits -> end (); ++i) { + + printf ("Orbit %d: ", orbCnt++); + + for (std::vector::iterator j = i -> begin (); j != i -> end (); ++j) + printf (" %d", *j); + + printf ("\n"); + } + } +#endif + + +#if 0 + if (nNonTrivialOrbits) + for (int i=0; i< nVars (); i++) { + + std::vector< int > *branch_orbit = Find_Orbit (i); + + if (branch_orbit -> size () > 1) { + printf ("x%04d: ", i); + + for (std::vector::iterator it = branch_orbit -> begin (); it != branch_orbit -> end (); ++it) + printf ("%d ", *it); + printf ("\n"); + } + } +#endif + delete new_orbits; +} +void +CbcSymmetry::fillOrbits() +{ + for (int i=0;i > *orbits = nauty_info_ -> getOrbits (); + + for (std::vector >::iterator i = orbits -> begin (); i != orbits -> end (); ++i) { + int nUseful=0; + int jColumn=-2; + for (std::vector::iterator j = i -> begin (); j != i -> end (); ++j) { + int iColumn=*j; + if (iColumn1) { + numberUsefulOrbits_++; + numberUsefulObjects_ += nUseful; + } else if (jColumn>=0) { + assert (nUseful); + whichOrbit_[jColumn]=-2; + } + } + delete orbits; +} +int +CbcSymmetry::largestOrbit(const double * lower, const double * upper) const +{ + int * counts = new int[numberUsefulOrbits_]; + memset(counts,0,numberUsefulOrbits_*sizeof(int)); + for (int i=0;i=0) { + if (lower[i]==0.0&&upper[i]==1.0) + counts[iOrbit]++; + } + } + int iOrbit=-1; + int maxOrbit=0; + for (int i=0;imaxOrbit) { + maxOrbit=counts[i]; + iOrbit=i; + } + } + delete [] counts; + return iOrbit; +} + +std::vector *CbcSymmetry::Find_Orbit(int index) const{ + + std::vector *orbit = new std::vector ; + int which_orbit = -1; + std::vector > *new_orbits = nauty_info_->getOrbits(); + + for (unsigned int i = 0; i < new_orbits -> size(); i++) { + for (unsigned int j = 0; j < (*new_orbits)[i].size(); j++) { + // for (std::vector :: iterator j = new_orbits[i].begin(); new_orbits[i].end(); ++j){ + if( (*new_orbits)[i][j] == index) + which_orbit = i; + } + } + + // for (std::vector :: iterator j = new_orbits[which_orbit].begin(); new_orbits[which_orbit].end(), ++j) + for (unsigned int j = 0; j < (*new_orbits)[which_orbit].size(); j++) + orbit -> push_back ((*new_orbits)[which_orbit][j]); + + delete new_orbits; + + return orbit; +} + + +void CbcSymmetry::ChangeBounds (const double * new_lb, const double * new_ub, + int num_cols, bool justFixedAtOne) const { + if (justFixedAtOne) + nautyFixCalls_++; + else + nautyBranchCalls_++; + std::sort(node_info_. begin (), node_info_. end (), index_sort); + + for (int i = 0; i < num_cols; i++) { + // printf("Var %d lower bound: %f upper bound %f \n", i, new_lb[i], new_ub[i]); + + assert (node_info_[i].get_index () == i); + double newLower = new_lb[i]; + double newUpper = new_ub[i]; + if (justFixedAtOne) { + // free up all fixed at zero + if (!newLower) + newUpper = 1.0; + } + node_info_[i ].bounds ( newLower , newUpper ); + //printf("Var %d INPUT lower bound: %f upper bound %f \n", i, node_info_[i].get_lb(), node_info_[i].get_ub()); + } +} +void CbcSymmetry::setupSymmetry (const OsiSolverInterface & solver) { + double startCPU = CoinCpuTime (); + const double *objective = solver.getObjCoefficients() ; + const double *columnLower = solver.getColLower() ; + const double *columnUpper = solver.getColUpper() ; + int numberColumns = solver.getNumCols() ; + int numberRows = solver.getNumRows(); + int iRow, iColumn; + + // Row copy + CoinPackedMatrix matrixByRow(*solver.getMatrixByRow()); + const double * elementByRow = matrixByRow.getElements(); + const int * column = matrixByRow.getIndices(); + const CoinBigIndex * rowStart = matrixByRow.getVectorStarts(); + const int * rowLength = matrixByRow.getVectorLengths(); + + const double * rowLower = solver.getRowLower(); + const double * rowUpper = solver.getRowUpper(); + // // Find Coefficients + + /// initialize nauty + + int num_affine = 0; + + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + if (objective[iColumn] && objective[iColumn]!=1.0) + num_affine++; + } + for (iRow = 0; iRow < numberRows; iRow++) { + for (CoinBigIndex j = rowStart[iRow]; + j < rowStart[iRow] + rowLength[iRow]; j++) { + int jColumn = column[j]; + double value = elementByRow[j]; + if (value!=1.0) + num_affine++; + } + } + + // Create Nauty object + + int coef_count= numberRows + numberColumns +1; + int nc = num_affine + coef_count; + // create graph (part 1) + + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + Node var_vertex; + var_vertex.node(iColumn,0.0,columnLower[iColumn],columnUpper[iColumn],-1,-1 ); + node_info_.push_back(var_vertex); + } + // objective + int index = numberColumns; + { + Node vertex; + vertex.node( index , 0.0 , -COIN_DBL_MAX, COIN_DBL_MAX, + COUENNE_HACKED_EXPRGROUP, 0); + node_info_.push_back( vertex); + } + + // compute space for sparse + size_t * v = NULL; + int * d = NULL; + int * e = NULL; + bool sparse=false; + double spaceDense = nc+WORDSIZE-1; + spaceDense *= nc+WORDSIZE-1; + spaceDense /= WORDSIZE; + int spaceSparse = 0; + { + size_t numberElements = 0; + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + double value = objective[iColumn]; + if (value) { + if (value==1.0) { + numberElements+=2; + } else { + numberElements+=4; + coef_count ++; + } + } + } + for (iRow = 0; iRow < numberRows; iRow++) { + for (CoinBigIndex j = rowStart[iRow]; + j < rowStart[iRow] + rowLength[iRow]; j++) { + int jColumn = column[j]; + double value = elementByRow[j]; + if (value==1.0) { + numberElements+=2; + } else { + numberElements+=4; + coef_count ++; + } + } + } + spaceSparse = 2*nc+numberElements; + //printf("Space for sparse is %d for dense %g\n", + // spaceSparse,spaceDense); +#ifdef NTY_TRACES + bool goSparse = true; +#else + bool goSparse = (spaceSparseaddElement(index,iColumn); + nauty_info_->addElement(iColumn,index); + } else { + Node coef_vertex; + coef_vertex.node( coef_count, value, value, value, -2, 0 ); + node_info_.push_back(coef_vertex); + nauty_info_->addElement(index, coef_count); + nauty_info_->addElement(coef_count, index); + nauty_info_->addElement(coef_count, iColumn); + nauty_info_->addElement(iColumn, coef_count); + coef_count ++; + } + } + } + index++; + for (iRow = 0; iRow < numberRows; iRow++) { + Node vertex; + vertex.node( index , 0.0 , rowLower[iRow], rowUpper[iRow], + COUENNE_HACKED_EXPRGROUP, 0); + node_info_.push_back( vertex); + for (CoinBigIndex j = rowStart[iRow]; + j < rowStart[iRow] + rowLength[iRow]; j++) { + int jColumn = column[j]; + double value = elementByRow[j]; + if (value==1.0) { + nauty_info_->addElement(index,jColumn); + nauty_info_->addElement(jColumn,index); + } else { + Node coef_vertex; + coef_vertex.node( coef_count, value, value, value, -2, 0 ); + node_info_.push_back(coef_vertex); + nauty_info_->addElement(index, coef_count); + nauty_info_->addElement(coef_count, index); + nauty_info_->addElement(coef_count, jColumn); + nauty_info_->addElement(jColumn, coef_count); + coef_count ++; + } + } + index++; + } + } + numberColumns_ = numberColumns; + whichOrbit_ = new int [2*numberColumns_]; + nautyBranchCalls_ = 0; + nautyBranchSucceeded_ = 0; + nautyFixCalls_ = 0; + nautyFixSucceeded_ = 0; + nautyTime_ = 0.0; + nautyFixes_= 0.0; + nautyOtherBranches_ = 0.0; + Compute_Symmetry (); + fillOrbits(); + //whichOrbit_[2]=numberUsefulOrbits_; + //Print_Orbits (); + // stats in array + if (spaceDensegetNumCols(); + char * status = new char [numberColumns]; + ChangeBounds(solver->getColLower(), + solver->getColUpper(), + solver->getNumCols(),true); + Compute_Symmetry(); + fillOrbits(); + int n=0; + //#define PRINT_MORE 1 + const int * alternativeOrbits = whichOrbit(); + if (alternativeOrbits) { + for (int i=0;igetColUpper()[i]) { + if (solver->getColLower()[i]) { + type='1'; + } else { + double value=solver->getColSolution()[i]; + if (value<0.0001) + type='L'; + else if (value>0.9999) + type='U'; + else + type='X'; + } + } + status[i]=type; + } + n=0; + for (int i=0;i1 + printf("In alternative orbit %d - %d free (%c), %d fixed to 0\n", + iOrbit,i,status[i],j); +#endif + status[i]='0'; // can fix on both branches + solver->setColUpper(i,0.0); + n++; + break; + } + } + } + } + } + delete [] status; + if (n) { + nautyFixSucceeded_++; + nautyFixes_ += n; +#if PRINT_MORE + printf("%d orbital fixes\n",n); +#endif + } + return n; +} +// Default Constructor +CbcSymmetry::CbcSymmetry () + : nauty_info_(NULL), + numberColumns_(0), + numberUsefulOrbits_(0), + numberUsefulObjects_(0), + whichOrbit_(NULL) +{ +} +// Copy constructor +CbcSymmetry::CbcSymmetry ( const CbcSymmetry & rhs) +{ + node_info_ = rhs.node_info_; + nauty_info_ = new CbcNauty(*rhs.nauty_info_); + numberUsefulOrbits_ = rhs.numberUsefulOrbits_; + numberUsefulObjects_ = rhs.numberUsefulObjects_; + numberColumns_ = rhs.numberColumns_; + if (rhs.whichOrbit_) + whichOrbit_=CoinCopyOfArray(rhs.whichOrbit_,numberColumns_); + else + whichOrbit_ = NULL; +} + +// Assignment operator +CbcSymmetry & +CbcSymmetry::operator=( const CbcSymmetry & rhs) +{ + if (this != &rhs) { + delete nauty_info_; + node_info_ = rhs.node_info_; + nauty_info_ = new CbcNauty(*rhs.nauty_info_); + delete [] whichOrbit_; + numberColumns_ = rhs.numberColumns_; + numberUsefulOrbits_ = rhs.numberUsefulOrbits_; + numberUsefulObjects_ = rhs.numberUsefulObjects_; + if (rhs.whichOrbit_) + whichOrbit_=CoinCopyOfArray(rhs.whichOrbit_,numberColumns_); + else + whichOrbit_ = NULL; + } + return *this; +} + +// Destructor +CbcSymmetry::~CbcSymmetry () +{ + delete nauty_info_; + delete [] whichOrbit_; +} + +CbcNauty::CbcNauty(int vertices, const size_t * v, const int * d, const int * e) +{ + //printf("Need sparse nauty - wordsize %d\n",WORDSIZE); + n_ = vertices; + m_ = (n_ + WORDSIZE - 1)/WORDSIZE; + if (v) + nel_ = v[n_]; + else + nel_ = 0; + + //printf ("size of long = %d (%d)\nwordsize = %d\nn,m = %d,%d\n", + // SIZEOF_LONG, sizeof (long), WORDSIZE, n_, m_); + + nauty_check (WORDSIZE, m_, n_, NAUTYVERSIONID); + + /// Apparently sizes are skewed on 64bit machines + +#define MULTIPLIER 1 + + if (!nel_) { + G_ = (graph *) malloc(MULTIPLIER * m_ * n_ * sizeof(int)); + GSparse_ = NULL; + } else { + G_ = NULL; + GSparse_ = (sparsegraph *) malloc(sizeof(sparsegraph)); + SG_INIT(*GSparse_); + SG_ALLOC(*GSparse_,n_,nel_,"malloc"); + GSparse_->nv = n_; /* Number of vertices */ + GSparse_->nde = nel_; + } + lab_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int)); + ptn_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int)); + active_ = NULL; + orbits_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int)); +#ifndef NTY_TRACES + options_ = (optionblk *) malloc(MULTIPLIER * sizeof(optionblk)); + stats_ = (statsblk *) malloc(MULTIPLIER * sizeof(statsblk)); +#else + options_ = (TracesOptions *) malloc(MULTIPLIER * sizeof(TracesOptions)); + stats_ = (TracesStats *) malloc(MULTIPLIER * sizeof(TracesStats)); +#endif + worksize_ = 100*m_; + workspace_ = (setword *) malloc(MULTIPLIER * worksize_*sizeof(setword)); + canonG_ = NULL; + if ((G_ == 0&&GSparse_ == 0) || lab_ == 0 || ptn_ == 0 || + orbits_ == 0 || options_ == 0 || stats_ == 0 || + workspace_ == 0) assert(0); + + // Zero allocated memory + if (G_) { + memset(G_, 0, m_*n_*sizeof(int)); + } else { + //for (int i=0;iv[i]=v[i]; + //} + memcpy(GSparse_->v,v,n_*sizeof(size_t)); + memcpy(GSparse_->d,d,n_*sizeof(int)); + memcpy(GSparse_->e,e,nel_*sizeof(int)); + } + memset(lab_, 0, n_*sizeof(int)); + memset(ptn_, 0, n_*sizeof(int)); + memset(orbits_, 0, n_*sizeof(int)); + memset(workspace_, 0, worksize_*sizeof(setword)); +#ifndef NTY_TRACES + memset(options_, 0,MULTIPLIER * sizeof(optionblk)); +#else + memset(options_, 0,MULTIPLIER * sizeof(TracesOptions)); +#endif + + // Set the options you want +#ifndef NTY_TRACES + options_->getcanon = FALSE; + options_->digraph = FALSE; + options_->writeautoms = FALSE; + options_->writemarkers = FALSE; + options_->defaultptn = TRUE; + options_->cartesian = FALSE; + options_->linelength = 78; + options_->outfile = NULL; + options_->userrefproc = NULL; + options_->userautomproc = NULL; + options_->userlevelproc = NULL; + options_->usernodeproc = NULL; + // options_->usertcellproc = NULL; + options_->invarproc = NULL; + options_->tc_level = 100; + options_->mininvarlevel = 0; + options_->maxinvarlevel = 1; + options_->invararg = 0; + options_->dispatch = &dispatch_graph; +#else + options_->getcanon = FALSE; + options_->writeautoms = FALSE; + options_->cartesian = FALSE; + options_->digraph = FALSE; + options_->defaultptn = TRUE; + options_->linelength = 78; +#endif + if (G_) { + // Make an empty graph + for (int j = 0; j < n_; j++) { + set *gv = GRAPHROW(G_, j, m_); + EMPTYSET(gv, m_); + } + } + + vstat_ = new int[n_]; + clearPartitions(); + afp_ = NULL; +} + +CbcNauty::~CbcNauty() +{ + if (G_) free(G_); + if (GSparse_) { + SG_FREE(*GSparse_); + free(GSparse_); + } + if (lab_) free(lab_); + if (ptn_) free(ptn_); + if (active_) free(active_); + if (orbits_) free(orbits_); + if (options_) free(options_); + if (stats_) free(stats_); + if (workspace_) free(workspace_); + if (canonG_) free(canonG_); + if (vstat_) delete [] vstat_; +} +// Copy constructor +CbcNauty::CbcNauty ( const CbcNauty & rhs) +{ + n_ = rhs.n_; + m_ = rhs.m_; + nel_ = rhs.nel_; + G_ = NULL; + GSparse_ = NULL; + if (!nel_) { + G_ = (graph *) malloc(MULTIPLIER * m_ * n_ * sizeof(int)); + } else { + GSparse_ = (sparsegraph *) malloc(sizeof(sparsegraph)); + SG_INIT(*GSparse_); + SG_ALLOC(*GSparse_,n_,nel_,"malloc"); + GSparse_->nv = n_; /* Number of vertices */ + GSparse_->nde = nel_; + } + lab_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int)); + ptn_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int)); + orbits_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int)); +#ifndef NTY_TRACES + options_ = (optionblk *) malloc(MULTIPLIER * sizeof(optionblk)); + stats_ = (statsblk *) malloc(MULTIPLIER * sizeof(statsblk)); +#else + options_ = (TracesOptions *) malloc(MULTIPLIER * sizeof(TracesOptions)); + stats_ = (TracesStats *) malloc(MULTIPLIER * sizeof(TracesStats)); +#endif + worksize_ = 100*m_; + workspace_ = (setword *) malloc(MULTIPLIER * worksize_*sizeof(setword)); + vstat_ = new int[n_]; + canonG_ = NULL; + if ((G_ == 0 && GSparse_ == 0) || lab_ == 0 || ptn_ == 0 || + orbits_ == 0 || options_ == 0 || stats_ == 0 || + workspace_ == 0) assert(0); + + // Copy allocated memory + if (G_) { + memcpy(G_, rhs.G_, m_*n_*sizeof(int)); + } else { + memcpy(GSparse_->v,rhs.GSparse_->v,n_*sizeof(size_t)); + memcpy(GSparse_->d,rhs.GSparse_->d,n_*sizeof(int)); + memcpy(GSparse_->e,rhs.GSparse_->e,nel_*sizeof(int)); + } + memcpy(lab_, rhs.lab_, n_*sizeof(int)); + memcpy(ptn_, rhs.ptn_, n_*sizeof(int)); + memcpy(orbits_, rhs.orbits_, n_*sizeof(int)); + memcpy(workspace_, rhs.workspace_, worksize_*sizeof(setword)); +#ifndef NTY_TRACES + memcpy(options_, rhs.options_, MULTIPLIER * sizeof(optionblk)); + memcpy(stats_, rhs.stats_, MULTIPLIER * sizeof(statsblk)); +#else + memcpy(options_, rhs.options_,MULTIPLIER * sizeof(TracesOptions)); + memcpy(stats_, rhs.stats_, MULTIPLIER * sizeof(TracesStats)); +#endif + memcpy(vstat_,rhs.vstat_,n_*sizeof(int)); + + // ? clearPartitions(); + active_ = NULL; + afp_ = rhs.afp_; // ? no copy ? +} + +// Assignment operator +CbcNauty & +CbcNauty::operator=( const CbcNauty & rhs) +{ + if (this != &rhs) { + if (G_) free(G_); + if (GSparse_) { + SG_FREE(*GSparse_); + free(GSparse_); + } + if (lab_) free(lab_); + if (ptn_) free(ptn_); + if (active_) free(active_); + if (orbits_) free(orbits_); + if (options_) free(options_); + if (stats_) free(stats_); + if (workspace_) free(workspace_); + if (canonG_) free(canonG_); + if (vstat_) delete [] vstat_; + { + n_ = rhs.n_; + m_ = rhs.m_; + nel_ = rhs.nel_; + G_ = NULL; + GSparse_ = NULL; + if (!nel_) { + G_ = (graph *) malloc(MULTIPLIER * m_ * n_ * sizeof(int)); + } else { + GSparse_ = (sparsegraph *) malloc(sizeof(sparsegraph)); + SG_INIT(*GSparse_); + SG_ALLOC(*GSparse_,n_,nel_,"malloc"); + GSparse_->nv = n_; /* Number of vertices */ + GSparse_->nde = nel_; + } + lab_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int)); + ptn_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int)); + orbits_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int)); +#ifndef NTY_TRACES + options_ = (optionblk *) malloc(MULTIPLIER * sizeof(optionblk)); + stats_ = (statsblk *) malloc(MULTIPLIER * sizeof(statsblk)); +#else + options_ = (TracesOptions *) malloc(MULTIPLIER * sizeof(TracesOptions)); + stats_ = (TracesStats *) malloc(MULTIPLIER * sizeof(TracesStats)); +#endif + worksize_ = 100*m_; + workspace_ = (setword *) malloc(MULTIPLIER * worksize_*sizeof(setword)); + vstat_ = new int[n_]; + canonG_ = NULL; + if ((G_ == 0 && GSparse_ == 0) || lab_ == 0 || ptn_ == 0 || + orbits_ == 0 || options_ == 0 || stats_ == 0 || + workspace_ == 0) assert(0); + + // Copy allocated memory + if (!nel_) { + memcpy(G_, rhs.G_, m_*n_*sizeof(int)); + } else { + memcpy(GSparse_->v,rhs.GSparse_->v,n_*sizeof(size_t)); + memcpy(GSparse_->d,rhs.GSparse_->d,n_*sizeof(int)); + memcpy(GSparse_->e,rhs.GSparse_->e,nel_*sizeof(int)); + } + memcpy(lab_, rhs.lab_, n_*sizeof(int)); + memcpy(ptn_, rhs.ptn_, n_*sizeof(int)); + memcpy(orbits_, rhs.orbits_, n_*sizeof(int)); + memcpy(workspace_, rhs.workspace_, worksize_*sizeof(setword)); +#ifndef NTY_TRACES + memcpy(options_, rhs.options_, MULTIPLIER * sizeof(optionblk)); + memcpy(stats_, rhs.stats_, MULTIPLIER * sizeof(statsblk)); +#else + memcpy(options_, rhs.options_,MULTIPLIER * sizeof(TracesOptions)); + memcpy(stats_, rhs.stats_, MULTIPLIER * sizeof(TracesStats)); +#endif + memcpy(vstat_,rhs.vstat_,n_*sizeof(int)); + + // ? clearPartitions(); + active_ = NULL; + afp_ = rhs.afp_; // ? no copy ? + } + } + return *this; +} + +void +CbcNauty::addElement(int ix, int jx) +{ + // Right now die if bad index. Can throw exception later + //printf("addelement %d %d \n", ix, jx); + assert(ix < n_ && jx < n_); + if(ix != jx){ //No Loops + set *gv = GRAPHROW(G_, ix, m_); + ADDELEMENT(gv, jx); + set *gv2 = GRAPHROW(G_, jx, m_); + ADDELEMENT(gv2, ix); + autoComputed_ = false; + } +} + +void +CbcNauty::clearPartitions() +{ + for (int j = 0; j < n_; j++) { + vstat_[j] = 1; + //printf("vstat %d = %d", j, vstat_[j]); + } + + autoComputed_ = false; +} + +void +CbcNauty::computeAuto() +{ + + // if (autoComputed_) return; + + //double startCPU = CoinCpuTime (); + + options_->defaultptn = FALSE; + + // Here we only implement the partitions + // [ fix1 | fix0 (union) free | constraints ] + int ix = 0; + + for( int color = 1; color <= n_; color++){ + for (int j = 0; j < n_; j++) { + if (vstat_[j] == color) { + lab_[ix] = j; + ptn_[ix] = color; + ix++; + } + } + if (ix > 0) ptn_[ix-1] = 0; + } + + /* + for (int j = 0; j < n_; j++) + printf("ptn %d = %d lab = %d \n", j, ptn_[j], lab_[j]); + */ + + // Should be number of columns + assert(ix == n_); + // Now the constraints if needed + + // Compute Partition + + if (G_) { +#ifndef NTY_TRACES + nauty(G_, lab_, ptn_, active_, orbits_, options_, + stats_, workspace_, worksize_, m_, n_, canonG_); +#else + abort(); +#endif + } else { +#if NAUTY_MAX_LEVEL + nauty_maxalllevel=NAUTY_MAX_LEVEL; +#endif +#ifndef NTY_TRACES + options_->dispatch = &dispatch_sparse; + sparsenauty(GSparse_, lab_, ptn_, orbits_, options_, + stats_, NULL); +#else + //options_->dispatch = &dispatch_sparse; + Traces(GSparse_, lab_, ptn_, orbits_, options_, + stats_, NULL); +#endif + } + autoComputed_ = true; + + //double endCPU = CoinCpuTime (); + + //nautyTime_ += endCPU - startCPU; + // Need to make sure all generators are written + if (afp_) fflush(afp_); +} + +void +CbcNauty::deleteElement(int ix, int jx) +{ + // Right now die if bad index. Can throw exception later + assert(ix < n_ && jx < n_); + set *gv = GRAPHROW(G_, ix, m_); + if (ISELEMENT(gv, jx)) { + DELELEMENT(gv, jx); + } + autoComputed_ = false; +} + +double +CbcNauty::getGroupSize() const +{ + if (!autoComputed_) return -1.0; + return( stats_->grpsize1 * pow(10.0, (double) stats_->grpsize2) ); +} + +int +CbcNauty::getNumGenerators() const +{ + if (!autoComputed_) return -1; + return(stats_->numgenerators); +} + +int +CbcNauty::getNumOrbits() const +{ + if (!autoComputed_) return -1; + return(stats_->numorbits); +} + +std::vector > +*CbcNauty::getOrbits() const +{ + std::vector > *orb = new std::vector >; + if (!autoComputed_) return orb; + orb -> resize(getNumOrbits()); + std::multimap orbmap; + std::set orbkeys; + for (int j = 0; j < n_; j++) { + orbkeys.insert(orbits_[j]); + orbmap.insert(std::make_pair(orbits_[j], j)); + } + + int orbix = 0; + for (std::set::iterator it = orbkeys.begin(); + it != orbkeys.end(); ++it) { + std::multimap::iterator pos; + for (pos = orbmap.lower_bound(*it); + pos != orbmap.upper_bound(*it); ++pos) { + (*orb)[orbix].push_back(pos->second); + } + orbix++; + } + + assert(orbix == getNumOrbits()); + return orb; +} + +void +CbcNauty::getVstat(double *v, int nv) +{ + assert(nv == n_); + memcpy(v, vstat_, nv * sizeof(VarStatus)); +} + +/* +bool +CbcNauty::isAllFixOneOrbit(const std::vector &orbit) const +{ + + for(std::vector::const_iterator it = orbit.begin(); + it != orbit.end(); ++it) { + if (*it >= n_) return false; + if (vstat_[*it] != FIX_AT_ONE) return false; + } + return true; +} + +bool +CbcNauty::isAllFreeOrbit(const std::vector &orbit) const +{ + for(std::vector::const_iterator it = orbit.begin(); + it != orbit.end(); ++it) { + if (*it >= n_) return false; + if (vstat_[*it] != FREE) return false; + } + return true; +} + +bool +CbcNauty::isConstraintOrbit(const std::vector &orbit) const +{ + for(std::vector::const_iterator it = orbit.begin(); + it != orbit.end(); ++it) { + if (*it >= n_) return true; + } + return false; + +} + +bool +CbcNauty::isMixedFreeZeroOrbit(const std::vector &orbit) const +{ + bool containsFree = false; + bool containsZero = false; + + for(std::vector::const_iterator it = orbit.begin(); + it != orbit.end(); ++it) { + if (*it >= n_) return false; + if (vstat_[*it] == FREE) containsFree = true; + if (vstat_[*it] == FIX_AT_ZERO) containsZero = true; + if (containsFree && containsZero) break; + } + return (containsFree && containsZero); +} +*/ + +void +CbcNauty::setWriteAutoms(const std::string &fname) +{ + afp_ = fopen(fname.c_str(), "w"); + options_->writeautoms = TRUE; +#ifndef NTY_TRACES + options_->writemarkers = FALSE; +#endif + options_->outfile = afp_; + +} + +void +CbcNauty::unsetWriteAutoms() +{ + fclose(afp_); + options_->writeautoms = FALSE; +} + +// Default Constructor +CbcOrbitalBranchingObject::CbcOrbitalBranchingObject() + : CbcBranchingObject(), + column_(-1), + numberOther_(0), + numberExtra_(0), + fixToZero_(NULL) +{ +} + +// Useful constructor +CbcOrbitalBranchingObject::CbcOrbitalBranchingObject (CbcModel * model, int column, + int way , + int numberExtra, + const int * extraToZero) + : CbcBranchingObject(model, -1, way, 0.5), + column_(column), + numberOther_(0), + numberExtra_(0), + fixToZero_(NULL) +{ + CbcSymmetry * symmetryInfo = model->symmetryInfo(); + assert (symmetryInfo); + // Filled in (hopefully) + const int * orbit = symmetryInfo->whichOrbit(); + int iOrbit=orbit[column]; + assert (iOrbit>=0); + int numberColumns = model->getNumCols(); + numberOther_=-1; + for (int i=0;i0); + nautyBranchSucceeded_++; + nautyOtherBranches_ += numberOther_; + numberExtra_ = numberExtra; + fixToZero_ = new int [numberOther_+numberExtra_]; + int n=0; + for (int i=0;ilogLevel()>1) + print(); + OsiSolverInterface * solver = model_->solver(); + if (way_ < 0) { + solver->setColUpper(column_,0.0); + for ( int i = 0; i < numberOther_+numberExtra_; i++) { + solver->setColUpper(fixToZero_[i],0.0); + } + way_ = 1; // Swap direction + } else { + solver->setColLower(column_,1.0); + for (int i = numberOther_; i < numberOther_+numberExtra_; i++) { + solver->setColUpper(fixToZero_[i],0.0); + } + way_ = -1; // Swap direction + } + return 0.0; +} +/* Update bounds in solver as in 'branch' and update given bounds. + branchState is -1 for 'down' +1 for 'up' */ +void +CbcOrbitalBranchingObject::fix(OsiSolverInterface * solver, + double * lower, double * upper, + int branchState) const +{ + if (branchState < 0) { + upper[column_]=0.0; + for ( int i = 0; i < numberOther_+numberExtra_; i++) { + upper[fixToZero_[i]]=0.0;; + } + } else { + lower[column_]=1.0; + for (int i = numberOther_; i < numberOther_+numberExtra_; i++) { + upper[fixToZero_[i]]=0.0;; + } + } +} +// Print what would happen +void +CbcOrbitalBranchingObject::print() +{ + if (way_ < 0) { + printf("Orbital Down - to zero %d",column_); + for ( int i = 0; i < numberOther_+numberExtra_; i++) { + printf(" %d",fixToZero_[i]); + } + } else { + printf("Orbital Up - to one %d, to zero",column_); + for (int i = numberOther_; i < numberOther_+numberExtra_; i++) { + printf(" %d",fixToZero_[i]); + } + } + printf("\n"); +} + +/** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. +*/ +int +CbcOrbitalBranchingObject::compareOriginalObject +(const CbcBranchingObject* brObj) const +{ + const CbcOrbitalBranchingObject* br = + dynamic_cast(brObj); + assert(!br); + abort(); + return 0; +} + +/** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. +*/ +CbcRangeCompare +CbcOrbitalBranchingObject::compareBranchingObject +(const CbcBranchingObject* brObj, const bool replaceIfOverlap) +{ + const CbcOrbitalBranchingObject* br = + dynamic_cast(brObj); + assert(!br); + abort(); + return CbcRangeDisjoint; +} +#endif + diff -Nru coinor-cbc-2.8.12/src/CbcSymmetry.hpp coinor-cbc-2.9.9+repack1/src/CbcSymmetry.hpp --- coinor-cbc-2.8.12/src/CbcSymmetry.hpp 1970-01-01 00:00:00.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcSymmetry.hpp 2015-07-07 21:16:56.000000000 +0000 @@ -0,0 +1,366 @@ +/* $Id: CbcSymmetry.hpp 1033 2013-12-14 19:34:28Z pbelotti $ + * + * Name: Hacked from CouenneProblem.hpp + * Author: Pietro Belotti, Lehigh University + * Andreas Waechter, IBM + * Purpose: define the class CouenneProblem + * + * (C) Carnegie-Mellon University, 2006-11. + * This file is licensed under the Eclipse Public License (EPL) + */ +/* + If this is much used then we could improve build experience + Download nauty - say to /disk/nauty25r9 + In that directory ./configure --enable-tls --enable-wordsize=32 + make + copy nauty.a to libnauty.a + + In Cbc's configure + add -DCOIN_HAS_NTY to CXXDEFS + add -I/disk/nauty25r9 to CXXDEFS or ADD_CXXFLAGS + add -L/disk/nauty25r9 -lnauty to LDFLAGS + + If you wish to use Traces rather than nauty then add -DNTY_TRACES + + To use it is -orbit on + + Nauty has this - +* Permission +* is hereby given for use and/or distribution with the exception of * +* sale for profit or application with nontrivial military significance. * + so you can use it internally even if you are a company. + */ +#ifndef CBC_SYMMETRY_HPP +#define CBC_SYMMETRY_HPP +extern "C" { +#include "nauty.h" +#include "nausparse.h" +#ifdef NTY_TRACES +#include "traces.h" +#endif +} + +#include +#include +#include + +#include "CbcModel.hpp" + +class OsiObject; +// when to give up (depth since last success) +#ifndef NTY_BAD_DEPTH +#define NTY_BAD_DEPTH 10 +#endif +class CbcNauty; + + + +#define COUENNE_HACKED_EPS 1.e-07 +#define COUENNE_HACKED_EPS_SYMM 1e-8 +#define COUENNE_HACKED_EXPRGROUP 8 + + +/** Class to deal with symmetry + * + * Hacked from Couenne + * Thanks, but it had been nice to make sure that there are no symbol collisions when building Couenne with this Cbc. + */ + +class CbcSymmetry { + class Node{ + int index; + double coeff; + double lb; + double ub; + int color; + int code; + int sign; + public: + void node(int, double, double, double, int, int); + inline void color_vertex (register int k) {color = k;} + inline int get_index () const {return index;} + inline double get_coeff () const {return coeff;} + inline double get_lb () const {return lb;} + inline double get_ub () const {return ub;} + inline int get_color () const {return color;} + inline int get_code () const {return code;} + inline int get_sign () const {return sign;} + inline void bounds(register double a, register double b){ lb = a; ub = b;} + }; + + struct myclass0 { + inline bool operator() (register const Node &a, register const Node &b) { + + return (( a.get_code () < b.get_code ()) || + (( a.get_code () == b.get_code () && + (( a.get_coeff () < b.get_coeff () - COUENNE_HACKED_EPS_SYMM) || + (( fabs (a.get_coeff () - b.get_coeff ()) < COUENNE_HACKED_EPS_SYMM) && + (( a.get_lb () < b.get_lb () - COUENNE_HACKED_EPS_SYMM) || + (( fabs (a.get_lb () - b.get_lb ()) < COUENNE_HACKED_EPS_SYMM) && + (( a.get_ub () < b.get_ub () - COUENNE_HACKED_EPS_SYMM) || + (( fabs (a.get_ub () - b.get_ub ()) < COUENNE_HACKED_EPS_SYMM) && + (( a.get_index () < b.get_index ()))))))))))); + + } + } ; + + + struct myclass { + inline bool operator() (register const Node &a, register const Node &b) { + return (a.get_index() < b.get_index() ); + } + }; + +struct less_than_str { + inline bool operator() (register const char *a, register const char *b) const + {return strcmp (a, b) < 0;} +}; + + public: + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CbcSymmetry (); + + /// Copy constructor + CbcSymmetry (const CbcSymmetry &); + + /// Assignment operator + CbcSymmetry & operator=(const CbcSymmetry& rhs); + + /// Destructor + ~CbcSymmetry (); + //@} + + // Symmetry Info + + std::vector *Find_Orbit(int) const; + + myclass0 node_sort; + myclass index_sort; + + void Compute_Symmetry() const; + int statsOrbits(CbcModel * model, int type) const; + //double timeNauty () const; + void Print_Orbits() const; + void fillOrbits(); + /// Fixes variables using orbits (returns number fixed) + int orbitalFixing(OsiSolverInterface * solver); + inline int * whichOrbit() + { return numberUsefulOrbits_ ? whichOrbit_ : NULL;} + inline int numberUsefulOrbits() const + { return numberUsefulOrbits_;} + inline int numberUsefulObjects() const + { return numberUsefulObjects_;} + int largestOrbit(const double * lower, const double * upper) const; + void ChangeBounds (const double * lower, const double * upper, + int numberColumns,bool justFixedAtOne) const; + inline bool compare (register Node &a, register Node &b) const; + CbcNauty *getNtyInfo () {return nauty_info_;} + + // bool node_sort ( Node a, Node b); + // bool index_sort ( Node a, Node b); + + /// empty if no NTY, symmetry data structure setup otherwise + void setupSymmetry (const OsiSolverInterface & solver); +private: + mutable std::vector node_info_; + mutable CbcNauty *nauty_info_; + int numberColumns_; + int numberUsefulOrbits_; + int numberUsefulObjects_; + int * whichOrbit_; +}; + +class CbcNauty +{ + +public: + enum VarStatus { FIX_AT_ZERO, FIX_AT_ONE, FREE }; + + /**@name Constructors and destructors */ + //@{ +private: + /// Default constructor + CbcNauty (); +public: + /// Normal constructor (if dense - NULLS) + CbcNauty (int n, const size_t * v, const int * d, const int * e); + + /// Copy constructor + CbcNauty (const CbcNauty &); + + /// Assignment operator + CbcNauty & operator=(const CbcNauty& rhs); + + /// Destructor + ~CbcNauty (); + //@} + + void addElement(int ix, int jx); + void clearPartitions(); + void computeAuto(); + void deleteElement(int ix, int jx); + void color_node(int ix, int color) { vstat_[ix] = color; } + void insertRHS(int rhs , int cons) {constr_rhs.insert( std::pair(rhs,cons));} + + double getGroupSize() const; + //int getNautyCalls() const { return nautyCalls_; } + //double getNautyTime() const { return nautyTime_; } + + int getN() const { return n_; } + + int getNumGenerators() const; + int getNumOrbits() const; + + /// Returns the orbits in a "convenient" form + std::vector > *getOrbits() const; + + void getVstat(double *v, int nv); + inline bool isSparse() const + { return GSparse_ != NULL;} + inline int errorStatus() const + { return stats_->errstatus;} + /** + * Methods to classify orbits. Not horribly efficient, but gets the job done + */ + // bool isAllFixOneOrbit(const std::vector &orbit) const; + // bool isAllFreeOrbit(const std::vector &orbit) const; + //bool isAutoComputed() const { return autoComputed_; } + //bool isConstraintOrbit(const std::vector &orbit) const; + //bool isMixedFreeZeroOrbit(const std::vector &orbit) const; + //void makeFree(int ix) { vstat_[ix] = FREE; } + + void setWriteAutoms (const std::string &afilename); + void unsetWriteAutoms(); + +private: + + // The base nauty stuff + graph *G_; + sparsegraph *GSparse_; + int *lab_; + int *ptn_; + set *active_; + int *orbits_; +#ifndef NTY_TRACES + optionblk *options_; + statsblk *stats_; +#else + TracesOptions *options_; + TracesStats *stats_; +#endif + setword *workspace_; + int worksize_; + int m_; + int n_; + size_t nel_; + graph *canonG_; + + bool autoComputed_; + + int *vstat_; + + //static int nautyCalls_; + //static double nautyTime_; + + std::multimap constr_rhs; + std::multimap::iterator it; + + std::pair::iterator, + std::multimap::iterator> ret; + + // File pointer for automorphism group + FILE *afp_; + +}; + + +/** Branching object for Orbital branching + + Variable_ is the set id number (redundant, as the object also holds a + pointer to the set. + */ +class CbcOrbitalBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcOrbitalBranchingObject (); + + // Useful constructor + CbcOrbitalBranchingObject (CbcModel * model, int column, + int way, + int numberExtra, const int * extraToZero); + + // Copy constructor + CbcOrbitalBranchingObject ( const CbcOrbitalBranchingObject &); + + // Assignment operator + CbcOrbitalBranchingObject & operator=( const CbcOrbitalBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcOrbitalBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + /** Update bounds in solver as in 'branch' and update given bounds. + branchState is -1 for 'down' +1 for 'up' */ + virtual void fix(OsiSolverInterface * solver, + double * lower, double * upper, + int branchState) const ; + + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch() { + CbcBranchingObject::previousBranch(); + } + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return SoSBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +private: + /// Column to go to 1 + int column_; + /// Number (without column) going to zero on down branch + int numberOther_; + /// Number extra + int numberExtra_; + /// Fix to zero + int * fixToZero_; +}; + +#endif diff -Nru coinor-cbc-2.8.12/src/CbcThread.cpp coinor-cbc-2.9.9+repack1/src/CbcThread.cpp --- coinor-cbc-2.8.12/src/CbcThread.cpp 2013-10-19 15:59:44.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcThread.cpp 2014-11-21 10:57:22.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcThread.cpp 1973 2013-10-19 15:59:44Z stefan $ */ +/* $Id: CbcThread.cpp 2097 2014-11-21 10:57:22Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -174,7 +174,8 @@ { struct timespec absTime2; my_gettime(&absTime2); - double time2 = (double)absTime2.tv_sec + 1.0e-9 * (double)absTime2.tv_nsec; + double time2 = absTime2.tv_sec + 1.0e-9 * + static_cast(absTime2.tv_nsec); return time2; } // Timed wait in nanoseconds - if negative then seconds @@ -594,6 +595,7 @@ void CbcBaseModel::stopThreads(int type) { + CbcModel * baseModel = children_[0].baseModel(); if (type < 0) { // max nodes ? bool finished = false; @@ -606,11 +608,20 @@ } } } + for (int i = 0; i < numberThreads_; i++) { + baseModel->incrementExtra(threadModel_[i]->getExtraNodeCount(), + threadModel_[i]->numberExtraIterations(), + threadModel_[i]->getFathomCount()); + threadModel_[i]->zeroExtra(); + } return; } for (int i = 0; i < numberThreads_; i++) { children_[i].wait(1, 0); assert (children_[i].returnCode() == -1); + baseModel->incrementExtra(threadModel_[i]->getExtraNodeCount(), + threadModel_[i]->numberExtraIterations(), + threadModel_[i]->getFathomCount()); threadModel_[i]->setInfoInChild(-2, NULL); children_[i].setReturnCode( 0); children_[i].exit(); @@ -639,7 +650,6 @@ CbcModel * baseModel = children_[0].baseModel(); int anyLeft = 0; // May be able to combine parts later - if (type == 0) { bool locked = true; #ifdef COIN_DEVELOP @@ -650,8 +660,9 @@ int iThread; for (iThread = 0; iThread < numberThreads_; iThread++) { if (children_[iThread].status()) { - if (children_[iThread].returnCode() == 0) + if (children_[iThread].returnCode() == 0) { break; + } } } if (iThread < numberThreads_) { @@ -754,8 +765,9 @@ int iThread; // Start one off if any available for (iThread = 0; iThread < numberThreads_; iThread++) { - if (children_[iThread].returnCode() == -1) + if (children_[iThread].returnCode() == -1) { break; + } } if (iThread < numberThreads_) { children_[iThread].setNode(node); @@ -877,6 +889,10 @@ threadModel_[i]->setNumberThreads(0); // say exit if (children_[i].deterministic() > 0) delete [] children_[i].delNode(); + if (children_[i].node()) { + delete children_[i].node(); + children_[i].setNode(NULL); + } children_[i].setReturnCode( 0); children_[i].unlockFromMaster(); #ifndef NDEBUG @@ -1317,7 +1333,7 @@ otherModel->globalCuts_ = globalCuts_; otherModel->numberSolutions_ = numberSolutions_; otherModel->numberHeuristicSolutions_ = numberHeuristicSolutions_; - otherModel->numberNodes_ = 1; //numberNodes_; + otherModel->numberNodes_ = numberNodes_; otherModel->numberIterations_ = numberIterations_; #ifdef JJF_ZERO if (maximumNumberCuts_ > otherModel->maximumNumberCuts_) { @@ -1416,12 +1432,21 @@ void CbcModel::moveToModel(CbcModel * baseModel, int mode) { +#ifdef THREAD_DEBUG + { + CbcThread * stuff = reinterpret_cast (masterThread_); + if (stuff) + printf("mode %d node_ %p createdNode_ %p - stuff %p\n", + mode,stuff->node(),stuff->createdNode(),stuff); + else + printf("mode %d null stuff\n",mode); + } +#endif if (mode == 0) { setCutoff(baseModel->getCutoff()); bestObjective_ = baseModel->bestObjective_; //assert (!baseModel->globalCuts_.sizeRowCuts()); - if (numberSolutions_ < baseModel->numberSolutions_) { - assert (baseModel->bestSolution_); + if (numberSolutions_ < baseModel->numberSolutions_&& baseModel->bestSolution_) { int numberColumns = solver_->getNumCols(); if (!bestSolution_) bestSolution_ = new double [numberColumns]; @@ -1462,6 +1487,15 @@ dynamicObject->copySome(baseObject); } } + // add new global cuts + CbcRowCuts * baseGlobal = baseModel->globalCuts(); + CbcRowCuts * thisGlobal = globalCuts(); + int baseNumberCuts = baseGlobal->sizeRowCuts(); + int thisNumberCuts = thisGlobal->sizeRowCuts(); + for (int i=thisNumberCuts;iaddCutIfNotDuplicate(*baseGlobal->cut(i)); + } + numberGlobalCutsIn_ = baseNumberCuts; } else if (mode == 1) { lockThread(); CbcThread * stuff = reinterpret_cast (masterThread_); @@ -1501,6 +1535,16 @@ baseModel->tree_->push(stuff->node()); if (stuff->createdNode()) baseModel->tree_->push(stuff->createdNode()); + // add new global cuts to base and take off + CbcRowCuts * baseGlobal = baseModel->globalCuts(); + CbcRowCuts * thisGlobal = globalCuts(); + int thisNumberCuts = thisGlobal->sizeRowCuts(); + for (int i=thisNumberCuts-1;i>=numberGlobalCutsIn_;i--) { + baseGlobal->addCutIfNotDuplicate(*thisGlobal->cut(i),thisGlobal->cut(i)->whichRow()); + thisGlobal->eraseRowCut(i); + } + //thisGlobal->truncate(numberGlobalCutsIn_); + numberGlobalCutsIn_ = 999999; unlockThread(); } else if (mode == 2) { baseModel->sumChangeObjective1_ += sumChangeObjective1_; @@ -1530,6 +1574,8 @@ //addedCuts_ = NULL; tree_ = NULL; } + if ((moreSpecialOptions2_&32)!=0) + delete eventHandler_; eventHandler_ = NULL; delete solverCharacteristics_; solverCharacteristics_ = NULL; @@ -1541,7 +1587,12 @@ } } else if (mode == -1) { delete eventHandler_; - eventHandler_ = baseModel->eventHandler_; + if ((moreSpecialOptions2_&32)==0||!baseModel->eventHandler_) { + eventHandler_ = baseModel->eventHandler_; + } else { + eventHandler_ = baseModel->eventHandler_->clone(); + eventHandler_->setModel(this); + } assert (!statistics_); assert(baseModel->solverCharacteristics_); solverCharacteristics_ = new OsiBabSolver (*baseModel->solverCharacteristics_); @@ -1567,7 +1618,11 @@ tree_ = new CbcTree(); tree_->setComparison(*nodeCompare_) ; } + delete continuousSolver_; continuousSolver_ = baseModel->continuousSolver_->clone(); + // make sure solvers have correct message handler + solver_->passInMessageHandler(handler_); + continuousSolver_->passInMessageHandler(handler_); bool newMethod = (baseModel->branchingMethod_ && baseModel->branchingMethod_->chooseMethod()); if (newMethod) { // new method uses solver - but point to base model @@ -1590,7 +1645,10 @@ delete generator_[i]; generator_[i] = new CbcCutGenerator(*baseModel->generator_[i]); // refreshModel was overkill as thought too many rows - generator_[i]->setModel(this); + if (generator_[i]->needsRefresh()) + generator_[i]->refreshModel(this); + else + generator_[i]->setModel(this); } } else if (mode == 10) { setCutoff(baseModel->getCutoff()); @@ -1649,6 +1707,12 @@ baseModel->bestSolution_ = new double[numberColumns]; CoinCopyN(bestSolution_, numberColumns, baseModel->bestSolution_); baseModel->setCutoff(getCutoff()); + baseModel->handler_->message(CBC_ROUNDING, messages_) + << bestObjective_ + << "heuristic" + << baseModel->numberIterations_ + << baseModel->numberNodes_ << getCurrentSeconds() + << CoinMessageEol; } //stateOfSearch_ if (stuff->saveStuff()[0] != searchStrategy_) { @@ -1840,7 +1904,7 @@ resizeWhichGenerator(numberBefore, numberAfter); for (j = numberRowCutsBefore; j < numberRowCutsAfter; j++) { - whichGenerator_[numberBefore++] = i ; + whichGenerator_[numberBefore++] = i ; const OsiRowCut * thisCut = theseCuts.rowCutPtr(j) ; if (thisCut->lb() > thisCut->ub()) status = -1; // sub-problem is infeasible @@ -1876,7 +1940,7 @@ if (messageHandler()->logLevel() > 2) printf("Old cut added - violation %g\n", thisCut->violated(cbcColSolution_)) ; - whichGenerator_[numberOld++] = -1; + whichGenerator_[numberOld++] = 999; theseCuts.insert(*thisCut) ; } } diff -Nru coinor-cbc-2.8.12/src/CbcThread.hpp coinor-cbc-2.9.9+repack1/src/CbcThread.hpp --- coinor-cbc-2.8.12/src/CbcThread.hpp 2014-03-25 12:59:22.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcThread.hpp 2014-03-25 11:18:50.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcThread.hpp 2023 2014-03-25 12:59:22Z forrest $ */ +/* $Id: CbcThread.hpp 2022 2014-03-25 11:18:50Z forrest $ */ // Copyright (C) 2009, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/CbcTree.cpp coinor-cbc-2.9.9+repack1/src/CbcTree.cpp --- coinor-cbc-2.8.12/src/CbcTree.cpp 2014-03-25 12:59:22.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcTree.cpp 2014-11-21 10:57:22.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcTree.cpp 2023 2014-03-25 12:59:22Z forrest $ */ +/* $Id: CbcTree.cpp 2097 2014-11-21 10:57:22Z forrest $ */ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -363,6 +363,9 @@ CbcTree::push(CbcNode * x) { x->setNodeNumber(maximumNodeNumber_); + lastObjective_ = x->objectiveValue(); + lastDepth_ = x->depth(); + lastUnsatisfied_ = x->numberUnsatisfied(); maximumNodeNumber_++; # if CBC_DEBUG_HEAP > 2 CbcNodeInfo *info = x->nodeInfo() ; @@ -567,6 +570,8 @@ } if (value >= cutoff || !node->active()) { if (node) { + if (cutoff<-1.0e30) + node->nodeInfo()->deactivate(7); nodeArray[--kDelete] = node; depth[kDelete] = node->depth(); } @@ -616,24 +621,48 @@ */ for (j = nNodes - 1; j >= kDelete; j--) { CbcNode * node = nodeArray[j]; - CoinWarmStartBasis *lastws = model->getEmptyBasis() ; + CoinWarmStartBasis *lastws = (cutoff!=-COIN_DBL_MAX) ? model->getEmptyBasis() : NULL; model->addCuts1(node, lastws); // Decrement cut counts assert (node); //assert (node->nodeInfo()); int numberLeft = (node->nodeInfo()) ? node->nodeInfo()->numberBranchesLeft() : 0; - int i; - for (i = 0; i < model->currentNumberCuts(); i++) { + if (cutoff != -COIN_DBL_MAX) { + // normal + for (int i = 0; i < model->currentNumberCuts(); i++) { // take off node CoinWarmStartBasis::Status status = lastws->getArtifStatus(i + model->numberRowsAtContinuous()); if (status != CoinWarmStartBasis::basic && model->addedCuts()[i]) { - if (!model->addedCuts()[i]->decrement(numberLeft)) + if (!model->addedCuts()[i]->decrement(numberLeft)) delete model->addedCuts()[i]; } - } + } + } else { + // quick + for (int i = 0; i < model->currentNumberCuts(); i++) { + // take off node + if (model->addedCuts()[i]) { + if (model->parallelMode()!=1||true) { + if (!model->addedCuts()[i]->decrement(numberLeft)) + delete model->addedCuts()[i]; + } + } + } + } +#ifdef CBC_THREAD + if (model->parallelMode() > 0 && model->master()) { + // delete reference to node + int numberThreads = model->master()->numberThreads(); + for (int i=0;imaster()->child(i); + if (child->createdNode()==node) + child->setCreatedNode(NULL); + } + } +#endif // node should not have anything pointing to it if (node->nodeInfo()) node->nodeInfo()->throwAway(); @@ -650,8 +679,8 @@ for (int i=0;ichild(i); if (child->node()) { - // adjust double value = child->node()->objectiveValue(); + // adjust bestPossibleObjective = CoinMin(bestPossibleObjective, value); } } @@ -733,7 +762,7 @@ if (lastNode_) { if (lastNode_->nodeInfo()->parent() == x->nodeInfo()) { // x is parent of lastNode_ so put x on heap - //#define CBCTREE_PRINT + //#define CBCTREE_PRINT #ifdef CBCTREE_PRINT printf("pushX x %x (%x at depth %d n %d) is parent of lastNode_ %x (%x at depth %d n %d)\n", x, x->nodeInfo(), x->depth(), x->nodeNumber(), @@ -931,8 +960,8 @@ for (int i=0;ichild(i); if (child->node()) { - // adjust double value = child->node()->objectiveValue(); + // adjust bestPossibleObjective = CoinMin(bestPossibleObjective, value); } } @@ -994,8 +1023,8 @@ for (int i=0;ichild(i); if (child->node()) { - // adjust double value = child->node()->objectiveValue(); + // adjust bestPossibleObjective = CoinMin(bestPossibleObjective, value); } } @@ -1312,8 +1341,8 @@ for (int i=0;ichild(i); if (child->node()) { - // adjust double value = child->node()->objectiveValue(); + // adjust bestPossibleObjective = CoinMin(bestPossibleObjective, value); } } diff -Nru coinor-cbc-2.8.12/src/CbcTree.hpp coinor-cbc-2.9.9+repack1/src/CbcTree.hpp --- coinor-cbc-2.8.12/src/CbcTree.hpp 2012-11-22 19:00:22.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/CbcTree.hpp 2013-07-21 09:05:45.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: CbcTree.hpp 1813 2012-11-22 19:00:22Z forrest $ */ +/* $Id: CbcTree.hpp 1943 2013-07-21 09:05:45Z forrest $ */ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -162,6 +162,18 @@ /// Get bounds inline int * newBounds() const { return newBound_; } + /// Last objective in branch-and-cut search tree + inline double lastObjective() const { + return lastObjective_; + } + /// Last depth in branch-and-cut search tree + inline int lastDepth() const { + return lastDepth_; + } + /// Last number of objects unsatisfied + inline int lastUnsatisfied() const { + return lastUnsatisfied_; + } /// Adds branching information to complete state void addBranchingInformation(const CbcModel * model, const CbcNodeInfo * nodeInfo, const double * currentLower, @@ -181,7 +193,7 @@ protected: /// Storage vector for the heap std::vector nodes_; - /// Sort predicate for heap ordering. + /// Sort predicate for heap ordering. CbcCompare comparison_; /// Maximum "node" number so far to split ties int maximumNodeNumber_; @@ -189,6 +201,12 @@ int numberBranching_; /// Maximum size of variable list int maximumBranching_; + /// Objective of last node pushed on tree + double lastObjective_; + /// Depth of last node pushed on tree + int lastDepth_; + /// Number unsatisfied of last node pushed on tree + int lastUnsatisfied_; /** Integer variables branched or bounded top bit set if new upper bound next bit set if a branch diff -Nru coinor-cbc-2.8.12/src/ClpAmplObjective.hpp coinor-cbc-2.9.9+repack1/src/ClpAmplObjective.hpp --- coinor-cbc-2.8.12/src/ClpAmplObjective.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/ClpAmplObjective.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: ClpAmplObjective.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: ClpAmplObjective.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/ClpConstraintAmpl.hpp coinor-cbc-2.9.9+repack1/src/ClpConstraintAmpl.hpp --- coinor-cbc-2.8.12/src/ClpConstraintAmpl.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/ClpConstraintAmpl.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: ClpConstraintAmpl.hpp 1902 2013-04-10 16:58:16Z stefan $ */ +/* $Id: ClpConstraintAmpl.hpp 1899 2013-04-09 18:12:08Z stefan $ */ // Copyright (C) 2007, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/config_cbc_default.h coinor-cbc-2.9.9+repack1/src/config_cbc_default.h --- coinor-cbc-2.8.12/src/config_cbc_default.h 2014-08-28 03:30:12.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/config_cbc_default.h 2017-06-12 10:55:45.000000000 +0000 @@ -5,13 +5,13 @@ /***************************************************************************/ /* Version number of project */ -#define CBC_VERSION "2.8.12" +#define CBC_VERSION "2.9.9" /* Major Version number of project */ #define CBC_VERSION_MAJOR 2 /* Minor Version number of project */ -#define CBC_VERSION_MINOR 8 +#define CBC_VERSION_MINOR 9 /* Release Version number of project */ -#define CBC_VERSION_RELEASE 12 +#define CBC_VERSION_RELEASE 9 diff -Nru coinor-cbc-2.8.12/src/config.h.in coinor-cbc-2.9.9+repack1/src/config.h.in --- coinor-cbc-2.8.12/src/config.h.in 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/config.h.in 2015-07-07 20:44:40.000000000 +0000 @@ -58,6 +58,9 @@ /* Define to 1 if the Netlib package is available */ #undef COIN_HAS_NETLIB +/* Define to 1 if the Nauty package is available */ +#undef COIN_HAS_NTY + /* Define to 1 if the OsiTests package is available */ #undef COIN_HAS_OSITESTS diff -Nru coinor-cbc-2.8.12/src/Makefile.am coinor-cbc-2.9.9+repack1/src/Makefile.am --- coinor-cbc-2.8.12/src/Makefile.am 2014-08-23 16:31:35.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/Makefile.am 2015-07-07 20:44:40.000000000 +0000 @@ -2,7 +2,7 @@ # All Rights Reserved. # This file is distributed under the Eclipse Public License. -## $Id: Makefile.am 2059 2014-08-23 16:31:35Z tkr $ +## $Id: Makefile.am 2206 2015-07-07 20:44:40Z stefan $ # Author: Andreas Waechter IBM 2006-04-13 @@ -69,6 +69,7 @@ CbcHeuristicRENS.cpp CbcHeuristicRENS.hpp \ CbcHeuristicRINS.cpp CbcHeuristicRINS.hpp \ CbcHeuristicVND.cpp CbcHeuristicVND.hpp \ + CbcHeuristicDW.cpp CbcHeuristicDW.hpp \ CbcMessage.cpp CbcMessage.hpp \ CbcModel.cpp CbcModel.hpp \ CbcNode.cpp CbcNode.hpp \ @@ -86,6 +87,7 @@ CbcStatistics.cpp CbcStatistics.hpp \ CbcStrategy.cpp CbcStrategy.hpp \ CbcSubProblem.cpp CbcSubProblem.hpp \ + CbcSymmetry.cpp CbcSymmetry.hpp \ CbcThread.cpp CbcThread.hpp \ CbcTree.cpp CbcTree.hpp \ CbcTreeLocal.cpp CbcTreeLocal.hpp @@ -117,6 +119,10 @@ bin_PROGRAMS = AM_CPPFLAGS = $(COINDEPEND_CFLAGS) $(CLP_CFLAGS) $(CPX_CFLAGS) $(ASL_CFLAGS) +if COIN_HAS_NTY +AM_CPPFLAGS += -I$(NTYINCDIR) +endif + ######################################################################## # cbc program # ######################################################################## @@ -241,6 +247,7 @@ CbcHeuristicRENS.hpp \ CbcHeuristicRINS.hpp \ CbcHeuristicVND.hpp \ + CbcHeuristicDW.hpp \ CbcMessage.hpp \ CbcModel.hpp \ CbcNode.hpp \ @@ -248,6 +255,7 @@ CbcNWay.hpp \ CbcObject.hpp \ CbcObjectUpdateData.hpp \ + CbcParam.hpp \ CbcPartialNodeInfo.hpp \ CbcSimpleInteger.hpp \ CbcSimpleIntegerDynamicPseudoCost.hpp \ diff -Nru coinor-cbc-2.8.12/src/Makefile.in coinor-cbc-2.9.9+repack1/src/Makefile.in --- coinor-cbc-2.8.12/src/Makefile.in 2014-08-23 16:31:35.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/Makefile.in 2016-02-21 15:25:08.000000000 +0000 @@ -45,6 +45,7 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) +@COIN_HAS_NTY_TRUE@am__append_1 = -I$(NTYINCDIR) ######################################################################## # cbc program # @@ -52,7 +53,7 @@ # Name of the executable compiled in this directory. We want it to be # installed in the 'bin' directory -@COIN_HAS_CLP_TRUE@am__append_1 = cbc +@COIN_HAS_CLP_TRUE@am__append_2 = cbc ######################################################################## # cbc-generic program # @@ -60,12 +61,12 @@ # Name of the executable compiled in this directory. We want it to be # installed in the 'bin' directory -@CBC_BUILD_CBC_GENERIC_TRUE@am__append_2 = cbc-generic +@CBC_BUILD_CBC_GENERIC_TRUE@am__append_3 = cbc-generic # List all additionally required solver and Osi libraries # the linker flags for all available LP solvers should already be included in $CBCGENERIC_LIBS, # so just add compiler flags here (all we can think of) -@CBC_BUILD_CBC_GENERIC_TRUE@am__append_3 = $(DYLP_CFLAGS) $(GLPK_CFLAGS) $(MSK_CFLAGS) $(SPX_CFLAGS) $(VOL_CFLAGS) $(XPR_CFLAGS) +@CBC_BUILD_CBC_GENERIC_TRUE@am__append_4 = $(DYLP_CFLAGS) $(GLPK_CFLAGS) $(MSK_CFLAGS) $(SPX_CFLAGS) $(VOL_CFLAGS) $(XPR_CFLAGS) subdir = src DIST_COMMON = $(includecoin_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ @@ -109,12 +110,13 @@ CbcHeuristicGreedy.lo CbcHeuristicLocal.lo \ CbcHeuristicPivotAndFix.lo CbcHeuristicRandRound.lo \ CbcHeuristicRENS.lo CbcHeuristicRINS.lo CbcHeuristicVND.lo \ - CbcMessage.lo CbcModel.lo CbcNode.lo CbcNodeInfo.lo CbcNWay.lo \ - CbcObject.lo CbcObjectUpdateData.lo CbcPartialNodeInfo.lo \ - CbcSimpleInteger.lo CbcSimpleIntegerDynamicPseudoCost.lo \ + CbcHeuristicDW.lo CbcMessage.lo CbcModel.lo CbcNode.lo \ + CbcNodeInfo.lo CbcNWay.lo CbcObject.lo CbcObjectUpdateData.lo \ + CbcPartialNodeInfo.lo CbcSimpleInteger.lo \ + CbcSimpleIntegerDynamicPseudoCost.lo \ CbcSimpleIntegerPseudoCost.lo CbcSOS.lo CbcStatistics.lo \ - CbcStrategy.lo CbcSubProblem.lo CbcThread.lo CbcTree.lo \ - CbcTreeLocal.lo + CbcStrategy.lo CbcSubProblem.lo CbcSymmetry.lo CbcThread.lo \ + CbcTree.lo CbcTreeLocal.lo libCbc_la_OBJECTS = $(am_libCbc_la_OBJECTS) @DEPENDENCY_LINKING_TRUE@libCbcSolver_la_DEPENDENCIES = \ @DEPENDENCY_LINKING_TRUE@ $(am__DEPENDENCIES_1) libCbc.la @@ -247,18 +249,24 @@ COIN_HAS_COINDEPEND_TRUE = @COIN_HAS_COINDEPEND_TRUE@ COIN_HAS_CPX_FALSE = @COIN_HAS_CPX_FALSE@ COIN_HAS_CPX_TRUE = @COIN_HAS_CPX_TRUE@ +COIN_HAS_DOXYGEN_FALSE = @COIN_HAS_DOXYGEN_FALSE@ +COIN_HAS_DOXYGEN_TRUE = @COIN_HAS_DOXYGEN_TRUE@ COIN_HAS_DYLP_FALSE = @COIN_HAS_DYLP_FALSE@ COIN_HAS_DYLP_TRUE = @COIN_HAS_DYLP_TRUE@ COIN_HAS_GLPK_FALSE = @COIN_HAS_GLPK_FALSE@ COIN_HAS_GLPK_TRUE = @COIN_HAS_GLPK_TRUE@ COIN_HAS_GRB_FALSE = @COIN_HAS_GRB_FALSE@ COIN_HAS_GRB_TRUE = @COIN_HAS_GRB_TRUE@ +COIN_HAS_LATEX_FALSE = @COIN_HAS_LATEX_FALSE@ +COIN_HAS_LATEX_TRUE = @COIN_HAS_LATEX_TRUE@ COIN_HAS_MIPLIB3_FALSE = @COIN_HAS_MIPLIB3_FALSE@ COIN_HAS_MIPLIB3_TRUE = @COIN_HAS_MIPLIB3_TRUE@ COIN_HAS_MSK_FALSE = @COIN_HAS_MSK_FALSE@ COIN_HAS_MSK_TRUE = @COIN_HAS_MSK_TRUE@ COIN_HAS_NETLIB_FALSE = @COIN_HAS_NETLIB_FALSE@ COIN_HAS_NETLIB_TRUE = @COIN_HAS_NETLIB_TRUE@ +COIN_HAS_NTY_FALSE = @COIN_HAS_NTY_FALSE@ +COIN_HAS_NTY_TRUE = @COIN_HAS_NTY_TRUE@ COIN_HAS_OSITESTS_FALSE = @COIN_HAS_OSITESTS_FALSE@ COIN_HAS_OSITESTS_TRUE = @COIN_HAS_OSITESTS_TRUE@ COIN_HAS_PKGCONFIG_FALSE = @COIN_HAS_PKGCONFIG_FALSE@ @@ -365,6 +373,8 @@ NETLIB_DEPENDENCIES = @NETLIB_DEPENDENCIES@ NETLIB_LIBS = @NETLIB_LIBS@ NETLIB_LIBS_INSTALLED = @NETLIB_LIBS_INSTALLED@ +NTYINCDIR = @NTYINCDIR@ +NTYLIB = @NTYLIB@ OBJEXT = @OBJEXT@ OPT_CFLAGS = @OPT_CFLAGS@ OPT_CXXFLAGS = @OPT_CXXFLAGS@ @@ -472,6 +482,7 @@ coin_doxy_tagname = @coin_doxy_tagname@ coin_doxy_usedot = @coin_doxy_usedot@ coin_have_doxygen = @coin_have_doxygen@ +coin_have_latex = @coin_have_latex@ datadir = @datadir@ exec_prefix = @exec_prefix@ have_autoconf = @have_autoconf@ @@ -562,6 +573,7 @@ CbcHeuristicRENS.cpp CbcHeuristicRENS.hpp \ CbcHeuristicRINS.cpp CbcHeuristicRINS.hpp \ CbcHeuristicVND.cpp CbcHeuristicVND.hpp \ + CbcHeuristicDW.cpp CbcHeuristicDW.hpp \ CbcMessage.cpp CbcMessage.hpp \ CbcModel.cpp CbcModel.hpp \ CbcNode.cpp CbcNode.hpp \ @@ -579,6 +591,7 @@ CbcStatistics.cpp CbcStatistics.hpp \ CbcStrategy.cpp CbcStrategy.hpp \ CbcSubProblem.cpp CbcSubProblem.hpp \ + CbcSymmetry.cpp CbcSymmetry.hpp \ CbcThread.cpp CbcThread.hpp \ CbcTree.cpp CbcTree.hpp \ CbcTreeLocal.cpp CbcTreeLocal.hpp @@ -609,8 +622,8 @@ # List additional defines AM_CPPFLAGS = $(COINDEPEND_CFLAGS) $(CLP_CFLAGS) $(CPX_CFLAGS) \ - $(ASL_CFLAGS) $(am__append_3) -DCOIN_NO_CLP_MESSAGE \ - -DUSE_CBCCONFIG + $(ASL_CFLAGS) $(am__append_1) $(am__append_4) \ + -DCOIN_NO_CLP_MESSAGE -DUSE_CBCCONFIG # List all source files for this executable, including headers @COIN_HAS_CLP_TRUE@cbc_SOURCES = CoinSolve.cpp @@ -696,6 +709,7 @@ CbcHeuristicRENS.hpp \ CbcHeuristicRINS.hpp \ CbcHeuristicVND.hpp \ + CbcHeuristicDW.hpp \ CbcMessage.hpp \ CbcModel.hpp \ CbcNode.hpp \ @@ -703,6 +717,7 @@ CbcNWay.hpp \ CbcObject.hpp \ CbcObjectUpdateData.hpp \ + CbcParam.hpp \ CbcPartialNodeInfo.hpp \ CbcSimpleInteger.hpp \ CbcSimpleIntegerDynamicPseudoCost.hpp \ @@ -893,6 +908,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcGeneric.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcHeuristic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcHeuristicDINS.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcHeuristicDW.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcHeuristicDive.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcHeuristicDiveCoefficient.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcHeuristicDiveFractional.Plo@am__quote@ @@ -930,6 +946,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcStatistics.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcStrategy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcSubProblem.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcSymmetry.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcThread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcTree.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcTreeLocal.Plo@am__quote@ diff -Nru coinor-cbc-2.8.12/src/OsiCbc/Makefile.am coinor-cbc-2.9.9+repack1/src/OsiCbc/Makefile.am --- coinor-cbc-2.8.12/src/OsiCbc/Makefile.am 2013-12-15 23:57:12.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/OsiCbc/Makefile.am 2013-11-21 19:57:20.000000000 +0000 @@ -2,7 +2,7 @@ # All Rights Reserved. # This file is distributed under the Eclipse Public License. -## $Id: Makefile.am 1992 2013-12-15 23:57:12Z tkr $ +## $Id: Makefile.am 1979 2013-11-21 19:57:20Z stefan $ # Author: Andreas Waechter IBM 2006-04-13 diff -Nru coinor-cbc-2.8.12/src/OsiCbc/Makefile.in coinor-cbc-2.9.9+repack1/src/OsiCbc/Makefile.in --- coinor-cbc-2.8.12/src/OsiCbc/Makefile.in 2013-12-15 23:57:12.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/OsiCbc/Makefile.in 2016-02-21 15:25:08.000000000 +0000 @@ -174,18 +174,24 @@ COIN_HAS_COINDEPEND_TRUE = @COIN_HAS_COINDEPEND_TRUE@ COIN_HAS_CPX_FALSE = @COIN_HAS_CPX_FALSE@ COIN_HAS_CPX_TRUE = @COIN_HAS_CPX_TRUE@ +COIN_HAS_DOXYGEN_FALSE = @COIN_HAS_DOXYGEN_FALSE@ +COIN_HAS_DOXYGEN_TRUE = @COIN_HAS_DOXYGEN_TRUE@ COIN_HAS_DYLP_FALSE = @COIN_HAS_DYLP_FALSE@ COIN_HAS_DYLP_TRUE = @COIN_HAS_DYLP_TRUE@ COIN_HAS_GLPK_FALSE = @COIN_HAS_GLPK_FALSE@ COIN_HAS_GLPK_TRUE = @COIN_HAS_GLPK_TRUE@ COIN_HAS_GRB_FALSE = @COIN_HAS_GRB_FALSE@ COIN_HAS_GRB_TRUE = @COIN_HAS_GRB_TRUE@ +COIN_HAS_LATEX_FALSE = @COIN_HAS_LATEX_FALSE@ +COIN_HAS_LATEX_TRUE = @COIN_HAS_LATEX_TRUE@ COIN_HAS_MIPLIB3_FALSE = @COIN_HAS_MIPLIB3_FALSE@ COIN_HAS_MIPLIB3_TRUE = @COIN_HAS_MIPLIB3_TRUE@ COIN_HAS_MSK_FALSE = @COIN_HAS_MSK_FALSE@ COIN_HAS_MSK_TRUE = @COIN_HAS_MSK_TRUE@ COIN_HAS_NETLIB_FALSE = @COIN_HAS_NETLIB_FALSE@ COIN_HAS_NETLIB_TRUE = @COIN_HAS_NETLIB_TRUE@ +COIN_HAS_NTY_FALSE = @COIN_HAS_NTY_FALSE@ +COIN_HAS_NTY_TRUE = @COIN_HAS_NTY_TRUE@ COIN_HAS_OSITESTS_FALSE = @COIN_HAS_OSITESTS_FALSE@ COIN_HAS_OSITESTS_TRUE = @COIN_HAS_OSITESTS_TRUE@ COIN_HAS_PKGCONFIG_FALSE = @COIN_HAS_PKGCONFIG_FALSE@ @@ -292,6 +298,8 @@ NETLIB_DEPENDENCIES = @NETLIB_DEPENDENCIES@ NETLIB_LIBS = @NETLIB_LIBS@ NETLIB_LIBS_INSTALLED = @NETLIB_LIBS_INSTALLED@ +NTYINCDIR = @NTYINCDIR@ +NTYLIB = @NTYLIB@ OBJEXT = @OBJEXT@ OPT_CFLAGS = @OPT_CFLAGS@ OPT_CXXFLAGS = @OPT_CXXFLAGS@ @@ -399,6 +407,7 @@ coin_doxy_tagname = @coin_doxy_tagname@ coin_doxy_usedot = @coin_doxy_usedot@ coin_have_doxygen = @coin_have_doxygen@ +coin_have_latex = @coin_have_latex@ datadir = @datadir@ exec_prefix = @exec_prefix@ have_autoconf = @have_autoconf@ diff -Nru coinor-cbc-2.8.12/src/OsiCbc/OsiCbcSolverInterface.cpp coinor-cbc-2.9.9+repack1/src/OsiCbc/OsiCbcSolverInterface.cpp --- coinor-cbc-2.8.12/src/OsiCbc/OsiCbcSolverInterface.cpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/OsiCbc/OsiCbcSolverInterface.cpp 2014-09-28 10:31:40.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: OsiCbcSolverInterface.cpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: OsiCbcSolverInterface.cpp 2083 2014-09-28 10:31:40Z forrest $ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -121,21 +121,33 @@ bool OsiCbcSolverInterface::isAbandoned() const { - return modelPtr_->solver()->isAbandoned(); + if (modelPtr_->status()!=-1) + return modelPtr_->isAbandoned(); + else + return modelPtr_->solver()->isAbandoned(); } bool OsiCbcSolverInterface::isProvenOptimal() const { - return modelPtr_->solver()->isProvenOptimal(); + if (modelPtr_->status()!=-1) + return modelPtr_->isProvenOptimal(); + else + return modelPtr_->solver()->isProvenOptimal(); } bool OsiCbcSolverInterface::isProvenPrimalInfeasible() const { - return modelPtr_->solver()->isProvenPrimalInfeasible(); + if (modelPtr_->status()!=-1) + return modelPtr_->isProvenInfeasible(); + else + return modelPtr_->solver()->isProvenPrimalInfeasible(); } bool OsiCbcSolverInterface::isProvenDualInfeasible() const { + if (modelPtr_->status()!=-1) + return modelPtr_->isProvenDualInfeasible(); + else return modelPtr_->solver()->isProvenDualInfeasible(); } bool OsiCbcSolverInterface::isPrimalObjectiveLimitReached() const @@ -150,7 +162,10 @@ bool OsiCbcSolverInterface::isIterationLimitReached() const { - return modelPtr_->solver()->isIterationLimitReached(); + if (modelPtr_->status()!=-1) + return modelPtr_->isNodeLimitReached(); + else + return modelPtr_->solver()->isIterationLimitReached(); } //############################################################################# diff -Nru coinor-cbc-2.8.12/src/OsiCbc/OsiCbcSolverInterface.hpp coinor-cbc-2.9.9+repack1/src/OsiCbc/OsiCbcSolverInterface.hpp --- coinor-cbc-2.8.12/src/OsiCbc/OsiCbcSolverInterface.hpp 2013-04-10 16:58:16.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/OsiCbc/OsiCbcSolverInterface.hpp 2013-04-09 18:12:08.000000000 +0000 @@ -1,4 +1,4 @@ -// $Id: OsiCbcSolverInterface.hpp 1902 2013-04-10 16:58:16Z stefan $ +// $Id: OsiCbcSolverInterface.hpp 1899 2013-04-09 18:12:08Z stefan $ // Copyright (C) 2000, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). diff -Nru coinor-cbc-2.8.12/src/unitTestClp.cpp coinor-cbc-2.9.9+repack1/src/unitTestClp.cpp --- coinor-cbc-2.8.12/src/unitTestClp.cpp 2013-11-25 15:50:40.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/src/unitTestClp.cpp 2016-02-22 00:11:27.000000000 +0000 @@ -1,4 +1,4 @@ -/* $Id: unitTestClp.cpp 1985 2013-11-25 15:50:40Z tkr $ */ +/* $Id: unitTestClp.cpp 2271 2016-02-22 00:11:27Z tkr $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -168,7 +168,7 @@ std::vector objValueC ; std::vector objValue ; std::vector testSet ; - std::vector rowCutDebugger ; + std::vector rowCutDebugger ; /* A macro to make the vector creation marginally readable. Parameters are name, rows, columns, integer objective, continuous objective, set ID, @@ -200,6 +200,7 @@ Load up the problem vector. Note that the row counts here include the objective function. */ +#if 1 PUSH_MPS("10teams", 230, 2025, 924, 917, 1, false); PUSH_MPS("air03", 124, 10757, 340160, 338864.25, 0, false); PUSH_MPS("air04", 823, 8904, 56137, 55535.436, 2, false); @@ -263,6 +264,7 @@ PUSH_MPS("stein45", 331, 45, 30, 22.0, 1, false); PUSH_MPS("swath", 884, 6805, 497.603, 334.4968581, 7, false); PUSH_MPS("vpm1", 234, 378, 20, 15.4167, 0, false); +#endif PUSH_MPS("vpm2", 234, 378, 13.75, 9.8892645972, 0, false); } #undef PUSH_MPS @@ -580,14 +582,21 @@ } # endif if (stuff && stuff[8] >= 1) { + printf("Fast node size Columns %d rows %d - depth %d\n", + modelC->numberColumns(),modelC->numberRows(), + model->fastNodeDepth()); if (modelC->numberColumns() + modelC->numberRows() <= 10000 && model->fastNodeDepth() == -1) - model->setFastNodeDepth(-9); + model->setFastNodeDepth(-10/*-9*/); } } - //OsiObject * obj = new CbcBranchToFixLots(model,0.3,0.0,3,3000003); - //model->addObjects(1,&obj); - //delete obj; +#ifdef CONFLICT_CUTS + { + model->setCutoffAsConstraint(true); + int moreOptions=model->moreSpecialOptions(); + model->setMoreSpecialOptions(moreOptions|4194304); + } +#endif /* Finally, the actual call to solve the MIP with branch-and-cut. */ diff -Nru coinor-cbc-2.8.12/test/CInterfaceTest.c coinor-cbc-2.9.9+repack1/test/CInterfaceTest.c --- coinor-cbc-2.8.12/test/CInterfaceTest.c 2014-08-23 16:31:35.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/test/CInterfaceTest.c 2014-10-02 15:55:43.000000000 +0000 @@ -8,8 +8,13 @@ #include #include #include +#include #include +#ifndef INFINITY /* workaround for non-C99 compilers */ +#define INFINITY (HUGE_VAL * 2) +#endif + static int callback_called = 0; diff -Nru coinor-cbc-2.8.12/test/Makefile.am coinor-cbc-2.9.9+repack1/test/Makefile.am --- coinor-cbc-2.8.12/test/Makefile.am 2014-08-23 16:31:35.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/test/Makefile.am 2014-08-08 04:07:42.000000000 +0000 @@ -2,7 +2,7 @@ # All Rights Reserved. # This file is distributed under the Eclipse Public License. -## $Id: Makefile.am 2059 2014-08-23 16:31:35Z tkr $ +## $Id: Makefile.am 2054 2014-08-08 04:07:42Z mlubin $ # Author: Andreas Waechter IBM 2006-04-13 diff -Nru coinor-cbc-2.8.12/test/Makefile.in coinor-cbc-2.9.9+repack1/test/Makefile.in --- coinor-cbc-2.8.12/test/Makefile.in 2014-08-23 16:31:35.000000000 +0000 +++ coinor-cbc-2.9.9+repack1/test/Makefile.in 2016-02-21 15:25:08.000000000 +0000 @@ -168,18 +168,24 @@ COIN_HAS_COINDEPEND_TRUE = @COIN_HAS_COINDEPEND_TRUE@ COIN_HAS_CPX_FALSE = @COIN_HAS_CPX_FALSE@ COIN_HAS_CPX_TRUE = @COIN_HAS_CPX_TRUE@ +COIN_HAS_DOXYGEN_FALSE = @COIN_HAS_DOXYGEN_FALSE@ +COIN_HAS_DOXYGEN_TRUE = @COIN_HAS_DOXYGEN_TRUE@ COIN_HAS_DYLP_FALSE = @COIN_HAS_DYLP_FALSE@ COIN_HAS_DYLP_TRUE = @COIN_HAS_DYLP_TRUE@ COIN_HAS_GLPK_FALSE = @COIN_HAS_GLPK_FALSE@ COIN_HAS_GLPK_TRUE = @COIN_HAS_GLPK_TRUE@ COIN_HAS_GRB_FALSE = @COIN_HAS_GRB_FALSE@ COIN_HAS_GRB_TRUE = @COIN_HAS_GRB_TRUE@ +COIN_HAS_LATEX_FALSE = @COIN_HAS_LATEX_FALSE@ +COIN_HAS_LATEX_TRUE = @COIN_HAS_LATEX_TRUE@ COIN_HAS_MIPLIB3_FALSE = @COIN_HAS_MIPLIB3_FALSE@ COIN_HAS_MIPLIB3_TRUE = @COIN_HAS_MIPLIB3_TRUE@ COIN_HAS_MSK_FALSE = @COIN_HAS_MSK_FALSE@ COIN_HAS_MSK_TRUE = @COIN_HAS_MSK_TRUE@ COIN_HAS_NETLIB_FALSE = @COIN_HAS_NETLIB_FALSE@ COIN_HAS_NETLIB_TRUE = @COIN_HAS_NETLIB_TRUE@ +COIN_HAS_NTY_FALSE = @COIN_HAS_NTY_FALSE@ +COIN_HAS_NTY_TRUE = @COIN_HAS_NTY_TRUE@ COIN_HAS_OSITESTS_FALSE = @COIN_HAS_OSITESTS_FALSE@ COIN_HAS_OSITESTS_TRUE = @COIN_HAS_OSITESTS_TRUE@ COIN_HAS_PKGCONFIG_FALSE = @COIN_HAS_PKGCONFIG_FALSE@ @@ -286,6 +292,8 @@ NETLIB_DEPENDENCIES = @NETLIB_DEPENDENCIES@ NETLIB_LIBS = @NETLIB_LIBS@ NETLIB_LIBS_INSTALLED = @NETLIB_LIBS_INSTALLED@ +NTYINCDIR = @NTYINCDIR@ +NTYLIB = @NTYLIB@ OBJEXT = @OBJEXT@ OPT_CFLAGS = @OPT_CFLAGS@ OPT_CXXFLAGS = @OPT_CXXFLAGS@ @@ -393,6 +401,7 @@ coin_doxy_tagname = @coin_doxy_tagname@ coin_doxy_usedot = @coin_doxy_usedot@ coin_have_doxygen = @coin_have_doxygen@ +coin_have_latex = @coin_have_latex@ datadir = @datadir@ exec_prefix = @exec_prefix@ have_autoconf = @have_autoconf@