diff --git a/makefiles/Makefile.gen.mk b/makefiles/Makefile.gen.mk index ab9a612d8a..5f907ad86f 100644 --- a/makefiles/Makefile.gen.mk +++ b/makefiles/Makefile.gen.mk @@ -2274,7 +2274,6 @@ LP_LIB_OBJS = \ $(OBJ_DIR)/linear_solver/model_exporter.$O \ $(OBJ_DIR)/linear_solver/model_validator.$O \ $(OBJ_DIR)/linear_solver/scip_interface.$O \ - $(OBJ_DIR)/linear_solver/sulum_interface.$O \ $(OBJ_DIR)/linear_solver/linear_solver.pb.$O $(SRC_DIR)/linear_solver/glop_utils.h: \ @@ -2460,17 +2459,6 @@ $(OBJ_DIR)/linear_solver/scip_interface.$O: \ $(SRC_DIR)/base/timer.h $(CCC) $(CFLAGS) -c $(SRC_DIR)/linear_solver/scip_interface.cc $(OBJ_OUT)$(OBJ_DIR)$Slinear_solver$Sscip_interface.$O -$(OBJ_DIR)/linear_solver/sulum_interface.$O: \ - $(SRC_DIR)/linear_solver/sulum_interface.cc \ - $(SRC_DIR)/linear_solver/linear_solver.h \ - $(SRC_DIR)/base/commandlineflags.h \ - $(SRC_DIR)/base/hash.h \ - $(SRC_DIR)/base/integral_types.h \ - $(SRC_DIR)/base/logging.h \ - $(SRC_DIR)/base/stringprintf.h \ - $(SRC_DIR)/base/timer.h - $(CCC) $(CFLAGS) -c $(SRC_DIR)/linear_solver/sulum_interface.cc $(OBJ_OUT)$(OBJ_DIR)$Slinear_solver$Ssulum_interface.$O - $(GEN_DIR)/linear_solver/linear_solver.pb.cc: $(SRC_DIR)/linear_solver/linear_solver.proto $(PROTOBUF_DIR)/bin/protoc --proto_path=$(INC_DIR) --cpp_out=$(GEN_DIR) $(SRC_DIR)/linear_solver/linear_solver.proto diff --git a/makefiles/Makefile.port b/makefiles/Makefile.port index e6c5015763..7c7828d6b1 100755 --- a/makefiles/Makefile.port +++ b/makefiles/Makefile.port @@ -142,7 +142,6 @@ ifeq ("$(SYSTEM)","win") # Third party specific CBC_PLATFORM = $(CBC_PLATFORM_PREFIX)-$(VS_RELEASE)-Release - SCIP_MAKEFILE = \# SCIP not compiled # Java specific ifeq ($(JAVA_HOME),) @@ -203,4 +202,3 @@ ifeq ("$(SYSTEM)","unix") else @echo CMAKE_PLATFORM = $(CMAKE_PLATFORM) endif - diff --git a/makefiles/Makefile.third_party.unix.mk b/makefiles/Makefile.third_party.unix.mk index 501c9dce9d..6c19213e81 100644 --- a/makefiles/Makefile.third_party.unix.mk +++ b/makefiles/Makefile.third_party.unix.mk @@ -12,40 +12,6 @@ AUTOCONF_TAG = 2.69 AUTOMAKE_TAG = 1.15 LIBTOOL_TAG = 2.4.6 -# Build extra dependencies (GLPK, SCIP) from archive only if the -# archive is present. -# -# The GLPK archive should be glpk-4.57.tar.gz -GLPK_TAG = 4.57 -# The SCIP archive should be scipoptsuite-3.2.1.tgz -SCIP_TAG = 3.2.1 -# Version of Sulum -SULUM_TAG = 43 - -# Detect if SCIP archive is there. -ifeq ($(wildcard dependencies/archives/scipoptsuite-$(SCIP_TAG).tgz),) - SCIP_TARGET = - SCIP_MAKEFILE = "\# Download and put scipoptsuite-$(SCIP_TAG).tgz in the dependencies/archives directory to add support for SCIP." -else - SCIP_TARGET = dependencies/install/scipoptsuite-$(SCIP_TAG)/scip-$(SCIP_TAG)/bin/scip - SCIP_MAKEFILE = UNIX_SCIP_DIR = $(OR_ROOT_FULL)/dependencies/install/scipoptsuite-$(SCIP_TAG)/scip-$(SCIP_TAG) - ifeq ($(PLATFORM), LINUX) - BUILD_SCIP = make ZIMPL=false READLINE=false USRCXXFLAGS=-fPIC CFLAGS=-fPIC GMP=false - endif - ifeq ($(PLATFORM), MACOSX) - BUILD_SCIP = make ZIMPL=false READLINE=false GMP=false - endif -endif - -# Detect if GLPK archive is there. -ifeq ($(wildcard dependencies/archives/glpk-$(GLPK_TAG).tar.gz),) - GLPK_TARGET = - GLPK_MAKEFILE = "\# Download and put glpk-$(GLPK_TAG).tar.gz under dependencies/archives to add support for GLPK." -else - GLPK_TARGET = dependencies/install/bin/glpsol - GLPK_MAKEFILE = UNIX_GLPK_DIR = $(OR_ROOT_FULL)/dependencies/install -endif - # Detect if patchelf is needed ifeq ($(PLATFORM), LINUX) PATCHELF=dependencies/install/bin/patchelf @@ -110,8 +76,6 @@ install_third_party: \ install_protobuf \ install_swig \ install_cbc \ - install_glpk \ - install_scip \ $(CSHARP_THIRD_PARTY) bin: @@ -297,24 +261,6 @@ dependencies/sources/swig-$(SWIG_TAG)/configure: dependencies/sources/swig-$(SWI dependencies/sources/swig-$(SWIG_TAG)/autogen.sh: git clone -b rel-$(SWIG_TAG) https://github.com/swig/swig dependencies/sources/swig-$(SWIG_TAG) -# Install glpk if needed. -install_glpk: $(GLPK_TARGET) - -dependencies/install/bin/glpsol: dependencies/sources/glpk-$(GLPK_TAG)/Makefile - cd dependencies/sources/glpk-$(GLPK_TAG) && make install - -dependencies/sources/glpk-$(GLPK_TAG)/Makefile: dependencies/sources/glpk-$(GLPK_TAG)/configure $(ACLOCAL_TARGET) - cd dependencies/sources/glpk-$(GLPK_TAG) && $(SET_PATH) ./configure --prefix=$(OR_ROOT_FULL)/dependencies/install --with-pic - -dependencies/sources/glpk-$(GLPK_TAG)/configure: dependencies/archives/glpk-$(GLPK_TAG).tar.gz - cd dependencies/sources && tar xvzmf ../archives/glpk-$(GLPK_TAG).tar.gz - -# Install scip if needed. -install_scip: $(SCIP_TARGET) - -dependencies/install/scipoptsuite-$(SCIP_TAG)/scip-$(SCIP_TAG)/bin/scip: dependencies/archives/scipoptsuite-$(SCIP_TAG).tgz - cd dependencies/install && tar xvzmf ../archives/scipoptsuite-$(SCIP_TAG).tgz && cd scipoptsuite-$(SCIP_TAG) && $(BUILD_SCIP) - # Install patchelf on linux platforms. dependencies/install/bin/patchelf: dependencies/sources/patchelf-0.8/Makefile cd dependencies/sources/patchelf-0.8 && make && make install @@ -428,16 +374,15 @@ Makefile.local: makefiles/Makefile.third_party.unix.mk @echo PATH_TO_CSHARP_COMPILER = $(DETECTED_MCS_BINARY)>> Makefile.local @echo CLR_KEYFILE = bin/or-tools.snk>> Makefile.local @echo >> Makefile.local - @echo $(GLPK_MAKEFILE)>> Makefile.local - @echo $(SCIP_MAKEFILE)>> Makefile.local - @echo \# Define UNIX_SLM_DIR to use Sulum Optimization.>> Makefile.local - @echo \# Define UNIX_GUROBI_DIR and GUROBI_LIB_VERSION to use Gurobi.>> Makefile.local - @echo \# Define UNIX_CPLEX_DIR to use CPLEX.>> Makefile.local + @echo "# Define UNIX_GLPK_DIR to point to a compiled version of GLPK to use it" >> Makefile.local + @echo "# Define UNIX_SCIP_DIR to point to a compiled version of SCIP to use it ">> Makefile.local + @echo "# i.e.: /scipoptsuite-4.0.0/scip-4.0.0" >> Makefile.local + @echo "# compile scip with GMP=false READLINE=false" >> Makefile.local + @echo "# Define UNIX_GUROBI_DIR and GUROBI_LIB_VERSION to use Gurobi" >> Makefile.local + @echo "# Define UNIX_CPLEX_DIR to use CPLEX" >> Makefile.local @echo >> Makefile.local @echo UNIX_GFLAGS_DIR = $(OR_ROOT_FULL)/dependencies/install>> Makefile.local @echo UNIX_PROTOBUF_DIR = $(OR_ROOT_FULL)/dependencies/install>> Makefile.local @echo UNIX_SWIG_BINARY = $(OR_ROOT_FULL)/dependencies/install/bin/swig>> Makefile.local @echo UNIX_CLP_DIR = $(OR_ROOT_FULL)/dependencies/install>> Makefile.local @echo UNIX_CBC_DIR = $(OR_ROOT_FULL)/dependencies/install>> Makefile.local - @echo UNIX_SCIP_TAG = $(SCIP_TAG)>> Makefile.local - @echo UNIX_SULUM_VERSION = $(SULUM_TAG) >> Makefile.local diff --git a/makefiles/Makefile.third_party.win.mk b/makefiles/Makefile.third_party.win.mk index bf80a3a723..31631f84b2 100644 --- a/makefiles/Makefile.third_party.win.mk +++ b/makefiles/Makefile.third_party.win.mk @@ -6,35 +6,9 @@ ZLIB_TAG = 1.2.11 ZLIB_ARCHIVE_TAG = 1211 SWIG_TAG = 3.0.12 -# Build extra dependencies (GLPK, SCIP) from archive only if the archive is present. -# The archive should be glpk-4.57.tar.gz -GLPK_TAG = 4.57 -# The archive should be scipoptsuite-3.2.0.tgz -SCIP_TAG = 3.2.0 -SOPLEX_TAG = 2.2.0 -# Version of Sulum -SULUM_TAG = 43 - # Added in support of clean third party targets TSVNCACHE_EXE = TSVNCache.exe -# Detect if scip archive is there. -ifeq ($(wildcard dependencies/archives/scipoptsuite-$(SCIP_TAG).tgz),) - SCIP_TARGET = - SCIP_MAKEFILE = \# WINDOWS_SCIP_DIR support not included. -else - SCIP_TARGET = dependencies/install/lib/scip.lib - SCIP_MAKEFILE = WINDOWS_SCIP_DIR = $(OR_ROOT_FULL)\\dependencies\\install -endif - -# Detect if GLPK archive is there. -ifeq ($(wildcard dependencies/archives/glpk-$(GLPK_TAG).tar.gz),) - GLPK_TARGET = - GLPK_MAKEFILE = \# GLPK support not included. -else - GLPK_TARGET = dependencies\install\bin\glpsol.exe - GLPK_MAKEFILE = WINDOWS_GLPK_DIR = $(OR_ROOT_FULL)\\dependencies\\install -endif # Main target. .PHONY: third_party build_third_party makefile_third_party third_party: build_third_party makefile_third_party @@ -85,9 +59,7 @@ build_third_party: \ install_gflags \ install_protobuf \ install_swig \ - install_coin_cbc \ - install_glpk \ - install_scip + install_coin_cbc bin: $(MKDIR_P) bin @@ -333,49 +305,6 @@ dependencies\install\swigwin-$(SWIG_TAG)\swig.exe: dependencies\archives\swigwin dependencies\archives\swigwin-$(SWIG_TAG).zip: tools\wget -P dependencies\archives --no-check-certificate http://prdownloads.sourceforge.net/swig/swigwin-$(SWIG_TAG).zip || (@echo wget failed to dowload http://prdownloads.sourceforge.net/swig/swigwin-$(SWIG_TAG).zip, try running 'tools\wget -P dependencies\archives --no-check-certificate http://prdownloads.sourceforge.net/swig/swigwin-$(SWIG_TAG).zip' then rerun 'make third_party' && exit 1) -# Install glpk if needed. -install_glpk: $(GLPK_TARGET) - -dependencies\install\bin\glpsol.exe: dependencies\sources\glpk-$(GLPK_TAG)\$(GLPK_PLATFORM)\glpsol.exe - copy dependencies\sources\glpk-$(GLPK_TAG)\$(GLPK_PLATFORM)\glpk.lib dependencies\install\lib - copy dependencies\sources\glpk-$(GLPK_TAG)\src\glpk.h dependencies\install\include - copy dependencies\sources\glpk-$(GLPK_TAG)\$(GLPK_PLATFORM)\glpsol.exe dependencies\install\bin - - dependencies\sources\glpk-$(GLPK_TAG)\$(GLPK_PLATFORM)\glpsol.exe: dependencies\sources\glpk-$(GLPK_TAG)\configure - copy dependencies\sources\glpk-$(GLPK_TAG)\$(GLPK_PLATFORM)\config_VC dependencies\sources\glpk-$(GLPK_TAG)\$(GLPK_PLATFORM)\config.h - cd dependencies\sources\glpk-$(GLPK_TAG)\$(GLPK_PLATFORM) && nmake -f makefile_VC - -dependencies\sources\glpk-$(GLPK_TAG)\configure: dependencies\archives\glpk-$(GLPK_TAG).tar.gz - cd dependencies\sources && ..\..\tools\gzip -dc ..\archives\glpk-$(GLPK_TAG).tar.gz | ..\..\tools\tar.exe xvmf - - $(SED) -i -e 's/nologo/nologo \/MD/g' dependencies\sources\glpk-$(GLPK_TAG)\$(GLPK_PLATFORM)/Makefile_VC - -# Install scip if needed. -install_scip: $(SCIP_TARGET) - -dependencies/install/lib/scip.lib: dependencies/archives/scipoptsuite-$(SCIP_TAG).tgz -# cd dependencies\install && ..\..\tools\gzip -dc ..\archives\scipoptsuite-$(SCIP_TAG).tgz | ..\..\tools\tar.exe xvmf - - cd dependencies\install && ..\..\tools\tar.exe xvmf ..\archives\scipoptsuite-$(SCIP_TAG).tgz - cd dependencies\install\scipoptsuite-$(SCIP_TAG) && ..\..\..\tools\gzip -dc soplex-$(SOPLEX_TAG).tgz | ..\..\..\tools\tar.exe xvmf - -# cd dependencies\install\scipoptsuite-$(SCIP_TAG) && ..\..\..\tools\gzip -dc scip-$(SCIP_TAG).tgz | ..\..\..\tools\tar.exe xvmf - - cd dependencies\install\scipoptsuite-$(SCIP_TAG) && ..\..\..\tools\gzip -d scip-$(SCIP_TAG).tgz - - cd dependencies\install\scipoptsuite-$(SCIP_TAG) && ..\..\..\tools\tar.exe xvmf scip-$(SCIP_TAG).tar - tools\upgrade_vs_project.cmd dependencies\\solutions\\Scip\\soplex\\soplex.vcxproj $(VS_RELEASE) - tools\upgrade_vs_project.cmd dependencies\\solutions\\Scip\\scip\\scip.vcxproj $(VS_RELEASE) - cd dependencies\solutions\Scip && msbuild /t:soplex - cd dependencies\solutions\Scip && msbuild /t:scip - -mkdir dependencies\install\include - -mkdir dependencies\install\include\scip - -mkdir dependencies\install\include\scip\scip - -mkdir dependencies\install\include\scip\blockmemshell - -mkdir dependencies\install\include\scip\lpi - -mkdir dependencies\install\include\scip\nlpi - copy dependencies\install\scipoptsuite-$(SCIP_TAG)\scip-$(SCIP_TAG)\src\scip\*.h dependencies\install\include\scip\scip - copy dependencies\install\scipoptsuite-$(SCIP_TAG)\scip-$(SCIP_TAG)\src\lpi\*.h dependencies\install\include\scip\lpi - copy dependencies\install\scipoptsuite-$(SCIP_TAG)\scip-$(SCIP_TAG)\src\nlpi\*.h dependencies\install\include\scip\nlpi - copy dependencies\install\scipoptsuite-$(SCIP_TAG)\scip-$(SCIP_TAG)\src\blockmemshell\*.h dependencies\install\include\scip\blockmemshell - git checkout dependencies/solutions/Scip/soplex/soplex.vcxproj - git checkout dependencies/solutions/Scip/scip/scip.vcxproj - # Install Java protobuf install_java_protobuf: dependencies/install/lib/protobuf.jar @@ -422,12 +351,10 @@ Makefile.local: makefiles/Makefile.third_party.$(SYSTEM).mk @echo $(SELECTED_JDK_DEF)>> Makefile.local @echo $(SELECTED_PATH_TO_PYTHON)>> Makefile.local @echo $(SELECTED_CSC_BINARY)>> Makefile.local - @echo #>> Makefile.local - @echo $(GLPK_MAKEFILE)>> Makefile.local - @echo $(SCIP_MAKEFILE)>> Makefile.local + @echo # >> Makefile.local + @echo # Define WINDOWS_SCIP_DIR to point to a compiled version of SCIP to use it >> Makefile.local + @echo # i.e.: \\scipoptsuite-4.0.0\\scip-4.0.0 @echo CLR_KEYFILE = bin\\or-tools.snk>> Makefile.local - @echo WINDOWS_SULUM_VERSION = $(SULUM_TAG)>> Makefile.local - @echo # Define WINDOWS_SLM_DIR to use Sulum Optimization.>> Makefile.local @echo # Define WINDOWS_GUROBI_DIR and GUROBI_LIB_VERSION to use Gurobi.>> Makefile.local @echo #>> Makefile.local @echo WINDOWS_ZLIB_DIR = $(OR_ROOT_FULL)\\dependencies\\install>> Makefile.local diff --git a/makefiles/Makefile.unix.mk b/makefiles/Makefile.unix.mk index 0b11d9cc3d..f6af898673 100644 --- a/makefiles/Makefile.unix.mk +++ b/makefiles/Makefile.unix.mk @@ -89,11 +89,6 @@ ifdef UNIX_SCIP_DIR SCIP_INC = -I$(UNIX_SCIP_DIR)/src -DUSE_SCIP SCIP_SWIG = $(SCIP_INC) endif -# This is needed to find SULUM include files. -ifdef UNIX_SLM_DIR - SLM_INC = -I$(UNIX_SLM_DIR)/header -DUSE_SLM - SLM_SWIG = $(SLM_INC) -endif ifdef UNIX_GUROBI_DIR GUROBI_INC = -I$(UNIX_GUROBI_DIR)/$(GUROBI_PLATFORM)/include -DUSE_GUROBI GUROBI_SWIG = $(GUROBI_INC) @@ -103,7 +98,7 @@ ifdef UNIX_CPLEX_DIR CPLEX_SWIG = $(CPLEX_INC) endif -SWIG_INC = $(GLPK_SWIG) $(CLP_SWIG) $(CBC_SWIG) $(SCIP_SWIG) $(SLM_SWIG) $(GUROBI_SWIG) $(CPLEX_SWIG) -DUSE_GLOP -DUSE_BOP +SWIG_INC = $(GLPK_SWIG) $(CLP_SWIG) $(CBC_SWIG) $(SCIP_SWIG) $(GUROBI_SWIG) $(CPLEX_SWIG) -DUSE_GLOP -DUSE_BOP # Compilation flags DEBUG = -O4 -DNDEBUG @@ -154,14 +149,7 @@ ifeq ($(PLATFORM),LINUX) else SCIP_ARCH = linux.x86.gnu.opt endif - SCIP_LNK = $(UNIX_SCIP_DIR)/lib/libscip.$(SCIP_ARCH).a $(UNIX_SCIP_DIR)/lib/libnlpi.cppad.$(SCIP_ARCH).a $(UNIX_SCIP_DIR)/lib/liblpispx.$(SCIP_ARCH).a $(UNIX_SCIP_DIR)/lib/libsoplex.$(SCIP_ARCH).a - endif - ifdef UNIX_SLM_DIR - ifeq ($(PTRLENGTH),64) - SLM_LNK = -Wl,-rpath $(UNIX_SLM_DIR)/linux64/bin/ -L$(UNIX_SLM_DIR)/linux64/bin/ -m64 -lc -ldl -lm -lpthread -lsulum$(UNIX_SULUM_VERSION) - else - SLM_LNK = -Wl,-rpath $(UNIX_SLM_DIR)/linux32/bin/ -L$(UNIX_SLM_DIR)/linux32/bin/ -m32 -lc -ldl -lm -lpthread -lsulum$(UNIX_SULUM_VERSION) - endif + SCIP_LNK = $(UNIX_SCIP_DIR)/lib/static/libscip.$(SCIP_ARCH).a $(UNIX_SCIP_DIR)/lib/static/libnlpi.cppad.$(SCIP_ARCH).a $(UNIX_SCIP_DIR)/lib/static/liblpispx.$(SCIP_ARCH).a $(UNIX_SCIP_DIR)/lib/static/libsoplex.$(SCIP_ARCH).a endif ifdef UNIX_GUROBI_DIR ifeq ($(PTRLENGTH),64) @@ -235,7 +223,7 @@ ifeq ($(PLATFORM),MACOSX) endif ifdef UNIX_SCIP_DIR SCIP_ARCH = darwin.x86_64.gnu.opt - SCIP_LNK = -force_load $(UNIX_SCIP_DIR)/lib/libscip.$(SCIP_ARCH).a $(UNIX_SCIP_DIR)/lib/libnlpi.cppad.$(SCIP_ARCH).a -force_load $(UNIX_SCIP_DIR)/lib/liblpispx.$(SCIP_ARCH).a -force_load $(UNIX_SCIP_DIR)/lib/libsoplex.$(SCIP_ARCH).a + SCIP_LNK = -force_load $(UNIX_SCIP_DIR)/lib/static/libscip.$(SCIP_ARCH).a $(UNIX_SCIP_DIR)/lib/static/libnlpi.cppad.$(SCIP_ARCH).a -force_load $(UNIX_SCIP_DIR)/lib/static/liblpispx2.$(SCIP_ARCH).a -force_load $(UNIX_SCIP_DIR)/lib/static/libsoplex.$(SCIP_ARCH).a endif ifdef UNIX_GUROBI_DIR GUROBI_LNK = -L$(UNIX_GUROBI_DIR)/mac64/bin/ -m64 -lc -ldl -lm -lpthread -lgurobi$(GUROBI_LIB_VERSION) @@ -243,16 +231,13 @@ ifeq ($(PLATFORM),MACOSX) ifdef UNIX_CPLEX_DIR CPLEX_LNK = -force_load $(UNIX_CPLEX_DIR)/cplex/lib/x86-64_osx/static_pic/libcplex.a -lm -lpthread -framework CoreFoundation -framework IOKit endif - ifdef UNIX_SLM_DIR - SLM_LNK = -rpath $(UNIX_SLM_DIR)/mac64/bin/ -L$(UNIX_SLM_DIR)/mac64/bin/ -lc -ldl -lm -lpthread -lsulum$(UNIX_SULUM_VERSION) - endif endif # MAC OS X CFLAGS = $(DEBUG) -I$(INC_DIR) -I$(EX_DIR) -I$(GEN_DIR) $(GFLAGS_INC) $(ARCH) \ -Wno-deprecated $(PROTOBUF_INC) $(CBC_INC) $(CLP_INC) $(GLPK_INC) \ - $(SCIP_INC) $(SLM_INC) $(GUROBI_INC) $(CPLEX_INC) -DUSE_GLOP -DUSE_BOP $(SPARSEHASH_INC) + $(SCIP_INC) $(GUROBI_INC) $(CPLEX_INC) -DUSE_GLOP -DUSE_BOP $(SPARSEHASH_INC) JNIFLAGS = $(JNIDEBUG) -I$(INC_DIR) -I$(EX_DIR) -I$(GEN_DIR) $(GFLAGS_INC) $(ARCH) \ - -Wno-deprecated $(PROTOBUF_INC) $(CBC_INC) $(CLP_INC) $(GLPK_INC) $(SCIP_INC) $(SLM_INC) $(GUROBI_INC) $(CPLEX_INC) -DUSE_GLOP -DUSE_BOP + -Wno-deprecated $(PROTOBUF_INC) $(CBC_INC) $(CLP_INC) $(GLPK_INC) $(SCIP_INC) $(GUROBI_INC) $(CPLEX_INC) -DUSE_GLOP -DUSE_BOP DEPENDENCIES_LNK = $(GLPK_LNK) $(CBC_LNK) $(CLP_LNK) $(SCIP_LNK) $(LM_LNK) $(GUROBI_LNK) $(CPLEX_LNK) $(GFLAGS_LNK) $(PROTOBUF_LNK) OR_TOOLS_LD_FLAGS = $(ZLIB_LNK) $(SYS_LNK) diff --git a/makefiles/Makefile.win.mk b/makefiles/Makefile.win.mk index 2bbbdef76a..6dd4a2c9e9 100644 --- a/makefiles/Makefile.win.mk +++ b/makefiles/Makefile.win.mk @@ -106,13 +106,6 @@ ifdef WINDOWS_SCIP_DIR STATIC_SCIP_LNK = $(SCIP_LNK_DIR)\\lib\\scip.lib $(SCIP_LNK_DIR)\\lib\\soplex.lib DYNAMIC_SCIP_LNK = $(SCIP_LNK_DIR)\\lib\\scip.lib $(SCIP_LNK_DIR)\\lib\\soplex.lib endif -# This is needed to find SULUM include files and libraries. -ifdef WINDOWS_SLM_DIR -SLM_INC = /I$(WINDOWS_SLM_DIR)\\header /DUSE_SLM -SLM_SWIG = -DUSE_SLM -DYNAMIC_SLM_LNK = $(WINDOWS_SLM_DIR)\\win$(PTRLENGTH)\\bin\\sulum$(WINDOWS_SULUM_VERSION).lib -STATIC_SLM_LNK = $(WINDOWS_SLM_DIR)\\win$(PTRLENGTH)\\bin\\sulum$(WINDOWS_SULUM_VERSION).lib -endif ifdef WINDOWS_GUROBI_DIR ifeq ($(PTRLENGTH),64) GUROBI_INC = /I$(WINDOWS_GUROBI_DIR)\win64\include /DUSE_GUROBI @@ -127,7 +120,7 @@ ifdef WINDOWS_GUROBI_DIR endif endif -SWIG_INC = $(GLPK_SWIG) $(CLP_SWIG) $(CBC_SWIG) $(SCIP_SWIG) $(SLM_SWIG) $(GUROBI_SWIG) -DUSE_GLOP -DUSE_BOP +SWIG_INC = $(GLPK_SWIG) $(CLP_SWIG) $(CBC_SWIG) $(SCIP_SWIG) $(GUROBI_SWIG) -DUSE_GLOP -DUSE_BOP JAVA_INC=/I"$(JDK_DIRECTORY)\\include" /I"$(JDK_DIRECTORY)\\include\\win32" JAVAC_BIN="$(JDK_DIRECTORY)/bin/javac" @@ -136,7 +129,7 @@ JAR_BIN="$(JDK_DIRECTORY)/bin/jar" CFLAGS= -nologo $(SYSCFLAGS) $(DEBUG) /I$(INC_DIR) /I$(EX_DIR) /I$(GEN_DIR) \ $(GFLAGS_INC) $(ZLIB_INC) $(MINISAT_INC) $(PROTOBUF_INC) $(CBC_INC) \ - $(CLP_INC) $(GLPK_INC) $(SCIP_INC) $(SLM_INC) $(GUROBI_INC) /DUSE_GLOP /DUSE_BOP \ + $(CLP_INC) $(GLPK_INC) $(SCIP_INC) $(GUROBI_INC) /DUSE_GLOP /DUSE_BOP \ /D__WIN32__ $(SPARSEHASH_INC) /DPSAPI_VERSION=1 $(ARCH) JNIFLAGS=$(CFLAGS) $(JAVA_INC) DYNAMIC_GFLAGS_LNK = $(WINDOWS_GFLAGS_DIR)\\lib\\gflags_static.lib @@ -145,7 +138,7 @@ ZLIB_LNK = $(WINDOWS_ZLIB_DIR)\\lib\\$(WINDOWS_ZLIB_NAME) DYNAMIC_PROTOBUF_LNK = $(PROTOBUF_DIR)\\lib\\libprotobuf.lib STATIC_PROTOBUF_LNK = $(PROTOBUF_DIR)\\lib\\libprotobuf.lib SYS_LNK=psapi.lib ws2_32.lib shlwapi.lib -DEPENDENCIES_LNK = $(STATIC_CBC_LNK) $(STATIC_CLP_LNK) $(STATIC_GLPK_LNK) $(STATIC_SCIP_LNK) $(STATIC_SLM_LNK) $(STATIC_GUROBI_LNK) $(STATIC_GFLAGS_LNK) $(STATIC_PROTOBUF_LNK) +DEPENDENCIES_LNK = $(STATIC_CBC_LNK) $(STATIC_CLP_LNK) $(STATIC_GLPK_LNK) $(STATIC_SCIP_LNK) $(STATIC_GUROBI_LNK) $(STATIC_GFLAGS_LNK) $(STATIC_PROTOBUF_LNK) OR_TOOLS_LD_FLAGS = $(ZLIB_LNK) $(SYS_LNK) COMMA := , diff --git a/src/linear_solver/csharp/linear_solver.swig b/src/linear_solver/csharp/linear_solver.swig index ea8b489922..bf8002bbf4 100644 --- a/src/linear_solver/csharp/linear_solver.swig +++ b/src/linear_solver/csharp/linear_solver.swig @@ -34,7 +34,6 @@ %{ #include "linear_solver/linear_solver.h" #include "linear_solver/linear_solver.pb.h" -#include "linear_solver/linear_solver_ext.h" %} // We need to forward-declare the proto here, so that the PROTO_* macros @@ -217,6 +216,5 @@ class MPSolutionResponse; %warnfilter(401) CoeffMap; %include "linear_solver/linear_solver.h" -%include "linear_solver/linear_solver_ext.h" %unignoreall diff --git a/src/linear_solver/java/linear_solver.swig b/src/linear_solver/java/linear_solver.swig index fb9606ee12..ac2f4f20bd 100644 --- a/src/linear_solver/java/linear_solver.swig +++ b/src/linear_solver/java/linear_solver.swig @@ -45,7 +45,6 @@ class MPSolutionResponse; %{ #include "linear_solver/linear_solver.h" -#include "linear_solver/linear_solver_ext.h" %} %typemap(javaimports) SWIGTYPE %{ diff --git a/src/linear_solver/linear_solver.cc b/src/linear_solver/linear_solver.cc index eaef829793..dc0da56c93 100644 --- a/src/linear_solver/linear_solver.cc +++ b/src/linear_solver/linear_solver.cc @@ -392,12 +392,6 @@ MPSolverInterface* BuildSolverInterface(MPSolver* const solver) { case MPSolver::SCIP_MIXED_INTEGER_PROGRAMMING: return BuildSCIPInterface(solver); #endif -#if defined(USE_SLM) - case MPSolver::SULUM_LINEAR_PROGRAMMING: - return BuildSLMInterface(solver, false); - case MPSolver::SULUM_MIXED_INTEGER_PROGRAMMING: - return BuildSLMInterface(solver, true); -#endif #if defined(USE_GUROBI) case MPSolver::GUROBI_LINEAR_PROGRAMMING: return BuildGurobiInterface(false, solver); @@ -463,10 +457,6 @@ bool MPSolver::SupportsProblemType(OptimizationProblemType problem_type) { #ifdef USE_GLOP if (problem_type == GLOP_LINEAR_PROGRAMMING) return true; #endif - #if defined(USE_SLM) - if (problem_type == SULUM_LINEAR_PROGRAMMING) return true; - if (problem_type == SULUM_MIXED_INTEGER_PROGRAMMING) return true; - #endif #ifdef USE_GUROBI if (problem_type == GUROBI_LINEAR_PROGRAMMING) return true; if (problem_type == GUROBI_MIXED_INTEGER_PROGRAMMING) return true; @@ -1619,4 +1609,3 @@ int MPSolverParameters::GetIntegerParam(MPSolverParameters::IntegerParam param) } // namespace operations_research - diff --git a/src/linear_solver/linear_solver.h b/src/linear_solver/linear_solver.h index 7029568db7..9adde73ce3 100644 --- a/src/linear_solver/linear_solver.h +++ b/src/linear_solver/linear_solver.h @@ -181,9 +181,6 @@ class MPSolver { #ifdef USE_GLOP GLOP_LINEAR_PROGRAMMING = 2, #endif - #if defined(USE_SLM) - SULUM_LINEAR_PROGRAMMING = 8, - #endif #ifdef USE_GUROBI GUROBI_LINEAR_PROGRAMMING = 6, #endif @@ -201,9 +198,6 @@ class MPSolver { #ifdef USE_CBC CBC_MIXED_INTEGER_PROGRAMMING = 5, #endif - #if defined(USE_SLM) - SULUM_MIXED_INTEGER_PROGRAMMING = 9, - #endif #if defined(USE_GUROBI) GUROBI_MIXED_INTEGER_PROGRAMMING = 7, #endif diff --git a/src/linear_solver/linear_solver_ext.h b/src/linear_solver/linear_solver_ext.h deleted file mode 100644 index 89c005400e..0000000000 --- a/src/linear_solver/linear_solver_ext.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2010-2014 Google -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_EXT_H_ -#define OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_EXT_H_ - -#include "base/hash.h" -#include "base/hash.h" -#include -#include -#include - -#include "base/commandlineflags.h" -#include "base/integral_types.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/timer.h" -#include "base/strutil.h" -#include "base/sparsetable.h" -#include "base/hash.h" -#include "linear_solver/linear_solver.h" - -#if defined(USE_SLM) - - extern "C" { - #include "sulumc.h" - } - -#endif - -namespace operations_research { -// Special API -#if defined(USE_SLM) - - // Helper functions specific to using Google OR Tools with Sulum Optimizer - // The advantage is these functions does directly to the outer API - - // Set a integer parameter in sulum as underlying solver - // Return : 'true' if set 'false' if out of range - bool SulumSetIntParam(MPSolver &solver, - int iprm, - int ival) - { - return ( SlmRetOk == SlmSetIntParam(solver.underlying_solver(), static_cast(iprm), ival ) ); - } - - // Get a integer parameter from sulum as underlying solver - // Return : 'true' if get 'false' if out of range - bool SulumGetIntParam(MPSolver &solver, - int iprm, - int &ival) - { - return ( SlmRetOk == SlmGetIntParam(solver.underlying_solver(), static_cast(iprm), &ival ) ); - } - - // Set a double parameter in sulum as underlying solver - // Return : 'true' if set 'false' if out of range - bool SulumSetDbParam(MPSolver &solver, - int dprm, - double dval) - { - return ( SlmRetOk == SlmSetDbParam(solver.underlying_solver(), static_cast(dprm), dval ) ); - } - - // Get a double parameter from sulum as underlying solver - // Return : 'true' if get 'false' if out of range - bool SulumGetDbParam(MPSolver &solver, - int dprm, - double &dval) - { - return ( SlmRetOk == SlmGetDbParam(solver.underlying_solver(), static_cast(dprm), &dval ) ); - } - -#endif -} // namespace operations_research - -#endif // OR_TOOLS_LINEAR_SOLVER_LINEAR_SOLVER_EXT_H_ diff --git a/src/linear_solver/scip_interface.cc b/src/linear_solver/scip_interface.cc index 563f161720..fc7795d3b3 100644 --- a/src/linear_solver/scip_interface.cc +++ b/src/linear_solver/scip_interface.cc @@ -525,7 +525,7 @@ MPSolver::ResultStatus SCIPInterface::Solve(const MPSolverParameters& param) { SCIP_Bool is_feasible; ORTOOLS_SCIP_CALL(SCIPcheckSol( - scip_, solution, /*printreason=*/FALSE, /*checkbounds=*/TRUE, + scip_, solution, /*printreason=*/FALSE, /*completely=*/FALSE, /*checkbounds=*/TRUE, /*checkintegrality=*/TRUE, /*checklprows=*/TRUE, &is_feasible)); VLOG(1) << "Solution hint is " << (is_feasible ? "FEASIBLE" : "INFEASIBLE"); @@ -536,7 +536,7 @@ MPSolver::ResultStatus SCIPInterface::Solve(const MPSolverParameters& param) { SCIP_Bool is_stored; if (SCIPisTransformed(scip_)) { ORTOOLS_SCIP_CALL(SCIPtrySolFree( - scip_, &solution, /*printreason=*/FALSE, /*checkbounds=*/TRUE, + scip_, &solution, /*printreason=*/FALSE, /*completely=*/FALSE, /*checkbounds=*/TRUE, /*checkintegrality=*/TRUE, /*checklprows=*/TRUE, &is_stored)); } else { ORTOOLS_SCIP_CALL(SCIPaddSolFree(scip_, &solution, &is_stored)); diff --git a/src/linear_solver/sulum_interface.cc b/src/linear_solver/sulum_interface.cc deleted file mode 100644 index 174a091aed..0000000000 --- a/src/linear_solver/sulum_interface.cc +++ /dev/null @@ -1,999 +0,0 @@ -// Copyright 2010-2014 Google -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#include -#include -#include "base/hash.h" -#include -#include -#include -#include -#include -#include -#include - -#include "base/commandlineflags.h" -#include "base/integral_types.h" -#include "base/logging.h" -#include "base/stringprintf.h" -#include "base/timer.h" -#include "base/hash.h" -#include "linear_solver/linear_solver.h" - -#if defined(USE_SLM) - -extern "C" { - #include "sulumc.h" -} - -void ExLogCallbackFunction(enum SlmStream str, const char *strprint, void *handle ) -{ - /* Print with printf */ - std::cout <(model_); - } - - virtual double ComputeExactConditionNumber() const; - - private: - // Configure the solver's parameters. - void ConfigureSLMParameters(const MPSolverParameters& param); - - // Set all parameters in the underlying solver. - virtual void SetParameters(const MPSolverParameters& param); - // Set each parameter in the underlying solver. - virtual void SetRelativeMipGap(double value); - virtual void SetPrimalTolerance(double value); - virtual void SetDualTolerance(double value); - virtual void SetPresolveMode(int value); - virtual void SetScalingMode(int value); - virtual void SetLpAlgorithm(int value); - - void ExtractOldConstraints(); - void ExtractOneConstraint(MPConstraint* const constraint, - int* const indices, - double* const coefs); - // Transforms basis status from SLM integer code to MPSolver::BasisStatus. - MPSolver::BasisStatus TransformSLMBasisStatus(SlmStatusKey slm_basis_status) const; - - // Computes the L1-norm of the current scaled basis. - // The L1-norm |A| is defined as max_j sum_i |a_ij| - // This method is available only for continuous problems. - double ComputeScaledBasisL1Norm( - int num_rows, int num_cols, - double* row_scaling_factor, double* column_scaling_factor) const; - - // Computes the L1-norm of the inverse of the current scaled - // basis. - // This method is available only for continuous problems. - double ComputeInverseScaledBasisL1Norm( - int num_rows, int num_cols, - double* row_scaling_factor, double* column_scaling_factor) const; - - SlmEnv_t env_; - SlmModel_t model_; - bool mip_; -}; - -// Creates a LP/MIP instance with the specified name and minimization objective. -SLMInterface::SLMInterface(MPSolver* const solver, bool mip) - : MPSolverInterface(solver), env_(NULL), model_(NULL), mip_(mip) { - CheckReturnKey(SlmMakeEnv(&env_)); - CheckReturnKey(SlmMakeModel(env_,&model_)); - - /* Add logging callback function */ - CheckReturnKey(SlmSetLoggingCallback(model_,&ExLogCallbackFunction,NULL)); - - if(solver_->name_.empty() == false) { - CheckReturnKey(SlmSetObjName(model_, solver_->name_.c_str())); - } - - SetOptimizationDirection(maximize_); -} - -// Frees the LP memory allocations. -SLMInterface::~SLMInterface() { - CHECK_NOTNULL(env_); - CHECK_NOTNULL(model_); - CheckReturnKey(SlmFreeModel(env_,&model_)); - CheckReturnKey(SlmFreeEnv(&env_)); - - env_ = NULL; - model_ = NULL; -} - -void SLMInterface::Reset() { - CHECK_NOTNULL(model_); - CheckReturnKey(SlmClear(model_)); - CheckReturnKey(SlmSetObjName(model_, solver_->name_.c_str())); - CheckReturnKey(SlmSetParamDefault(model_)); - SetOptimizationDirection(maximize_); - ResetExtractionInformation(); -} - -void SLMInterface::WriteModel(const std::string& filename) { - CheckReturnKey(SlmWriteProblem(model_, filename.c_str())); -} - -// ------ Model modifications and extraction ----- - -// Not cached -void SLMInterface::SetOptimizationDirection(bool maximize) { - maximize_ = maximize; - InvalidateSolutionSynchronization(); - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntObjSense,maximize_ == true ? SlmObjSenseMax : SlmObjSenseMin )); -} - -void SLMInterface::SetVariableBounds(int var_index, double lb, double ub) { - InvalidateSolutionSynchronization(); - if (variable_is_extracted(var_index)) { - // Not cached if the variable has been extracted. - DCHECK(model_ != NULL); - const double infinity = solver_->infinity(); - - SlmBoundKey bk; - double lo = lb; - double up = ub; - - if (lb != -infinity) { - if (ub != infinity) { - if (lb == ub) { - bk = SlmBndFx; - } else { - bk = SlmBndRa; - } - } else { - up = SlmInfinity; - bk = SlmBndLo; - } - } else if (ub != infinity) { - lo = -SlmInfinity; - bk = SlmBndUp; - } else { - lo = -SlmInfinity; - up = SlmInfinity; - bk = SlmBndFr; - } - - CheckReturnKey(SlmSetKeyVarsI(model_,var_index,bk)); - CheckReturnKey(SlmSetLoVarsI(model_,var_index,lo)); - CheckReturnKey(SlmSetUpVarsI(model_,var_index,up)); - } else { - sync_status_ = MUST_RELOAD; - } -} - -void SLMInterface::SetVariableInteger(int var_index, bool integer) { - InvalidateSolutionSynchronization(); - if (mip_) { - if (variable_is_extracted(var_index)) { - // Not cached if the variable has been extracted. - SlmVarType type; - CheckReturnKey(SlmGetTypeVarsI(model_,var_index,&type)); - - if(type ==SlmVarTypeCont) { - integer = false; - } - else { - integer = true; - } - } else { - sync_status_ = MUST_RELOAD; - } - } -} - -void SLMInterface::SetConstraintBounds(int index, double lb, double ub) { - InvalidateSolutionSynchronization(); - if (constraint_is_extracted(index)) { - // Not cached if the row has been extracted - DCHECK(model_ != NULL); - const double infinity = solver_->infinity(); - SlmBoundKey bk; - double lo = lb; - double up = ub; - - if (lb != -infinity) { - if (ub != infinity) { - if (lb == ub) { - bk = SlmBndFx; - } else { - bk = SlmBndRa; - } - } else { - up = SlmInfinity; - bk = SlmBndLo; - } - } else if (ub != infinity) { - lo = -SlmInfinity; - bk = SlmBndUp; - } else { - lo = -SlmInfinity; - up = SlmInfinity; - bk = SlmBndFr; - } - - CheckReturnKey(SlmSetKeyConsI(model_,index,bk)); - CheckReturnKey(SlmSetLoConsI(model_,index,lo)); - CheckReturnKey(SlmSetUpConsI(model_,index,up)); - } else { - sync_status_ = MUST_RELOAD; - } -} - -void SLMInterface::SetCoefficient(MPConstraint* const constraint, - const MPVariable* const variable, - double new_value, - double old_value) { - InvalidateSolutionSynchronization(); - const int constraint_index = constraint->index(); - const int variable_index = variable->index(); - if (constraint_is_extracted(constraint_index) && - variable_is_extracted(variable_index)) { - // The modification of the coefficient for an extracted row and - // variable is not cached. - DCHECK_LE(constraint_index, last_constraint_index_); - DCHECK_LE(variable_index, last_variable_index_); - CheckReturnKey(SlmSetAIJ(model_,constraint_index, variable_index, new_value)); - } else { - // The modification of an unextracted row or variable is cached - // and handled in ExtractModel. - sync_status_ = MUST_RELOAD; - } -} - -// Not cached -void SLMInterface::ClearConstraint(MPConstraint* const constraint) { - InvalidateSolutionSynchronization(); - const int constraint_index = constraint->index(); - // Constraint may not have been extracted yet. - if (constraint_is_extracted(constraint_index)) { - CheckReturnKey(SlmSetAConsI(model_, constraint_index, 0, NULL, NULL)); - } -} - -// Cached -void SLMInterface::SetObjectiveCoefficient(const MPVariable* const variable, - double coefficient) { - sync_status_ = MUST_RELOAD; -} - -// Cached -void SLMInterface::SetObjectiveOffset(double value) { - sync_status_ = MUST_RELOAD; -} - -// Clear objective of all its terms (linear) -void SLMInterface::ClearObjective() { - InvalidateSolutionSynchronization(); - for (const auto& it : solver_->objective_->coefficients_) { - const int var_index = it.first->index(); - // Variable may have not been extracted yet. - if (!variable_is_extracted(var_index)) { - DCHECK_NE(MODEL_SYNCHRONIZED, sync_status_); - } else { - CheckReturnKey(SlmSetObjVarsI(model_,var_index, 0.0)); - } - } - // Constant term. - CheckReturnKey(SlmSetObjFix(model_, 0.0)); -} - -void SLMInterface::AddRowConstraint(MPConstraint* const ct) { - sync_status_ = MUST_RELOAD; -} - -void SLMInterface::AddVariable(MPVariable* const var) { - sync_status_ = MUST_RELOAD; -} - -// Define new variables and add them to existing constraints. -void SLMInterface::ExtractNewVariables() { - int total_num_vars = solver_->variables_.size(); - if (total_num_vars > last_variable_index_) { - CheckReturnKey(SlmAddEmptyVars(model_,total_num_vars - last_variable_index_)); - for (int j = last_variable_index_; j < solver_->variables_.size(); ++j) { - MPVariable* const var = solver_->variables_[j]; - set_variable_as_extracted(var->index(), true); - if (!var->name().empty()) { - CheckReturnKey(SlmSetNameVarsI(model_,j, var->name().c_str())); - } - - SetVariableBounds(j, var->lb(), var->ub()); - SetVariableInteger(j, var->integer()); - - // The true objective coefficient will be set later in ExtractObjective. - double tmp_obj_coef = 0.0; - CheckReturnKey(SlmSetObjVarsI(model_,j, tmp_obj_coef)); - } - // Add new variables to the existing constraints. - ExtractOldConstraints(); - } -} - -// Extract again existing constraints if they contain new variables. -void SLMInterface::ExtractOldConstraints() { - int max_constraint_size = solver_->ComputeMaxConstraintSize( - 0, last_constraint_index_); - - std::unique_ptr indices(new int[max_constraint_size ]); - std::unique_ptr coefs(new double[max_constraint_size ]); - - for (int i = 0; i < last_constraint_index_; ++i) { - MPConstraint* const ct = solver_->constraints_[i]; - CHECK(constraint_is_extracted(i)); - const int size = ct->coefficients_.size(); - if (size == 0) { - continue; - } - // Update the constraint's coefficients if it contains new variables. - if (ct->ContainsNewVariables()) { - ExtractOneConstraint(ct, indices.get(), coefs.get()); - } - } -} - -// Extract one constraint. Arrays indices and coefs must be -// preallocated to have enough space to contain the constraint's -// coefficients. -void SLMInterface::ExtractOneConstraint(MPConstraint* const constraint, - int* const indices, - double* const coefs) { - int k = 0; - for (const auto& it : constraint->coefficients_) { - const int var_index = it.first->index(); - CHECK(variable_is_extracted(var_index)); - indices[k] = var_index; - coefs[k] = it.second; - ++k; - } - - CheckReturnKey(SlmSetAConsI(model_,constraint->index(), k, indices, coefs)); -} - -// Define new constraints on old and new variables. -void SLMInterface::ExtractNewConstraints() { - int total_num_rows = solver_->constraints_.size(); - if (last_constraint_index_ < total_num_rows) { - // Find the length of the longest row. - int64 newanz = 0; - int64 oldanz = 0; - - int max_row_length = 0; - for (int i = last_constraint_index_; i < total_num_rows; ++i) { - MPConstraint* const ct = solver_->constraints_[i]; - CHECK(!constraint_is_extracted(i)); - set_constraint_as_extracted(i, true); - if (ct->coefficients_.size() > max_row_length) { - max_row_length = ct->coefficients_.size(); - } - - newanz += ct->coefficients_.size(); - } - - int addrows = total_num_rows - last_constraint_index_; - - // Add sizes for efficiens - CheckReturnKey(SlmGetANz64(model_,&oldanz)); - CheckReturnKey(SlmHintAMaxNz64(model_,newanz+oldanz)); - CheckReturnKey(SlmAddEmptyCons(model_,addrows)); - - // Make space for dummy variable. - max_row_length = std::max(1, max_row_length); - std::unique_ptr indices(new int[max_row_length]); - std::unique_ptr coefs(new double[max_row_length]); - - // Add each new constraint. - for (int i = last_constraint_index_; i < total_num_rows; ++i) { - MPConstraint* const ct = solver_->constraints_[i]; - CHECK(constraint_is_extracted(i)); - int size = ct->coefficients_.size(); - int j = 0; - for (const auto& it : ct->coefficients_) { - const int var_index = it.first->index(); - CHECK(variable_is_extracted(var_index)); - indices[j] = var_index; - coefs[j] = it.second; - j++; - } - - if( size > 0 ) { - CheckReturnKey(SlmSetAConsI(model_,i,size,indices.get(),coefs.get())); - } - - SetConstraintBounds(i, ct->lb(),ct->ub()); - - if (!ct->name().empty()) { - std::string std_name = ct->name(); - CheckReturnKey(SlmSetNameConsI(model_,ct->index(), std_name.c_str())); - } - } - } -} - -void SLMInterface::ExtractObjective() { - // Linear objective: set objective coefficients for all variables - // (some might have been modified). - for (hash_map::const_iterator it = - solver_->objective_->coefficients_.begin(); - it != solver_->objective_->coefficients_.end(); - ++it) { - CheckReturnKey(SlmSetObjVarsI(model_,it->first->index(), it->second)); - } - // Constant term. - CheckReturnKey(SlmSetObjFix(model_, solver_->Objective().offset())); -} - -// Solve the problem using the parameter values specified. -MPSolver::ResultStatus SLMInterface::Solve(const MPSolverParameters& param) { - WallTimer timer; - timer.Start(); - - // Note that SLM provides incrementality for LP but not for MIP. - if (param.GetIntegerParam(MPSolverParameters::INCREMENTALITY) == - MPSolverParameters::INCREMENTALITY_OFF) { - Reset(); - } - - // Set log level. - if (quiet_) { - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntLogLevel,0)); - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntSimLogLevel,0)); - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntLogNoModuleMessage,SlmOff)); - } else { - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntLogLevel,5)); - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntSimLogLevel,5)); - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntLogNoModuleMessage,SlmOn)); - } - - ExtractModel(); - VLOG(1) << StringPrintf("Model built in %.3f seconds.", timer.Get()); - - // Configure parameters at every solve, even when the model has not - // been changed, in case some of the parameters such as the time - // limit have been changed since the last solve. - ConfigureSLMParameters(param); - - // Solve - timer.Restart(); - - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntUpdateSolQuality,SlmOn)); - - CheckReturnKey(SlmOptimize(model_)); - - VLOG(1) << StringPrintf("Solved in %.3f seconds.", timer.Get()); - - // Get the results. - CheckReturnKey(SlmGetDbInfo(model_,SlmInfoDbPrimObj,&objective_value_)); - - VLOG(1) << "objective=" << objective_value_; - for (int i = 0; i < solver_->variables_.size(); ++i) { - MPVariable* const var = solver_->variables_[i]; - double val; - CheckReturnKey(SlmGetSolPrimVarsI(model_,var->index(),&val)); - var->set_solution_value(val); - VLOG(3) << var->name() << ": value =" << val; - if (!mip_) { - double reduced_cost; - CheckReturnKey(SlmGetSolDualVarsI(model_,var->index(),&reduced_cost)); - var->set_reduced_cost(reduced_cost); - VLOG(4) << var->name() << ": reduced cost = " << reduced_cost; - } - } - for (int i = 0; i < solver_->constraints_.size(); ++i) { - MPConstraint* const ct = solver_->constraints_[i]; - if (!mip_) { - double dual_value; - CheckReturnKey(SlmGetSolDualConsI(model_,ct->index(),&dual_value)); - ct->set_dual_value(dual_value); - VLOG(4) << "row " << ct->index() - << ": dual value = " << dual_value; - } - } - - // Check the status: optimal, infeasible, etc. - SlmSolStatus tmp_status; - CheckReturnKey(SlmGetSolStatus(model_,&tmp_status)); - - switch(tmp_status) - { - case SlmSolStatUnk : - VLOG(1) << "slm result status: SlmSolStatUnk"; - result_status_ = MPSolver::INFEASIBLE; /* What ever that means.. */ - break; - case SlmSolStatOpt : - VLOG(1) << "slm result status: SlmSolStatOpt"; - result_status_ = MPSolver::OPTIMAL; - break; - case SlmSolStatPrimFeas : - VLOG(1) << "slm result status: SlmSolStatPrimFeas"; - result_status_ = MPSolver::FEASIBLE; /* What ever that means.. */ - break; - case SlmSolStatDualFeas : - VLOG(1) << "slm result status: SlmSolStatDualFeas"; - result_status_ = MPSolver::FEASIBLE; /* What ever that means.. */ - break; - case SlmSolStatPrimInf : - VLOG(1) << "slm result status: SlmSolStatPrimInf"; - result_status_ = MPSolver::INFEASIBLE; - break; - case SlmSolStatDualInf : - VLOG(1) << "slm result status: SlmSolStatDualInf"; - result_status_ = MPSolver::UNBOUNDED; /* Theoretically not correct, you need a primal feasible point in LP */ - break; - case SlmSolStatIntFeas : - VLOG(1) << "slm result status: SlmSolStatIntFeas"; - result_status_ = MPSolver::FEASIBLE; - break; - case SlmSolStatIntInf : - VLOG(1) << "slm result status: SlmSolStatIntInf"; - result_status_ = MPSolver::INFEASIBLE; - break; - } - - sync_status_ = SOLUTION_SYNCHRONIZED; - - return result_status_; -} - -MPSolver::BasisStatus -SLMInterface::TransformSLMBasisStatus(SlmStatusKey slm_basis_status) const { - switch (slm_basis_status) { - case SlmStaBa: - return MPSolver::BASIC; - case SlmStaLo: - return MPSolver::AT_LOWER_BOUND; - case SlmStaUp: - return MPSolver::AT_UPPER_BOUND; - case SlmStaSb: - return MPSolver::FREE; - case SlmStaFx: - return MPSolver::FIXED_VALUE; - default: - LOG(FATAL) << "Unknown SLM basis status"; - return MPSolver::FREE; - } -} - -MPSolverInterface* BuildSLMInterface(MPSolver* const solver, bool mip) { - return new SLMInterface(solver, mip); -} - -// ------ Query statistics on the solution and the solve ------ - -int64 SLMInterface::iterations() const { - int iter; - CheckSolutionIsSynchronized(); - if(mip_) { - LOG(WARNING) << "Total number of iterations is not available"; - return kUnknownNumberOfIterations; - } - else { - CheckReturnKey(SlmGetIntInfo(model_,SlmInfoIntSimIter,&iter)); - } - - return static_cast(iter); -} - -int64 SLMInterface::nodes() const { - if (mip_) { - CheckSolutionIsSynchronized(); - int nodes; - CheckReturnKey(SlmGetIntInfo(model_,SlmInfoIntMipNodes,&nodes)); - return static_cast(nodes); - } else { - LOG(FATAL) << "Number of nodes only available for discrete problems"; - return kUnknownNumberOfNodes; - } -} - -double SLMInterface::best_objective_bound() const { - if (mip_) { - CheckSolutionIsSynchronized(); - CheckBestObjectiveBoundExists(); - if (solver_->variables_.size() == 0 && solver_->constraints_.size() == 0) { - // Special case for empty model. - return solver_->Objective().offset(); - } else { - double best_objective_bound; - CheckReturnKey(SlmGetDbInfo(model_,SlmInfoDbMipBoundLP,&best_objective_bound)); - return best_objective_bound; - } - } else { - LOG(FATAL) << "Best objective bound only available for discrete problems"; - return 0.0; - } -} - -MPSolver::BasisStatus SLMInterface::row_status(int constraint_index) const { - // + 1 because of SLM indexing convention. - DCHECK_LE(1, constraint_index); - DCHECK_GT(last_constraint_index_ + 1, constraint_index); - SlmStatusKey slm_basis_status; - CheckReturnKey(SlmGetSolKeyPrimConsI(model_,constraint_index,&slm_basis_status)); - return TransformSLMBasisStatus(slm_basis_status); -} - -MPSolver::BasisStatus SLMInterface::column_status(int variable_index) const { - // + 1 because of SLM indexing convention. - DCHECK_LE(1, variable_index); - DCHECK_GT(last_variable_index_ + 1, variable_index); - SlmStatusKey slm_basis_status; - CheckReturnKey(SlmGetSolKeyPrimVarsI(model_,variable_index,&slm_basis_status)); - return TransformSLMBasisStatus(slm_basis_status); -} - -bool SLMInterface::CheckSolutionExists() const { - if (result_status_ == MPSolver::ABNORMAL) { - LOG(WARNING) << "Ignoring ABNORMAL status from SLM: This status may or may" - << " not indicate that a solution exists."; - return false; - } else { - // Call default implementation - return MPSolverInterface::CheckSolutionExists(); - } -} - -bool SLMInterface::CheckBestObjectiveBoundExists() const { - if (result_status_ == MPSolver::ABNORMAL) { - LOG(WARNING) << "Ignoring ABNORMAL status from SLM: This status may or may" - << " not indicate that information is available on the best" - << " objective bound."; - return false; - } else { - // Call default implementation - return MPSolverInterface::CheckBestObjectiveBoundExists(); - } -} - -double SLMInterface::ComputeExactConditionNumber() const { - CHECK(IsContinuous()) << - "Condition number only available for continuous problems"; - CheckSolutionIsSynchronized(); - // Simplex is the only LP algorithm supported in the wrapper for - // SLM, so when a solution exists, a basis exists. - CheckSolutionExists(); - int num_rows; - int num_cols; - - CheckReturnKey(SlmGetCons(model_,&num_rows)); - CheckReturnKey(SlmGetVars(model_,&num_cols)); - - std::unique_ptr row_scaling_factor(new double[num_rows]); - std::unique_ptr column_scaling_factor(new double[num_cols]); - - for (int row = 0; row < num_rows; ++row) { - row_scaling_factor[row] = 1.0; - } - for (int col = 0; col < num_cols; ++col) { - column_scaling_factor[col] = 1.0; - } - - return - ComputeInverseScaledBasisL1Norm( - num_rows, num_cols, - row_scaling_factor.get(), column_scaling_factor.get()) * - ComputeScaledBasisL1Norm( - num_rows, num_cols, - row_scaling_factor.get(), column_scaling_factor.get()); -} - -double SLMInterface::ComputeScaledBasisL1Norm( - int num_rows, int num_cols, - double* row_scaling_factor, double* column_scaling_factor) const { - double norm = 0.0; - - std::unique_ptr values(new double[num_rows]); - std::unique_ptr indices(new int[num_rows]); - for (int col = 0; col < num_cols; ++col) { - SlmStatusKey slm_basis_status; - - CheckReturnKey(SlmGetSolKeyPrimVarsI(model_,col,&slm_basis_status)); - - // Take into account only basic columns. - if (slm_basis_status == SlmStaBa) { - // Compute L1-norm of column 'col': sum_row |a_row,col|. - int num_nz; - - CheckReturnKey(SlmGetAVarsI(model_, col,&num_nz,indices.get(), values.get())); - - double column_norm = 0.0; - for (int k = 0; k < num_nz; k++) { - column_norm += fabs(values[k] * row_scaling_factor[indices[k]]); - } - column_norm *= fabs(column_scaling_factor[col]); - // Compute max_col column_norm - norm = std::max(norm, column_norm); - } - } - // Slack variables. - for (int row = 0; row < num_rows; ++row) { - SlmStatusKey slm_basis_status; - - CheckReturnKey(SlmGetSolKeyPrimConsI(model_,row,&slm_basis_status)); - - // Take into account only basic slack variables. - if (slm_basis_status == SlmStaBa) { - // Only one non-zero coefficient: +/- 1.0 in the corresponding - // row. The row has a scaling coefficient but the slack variable - // is never scaled on top of that. - const double column_norm = fabs(row_scaling_factor[row]); - // Compute max_col column_norm - norm = std::max(norm, column_norm); - } - } - - return norm; -} - -double SLMInterface::ComputeInverseScaledBasisL1Norm( - int num_rows, int num_cols, - double* row_scaling_factor, double* column_scaling_factor) const { - - // Currently we just refactor each time - int ret = SlmInitBasisSolves(model_); - - // Compute the LU factorization if it doesn't exist yet. - if ( ret != SlmRetOk ) { - switch (ret) { - case SlmRetBasisSingular: { - LOG(WARNING) - << "Not able to factorize: " - << "the basis matrix is singular within the working precision."; - return MPSolver::infinity(); - } - default: - CheckReturnKey(ret); - break; - } - } - - std::unique_ptr right_hand_side(new double[num_rows]); - std::unique_ptr basidx(new int[num_rows]); - - CheckReturnKey(SlmGetBasisHead(model_,basidx.get())); - - double norm = 0.0; - - // Iteratively solve B x = e_k, where e_k is the kth unit vector. - // The result of this computation is the kth column of B^-1. - - for (int k = 0; k < num_rows; ++k) { - for (int row = 0; row < num_rows; ++row) { - right_hand_side[row] = 0.0; - } - right_hand_side[k] = 1.0; - // Multiply input by inv(R). - for (int row = 0; row < num_rows; ++row) { - right_hand_side[row] /= row_scaling_factor[row]; - } - - CheckReturnKey(SlmSolveFtranDense(model_, right_hand_side.get())); - - // stores the result in the same vector where the right - // hand side was provided. - // Multiply result by inv(SB). - for (int row = 0; row < num_rows; ++row) { - const int k = basidx[row]; - if (k <= num_rows) { - // Auxiliary variable. - right_hand_side[row] *= row_scaling_factor[k]; - } else { - // Structural variable. - right_hand_side[row] /= column_scaling_factor[k - num_rows]; - } - } - - // Compute sum_row |vector_row|. - double column_norm = 0.0; - for (int row = 0; row < num_rows; ++row) { - column_norm += fabs(right_hand_side[row]); - } - - // Compute max_col column_norm - norm = std::max(norm, column_norm); - } - - return norm; -} - -// ------ Parameters ------ - -void SLMInterface::ConfigureSLMParameters(const MPSolverParameters& param) { - // Time limit - if (solver_->time_limit()) { - VLOG(1) << "Setting time limit = " << solver_->time_limit() << " ms."; - CheckReturnKey(SlmSetDbParam(model_,SlmPrmDbOptTimeLimit,solver_->time_limit())); - } - else - { - CheckReturnKey(SlmSetDbParam(model_,SlmPrmDbOptTimeLimit,DBL_MAX)); - } - - // Set parameters specified by the user. - SetParameters(param); -} - -void SLMInterface::SetParameters(const MPSolverParameters& param) { - SetCommonParameters(param); - if (mip_) { - SetMIPParameters(param); - } -} - -void SLMInterface::SetRelativeMipGap(double value) { - if (mip_) { - CheckReturnKey(SlmSetDbParam(model_,SlmPrmDbMipTolRelGap, value)); - } else { - LOG(WARNING) << "The relative MIP gap is only available " - << "for discrete problems."; - } -} - -void SLMInterface::SetPrimalTolerance(double value) { - CheckReturnKey(SlmSetDbParam(model_,SlmPrmDbSimTolPrim, value)); -} - -void SLMInterface::SetDualTolerance(double value) { - CheckReturnKey(SlmSetDbParam(model_,SlmPrmDbSimTolDual, value)); -} - -void SLMInterface::SetPresolveMode(int value) { - switch (value) { - case MPSolverParameters::PRESOLVE_OFF: { - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntPresolve,SlmPreOff)); - break; - } - case MPSolverParameters::PRESOLVE_ON: { - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntPresolve,SlmPreFree)); - break; - } - default: { - SetIntegerParamToUnsupportedValue(MPSolverParameters::PRESOLVE, value); - } - } -} - -void SLMInterface::SetLpAlgorithm(int value) { - switch (value) { - case MPSolverParameters::DUAL: { - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntOptimizer,SlmOptDual)); - break; - } - case MPSolverParameters::PRIMAL: { - CheckReturnKey(SlmSetIntParam(model_,SlmPrmIntOptimizer,SlmOptPrim)); - break; - } - case MPSolverParameters::BARRIER: - default: { - SetIntegerParamToUnsupportedValue(MPSolverParameters::LP_ALGORITHM, - value); - } - } -} - -void SLMInterface::SetScalingMode(int value) { - SetUnsupportedIntegerParam(MPSolverParameters::SCALING); -} -} // namespace operations_research -#endif // #if defined(USE_SLM)