#include "HCheckConfig.h" #include "catch.hpp" #include "ipm/ipx/ipx_status.h" #include "ipm/ipx/lp_solver.h" #include "lp_data/HConst.h" #include "lp_data/HighsCallback.h" #include "lp_data/HighsLp.h" #include "lp_data/HighsStatus.h" #include "parallel/HighsParallel.h" // Example for using IPX from its C++ interface. The program solves the Netlib // problem afiro. #include #include #include "ipm/ipx/lp_solver.h" const bool dev_run = false; using Int = ipxint; constexpr HighsInt num_var = 12; constexpr HighsInt num_constr = 9; const double obj[] = {-0.2194, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.32, -0.5564, 0.6, -0.48}; const double lb[num_var] = {0.0}; const double ub[] = {80.0, 283.303, 283.303, 312.813, 349.187, INFINITY, INFINITY, INFINITY, 57.201, 500.0, 500.501, 357.501}; // Constraint matrix in CSC format with 0-based indexing. const HighsInt Ap[] = {0, 2, 6, 10, 14, 18, 20, 22, 24, 26, 28, 30, 32}; const HighsInt Ai[] = {0, 5, 1, 6, 7, 8, 2, 6, 7, 8, 3, 6, 7, 8, 4, 6, 7, 8, 1, 2, 2, 3, 2, 4, 0, 6, 0, 5, 2, 5, 5, 7}; const double Ax[] = {-1.0, 0.301, 1.0, -1.0, 0.301, 1.06, 1.0, -1.0, 0.313, 1.06, 1.0, -1.0, 0.313, 0.96, 1.0, -1.0, 0.326, 0.86, -1.0, 0.99078, 1.00922, -1.0, 1.01802, -1.0, 1.4, 1.0, 0.109, -1.0, -0.419111, 1.0, 1.4, -1.0}; const double rhs[] = {0.0, 80.0, 0.0, 0.0, 0.0, 0.0, 0.0, 44.0, 300.0}; const char constr_type[] = {'<', '<', '=', '<', '<', '=', '<', '<', '<'}; TEST_CASE("test-ipx", "[highs_ipx]") { ipx::LpSolver lps; ipx::Parameters parameters; if (!dev_run) parameters.display = 0; parameters.highs_logging = false; lps.SetParameters(parameters); // Solve the LP. Int load_status = lps.LoadModel(num_var, obj, lb, ub, num_constr, Ap, Ai, Ax, rhs, constr_type); REQUIRE(load_status == 0); highs::parallel::initialize_scheduler(); HighsCallback callback; // Set pointer to null callback lps.SetCallback(&callback); Int status = lps.Solve(); bool is_solved = status == IPX_STATUS_solved; REQUIRE(is_solved); // Get solver and solution information. ipx::Info info = lps.GetInfo(); // Get the interior solution (available if IPM was started). double x[num_var], xl[num_var], xu[num_var], slack[num_constr]; double y[num_constr], zl[num_var], zu[num_var]; lps.GetInteriorSolution(x, xl, xu, slack, y, zl, zu); REQUIRE(fabs(x[11] - 339.9) < 1.0); REQUIRE(fabs(xl[11] - 339.94) < 1.0); REQUIRE(fabs(xu[11] - 17.55) < 1.0); REQUIRE(fabs(slack[8] - 234.76) < 1.0); REQUIRE(fabs(y[8]) < 1.0); REQUIRE(fabs(zl[11]) < 1.0); REQUIRE(fabs(zu[11]) < 1.0); // Get the basic solution (available if crossover terminated without error). double ipx_col_value[num_var], ipx_row_value[num_constr]; double ipx_row_dual[num_constr], ipx_col_dual[num_var]; Int ipx_row_status[num_constr], ipx_col_status[num_var]; lps.GetBasicSolution(ipx_col_value, ipx_row_value, ipx_row_dual, ipx_col_dual, ipx_row_status, ipx_col_status); REQUIRE(fabs(ipx_col_value[11] - 339.9) < 1); (void)(info); // surpress unused variable. }