From adb7d6ea01d5bd768a4101747da280a606f99d39 Mon Sep 17 00:00:00 2001 From: Hassan Date: Tue, 8 Dec 2020 00:18:08 -0700 Subject: [PATCH] adding MP readNL in this branch --- CMakeLists.txt | 20 +--- cmake/ExternalCoinUtils.cmake | 12 -- cmake/ExternalMP.cmake | 14 +-- cmake/FindGUROBI.cmake | 18 ++- cmake/FindMP.cmake | 3 +- examples/Gravity_test.cpp | 13 +- include/gravity/func.h | 4 +- include/gravity/model.h | 192 +++++++++++++++++++++++++++-- include/gravity/param.h | 2 +- include/gravity/utils.h | 16 --- include/gravity/var.h | 2 +- src/CMakeLists.txt | 10 +- src/model.cpp | 220 +++++++++++++++++++++++++++++----- 13 files changed, 414 insertions(+), 112 deletions(-) mode change 100755 => 100644 cmake/FindGUROBI.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 32934e661..f0feab3e5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ option(Ipopt "Link to IPOPT libraries" ON) option(MP "Link to AMPL MP libraries" OFF) -option(CoinUtils "Link to CoinUtils libraries" OFF) +option(CoinUtils "Link to CoinUtils libraries" ON) # Find XLNT (optional) option(Xlnt "Link to XLNT libraries" OFF) @@ -196,6 +196,8 @@ set(THIRDPARTY_INSTALL_PATH ${THIRDPARTY_BASE_PATH}) if(NOT WIN32) #CoinUtils if (CoinUtils) +include(ExternalProject) +#CoinUtils message(STATUS "Enable CoinUtils") add_definitions(-DUSE_CoinUtils) find_package(CoinUtils QUIET) @@ -217,11 +219,13 @@ endif(CoinUtils) #MP if (MP) +#MP message(STATUS "Enable AMPL MP") add_definitions(-DUSE_MP) find_package(MP QUIET) if (MP_FOUND) message("-- Found AMPL MP: ${MP_INCLUDE_DIRS}") + message("-- Found AMPL MP: ${CoinUtils_INCLUDE_DIRS}") include_directories(${MP_INCLUDE_DIRS}/..) set(LIBS ${LIBS} ${MP_LIBRARIES}) else(MP_FOUND) @@ -258,19 +262,6 @@ endif(HiGHS) if(Ipopt) -# Add Ipopt include dir and link to libraries -if(WIN32) -# include_directories("${PROJECT_SOURCE_DIR}/thirdparty/Ipopt") -include_directories("${PROJECT_SOURCE_DIR}/thirdparty/Ipopt/include/coin-or") -# add_subdirectory(thirdparty/Ipopt) -# find_library(IPOPT_LIBRARIES -# ipopt.dll -# HINTS /usr/local/lib -# HINTS ${PROJECT_SOURCE_DIR}/thirdparty/Ipopt -# HINTS ${IPOPT_ROOT_DIR}/lib -# ) -endif(WIN32) - message(STATUS "Enable IPOPT") add_definitions(-DUSE_IPOPT) find_package(IPOPT QUIET) @@ -288,6 +279,7 @@ elseif(WIN32) set(IPOPT_LIBRARIES ${PROJECT_SOURCE_DIR}/thirdparty/Ipopt/libipopt-3.lib) endif(APPLE) include(ExternalIpopt) + set(IPOPT_LIBRARIES ${THIRDPARTY_INSTALL_PATH}/Install/ipopt/build/lib/libipopt.so) endif (IPOPT_FOUND) endif(Ipopt) diff --git a/cmake/ExternalCoinUtils.cmake b/cmake/ExternalCoinUtils.cmake index 4bf12cbec..ea2ef45bf 100644 --- a/cmake/ExternalCoinUtils.cmake +++ b/cmake/ExternalCoinUtils.cmake @@ -4,17 +4,6 @@ unset(CoinUtils_HOME) # Download and build the CoinUtils library and add its properties to the third party arguments. set(CoinUtils_ROOT_DIR ${THIRDPARTY_INSTALL_PATH}/Install/CoinUtils/build CACHE INTERNAL "") -if(WIN32) -ExternalProject_Add(coinutils - DOWNLOAD_DIR ${THIRDPARTY_INSTALL_PATH} - DOWNLOAD_COMMAND git clone ${CoinUtils_DOWNLOAD_URL} && rmdir -fr ./Install/CoinUtils && move CoinUtils ./Install/CoinUtils && cd ./Install/CoinUtils && mkdir build && cd build && ../configure --prefix=${CoinUtils_ROOT_DIR} && make -j && make install - URL ${CoinUtils_DOWNLOAD_URL} - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CoinUtils_ROOT_DIR} - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" -) -else() ExternalProject_Add(coinutils DOWNLOAD_DIR ${THIRDPARTY_INSTALL_PATH} DOWNLOAD_COMMAND export HTTPS_PROXY=$ENV{HTTPS_PROXY} && git clone ${CoinUtils_DOWNLOAD_URL} && rm -fr ./Install/CoinUtils && mv CoinUtils ./Install/CoinUtils && cd ./Install/CoinUtils && mkdir build && cd build && ../configure --prefix=${CoinUtils_ROOT_DIR} && make -j24 && make install @@ -24,7 +13,6 @@ ExternalProject_Add(coinutils BUILD_COMMAND "" INSTALL_COMMAND "" ) -endif() list(APPEND GLOBAL_THIRDPARTY_LIB_ARGS "-DCoinUtils_ROOT_DIR:PATH=${CoinUtils_ROOT_DIR}") set(CoinUtils_INCLUDE_DIRS ${THIRDPARTY_INSTALL_PATH}/Install/CoinUtils/build/include/coin-or) include_directories(${CoinUtils_INCLUDE_DIRS}) diff --git a/cmake/ExternalMP.cmake b/cmake/ExternalMP.cmake index a3ffbc409..59e683af4 100644 --- a/cmake/ExternalMP.cmake +++ b/cmake/ExternalMP.cmake @@ -4,27 +4,15 @@ unset(MP_HOME) # Download and build the MP library and add its properties to the third party arguments. set(MP_ROOT_DIR ${THIRDPARTY_INSTALL_PATH}/Install/MP CACHE INTERNAL "") -if(WIN32) ExternalProject_Add(mp DOWNLOAD_DIR ${THIRDPARTY_INSTALL_PATH} - DOWNLOAD_COMMAND git clone ${MP_DOWNLOAD_URL} && rmdir -fr ./Install/MP && move mp ./Install/MP && cd ./Install/MP && mkdir build && cd build && cmake .. && make mp -j + DOWNLOAD_COMMAND export HTTPS_PROXY=$ENV{HTTPS_PROXY} && git clone ${MP_DOWNLOAD_URL} && rm -fr ./Install/MP && mv mp ./Install/MP && cd ./Install/MP && git submodule init && git submodule update && mkdir build && cd build && cmake -DBUILD=all .. && make -j24 URL ${MP_DOWNLOAD_URL} CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${MP_ROOT_DIR} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" ) -else() -ExternalProject_Add(mp - DOWNLOAD_DIR ${THIRDPARTY_INSTALL_PATH} - DOWNLOAD_COMMAND export HTTPS_PROXY=$ENV{HTTPS_PROXY} && git clone ${MP_DOWNLOAD_URL} && rm -fr ./Install/MP && mv mp ./Install/MP && cd ./Install/MP && mkdir build && cd build && cmake .. && make mp -j - URL ${MP_DOWNLOAD_URL} - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${MP_ROOT_DIR} - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" -) -endif() list(APPEND GLOBAL_THIRDPARTY_LIB_ARGS "-DMP_ROOT_DIR:PATH=${MP_ROOT_DIR}") set(MP_INCLUDE_DIRS ${THIRDPARTY_INSTALL_PATH}/Install/MP/include) diff --git a/cmake/FindGUROBI.cmake b/cmake/FindGUROBI.cmake old mode 100755 new mode 100644 index 40e7ee656..1d4907d37 --- a/cmake/FindGUROBI.cmake +++ b/cmake/FindGUROBI.cmake @@ -1,13 +1,12 @@ set(GUROBI_ROOT_DIR "$ENV{GUROBI_ROOT_DIR}" CACHE PATH "Gurobi root directory.") -set(GUROBI_VERSION_SHORT 119) message("Gurobi root" ${GUROBI_ROOT_DIR}) if(APPLE) -file(GLOB dirs /Library/gurobi1*) +file(GLOB dirs /Library/gurobi*) foreach(d in ${dirs}) string(REGEX MATCH "[0-9]+" GUROBI_VERSION "${d}") endforeach(d) elseif(UNIX) -file(GLOB dirs ${GUROBI_ROOT_DIR}/gurobi1*) +file(GLOB dirs ${GUROBI_ROOT_DIR}/gurobi*) foreach(d in ${dirs}) string(REGEX MATCH "[0-9]+" GUROBI_VERSION "${d}") endforeach(d) @@ -20,25 +19,24 @@ elseif(UNIX) string(CONCAT GUROBI_DIR ${GUROBI_ROOT_DIR};/gurobi;${GUROBI_VERSION};/linux64) endif() message("Looking for Gurobi in ${GUROBI_DIR}") -if(${GUROBI_DIR}) + string(SUBSTRING ${GUROBI_VERSION} 0 3 GUROBI_VERSION_SHORT) -endif() + message("Gurobi version short ${GUROBI_VERSION_SHORT}") -find_path(GUROBI_INCLUDE_DIR gurobi_c++.h HINTS "${GUROBI_DIR}/include" "${GUROBI_ROOT_DIR}/include") +find_path(GUROBI_INCLUDE_DIR gurobi_c++.h HINTS "${GUROBI_DIR}/include") if(APPLE) -find_library(GUROBI_LIBRARY libgurobi${GUROBI_VERSION_SHORT}.dylib HINTS ${GUROBI_DIR}/lib ${GUROBI_ROOT_DIR}/lib/macos_universal2) +find_library(GUROBI_LIBRARY libgurobi${GUROBI_VERSION_SHORT}.dylib HINTS ${GUROBI_DIR}/lib) elseif(UNIX) find_library(GUROBI_LIBRARY libgurobi${GUROBI_VERSION_SHORT}.so HINTS ${GUROBI_DIR}/lib) endif() -message("GUROBI_DIR ${GUROBI_DIR}") -find_library(GUROBI_CPP_LIBRARY libgurobi_c++.a HINTS "${GUROBI_DIR}/lib" ${GUROBI_ROOT_DIR}/lib/macos_universal2) +find_library(GUROBI_CPP_LIBRARY libgurobi_c++.a HINTS "${GUROBI_DIR}/lib") message("GUROBI_CPP_LIBRARY ${GUROBI_CPP_LIBRARY}") include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GUROBI DEFAULT_MSG GUROBI_LIBRARY GUROBI_CPP_LIBRARY GUROBI_INCLUDE_DIR) if(GUROBI_FOUND) - set(GRB_LICENSE_FILE "~/gurobi/gurobi.lic") + set(GRB_LICENSE_FILE "~/gurobi.research.lic") set(GUROBI_INCLUDE_DIRS ${GUROBI_INCLUDE_DIR}) set(GUROBI_LIBRARIES ${GUROBI_CPP_LIBRARY} ${GUROBI_LIBRARY}) message("CMAKE_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}") diff --git a/cmake/FindMP.cmake b/cmake/FindMP.cmake index a59108837..d9f8f8787 100755 --- a/cmake/FindMP.cmake +++ b/cmake/FindMP.cmake @@ -20,7 +20,8 @@ include(FindPackageHandleStandardArgs) find_package_handle_standard_args(MP DEFAULT_MSG MP_LIBRARY MP_INCLUDE_DIR) if(MP_FOUND) - message("—- Found MP under ${MP_INCLUDE_DIR}") + message("—- Found MP include under ${MP_INCLUDE_DIR}") + message("—- Found MP lib under ${MP_LIBRARY}") set(MP_INCLUDE_DIRS ${MP_INCLUDE_DIR}) set(MP_LIBRARIES ${MP_LIBRARY}) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") diff --git a/examples/Gravity_test.cpp b/examples/Gravity_test.cpp index 4cd097796..dbbeaf3fc 100755 --- a/examples/Gravity_test.cpp +++ b/examples/Gravity_test.cpp @@ -22,10 +22,17 @@ using namespace std; using namespace gravity; -TEST_CASE("testing MISDP solvers"){ - var<> x1("x1", -10, 150); - + +#ifdef USE_MP +TEST_CASE("testing readNL() function") { + Model<> M; + string NL_file = string(prj_dir)+"/data_sets/NL/ex4.nl"; + int status = M.readNL(NL_file); + CHECK(status==0); + CHECK(M.get_nb_vars()==36); + CHECK(M.get_nb_cons()==30); } +#endif TEST_CASE("testing range update"){ var<> x1("x1", -10, 150); diff --git a/include/gravity/func.h b/include/gravity/func.h index 6fda2e6ac..2ac1beeca 100755 --- a/include/gravity/func.h +++ b/include/gravity/func.h @@ -9697,12 +9697,12 @@ namespace gravity { else if(!f.is_constant()){ res._all_convexity = undet_; } - res._range->first = log(f._range->first); + res._range->first = std::log(f._range->first); if(f._range->second==numeric_limits::max()){ res._range->second = numeric_limits::max(); } else { - res._range->second = log(f._range->second); + res._range->second = std::log(f._range->second); } res._expr->_range->first = res._range->first; res._expr->_range->second = res._range->second; diff --git a/include/gravity/model.h b/include/gravity/model.h index 853424c29..1c4b280b7 100755 --- a/include/gravity/model.h +++ b/include/gravity/model.h @@ -35,6 +35,12 @@ #ifdef USE_BONMIN #include #endif +#include "mp/nl.h" +#include "mp/problem.h" +#include "CoinMpsIO.hpp" +#include "CoinFileIO.hpp" +#include "CoinModel.hpp" +#include "mp/expr-visitor.h" #include #include @@ -44,6 +50,7 @@ using namespace std; namespace gravity { + /** This function is used to rank constraints based on violation first and then sparsity second @param[in] tuple the first element in the tuple represents the violation magnitude, the second is the sparsity degree of the contraint, the third is the constraint id, and the last is the instance id */ @@ -57,13 +64,13 @@ const bool cstr_viol_compare(const tuple(c1) < get<1>(c2));// Second, rank based on increasing sparsity, lower sparsity lead to higher ranking. } - template - const bool cstr_compare(const shared_ptr>& c1, const shared_ptr>& c2) { - if(c1->get_nb_inst() > c2->get_nb_inst()) - return true; - return false; +template +const bool cstr_compare(const shared_ptr>& c1, const shared_ptr>& c2) { + if(c1->get_nb_inst() > c2->get_nb_inst()) + return true; + return false; // return c1->nb_linear_terms() > c2->nb_linear_terms(); - } +} const bool var_compare(const pair>& v1, const pair>& v2); @@ -7926,7 +7933,60 @@ const bool var_compare(const pair>& v1, const paireval(c,i,j); } - + int readMPS(const string& fname){ + //string mps_file = "/Users/l297598/Downloads/fhnw-binpack4-58.mps", gms_file="/Users/l297598/Downloads/nvs24.gms"; + CoinMpsIO m; + CoinMessageHandler* handler_ = new CoinMessageHandler();; + m.passInMessageHandler(handler_); + bool savePrefix = m.messageHandler()->prefix(); + m.messageHandler()->setPrefix(handler_->prefix()); + m.setSmallElementValue(m.getSmallElementValue()); + int status = 0; + try { + status = m.readMps(fname.c_str(), ""); + // status = m.readGms(gms_file.c_str()); + auto nb_vars = m.getNumCols(); + DebugOn("The number of variables is " << nb_vars << endl); + auto nb_cstr = m.getNumRows(); + DebugOn("The number of constraints is " << nb_cstr << endl); + if (m.reader()->whichSection() == COIN_QUAD_SECTION) { + CoinBigIndex *start = NULL; + int *column = NULL; + double *element = NULL; + status = m.readQuadraticMps(NULL, start, column, element, 2); + if (!status){ + // loadQuadraticObjective(nb_vars, start, column, element); + } + delete[] start; + delete[] column; + delete[] element; + } + if (m.reader()->whichSection() == COIN_CONIC_SECTION) { + CoinBigIndex *start = NULL; + int *column = NULL; + double *element = NULL; + int * coneType = NULL; + int nbCones = 0; + status = m.readConicMps(NULL, start, column, coneType, nbCones); + if (!status){ + // loadQuadraticObjective(nb_vars, start, column, element); + } + DebugOn("Problem has " << nbCones << " Cones" << endl); + delete[] start; + delete[] column; + delete[] coneType; + } + } + catch (CoinError e) { + e.print(); + status = -1; + } + delete handler_; + return status; + } + + template::value>::type* = nullptr> + int readNL(const string& fname); }; // void compute_constrs(vector& v, double* res, unsigned i, unsigned j); @@ -8104,6 +8164,124 @@ const bool var_compare(const pair>& v1, const pair> { + public: + + MPConverter(Model<>& m): _model(&m){}; + + Model<>* _model = nullptr; + + func<> VisitPow2(UnaryExpr e) { + return pow(Visit(e.arg()),2); + } + + + double VisitNumericConstant(mp::NumericConstant c) { + return (c.value()); + } + + func<> VisitMinus(UnaryExpr e) { + return -1*Visit(e.arg()); + } + + func<> VisitSum(SumExpr e){ + func<> sum; + for (SumExpr::iterator i = e.begin(), end = e.end(); i != end; ++i){ + sum += Visit(*i); + } + return sum; + } + + var<> get_cont_int_var(int index){ + auto x = _model->get_var("x"); + auto y = _model->get_var("y"); + if(index >= y.get_id())/* Integer variable */ + return y(index); + /* Continuous variable */ + return x(index); + } + + var<> VisitVariable(mp::Reference r) { + return get_cont_int_var(r.index()); + } + + double VisitConstant(NumericConstant n) { return n.value(); } +// func<> Visit(NumericExpr e) { +// return ExprVisitor>::Visit(e); +// } + func<> VisitAdd(BinaryExpr e) { + return Visit(e.lhs()) + Visit(e.rhs()); + } + + func<> VisitSub(BinaryExpr e) { + return Visit(e.lhs()) - Visit(e.rhs()); + } + + func<> VisitMul(BinaryExpr e) { + return Visit(e.lhs()) * Visit(e.rhs()); + } + + func<> VisitDiv(BinaryExpr e) { + return Visit(e.lhs()) / Visit(e.rhs()); + } + + + func<> VisitPow(BinaryExpr e) { + return pow(Visit(e.lhs()), Visit(e.rhs()).eval()); + } + +// func<> VisitLess(BinaryExpr e) { +// return IloMax(Visit(e.lhs()) - Visit(e.rhs()), 0.0); +// } +// +// func<> VisitMin(VarArgExpr e) { +// return IloMin(ConvertArgs(e)); +// } +// +// func<> VisitMax(VarArgExpr e) { +// return IloMax(ConvertArgs(e)); +// } +// +// func<> VisitMinus(UnaryExpr e) { +// return -Visit(e.arg()); +// } + + func<> VisitAbs(UnaryExpr e) { + return abs(Visit(e.arg())); + } + + func<> VisitSin(UnaryExpr e) { + return sin(Visit(e.arg())); + } + + func<> VisitCos(UnaryExpr e) { + return cos(Visit(e.arg())); + } + + func<> VisitSqrt(UnaryExpr e) { + return sqrt(Visit(e.arg())); + } + + func<> VisitExp(UnaryExpr e) { + return exp(Visit(e.arg())); + } + + func<> VisitLog(UnaryExpr e) { + return log(Visit(e.arg())); + } +// func<> VisitFloor(UnaryExpr e) { +// return IloFloor(Visit(e.arg())); +// } +// +// func<> VisitCeil(UnaryExpr e) { +// return IloCeil(Visit(e.arg())); +// } + }; + + + } diff --git a/include/gravity/param.h b/include/gravity/param.h index d3a7f152f..582fb2fb5 100755 --- a/include/gravity/param.h +++ b/include/gravity/param.h @@ -93,7 +93,7 @@ namespace gravity { _imag = p._imag; _mag = p._mag; _ang = p._ang; _indices = p._indices; _off=p._off; - _in=make_shared(*p._in); + _in=p._in; _dim[0] = p._dim[0]; _dim[1] = p._dim[1]; } diff --git a/include/gravity/utils.h b/include/gravity/utils.h index 217cd2254..479de909c 100644 --- a/include/gravity/utils.h +++ b/include/gravity/utils.h @@ -9,22 +9,6 @@ #define Gravity___Utils_h //the following are UBUNTU/LINUX ONLY terminal color codes. #define RESET "\033[0m" -#define BLACK "\033[30m" /* Black */ -#define RED "\033[31m" /* Red */ -#define GREEN "\033[32m" /* Green */ -#define YELLOW "\033[33m" /* Yellow */ -#define BLUE "\033[34m" /* Blue */ -#define MAGENTA "\033[35m" /* Magenta */ -#define CYAN "\033[36m" /* Cyan */ -#define WHITE "\033[37m" /* White */ -#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */ -#define BOLDRED "\033[1m\033[31m" /* Bold Red */ -#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */ -#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */ -#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */ -#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */ -#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */ -#define BOLDWHITE "\033[1m\033[37m" /* Bold White */ #ifdef USE_OPT_PARSER #include #endif diff --git a/include/gravity/var.h b/include/gravity/var.h index 2a14156c4..0b0aa32d5 100644 --- a/include/gravity/var.h +++ b/include/gravity/var.h @@ -267,7 +267,7 @@ namespace gravity { (res._ub->in(*res._indices)); } // res._range = make_shared>(res._lb->_range->first,res._ub->_range->second); - res._range = make_shared>(res._lb->eval(t1, args...),res._ub->eval(t1, args...)); +// res._range = make_shared>(res._lb->eval(t1, args...),res._ub->eval(t1, args...)); return res; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f9e4582cf..c8e6a6d1d 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,6 +60,12 @@ endif() add_library(gravity STATIC ${SOURCES} ${HEADERS}) +if(ADD_MP) + add_dependencies(gravity mp) +endif() +if(ADD_CoinUtils) + add_dependencies(gravity coinutils) +endif() if(ADD_EIGEN) add_dependencies(gravity eigen) endif(ADD_EIGEN) @@ -73,11 +79,11 @@ endif() if(OPT_PARSER) add_dependencies(gravity opt_parser) -target_link_libraries(gravity ${CPLEX_LIBRARIES} ${GUROBI_LIBRARIES} ${LASlib_LIBRARIES} ${IPOPT_LIBRARIES} ${BONMIN_LIBRARIES} ${SDPA_LIBRARIES} ${MOSEK_LIBRARIES} ${XLNT_LIBRARIES} ${OpenMPI_LIBRARIES} ${QHULL_LIBRARIES} liboption_parser.a nlohmann_json::nlohmann_json) +target_link_libraries(gravity ${CPLEX_LIBRARIES} ${GUROBI_LIBRARIES} ${LASlib_LIBRARIES} ${IPOPT_LIBRARIES} ${BONMIN_LIBRARIES} ${SDPA_LIBRARIES} ${MOSEK_LIBRARIES} ${XLNT_LIBRARIES} ${OpenMPI_LIBRARIES} ${QHULL_LIBRARIES} ${MP_LIBRARY} ${CoinUtils_LIBRARY} liboption_parser.a nlohmann_json::nlohmann_json) endif() if(NOT OPT_PARSER) -target_link_libraries(gravity ${CPLEX_LIBRARIES} ${GUROBI_LIBRARIES} ${LASlib_LIBRARIES} ${IPOPT_LIBRARIES} ${BONMIN_LIBRARIES} ${SDPA_LIBRARIES} ${MOSEK_LIBRARIES} ${XLNT_LIBRARIES} ${OpenMPI_LIBRARIES} ${QHULL_LIBRARIES} nlohmann_json::nlohmann_json) +target_link_libraries(gravity ${CPLEX_LIBRARIES} ${GUROBI_LIBRARIES} ${LASlib_LIBRARIES} ${IPOPT_LIBRARIES} ${BONMIN_LIBRARIES} ${SDPA_LIBRARIES} ${MOSEK_LIBRARIES} ${XLNT_LIBRARIES} ${OpenMPI_LIBRARIES} ${QHULL_LIBRARIES} ${MP_LIBRARY} ${CoinUtils_LIBRARY} nlohmann_json::nlohmann_json) endif() if(Matplot) diff --git a/src/model.cpp b/src/model.cpp index c59f8a9c5..ef2705e16 100755 --- a/src/model.cpp +++ b/src/model.cpp @@ -6669,9 +6669,9 @@ template void Model::update_upper_bound(shared_ptr>& obbt_model, vector>>& batch_models, vector& ub_sol, SolverType ub_solver_type, double ub_solver_tol, bool& terminate, bool linearize, double& upper_bound, double lb_scale_value, double lower_bound, double& gap, const double abs_tol, const double rel_tol, const double zero_tol){ { #ifdef USE_MPI - int worker_id, nb_workers; - auto err_rank = MPI_Comm_rank(MPI_COMM_WORLD, &worker_id); - auto err_size = MPI_Comm_size(MPI_COMM_WORLD, &nb_workers); + int worker_id, nb_workers; + auto err_rank = MPI_Comm_rank(MPI_COMM_WORLD, &worker_id); + auto err_size = MPI_Comm_size(MPI_COMM_WORLD, &nb_workers); #endif this->copy_bounds(obbt_model); this->copy_solution(obbt_model); @@ -6684,34 +6684,34 @@ void Model::update_upper_bound(shared_ptr>& obbt_model, vector if(new_ub<=(upper_bound-1e-3)){ upper_bound = new_ub; get_solution(ub_sol); - + #ifdef USE_MPI if(worker_id==0){ #endif - DebugOn("Found a better feasible point!"< ub("ub"); - ub = upper_bound/lb_scale_value; - func obj; - obj.deep_copy(*obbt_model->_obj); - Constraint obj_ub("obj|ub"); - obj_ub = obj - ub; - mod->add(obj_ub<=0); - } - else { - auto ub = static_pointer_cast>(mod->get_constraint("obj|ub")->_params->begin()->second.first); - ub->set_val(upper_bound/lb_scale_value); - mod->reset_constrs(); + for(auto &mod:batch_models){ + if(mod->_cons_name.count("obj|ub")==0){ + param<> ub("ub"); + ub = upper_bound/lb_scale_value; + func obj; + obj.deep_copy(*obbt_model->_obj); + Constraint obj_ub("obj|ub"); + obj_ub = obj - ub; + mod->add(obj_ub<=0); + } + else { + auto ub = static_pointer_cast>(mod->get_constraint("obj|ub")->_params->begin()->second.first); + ub->set_val(upper_bound/lb_scale_value); + mod->reset_constrs(); + } } - } - - DebugOff("I have updated all batch models with new ub!\n"); + + DebugOff("I have updated all batch models with new ub!\n"); } gap=(upper_bound- lower_bound)/(std::abs(upper_bound)+zero_tol)*100; DebugOff("Gap "<::update_upper_bound(shared_ptr>& obbt_model, vector terminate=true; } - + } } else { if(status_old==0){ - set_solution(ub_sol); - _obj->set_val(upper_bound); - _status=0; + set_solution(ub_sol); + _obj->set_val(upper_bound); + _status=0; + } + } + } +} + +template +template::value>::type*> +int Model::readNL(const string& fname){ + mp::Problem p; + mp::ReadNLFile(fname, p); + auto nb_vars = p.num_vars(); + auto nb_cstr = p.num_algebraic_cons(); + DebugOn("The number of variables is " << nb_vars << endl); + DebugOn("The number of constraints is " << nb_cstr << endl); + indices C("C"), I("I"), LinConstr("LinConstr"), QuadConstr("QuadConstr"), NonLinConstr("NonLinConstr"); + int nb_cont = 0; + int nb_int = 0; + int nb_other = 0; + vector C_ids,I_ids; + for (const auto v: p.vars()) { + if(v.type()==mp::var::CONTINUOUS){ + nb_cont++; + C.insert(to_string(v.index())); + C_ids.push_back(v.index()); + } + else if(v.type()==mp::var::INTEGER){ + I.insert(to_string(v.index())); + I_ids.push_back(v.index()); + nb_int++; + } + else{ + throw invalid_argument("Unrecognised variable type, can only be continuous or integer"); + } + } + DebugOn("Number of continuous variables = " << nb_cont << endl); + DebugOn("Number of integer variables = " << nb_int << endl); + + param<> x_ub("x_ub"), x_lb("x_lb"); + param y_ub("y_ub"), y_lb("y_lb"); + x_ub.in(C);x_lb.in(C); + y_ub.in(I);y_lb.in(I); + for (int i = 0; i x("x", x_lb, x_ub); + var y("y", y_lb, y_ub); + + param<> rhs("rhs"); + int nb_lin = 0; + int nb_nonlin = 0; + int index = 0; + _name = fname; + + add(x.in(C)); + add(y.in(I)); + + replace_integers(); + + MPConverter converter(*this); + map> constr_sparsity; + vector C_lin, C_nonlin, C_quad; + for (const auto con: p.algebraic_cons()) { + auto lexpr = con.linear_expr(); + auto nl_expr = con.nonlinear_expr(); + if (nl_expr){ + auto expr = converter.Visit(nl_expr); + expr.print(); + nb_nonlin++; + C_nonlin.push_back(index); + NonLinConstr.insert(to_string(index)); + for (const auto term: lexpr){ + auto coef = term.coef(); + auto var_id = term.var_index(); + expr += coef*converter.get_cont_int_var(var_id); + } + + auto c_lb = con.lb(); + auto c_ub = con.ub(); + if(c_lb==c_ub){ + Constraint<> c("NL_C_eq_"+to_string(index)); + c += expr; + add(c == c_lb); + } + else { + if(c_lb>numeric_limits::lowest()){ + Constraint<> c("NL_C_lb_"+to_string(index)); + c += expr; + add(c >= c_lb); + } + if(c_ub::max()){ + Constraint<> c("NL_C_ub_"+to_string(index)); + c += expr; + add(c <= c_ub); + } + } + } + else{ + int nb_terms = lexpr.num_terms(); + constr_sparsity[nb_terms].push_back(index); + func<> expr; + for (const auto term: lexpr){ + auto coef = term.coef(); + auto var_id = term.var_index(); + expr += coef*converter.get_cont_int_var(var_id); + } + + auto c_lb = con.lb(); + auto c_ub = con.ub(); + if(c_lb==c_ub){ + Constraint<> c("Lin_C_eq_"+to_string(index)); + c += expr; + add(c == c_lb); + } + else { + if(c_lb>numeric_limits::lowest()){ + Constraint<> c("Lin_C_lb_"+to_string(index)); + c += expr; + add(c >= c_lb); + } + if(c_ub::max()){ + Constraint<> c("Lin_C_ub_"+to_string(index)); + c += expr; + add(c <= c_ub); + } } + LinConstr.insert(to_string(index)); + C_lin.push_back(index); + nb_lin++; } + + index++; } + DebugOn("Number of linear constraints = " << nb_lin << endl); + DebugOn("Number of non linear constraints = " << nb_nonlin << endl); + DebugOn("Number of sparsity degrees for linear constraints = " << constr_sparsity.size() << endl); + + print(); + return 0; } + + + +// template std::tuple gravity::Model::run_obbt(shared_ptr> relaxed_model, double max_time, unsigned max_iter, double rel_tol, double abs_tol, unsigned nb_threads, SolverType ub_solver_type, SolverType lb_solver_type, double ub_solver_tol, double lb_solver_tol, double range_tol, bool linearize); +// +// template std::tuple gravity::Model::run_obbt_one_iteration(shared_ptr> relaxed_model, double max_time, unsigned max_iter, double rel_tol, double abs_tol, unsigned nb_threads, SolverType ub_solver_type, SolverType lb_solver_type, double ub_solver_tol, double lb_solver_tol, double range_tol, bool linearize, shared_ptr> obbt_model, Model & interior_model); + + template Constraint Model::lift(Constraint& c, string model_type); + template Constraint<> Model<>::lift(Constraint<>& c, string model_type); + template int gravity::Model::readNL(const string&); + + + // template void Model::run_obbt(double max_time, unsigned max_iter); + // template func constant::get_real() const; + // template class Model; + // template class Model; + +} + template template void Model::batch_models_obj_lb_constr(vector>>& batch_models, int nb_threads, double lower_bound_lin, double lower_bound_old, double lower_bound_nonlin_init, double upper_bound, double ub_scale_value){ @@ -7208,6 +7367,7 @@ std::tuple Model std::get<10>(res)=fail; return res; } + template std::tuple gravity::Model::run_obbt(shared_ptr> relaxed_model, double max_time, unsigned max_iter, double rel_tol, double abs_tol, unsigned nb_threads, SolverType ub_solver_type, SolverType lb_solver_type, double ub_solver_tol, double lb_solver_tol, double range_tol, bool linearize, bool scale_objective, bool lag, int nb_refine, int nb_root_refine, int nb_root_ref_init, double viol_obbt_init, double viol_root_init, bool initialize_primal, double upper_bound_prev); @@ -7221,8 +7381,8 @@ template void Model::batch_models_obj_lb_constr(vector::update_upper_bound(shared_ptr>& obbt_model, vector>>& batch_models, vector& ub_sol, SolverType ub_solver_type, double ub_solver_tol, bool& terminate, bool linearize, double& upper_bound, double lb_scale_value, double lower_bound, double& gap, const double abs_tol, const double rel_tol, const double zero_tol); template void Model::model_fix_int(shared_ptr> relax); template shared_ptr> Model::outer_approximate_continuous_relaxation(int nb_max, int& constr_viol); -template Constraint Model::lift(Constraint& c, string model_type); -template Constraint<> Model<>::lift(Constraint<>& c, string model_type); +//template Constraint Model::lift(Constraint& c, string model_type); +//template Constraint<> Model<>::lift(Constraint<>& c, string model_type); // template void Model::run_obbt(double max_time, unsigned max_iter); @@ -7230,4 +7390,4 @@ template Constraint<> Model<>::lift(Constraint<>& c, string model_type); // template class Model; // template class Model; -} +//}