lpsolver 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/README.md +70 -26
- data/ext/lpsolver/Makefile +273 -0
- data/ext/lpsolver/ext.c +353 -0
- data/ext/lpsolver/ext.o +0 -0
- data/ext/lpsolver/extconf.rb +79 -0
- data/ext/lpsolver/native.so +0 -0
- data/ext/lpsolver-highs/AUTHORS +7 -0
- data/ext/lpsolver-highs/BUILD.bazel +243 -0
- data/ext/lpsolver-highs/CITATION.cff +29 -0
- data/ext/lpsolver-highs/CMakeCache.txt +406 -0
- data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeCCompiler.cmake +81 -0
- data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeCXXCompiler.cmake +101 -0
- data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeDetermineCompilerABI_C.bin +0 -0
- data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeDetermineCompilerABI_CXX.bin +0 -0
- data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeSystem.cmake +15 -0
- data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdC/CMakeCCompilerId.c +904 -0
- data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdC/a.out +0 -0
- data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdCXX/CMakeCXXCompilerId.cpp +919 -0
- data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdCXX/a.out +0 -0
- data/ext/lpsolver-highs/CMakeFiles/CMakeConfigureLog.yaml +576 -0
- data/ext/lpsolver-highs/CMakeFiles/cmake.check_cache +1 -0
- data/ext/lpsolver-highs/CMakeLists.txt +983 -0
- data/ext/lpsolver-highs/CODE_OF_CONDUCT.md +128 -0
- data/ext/lpsolver-highs/CONTRIBUTING.md +31 -0
- data/ext/lpsolver-highs/FEATURES.md +61 -0
- data/ext/lpsolver-highs/LICENSE.txt +21 -0
- data/ext/lpsolver-highs/MODULE.bazel +38 -0
- data/ext/lpsolver-highs/README.md +281 -0
- data/ext/lpsolver-highs/THIRD_PARTY_NOTICES.md +78 -0
- data/ext/lpsolver-highs/Version.txt +4 -0
- data/ext/lpsolver-highs/WORKSPACE +33 -0
- data/ext/lpsolver-highs/app/CMakeLists.txt +110 -0
- data/ext/lpsolver-highs/app/HighsRuntimeOptions.h +292 -0
- data/ext/lpsolver-highs/app/RunHighs.cpp +147 -0
- data/ext/lpsolver-highs/app/highs_webdemo_shell.html +73 -0
- data/ext/lpsolver-highs/build/bin/highs +0 -0
- data/ext/lpsolver-highs/build/include/highs/HConfig.h +22 -0
- data/ext/lpsolver-highs/build/include/highs/Highs.h +1812 -0
- data/ext/lpsolver-highs/build/include/highs/interfaces/highs_c_api.h +2651 -0
- data/ext/lpsolver-highs/build/include/highs/io/Filereader.h +45 -0
- data/ext/lpsolver-highs/build/include/highs/io/FilereaderLp.h +49 -0
- data/ext/lpsolver-highs/build/include/highs/io/FilereaderMps.h +27 -0
- data/ext/lpsolver-highs/build/include/highs/io/HMPSIO.h +78 -0
- data/ext/lpsolver-highs/build/include/highs/io/HMpsFF.h +245 -0
- data/ext/lpsolver-highs/build/include/highs/io/HighsIO.h +118 -0
- data/ext/lpsolver-highs/build/include/highs/io/LoadOptions.h +24 -0
- data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/builder.hpp +25 -0
- data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/def.hpp +19 -0
- data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/model.hpp +68 -0
- data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/reader.hpp +10 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/IpxSolution.h +32 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/IpxWrapper.h +106 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu.h +161 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_factorize.h +247 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_get_factors.h +108 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_initialize.h +119 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_factorize.h +34 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_free.h +19 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_get_factors.h +34 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_initialize.h +46 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_solve_dense.h +29 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_solve_for_update.h +42 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_solve_sparse.h +32 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_update.h +31 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_object.h +30 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_solve_dense.h +75 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_solve_for_update.h +169 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_solve_sparse.h +112 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_update.h +125 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_def.h +39 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_file.h +21 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_internal.h +220 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_list.h +173 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/basiclu_kernel.h +20 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/basiclu_wrapper.h +47 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/basis.h +350 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/conjugate_residuals.h +74 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/control.h +167 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/crossover.h +157 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/diagonal_precond.h +45 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/forrest_tomlin.h +102 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/guess_basis.h +21 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/indexed_vector.h +113 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/info.h +27 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipm.h +94 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_c.h +47 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_config.h +9 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_info.h +111 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_internal.h +89 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_parameters.h +76 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_status.h +57 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/iterate.h +331 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/kkt_solver.h +70 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/kkt_solver_basis.h +66 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/kkt_solver_diag.h +48 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/linear_operator.h +26 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/lp_solver.h +204 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/lu_factorization.h +79 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/lu_update.h +129 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/maxvolume.h +54 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/model.h +413 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/multistream.h +52 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/normal_matrix.h +44 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/power_method.h +44 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/sparse_matrix.h +195 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/sparse_utils.h +58 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/splitted_normal_matrix.h +63 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/starting_basis.h +39 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/symbolic_invert.h +29 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/timer.h +25 -0
- data/ext/lpsolver-highs/build/include/highs/ipm/ipx/utils.h +37 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HConst.h +430 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HStruct.h +213 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsAnalysis.h +23 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsCallback.h +104 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsCallbackStruct.h +70 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsDebug.h +34 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsIis.h +139 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsInfo.h +421 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsInfoDebug.h +27 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsLp.h +97 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsLpSolverObject.h +47 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsLpUtils.h +330 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsModelUtils.h +129 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsOptions.h +1715 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsRanging.h +43 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsSolution.h +179 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsSolutionDebug.h +87 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsSolve.h +29 -0
- data/ext/lpsolver-highs/build/include/highs/lp_data/HighsStatus.h +29 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsCliqueTable.h +329 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsConflictPool.h +109 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsCutGeneration.h +108 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsCutPool.h +168 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsDebugSol.h +133 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsDomain.h +657 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsDomainChange.h +48 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsDynamicRowMatrix.h +104 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsGFkSolve.h +439 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsImplications.h +194 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsLpAggregator.h +50 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsLpRelaxation.h +361 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsMipAnalysis.h +71 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsMipSolver.h +159 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsMipSolverData.h +313 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsModkSeparator.h +60 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsNodeQueue.h +312 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsObjectiveFunction.h +71 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsPathSeparator.h +39 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsPrimalHeuristics.h +75 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsPseudocost.h +366 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsRedcostFixing.h +42 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsSearch.h +241 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsSeparation.h +41 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsSeparator.h +60 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsTableauSeparator.h +34 -0
- data/ext/lpsolver-highs/build/include/highs/mip/HighsTransformedLp.h +63 -0
- data/ext/lpsolver-highs/build/include/highs/mip/MipTimer.h +544 -0
- data/ext/lpsolver-highs/build/include/highs/mip/feasibilityjump.hh +800 -0
- data/ext/lpsolver-highs/build/include/highs/model/HighsHessian.h +54 -0
- data/ext/lpsolver-highs/build/include/highs/model/HighsHessianUtils.h +47 -0
- data/ext/lpsolver-highs/build/include/highs/model/HighsModel.h +42 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsBinarySemaphore.h +108 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsCacheAlign.h +82 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsCombinable.h +116 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsMutex.h +124 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsParallel.h +128 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsRaceTimer.h +38 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsSchedulerConstants.h +19 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsSpinMutex.h +48 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsSplitDeque.h +606 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsTask.h +170 -0
- data/ext/lpsolver-highs/build/include/highs/parallel/HighsTaskExecutor.h +217 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/CupdlpWrapper.h +108 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/HiPdlpTimer.h +155 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/HiPdlpWrapper.h +26 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_cs.h +40 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_defs.h +447 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_linalg.h +189 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_proj.h +19 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_restart.h +31 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_scaling.h +26 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_solver.h +105 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_step.h +37 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_utils.c +1850 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/defs.hpp +222 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/linalg.hpp +61 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/logger.hpp +80 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/pdhg.hpp +358 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/restart.hpp +96 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/scaling.hpp +74 -0
- data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/solver_results.hpp +65 -0
- data/ext/lpsolver-highs/build/include/highs/pdqsort/pdqsort.h +532 -0
- data/ext/lpsolver-highs/build/include/highs/presolve/HPresolve.h +505 -0
- data/ext/lpsolver-highs/build/include/highs/presolve/HPresolveAnalysis.h +52 -0
- data/ext/lpsolver-highs/build/include/highs/presolve/HighsPostsolveStack.h +943 -0
- data/ext/lpsolver-highs/build/include/highs/presolve/HighsSymmetry.h +284 -0
- data/ext/lpsolver-highs/build/include/highs/presolve/ICrash.h +124 -0
- data/ext/lpsolver-highs/build/include/highs/presolve/ICrashUtil.h +62 -0
- data/ext/lpsolver-highs/build/include/highs/presolve/ICrashX.h +23 -0
- data/ext/lpsolver-highs/build/include/highs/presolve/PresolveComponent.h +90 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/a_asm.hpp +77 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/a_quass.hpp +22 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/basis.hpp +159 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/crashsolution.hpp +20 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/dantzigpricing.hpp +80 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/devexpricing.hpp +108 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/eventhandler.hpp +30 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/factor.hpp +408 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/feasibility_bounded.hpp +114 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/feasibility_highs.hpp +301 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/gradient.hpp +46 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/instance.hpp +70 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/matrix.hpp +342 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/perturbation.hpp +15 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/pricing.hpp +22 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/qpconst.hpp +34 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/qpvector.hpp +242 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/quass.hpp +27 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/ratiotest.hpp +26 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/runtime.hpp +45 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/scaling.hpp +15 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/settings.hpp +84 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/snippets.hpp +36 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/statistics.hpp +30 -0
- data/ext/lpsolver-highs/build/include/highs/qpsolver/steepestedgepricing.hpp +173 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HApp.h +550 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HEkk.h +419 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HEkkDual.h +513 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HEkkDualRHS.h +134 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HEkkDualRow.h +201 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HEkkPrimal.h +191 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HSimplex.h +42 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HSimplexDebug.h +48 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HSimplexNla.h +158 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HSimplexReport.h +21 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/HighsSimplexAnalysis.h +500 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/SimplexConst.h +273 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/SimplexStruct.h +263 -0
- data/ext/lpsolver-highs/build/include/highs/simplex/SimplexTimer.h +414 -0
- data/ext/lpsolver-highs/build/include/highs/test_kkt/DevKkt.h +143 -0
- data/ext/lpsolver-highs/build/include/highs/test_kkt/KktCh2.h +79 -0
- data/ext/lpsolver-highs/build/include/highs/util/FactorTimer.h +199 -0
- data/ext/lpsolver-highs/build/include/highs/util/HFactor.h +587 -0
- data/ext/lpsolver-highs/build/include/highs/util/HFactorConst.h +81 -0
- data/ext/lpsolver-highs/build/include/highs/util/HFactorDebug.h +55 -0
- data/ext/lpsolver-highs/build/include/highs/util/HSet.h +89 -0
- data/ext/lpsolver-highs/build/include/highs/util/HVector.h +22 -0
- data/ext/lpsolver-highs/build/include/highs/util/HVectorBase.h +102 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsCDouble.h +323 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsComponent.h +53 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsDataStack.h +83 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsDisjointSets.h +107 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsHash.h +1274 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsHashTree.h +1461 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsInt.h +36 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsIntegers.h +212 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsLinearSumBounds.h +203 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsMatrixPic.h +37 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsMatrixSlice.h +561 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsMatrixUtils.h +57 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsMemoryAllocation.h +63 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsRandom.h +242 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsRbTree.h +452 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsSort.h +131 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsSparseMatrix.h +151 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsSparseVectorSum.h +95 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsSplay.h +135 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsTimer.h +385 -0
- data/ext/lpsolver-highs/build/include/highs/util/HighsUtils.h +272 -0
- data/ext/lpsolver-highs/build/include/highs/util/stringutil.h +46 -0
- data/ext/lpsolver-highs/build/include/highs/zstr/strict_fstream.hpp +237 -0
- data/ext/lpsolver-highs/build/include/highs/zstr/zstr.hpp +473 -0
- data/ext/lpsolver-highs/build/include/highs_export.h +43 -0
- data/ext/lpsolver-highs/build/lib/cmake/highs/highs-config-version.cmake +65 -0
- data/ext/lpsolver-highs/build/lib/cmake/highs/highs-config.cmake +36 -0
- data/ext/lpsolver-highs/build/lib/cmake/highs/highs-targets-release.cmake +19 -0
- data/ext/lpsolver-highs/build/lib/cmake/highs/highs-targets.cmake +111 -0
- data/ext/lpsolver-highs/build/lib/libhighs.a +0 -0
- data/ext/lpsolver-highs/build/lib/pkgconfig/highs.pc +12 -0
- data/ext/lpsolver-highs/build/share/doc/HIGHS/AUTHORS +7 -0
- data/ext/lpsolver-highs/build/share/doc/HIGHS/CITATION.cff +29 -0
- data/ext/lpsolver-highs/build/share/doc/HIGHS/CODE_OF_CONDUCT.md +128 -0
- data/ext/lpsolver-highs/build/share/doc/HIGHS/CONTRIBUTING.md +31 -0
- data/ext/lpsolver-highs/build/share/doc/HIGHS/FEATURES.md +61 -0
- data/ext/lpsolver-highs/build/share/doc/HIGHS/LICENSE.txt +21 -0
- data/ext/lpsolver-highs/build/share/doc/HIGHS/README.md +281 -0
- data/ext/lpsolver-highs/build_webdemo.sh +46 -0
- data/ext/lpsolver-highs/check/Avgas.cpp +245 -0
- data/ext/lpsolver-highs/check/Avgas.h +44 -0
- data/ext/lpsolver-highs/check/CMakeLists.txt +573 -0
- data/ext/lpsolver-highs/check/HCheckConfig.h.bazel.in +6 -0
- data/ext/lpsolver-highs/check/HCheckConfig.h.in +12 -0
- data/ext/lpsolver-highs/check/HCheckConfig.h.meson.in +6 -0
- data/ext/lpsolver-highs/check/SpecialLps.h +405 -0
- data/ext/lpsolver-highs/check/TestAlienBasis.cpp +720 -0
- data/ext/lpsolver-highs/check/TestBasis.cpp +359 -0
- data/ext/lpsolver-highs/check/TestBasisSolves.cpp +669 -0
- data/ext/lpsolver-highs/check/TestCAPI.c +2513 -0
- data/ext/lpsolver-highs/check/TestCallbacks.cpp +608 -0
- data/ext/lpsolver-highs/check/TestCheckSolution.cpp +740 -0
- data/ext/lpsolver-highs/check/TestCrossover.cpp +111 -0
- data/ext/lpsolver-highs/check/TestDualize.cpp +172 -0
- data/ext/lpsolver-highs/check/TestEkk.cpp +100 -0
- data/ext/lpsolver-highs/check/TestFactor.cpp +389 -0
- data/ext/lpsolver-highs/check/TestFilereader.cpp +568 -0
- data/ext/lpsolver-highs/check/TestFortranAPI.f90 +65 -0
- data/ext/lpsolver-highs/check/TestHSet.cpp +80 -0
- data/ext/lpsolver-highs/check/TestHighsCDouble.cpp +109 -0
- data/ext/lpsolver-highs/check/TestHighsGFkSolve.cpp +102 -0
- data/ext/lpsolver-highs/check/TestHighsHash.cpp +126 -0
- data/ext/lpsolver-highs/check/TestHighsHessian.cpp +329 -0
- data/ext/lpsolver-highs/check/TestHighsIntegers.cpp +42 -0
- data/ext/lpsolver-highs/check/TestHighsModel.cpp +134 -0
- data/ext/lpsolver-highs/check/TestHighsParallel.cpp +277 -0
- data/ext/lpsolver-highs/check/TestHighsRbTree.cpp +109 -0
- data/ext/lpsolver-highs/check/TestHighsSparseMatrix.cpp +126 -0
- data/ext/lpsolver-highs/check/TestHighsVersion.cpp +61 -0
- data/ext/lpsolver-highs/check/TestHipo.cpp +122 -0
- data/ext/lpsolver-highs/check/TestICrash.cpp +46 -0
- data/ext/lpsolver-highs/check/TestIO.cpp +163 -0
- data/ext/lpsolver-highs/check/TestIis.cpp +1063 -0
- data/ext/lpsolver-highs/check/TestInfo.cpp +116 -0
- data/ext/lpsolver-highs/check/TestIpm.cpp +226 -0
- data/ext/lpsolver-highs/check/TestIpx.cpp +96 -0
- data/ext/lpsolver-highs/check/TestLPFileFormat.cpp +22 -0
- data/ext/lpsolver-highs/check/TestLogging.cpp +69 -0
- data/ext/lpsolver-highs/check/TestLpModification.cpp +2497 -0
- data/ext/lpsolver-highs/check/TestLpOrientation.cpp +121 -0
- data/ext/lpsolver-highs/check/TestLpSolvers.cpp +555 -0
- data/ext/lpsolver-highs/check/TestLpValidation.cpp +689 -0
- data/ext/lpsolver-highs/check/TestMain.cpp +6 -0
- data/ext/lpsolver-highs/check/TestMipSolver.cpp +1406 -0
- data/ext/lpsolver-highs/check/TestModelProperties.cpp +143 -0
- data/ext/lpsolver-highs/check/TestMultiObjective.cpp +198 -0
- data/ext/lpsolver-highs/check/TestNames.cpp +187 -0
- data/ext/lpsolver-highs/check/TestOptions.cpp +544 -0
- data/ext/lpsolver-highs/check/TestPdlp.cpp +327 -0
- data/ext/lpsolver-highs/check/TestPdlpHi.cpp +40 -0
- data/ext/lpsolver-highs/check/TestPresolve.cpp +912 -0
- data/ext/lpsolver-highs/check/TestQpSolver.cpp +1345 -0
- data/ext/lpsolver-highs/check/TestRanging.cpp +558 -0
- data/ext/lpsolver-highs/check/TestRays.cpp +1010 -0
- data/ext/lpsolver-highs/check/TestSemiVariables.cpp +329 -0
- data/ext/lpsolver-highs/check/TestSetup.cpp +12 -0
- data/ext/lpsolver-highs/check/TestSort.cpp +247 -0
- data/ext/lpsolver-highs/check/TestSpecialLps.cpp +775 -0
- data/ext/lpsolver-highs/check/TestThrow.cpp +83 -0
- data/ext/lpsolver-highs/check/TestTspSolver.cpp +19 -0
- data/ext/lpsolver-highs/check/TestUserScale.cpp +444 -0
- data/ext/lpsolver-highs/check/cublas_example.cpp +76 -0
- data/ext/lpsolver-highs/check/cublas_gpu_start.cpp +88 -0
- data/ext/lpsolver-highs/check/hipo_test_option_files/hipo_options_0 +1 -0
- data/ext/lpsolver-highs/check/instances/1448.lp +1 -0
- data/ext/lpsolver-highs/check/instances/1449a.lp +1 -0
- data/ext/lpsolver-highs/check/instances/1449b.lp +1 -0
- data/ext/lpsolver-highs/check/instances/1451.lp +8 -0
- data/ext/lpsolver-highs/check/instances/2122.lp +1822 -0
- data/ext/lpsolver-highs/check/instances/2171.mps +717 -0
- data/ext/lpsolver-highs/check/instances/25fv47.mps +6919 -0
- data/ext/lpsolver-highs/check/instances/2821-duplicate.mps +31 -0
- data/ext/lpsolver-highs/check/instances/2821-qmatrix.mps +31 -0
- data/ext/lpsolver-highs/check/instances/2821-quadobj.mps +29 -0
- data/ext/lpsolver-highs/check/instances/2821-summation.mps +30 -0
- data/ext/lpsolver-highs/check/instances/2821.mps +29 -0
- data/ext/lpsolver-highs/check/instances/2894.mps +89 -0
- data/ext/lpsolver-highs/check/instances/80bau3b.mps +23732 -0
- data/ext/lpsolver-highs/check/instances/WithInf.set +3 -0
- data/ext/lpsolver-highs/check/instances/adlittle.mps +335 -0
- data/ext/lpsolver-highs/check/instances/afiro.mps +83 -0
- data/ext/lpsolver-highs/check/instances/avgas.mps +51 -0
- data/ext/lpsolver-highs/check/instances/bell5.mps +384 -0
- data/ext/lpsolver-highs/check/instances/bgetam.mps +2112 -0
- data/ext/lpsolver-highs/check/instances/blending.mps +13 -0
- data/ext/lpsolver-highs/check/instances/box1.mps +1085 -0
- data/ext/lpsolver-highs/check/instances/chip.mps +13 -0
- data/ext/lpsolver-highs/check/instances/comment.mps +23 -0
- data/ext/lpsolver-highs/check/instances/cplex1.mps +9674 -0
- data/ext/lpsolver-highs/check/instances/dD2e.mps +10 -0
- data/ext/lpsolver-highs/check/instances/dcmulti.mps +2310 -0
- data/ext/lpsolver-highs/check/instances/e226.mps +1733 -0
- data/ext/lpsolver-highs/check/instances/egout-ac.mps +473 -0
- data/ext/lpsolver-highs/check/instances/egout.mps +403 -0
- data/ext/lpsolver-highs/check/instances/etamacro.mps +2084 -0
- data/ext/lpsolver-highs/check/instances/ex72a.mps +849 -0
- data/ext/lpsolver-highs/check/instances/fixed-binary.lp +11 -0
- data/ext/lpsolver-highs/check/instances/flugpl.mps +111 -0
- data/ext/lpsolver-highs/check/instances/flugpl_illegal_integer.sol +24 -0
- data/ext/lpsolver-highs/check/instances/flugpl_integer.sol +25 -0
- data/ext/lpsolver-highs/check/instances/forest6.mps +261 -0
- data/ext/lpsolver-highs/check/instances/galenet.mps +34 -0
- data/ext/lpsolver-highs/check/instances/gams10am.mps +478 -0
- data/ext/lpsolver-highs/check/instances/garbage.ems +3 -0
- data/ext/lpsolver-highs/check/instances/garbage.lp +3 -0
- data/ext/lpsolver-highs/check/instances/garbage.mps +3 -0
- data/ext/lpsolver-highs/check/instances/gas11.mps +2924 -0
- data/ext/lpsolver-highs/check/instances/gesa2.mps +5459 -0
- data/ext/lpsolver-highs/check/instances/greenbea.mps +19215 -0
- data/ext/lpsolver-highs/check/instances/gt2.mps +534 -0
- data/ext/lpsolver-highs/check/instances/infeasible-mip0.mps +140 -0
- data/ext/lpsolver-highs/check/instances/infeasible-mip1.mps +371 -0
- data/ext/lpsolver-highs/check/instances/israel.mps +1490 -0
- data/ext/lpsolver-highs/check/instances/issue-2095.mps +836 -0
- data/ext/lpsolver-highs/check/instances/issue-2173.mps +3331 -0
- data/ext/lpsolver-highs/check/instances/issue-2204.mps +143 -0
- data/ext/lpsolver-highs/check/instances/issue-2290.mps +158 -0
- data/ext/lpsolver-highs/check/instances/issue-2388.lp +76 -0
- data/ext/lpsolver-highs/check/instances/issue-2402.mps +435 -0
- data/ext/lpsolver-highs/check/instances/issue-2446.mps +9154 -0
- data/ext/lpsolver-highs/check/instances/issue-2585.lp +16 -0
- data/ext/lpsolver-highs/check/instances/issue-2874-3.mps +97 -0
- data/ext/lpsolver-highs/check/instances/klein1.mps +422 -0
- data/ext/lpsolver-highs/check/instances/lseu.mps +371 -0
- data/ext/lpsolver-highs/check/instances/model.xyz +1 -0
- data/ext/lpsolver-highs/check/instances/nan0.mps +13 -0
- data/ext/lpsolver-highs/check/instances/nan1.mps +13 -0
- data/ext/lpsolver-highs/check/instances/nan2.mps +13 -0
- data/ext/lpsolver-highs/check/instances/no-newline-eof.lp +5 -0
- data/ext/lpsolver-highs/check/instances/p01.mps +909 -0
- data/ext/lpsolver-highs/check/instances/p0548.mps +1992 -0
- data/ext/lpsolver-highs/check/instances/primal1.mps +3909 -0
- data/ext/lpsolver-highs/check/instances/qap04.mps +606 -0
- data/ext/lpsolver-highs/check/instances/qcqp.lp +8 -0
- data/ext/lpsolver-highs/check/instances/qjh.lp +9 -0
- data/ext/lpsolver-highs/check/instances/qjh.mps +18 -0
- data/ext/lpsolver-highs/check/instances/qjh_qmatrix.mps +19 -0
- data/ext/lpsolver-highs/check/instances/qjh_quadobj.mps +18 -0
- data/ext/lpsolver-highs/check/instances/qjh_quadobj_qmatrix.mps +25 -0
- data/ext/lpsolver-highs/check/instances/qjh_uncon.lp +10 -0
- data/ext/lpsolver-highs/check/instances/qjh_uncon.mps +17 -0
- data/ext/lpsolver-highs/check/instances/qpinfeasible.lp +8 -0
- data/ext/lpsolver-highs/check/instances/qptestnw.lp +7 -0
- data/ext/lpsolver-highs/check/instances/qpunbounded.lp +5 -0
- data/ext/lpsolver-highs/check/instances/refinery.mps +1882 -0
- data/ext/lpsolver-highs/check/instances/rgn.mps +559 -0
- data/ext/lpsolver-highs/check/instances/scrs8.mps +2717 -0
- data/ext/lpsolver-highs/check/instances/sctest.mps +66 -0
- data/ext/lpsolver-highs/check/instances/semi-continuous.lp +13 -0
- data/ext/lpsolver-highs/check/instances/semi-continuous.mps +24 -0
- data/ext/lpsolver-highs/check/instances/semi-integer.lp +15 -0
- data/ext/lpsolver-highs/check/instances/semi-integer.mps +22 -0
- data/ext/lpsolver-highs/check/instances/shell.mps +4039 -0
- data/ext/lpsolver-highs/check/instances/silly-names.mps +14 -0
- data/ext/lpsolver-highs/check/instances/small_mip.mps +87 -0
- data/ext/lpsolver-highs/check/instances/smalllp.mps +21 -0
- data/ext/lpsolver-highs/check/instances/sp150x300d.mps +1983 -0
- data/ext/lpsolver-highs/check/instances/stair.mps +2499 -0
- data/ext/lpsolver-highs/check/instances/standata.mps +2317 -0
- data/ext/lpsolver-highs/check/instances/standgub.mps +2428 -0
- data/ext/lpsolver-highs/check/instances/standmps.mps +2695 -0
- data/ext/lpsolver-highs/check/instances/test.mps +53 -0
- data/ext/lpsolver-highs/check/instances/vol1.mps +1895 -0
- data/ext/lpsolver-highs/check/instances/warnings.mps +68 -0
- data/ext/lpsolver-highs/check/instances/woodinfe.mps +216 -0
- data/ext/lpsolver-highs/check/matrix_multiplication.hpp +49 -0
- data/ext/lpsolver-highs/check/meson.build +92 -0
- data/ext/lpsolver-highs/check/pythontest.py +11 -0
- data/ext/lpsolver-highs/check/sample_options_file +8 -0
- data/ext/lpsolver-highs/cmake/CheckAtomic.cmake +74 -0
- data/ext/lpsolver-highs/cmake/FindCUDAConf.cmake +44 -0
- data/ext/lpsolver-highs/cmake/FindHipoDeps.cmake +351 -0
- data/ext/lpsolver-highs/cmake/README.md +243 -0
- data/ext/lpsolver-highs/cmake/cpp-highs.cmake +243 -0
- data/ext/lpsolver-highs/cmake/dotnet.cmake +94 -0
- data/ext/lpsolver-highs/cmake/highs-config.cmake.in +22 -0
- data/ext/lpsolver-highs/cmake/python-highs.cmake +74 -0
- data/ext/lpsolver-highs/cmake/set-version.cmake +26 -0
- data/ext/lpsolver-highs/cmake/sources-python.cmake +461 -0
- data/ext/lpsolver-highs/cmake/sources.cmake +618 -0
- data/ext/lpsolver-highs/docs/HiGHS_CopyrightHeader.pl +78 -0
- data/ext/lpsolver-highs/docs/HiGHS_CopyrightHeaderUpdateAll +32 -0
- data/ext/lpsolver-highs/docs/Project.toml +7 -0
- data/ext/lpsolver-highs/docs/README.md +27 -0
- data/ext/lpsolver-highs/docs/c_api_gen/HConfig.h +1 -0
- data/ext/lpsolver-highs/docs/c_api_gen/build.jl +48 -0
- data/ext/lpsolver-highs/docs/make.jl +115 -0
- data/ext/lpsolver-highs/docs/src/assets/logo.png +0 -0
- data/ext/lpsolver-highs/docs/src/callbacks.md +171 -0
- data/ext/lpsolver-highs/docs/src/executable.md +88 -0
- data/ext/lpsolver-highs/docs/src/guide/advanced.md +66 -0
- data/ext/lpsolver-highs/docs/src/guide/basic.md +116 -0
- data/ext/lpsolver-highs/docs/src/guide/further.md +193 -0
- data/ext/lpsolver-highs/docs/src/guide/gpu.md +58 -0
- data/ext/lpsolver-highs/docs/src/guide/index.md +18 -0
- data/ext/lpsolver-highs/docs/src/guide/kkt.md +219 -0
- data/ext/lpsolver-highs/docs/src/guide/numerics.md +55 -0
- data/ext/lpsolver-highs/docs/src/index.md +86 -0
- data/ext/lpsolver-highs/docs/src/installation.md +130 -0
- data/ext/lpsolver-highs/docs/src/interfaces/c_api.md +6 -0
- data/ext/lpsolver-highs/docs/src/interfaces/cpp/examples.md +1 -0
- data/ext/lpsolver-highs/docs/src/interfaces/cpp/index.md +29 -0
- data/ext/lpsolver-highs/docs/src/interfaces/cpp/library.md +107 -0
- data/ext/lpsolver-highs/docs/src/interfaces/csharp.md +55 -0
- data/ext/lpsolver-highs/docs/src/interfaces/fortran.md +11 -0
- data/ext/lpsolver-highs/docs/src/interfaces/julia/index.md +130 -0
- data/ext/lpsolver-highs/docs/src/interfaces/other.md +41 -0
- data/ext/lpsolver-highs/docs/src/interfaces/python/example-py.md +275 -0
- data/ext/lpsolver-highs/docs/src/interfaces/python/index.md +91 -0
- data/ext/lpsolver-highs/docs/src/interfaces/python/model-py.md +90 -0
- data/ext/lpsolver-highs/docs/src/options/definitions.md +529 -0
- data/ext/lpsolver-highs/docs/src/options/intro.md +46 -0
- data/ext/lpsolver-highs/docs/src/parallel.md +88 -0
- data/ext/lpsolver-highs/docs/src/solvers.md +168 -0
- data/ext/lpsolver-highs/docs/src/structures/classes/HighsHessian.md +9 -0
- data/ext/lpsolver-highs/docs/src/structures/classes/HighsIis.md +16 -0
- data/ext/lpsolver-highs/docs/src/structures/classes/HighsLp.md +19 -0
- data/ext/lpsolver-highs/docs/src/structures/classes/HighsModel.md +6 -0
- data/ext/lpsolver-highs/docs/src/structures/classes/HighsSparseMatrix.md +10 -0
- data/ext/lpsolver-highs/docs/src/structures/classes/index.md +11 -0
- data/ext/lpsolver-highs/docs/src/structures/enums.md +114 -0
- data/ext/lpsolver-highs/docs/src/structures/index.md +12 -0
- data/ext/lpsolver-highs/docs/src/structures/structs/HighsBasis.md +8 -0
- data/ext/lpsolver-highs/docs/src/structures/structs/HighsInfo.md +148 -0
- data/ext/lpsolver-highs/docs/src/structures/structs/HighsLinearObjective.md +11 -0
- data/ext/lpsolver-highs/docs/src/structures/structs/HighsSolution.md +10 -0
- data/ext/lpsolver-highs/docs/src/structures/structs/index.md +10 -0
- data/ext/lpsolver-highs/docs/src/terminology.md +163 -0
- data/ext/lpsolver-highs/examples/CMakeLists.txt +26 -0
- data/ext/lpsolver-highs/examples/Docs.py +104 -0
- data/ext/lpsolver-highs/examples/branch-and-price.py +465 -0
- data/ext/lpsolver-highs/examples/call_highs_from_c.c +685 -0
- data/ext/lpsolver-highs/examples/call_highs_from_c_minimal.c +659 -0
- data/ext/lpsolver-highs/examples/call_highs_from_cpp.cpp +178 -0
- data/ext/lpsolver-highs/examples/call_highs_from_csharp.cs +83 -0
- data/ext/lpsolver-highs/examples/call_highs_from_fortran.f90 +579 -0
- data/ext/lpsolver-highs/examples/call_highs_from_python.py +448 -0
- data/ext/lpsolver-highs/examples/call_highs_from_python_highspy.py +71 -0
- data/ext/lpsolver-highs/examples/call_highs_from_python_mps.py +59 -0
- data/ext/lpsolver-highs/examples/callback_gap.py +71 -0
- data/ext/lpsolver-highs/examples/chip.py +43 -0
- data/ext/lpsolver-highs/examples/chip0.py +29 -0
- data/ext/lpsolver-highs/examples/distillation.py +77 -0
- data/ext/lpsolver-highs/examples/knapsack.py +43 -0
- data/ext/lpsolver-highs/examples/minimal.py +11 -0
- data/ext/lpsolver-highs/examples/multi_objective.py +139 -0
- data/ext/lpsolver-highs/examples/multiple_objective.py +120 -0
- data/ext/lpsolver-highs/examples/network_flow.py +37 -0
- data/ext/lpsolver-highs/examples/nqueens.py +29 -0
- data/ext/lpsolver-highs/examples/plot_highs_log.py +134 -0
- data/ext/lpsolver-highs/extern/CLI11.hpp +11546 -0
- data/ext/lpsolver-highs/extern/LICENCE_1_0.txt +23 -0
- data/ext/lpsolver-highs/extern/amd/License.txt +35 -0
- data/ext/lpsolver-highs/extern/amd/SuiteSparse_config.c +54 -0
- data/ext/lpsolver-highs/extern/amd/SuiteSparse_config.h +56 -0
- data/ext/lpsolver-highs/extern/amd/amd.h +357 -0
- data/ext/lpsolver-highs/extern/amd/amd_1.c +172 -0
- data/ext/lpsolver-highs/extern/amd/amd_2.c +1761 -0
- data/ext/lpsolver-highs/extern/amd/amd_aat.c +179 -0
- data/ext/lpsolver-highs/extern/amd/amd_control.c +65 -0
- data/ext/lpsolver-highs/extern/amd/amd_defaults.c +37 -0
- data/ext/lpsolver-highs/extern/amd/amd_info.c +120 -0
- data/ext/lpsolver-highs/extern/amd/amd_internal.h +137 -0
- data/ext/lpsolver-highs/extern/amd/amd_order.c +195 -0
- data/ext/lpsolver-highs/extern/amd/amd_post_tree.c +105 -0
- data/ext/lpsolver-highs/extern/amd/amd_postorder.c +140 -0
- data/ext/lpsolver-highs/extern/amd/amd_preprocess.c +107 -0
- data/ext/lpsolver-highs/extern/amd/amd_valid.c +93 -0
- data/ext/lpsolver-highs/extern/amd/changes.txt +8 -0
- data/ext/lpsolver-highs/extern/catch.hpp +18861 -0
- data/ext/lpsolver-highs/extern/metis/Changes.txt +31 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/GKlib.h +62 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/error.c +21 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_arch.h +64 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_defs.h +19 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_macros.h +50 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkblas.h +51 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkmemory.h +80 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkpqueue.h +329 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkrandom.h +89 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_mksort.h +271 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_ms_inttypes.h +41 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_ms_stat.h +22 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_ms_stdint.h +41 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_proto.h +50 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_struct.h +66 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/gk_types.h +15 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/mcore.c +176 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/memory.c +23 -0
- data/ext/lpsolver-highs/extern/metis/GKlib/random.c +37 -0
- data/ext/lpsolver-highs/extern/metis/LICENSE.txt +18 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/auxapi.c +27 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/balance.c +491 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/bucketsort.c +44 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/coarsen.c +895 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/compress.c +231 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/contig.c +83 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/defs.h +39 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/fm.c +527 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/gklib.c +55 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/gklib_defs.h +33 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/graph.c +268 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/initpart.c +385 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/macros.h +59 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/mcutil.c +162 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/metislib.h +35 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/mmd.c +598 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/ometis.c +661 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/options.c +260 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/proto.h +172 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/refine.c +99 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/separator.c +57 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/sfm.c +581 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/srefine.c +152 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/stdheaders.h +29 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/struct.h +117 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/util.c +59 -0
- data/ext/lpsolver-highs/extern/metis/libmetis/wspace.c +91 -0
- data/ext/lpsolver-highs/extern/metis/metis.h +271 -0
- data/ext/lpsolver-highs/extern/pdqsort/license.txt +16 -0
- data/ext/lpsolver-highs/extern/pdqsort/pdqsort.h +532 -0
- data/ext/lpsolver-highs/extern/rcm/LICENSE +19 -0
- data/ext/lpsolver-highs/extern/rcm/rcm.cpp +873 -0
- data/ext/lpsolver-highs/extern/rcm/rcm.h +22 -0
- data/ext/lpsolver-highs/extern/zstr/LICENSE +21 -0
- data/ext/lpsolver-highs/extern/zstr/strict_fstream.hpp +237 -0
- data/ext/lpsolver-highs/extern/zstr/zstr.hpp +473 -0
- data/ext/lpsolver-highs/flake.lock +61 -0
- data/ext/lpsolver-highs/flake.nix +73 -0
- data/ext/lpsolver-highs/highs/CMakeLists.txt +499 -0
- data/ext/lpsolver-highs/highs/HConfig.h.bazel.in +25 -0
- data/ext/lpsolver-highs/highs/HConfig.h.in +22 -0
- data/ext/lpsolver-highs/highs/HConfig.h.meson.in +17 -0
- data/ext/lpsolver-highs/highs/Highs.h +1812 -0
- data/ext/lpsolver-highs/highs/HighsRun.md +143 -0
- data/ext/lpsolver-highs/highs/highs_bindings.cpp +1826 -0
- data/ext/lpsolver-highs/highs/highspy/__init__.py +93 -0
- data/ext/lpsolver-highs/highs/highspy/__init__.pyi +91 -0
- data/ext/lpsolver-highs/highs/highspy/_core/__init__.pyi +1058 -0
- data/ext/lpsolver-highs/highs/highspy/_core/cb.pyi +118 -0
- data/ext/lpsolver-highs/highs/highspy/_core/simplex_constants.pyi +472 -0
- data/ext/lpsolver-highs/highs/highspy/highs.py +2430 -0
- data/ext/lpsolver-highs/highs/interfaces/highs_c_api.cpp +1812 -0
- data/ext/lpsolver-highs/highs/interfaces/highs_c_api.h +2651 -0
- data/ext/lpsolver-highs/highs/interfaces/highs_csharp_api.cs +1142 -0
- data/ext/lpsolver-highs/highs/interfaces/highs_fortran_api.f90 +873 -0
- data/ext/lpsolver-highs/highs/io/Filereader.cpp +87 -0
- data/ext/lpsolver-highs/highs/io/Filereader.h +45 -0
- data/ext/lpsolver-highs/highs/io/FilereaderLp.cpp +539 -0
- data/ext/lpsolver-highs/highs/io/FilereaderLp.h +49 -0
- data/ext/lpsolver-highs/highs/io/FilereaderMps.cpp +86 -0
- data/ext/lpsolver-highs/highs/io/FilereaderMps.h +27 -0
- data/ext/lpsolver-highs/highs/io/HMPSIO.cpp +1001 -0
- data/ext/lpsolver-highs/highs/io/HMPSIO.h +78 -0
- data/ext/lpsolver-highs/highs/io/HMpsFF.cpp +2113 -0
- data/ext/lpsolver-highs/highs/io/HMpsFF.h +245 -0
- data/ext/lpsolver-highs/highs/io/HighsIO.cpp +371 -0
- data/ext/lpsolver-highs/highs/io/HighsIO.h +118 -0
- data/ext/lpsolver-highs/highs/io/LoadOptions.cpp +60 -0
- data/ext/lpsolver-highs/highs/io/LoadOptions.h +24 -0
- data/ext/lpsolver-highs/highs/io/filereaderlp/LICENSE +19 -0
- data/ext/lpsolver-highs/highs/io/filereaderlp/builder.hpp +25 -0
- data/ext/lpsolver-highs/highs/io/filereaderlp/def.hpp +19 -0
- data/ext/lpsolver-highs/highs/io/filereaderlp/model.hpp +68 -0
- data/ext/lpsolver-highs/highs/io/filereaderlp/reader.cpp +1375 -0
- data/ext/lpsolver-highs/highs/io/filereaderlp/reader.hpp +10 -0
- data/ext/lpsolver-highs/highs/ipm/IpxSolution.h +32 -0
- data/ext/lpsolver-highs/highs/ipm/IpxWrapper.cpp +1526 -0
- data/ext/lpsolver-highs/highs/ipm/IpxWrapper.h +106 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu.h +161 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_factorize.c +132 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_factorize.h +247 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_get_factors.c +148 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_get_factors.h +108 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_initialize.c +24 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_initialize.h +119 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_factorize.h +34 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_free.h +19 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_get_factors.h +34 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_initialize.h +46 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_solve_dense.h +29 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_solve_for_update.h +42 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_solve_sparse.h +32 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_update.h +31 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_object.c +325 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_object.h +30 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_dense.c +46 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_dense.h +75 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_for_update.c +79 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_for_update.h +169 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_sparse.c +63 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_sparse.h +112 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_update.c +44 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_update.h +125 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_build_factors.c +441 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_condest.c +124 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_def.h +39 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_dfs.c +141 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_factorize_bump.c +56 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_file.c +184 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_file.h +21 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_garbage_perm.c +53 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_initialize.c +56 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_internal.c +352 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_internal.h +220 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_list.h +173 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_markowitz.c +188 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_matrix_norm.c +51 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_pivot.c +1247 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_residual_test.c +155 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_setup_bump.c +198 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_singletons.c +511 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_dense.c +129 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_for_update.c +360 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_sparse.c +284 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_symbolic.c +48 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_triangular.c +140 -0
- data/ext/lpsolver-highs/highs/ipm/basiclu/lu_update.c +908 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Auxiliary.cpp +301 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Auxiliary.h +104 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/IntConfig.h +27 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/KrylovMethods.cpp +193 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/KrylovMethods.h +30 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Log.cpp +60 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Log.h +62 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/OrderingPrint.h +10 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/VectorOperations.cpp +117 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/VectorOperations.h +59 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/mycblas.h +85 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Analyse.cpp +1367 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Analyse.h +122 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CallAndTimeBlas.cpp +114 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CallAndTimeBlas.h +46 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CliqueStack.cpp +82 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CliqueStack.h +83 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DataCollector.cpp +326 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DataCollector.h +86 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DenseFact.h +48 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DenseFactHybrid.cpp +279 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DenseFactKernel.cpp +284 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DgemmParallel.cpp +38 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DgemmParallel.h +32 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FactorHiGHS.cpp +57 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FactorHiGHS.h +112 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FactorHiGHSSettings.h +63 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Factorise.cpp +405 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Factorise.h +85 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FormatHandler.cpp +46 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FormatHandler.h +95 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridHybridFormatHandler.cpp +238 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridHybridFormatHandler.h +31 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridSolveHandler.cpp +272 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridSolveHandler.h +26 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/KrylovMethodsIpm.cpp +83 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/KrylovMethodsIpm.h +45 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Numeric.cpp +54 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Numeric.h +46 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/ReturnValues.h +19 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/SolveHandler.cpp +10 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/SolveHandler.h +48 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Swaps.cpp +70 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Swaps.h +19 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Symbolic.cpp +101 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Symbolic.h +220 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Timing.h +114 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Control.cpp +38 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Control.h +41 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/FactorHiGHSSolver.cpp +887 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/FactorHiGHSSolver.h +92 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Info.h +58 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/IpmData.cpp +8 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/IpmData.h +37 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Iterate.cpp +640 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Iterate.h +172 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/LinearSolver.h +81 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/LogHighs.cpp +71 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/LogHighs.h +33 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Model.cpp +403 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Model.h +136 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Options.h +35 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Parameters.h +63 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/PreProcess.cpp +646 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/PreProcess.h +94 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Refine.cpp +214 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Solver.cpp +1346 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Solver.h +338 -0
- data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Status.h +88 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_kernel.cc +71 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_kernel.h +20 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_wrapper.cc +299 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_wrapper.h +47 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/basis.cc +966 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/basis.h +350 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/conjugate_residuals.cc +217 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/conjugate_residuals.h +74 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/control.cc +151 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/control.h +167 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/crossover.cc +479 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/crossover.h +157 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/diagonal_precond.cc +70 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/diagonal_precond.h +45 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/forrest_tomlin.cc +360 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/forrest_tomlin.h +102 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/guess_basis.cc +233 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/guess_basis.h +21 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/indexed_vector.cc +30 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/indexed_vector.h +113 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/info.cc +124 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/info.h +27 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/ipm.cc +897 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/ipm.h +94 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/ipx_c.cc +83 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/ipx_c.h +47 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/ipx_config.h +9 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/ipx_info.h +111 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/ipx_internal.h +89 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/ipx_parameters.h +76 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/ipx_status.h +57 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/iterate.cc +683 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/iterate.h +331 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver.cc +23 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver.h +70 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_basis.cc +387 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_basis.h +66 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_diag.cc +120 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_diag.h +48 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/linear_operator.cc +10 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/linear_operator.h +26 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/lp_solver.cc +686 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/lp_solver.h +204 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/lu_factorization.cc +131 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/lu_factorization.h +79 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/lu_update.cc +62 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/lu_update.h +129 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/maxvolume.cc +337 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/maxvolume.h +54 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/model.cc +1528 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/model.h +413 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/multistream.h +52 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/normal_matrix.cc +126 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/normal_matrix.h +44 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/power_method.h +44 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/sparse_matrix.cc +382 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/sparse_matrix.h +195 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/sparse_utils.cc +92 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/sparse_utils.h +58 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/splitted_normal_matrix.cc +117 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/splitted_normal_matrix.h +63 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/starting_basis.cc +182 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/starting_basis.h +39 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/symbolic_invert.cc +183 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/symbolic_invert.h +29 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/timer.cc +16 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/timer.h +25 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/utils.cc +95 -0
- data/ext/lpsolver-highs/highs/ipm/ipx/utils.h +37 -0
- data/ext/lpsolver-highs/highs/lp_data/HConst.h +430 -0
- data/ext/lpsolver-highs/highs/lp_data/HStruct.h +213 -0
- data/ext/lpsolver-highs/highs/lp_data/Highs.cpp +4949 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsAnalysis.h +23 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsCallback.cpp +323 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsCallback.h +104 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsCallbackStruct.h +70 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsDebug.cpp +54 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsDebug.h +34 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsDeprecated.cpp +181 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsIis.cpp +1290 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsIis.h +139 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsInfo.cpp +426 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsInfo.h +421 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsInfoDebug.cpp +175 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsInfoDebug.h +27 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsInterface.cpp +4344 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsLp.cpp +564 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsLp.h +97 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsLpSolverObject.h +47 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsLpUtils.cpp +3794 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsLpUtils.h +330 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsModelUtils.cpp +1650 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsModelUtils.h +129 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsOptions.cpp +1176 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsOptions.h +1715 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsRanging.cpp +733 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsRanging.h +43 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsSolution.cpp +2194 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsSolution.h +179 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsSolutionDebug.cpp +490 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsSolutionDebug.h +87 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsSolve.cpp +747 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsSolve.h +29 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsStatus.cpp +48 -0
- data/ext/lpsolver-highs/highs/lp_data/HighsStatus.h +29 -0
- data/ext/lpsolver-highs/highs/lp_data/Iis.md +113 -0
- data/ext/lpsolver-highs/highs/meson.build +433 -0
- data/ext/lpsolver-highs/highs/mip/HighsCliqueTable.cpp +2236 -0
- data/ext/lpsolver-highs/highs/mip/HighsCliqueTable.h +329 -0
- data/ext/lpsolver-highs/highs/mip/HighsConflictPool.cpp +201 -0
- data/ext/lpsolver-highs/highs/mip/HighsConflictPool.h +109 -0
- data/ext/lpsolver-highs/highs/mip/HighsCutGeneration.cpp +1491 -0
- data/ext/lpsolver-highs/highs/mip/HighsCutGeneration.h +108 -0
- data/ext/lpsolver-highs/highs/mip/HighsCutPool.cpp +526 -0
- data/ext/lpsolver-highs/highs/mip/HighsCutPool.h +168 -0
- data/ext/lpsolver-highs/highs/mip/HighsDebugSol.cpp +313 -0
- data/ext/lpsolver-highs/highs/mip/HighsDebugSol.h +133 -0
- data/ext/lpsolver-highs/highs/mip/HighsDomain.cpp +3861 -0
- data/ext/lpsolver-highs/highs/mip/HighsDomain.h +657 -0
- data/ext/lpsolver-highs/highs/mip/HighsDomainChange.h +48 -0
- data/ext/lpsolver-highs/highs/mip/HighsDynamicRowMatrix.cpp +199 -0
- data/ext/lpsolver-highs/highs/mip/HighsDynamicRowMatrix.h +104 -0
- data/ext/lpsolver-highs/highs/mip/HighsFeasibilityJump.cpp +139 -0
- data/ext/lpsolver-highs/highs/mip/HighsGFkSolve.cpp +106 -0
- data/ext/lpsolver-highs/highs/mip/HighsGFkSolve.h +439 -0
- data/ext/lpsolver-highs/highs/mip/HighsImplications.cpp +915 -0
- data/ext/lpsolver-highs/highs/mip/HighsImplications.h +194 -0
- data/ext/lpsolver-highs/highs/mip/HighsLpAggregator.cpp +56 -0
- data/ext/lpsolver-highs/highs/mip/HighsLpAggregator.h +50 -0
- data/ext/lpsolver-highs/highs/mip/HighsLpRelaxation.cpp +1609 -0
- data/ext/lpsolver-highs/highs/mip/HighsLpRelaxation.h +361 -0
- data/ext/lpsolver-highs/highs/mip/HighsMipAnalysis.cpp +313 -0
- data/ext/lpsolver-highs/highs/mip/HighsMipAnalysis.h +71 -0
- data/ext/lpsolver-highs/highs/mip/HighsMipSolver.cpp +1002 -0
- data/ext/lpsolver-highs/highs/mip/HighsMipSolver.h +159 -0
- data/ext/lpsolver-highs/highs/mip/HighsMipSolverData.cpp +2936 -0
- data/ext/lpsolver-highs/highs/mip/HighsMipSolverData.h +313 -0
- data/ext/lpsolver-highs/highs/mip/HighsModkSeparator.cpp +267 -0
- data/ext/lpsolver-highs/highs/mip/HighsModkSeparator.h +60 -0
- data/ext/lpsolver-highs/highs/mip/HighsNodeQueue.cpp +443 -0
- data/ext/lpsolver-highs/highs/mip/HighsNodeQueue.h +312 -0
- data/ext/lpsolver-highs/highs/mip/HighsObjectiveFunction.cpp +124 -0
- data/ext/lpsolver-highs/highs/mip/HighsObjectiveFunction.h +71 -0
- data/ext/lpsolver-highs/highs/mip/HighsPathSeparator.cpp +549 -0
- data/ext/lpsolver-highs/highs/mip/HighsPathSeparator.h +39 -0
- data/ext/lpsolver-highs/highs/mip/HighsPrimalHeuristics.cpp +1673 -0
- data/ext/lpsolver-highs/highs/mip/HighsPrimalHeuristics.h +75 -0
- data/ext/lpsolver-highs/highs/mip/HighsPseudocost.cpp +129 -0
- data/ext/lpsolver-highs/highs/mip/HighsPseudocost.h +366 -0
- data/ext/lpsolver-highs/highs/mip/HighsRedcostFixing.cpp +316 -0
- data/ext/lpsolver-highs/highs/mip/HighsRedcostFixing.h +42 -0
- data/ext/lpsolver-highs/highs/mip/HighsSearch.cpp +1881 -0
- data/ext/lpsolver-highs/highs/mip/HighsSearch.h +241 -0
- data/ext/lpsolver-highs/highs/mip/HighsSeparation.cpp +186 -0
- data/ext/lpsolver-highs/highs/mip/HighsSeparation.h +41 -0
- data/ext/lpsolver-highs/highs/mip/HighsSeparator.cpp +39 -0
- data/ext/lpsolver-highs/highs/mip/HighsSeparator.h +60 -0
- data/ext/lpsolver-highs/highs/mip/HighsTableauSeparator.cpp +244 -0
- data/ext/lpsolver-highs/highs/mip/HighsTableauSeparator.h +34 -0
- data/ext/lpsolver-highs/highs/mip/HighsTransformedLp.cpp +563 -0
- data/ext/lpsolver-highs/highs/mip/HighsTransformedLp.h +63 -0
- data/ext/lpsolver-highs/highs/mip/MipTimer.h +544 -0
- data/ext/lpsolver-highs/highs/mip/feasibilityjump.hh +800 -0
- data/ext/lpsolver-highs/highs/model/HighsHessian.cpp +263 -0
- data/ext/lpsolver-highs/highs/model/HighsHessian.h +54 -0
- data/ext/lpsolver-highs/highs/model/HighsHessianUtils.cpp +584 -0
- data/ext/lpsolver-highs/highs/model/HighsHessianUtils.h +47 -0
- data/ext/lpsolver-highs/highs/model/HighsModel.cpp +46 -0
- data/ext/lpsolver-highs/highs/model/HighsModel.h +42 -0
- data/ext/lpsolver-highs/highs/parallel/HighsBinarySemaphore.h +108 -0
- data/ext/lpsolver-highs/highs/parallel/HighsCacheAlign.h +82 -0
- data/ext/lpsolver-highs/highs/parallel/HighsCombinable.h +116 -0
- data/ext/lpsolver-highs/highs/parallel/HighsMutex.h +124 -0
- data/ext/lpsolver-highs/highs/parallel/HighsParallel.h +128 -0
- data/ext/lpsolver-highs/highs/parallel/HighsRaceTimer.h +38 -0
- data/ext/lpsolver-highs/highs/parallel/HighsSchedulerConstants.h +19 -0
- data/ext/lpsolver-highs/highs/parallel/HighsSpinMutex.h +48 -0
- data/ext/lpsolver-highs/highs/parallel/HighsSplitDeque.h +606 -0
- data/ext/lpsolver-highs/highs/parallel/HighsTask.h +170 -0
- data/ext/lpsolver-highs/highs/parallel/HighsTaskExecutor.cpp +43 -0
- data/ext/lpsolver-highs/highs/parallel/HighsTaskExecutor.h +217 -0
- data/ext/lpsolver-highs/highs/pdlp/CupdlpWrapper.cpp +848 -0
- data/ext/lpsolver-highs/highs/pdlp/CupdlpWrapper.h +108 -0
- data/ext/lpsolver-highs/highs/pdlp/HiPdlpTimer.h +155 -0
- data/ext/lpsolver-highs/highs/pdlp/HiPdlpWrapper.cpp +141 -0
- data/ext/lpsolver-highs/highs/pdlp/HiPdlpWrapper.h +26 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/Diff +12 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/Meld +7 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/Merge +2 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/README.md +95 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/CMakeLists.txt +58 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cuda_kernels.cu +338 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cuda_kernels.cuh +319 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cudalinalg.cu +386 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cudalinalg.cuh +149 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/test_cublas.c +154 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/test_cuda_linalg.c +79 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp.h +16 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_cs.c +214 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_cs.h +40 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_defs.h +447 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_linalg.c +802 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_linalg.h +189 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_proj.c +148 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_proj.h +19 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_restart.c +124 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_restart.h +31 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_scaling.c +425 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_scaling.h +26 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_solver.c +1498 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_solver.h +105 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_step.c +478 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_step.h +37 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_utils.c +1850 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_utils.h +212 -0
- data/ext/lpsolver-highs/highs/pdlp/cupdlp/glbopts.h +342 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/defs.hpp +222 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/linalg.cc +231 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/linalg.hpp +61 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/logger.cc +225 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/logger.hpp +80 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg.cc +2798 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg.cu +497 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg.hpp +358 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg_kernels.hpp +77 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdlp_gpu_debug.hpp +62 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/restart.cc +132 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/restart.hpp +96 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/scaling.cc +307 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/scaling.hpp +74 -0
- data/ext/lpsolver-highs/highs/pdlp/hipdlp/solver_results.hpp +65 -0
- data/ext/lpsolver-highs/highs/presolve/HPresolve.cpp +8511 -0
- data/ext/lpsolver-highs/highs/presolve/HPresolve.h +505 -0
- data/ext/lpsolver-highs/highs/presolve/HPresolveAnalysis.cpp +239 -0
- data/ext/lpsolver-highs/highs/presolve/HPresolveAnalysis.h +52 -0
- data/ext/lpsolver-highs/highs/presolve/HighsPostsolveStack.cpp +1368 -0
- data/ext/lpsolver-highs/highs/presolve/HighsPostsolveStack.h +943 -0
- data/ext/lpsolver-highs/highs/presolve/HighsSymmetry.cpp +1921 -0
- data/ext/lpsolver-highs/highs/presolve/HighsSymmetry.h +284 -0
- data/ext/lpsolver-highs/highs/presolve/ICrash.cpp +474 -0
- data/ext/lpsolver-highs/highs/presolve/ICrash.h +124 -0
- data/ext/lpsolver-highs/highs/presolve/ICrashUtil.cpp +267 -0
- data/ext/lpsolver-highs/highs/presolve/ICrashUtil.h +62 -0
- data/ext/lpsolver-highs/highs/presolve/ICrashX.cpp +173 -0
- data/ext/lpsolver-highs/highs/presolve/ICrashX.h +23 -0
- data/ext/lpsolver-highs/highs/presolve/PresolveComponent.cpp +45 -0
- data/ext/lpsolver-highs/highs/presolve/PresolveComponent.h +90 -0
- data/ext/lpsolver-highs/highs/qpsolver/README.md +185 -0
- data/ext/lpsolver-highs/highs/qpsolver/a_asm.cpp +139 -0
- data/ext/lpsolver-highs/highs/qpsolver/a_asm.hpp +77 -0
- data/ext/lpsolver-highs/highs/qpsolver/a_quass.cpp +194 -0
- data/ext/lpsolver-highs/highs/qpsolver/a_quass.hpp +22 -0
- data/ext/lpsolver-highs/highs/qpsolver/basis.cpp +443 -0
- data/ext/lpsolver-highs/highs/qpsolver/basis.hpp +159 -0
- data/ext/lpsolver-highs/highs/qpsolver/crashsolution.hpp +20 -0
- data/ext/lpsolver-highs/highs/qpsolver/dantzigpricing.hpp +80 -0
- data/ext/lpsolver-highs/highs/qpsolver/devexharrispricing.hpp +98 -0
- data/ext/lpsolver-highs/highs/qpsolver/devexpricing.hpp +108 -0
- data/ext/lpsolver-highs/highs/qpsolver/eventhandler.hpp +30 -0
- data/ext/lpsolver-highs/highs/qpsolver/factor.hpp +408 -0
- data/ext/lpsolver-highs/highs/qpsolver/feasibility_bounded.hpp +114 -0
- data/ext/lpsolver-highs/highs/qpsolver/feasibility_highs.hpp +301 -0
- data/ext/lpsolver-highs/highs/qpsolver/gradient.hpp +46 -0
- data/ext/lpsolver-highs/highs/qpsolver/instance.hpp +70 -0
- data/ext/lpsolver-highs/highs/qpsolver/matrix.hpp +342 -0
- data/ext/lpsolver-highs/highs/qpsolver/perturbation.cpp +41 -0
- data/ext/lpsolver-highs/highs/qpsolver/perturbation.hpp +15 -0
- data/ext/lpsolver-highs/highs/qpsolver/pricing.hpp +22 -0
- data/ext/lpsolver-highs/highs/qpsolver/qpconst.hpp +34 -0
- data/ext/lpsolver-highs/highs/qpsolver/qpvector.hpp +242 -0
- data/ext/lpsolver-highs/highs/qpsolver/quass.cpp +551 -0
- data/ext/lpsolver-highs/highs/qpsolver/quass.hpp +27 -0
- data/ext/lpsolver-highs/highs/qpsolver/ratiotest.cpp +146 -0
- data/ext/lpsolver-highs/highs/qpsolver/ratiotest.hpp +26 -0
- data/ext/lpsolver-highs/highs/qpsolver/reducedcosts.hpp +46 -0
- data/ext/lpsolver-highs/highs/qpsolver/reducedgradient.hpp +95 -0
- data/ext/lpsolver-highs/highs/qpsolver/runtime.hpp +45 -0
- data/ext/lpsolver-highs/highs/qpsolver/scaling.cpp +123 -0
- data/ext/lpsolver-highs/highs/qpsolver/scaling.hpp +15 -0
- data/ext/lpsolver-highs/highs/qpsolver/settings.hpp +84 -0
- data/ext/lpsolver-highs/highs/qpsolver/snippets.hpp +36 -0
- data/ext/lpsolver-highs/highs/qpsolver/statistics.hpp +30 -0
- data/ext/lpsolver-highs/highs/qpsolver/steepestedgepricing.hpp +173 -0
- data/ext/lpsolver-highs/highs/simplex/HApp.h +550 -0
- data/ext/lpsolver-highs/highs/simplex/HEkk.cpp +4404 -0
- data/ext/lpsolver-highs/highs/simplex/HEkk.h +419 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkControl.cpp +146 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkDebug.cpp +1722 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkDual.cpp +3003 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkDual.h +513 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkDualMulti.cpp +1020 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkDualRHS.cpp +535 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkDualRHS.h +134 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkDualRow.cpp +697 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkDualRow.h +201 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkInterface.cpp +26 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkPrimal.cpp +2984 -0
- data/ext/lpsolver-highs/highs/simplex/HEkkPrimal.h +191 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplex.cpp +330 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplex.h +42 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplexDebug.cpp +145 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplexDebug.h +48 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplexNla.cpp +517 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplexNla.h +158 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplexNlaDebug.cpp +373 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplexNlaFreeze.cpp +28 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplexNlaProductForm.cpp +113 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplexReport.cpp +77 -0
- data/ext/lpsolver-highs/highs/simplex/HSimplexReport.h +21 -0
- data/ext/lpsolver-highs/highs/simplex/HighsSimplexAnalysis.cpp +1495 -0
- data/ext/lpsolver-highs/highs/simplex/HighsSimplexAnalysis.h +500 -0
- data/ext/lpsolver-highs/highs/simplex/SimplexConst.h +273 -0
- data/ext/lpsolver-highs/highs/simplex/SimplexStruct.h +263 -0
- data/ext/lpsolver-highs/highs/simplex/SimplexTimer.h +414 -0
- data/ext/lpsolver-highs/highs/test_kkt/DevKkt.cpp +469 -0
- data/ext/lpsolver-highs/highs/test_kkt/DevKkt.h +143 -0
- data/ext/lpsolver-highs/highs/test_kkt/KktCh2.cpp +305 -0
- data/ext/lpsolver-highs/highs/test_kkt/KktCh2.h +79 -0
- data/ext/lpsolver-highs/highs/util/FactorTimer.h +199 -0
- data/ext/lpsolver-highs/highs/util/HFactor.cpp +2597 -0
- data/ext/lpsolver-highs/highs/util/HFactor.h +587 -0
- data/ext/lpsolver-highs/highs/util/HFactorConst.h +81 -0
- data/ext/lpsolver-highs/highs/util/HFactorDebug.cpp +231 -0
- data/ext/lpsolver-highs/highs/util/HFactorDebug.h +55 -0
- data/ext/lpsolver-highs/highs/util/HFactorExtend.cpp +229 -0
- data/ext/lpsolver-highs/highs/util/HFactorRefactor.cpp +304 -0
- data/ext/lpsolver-highs/highs/util/HFactorUtils.cpp +122 -0
- data/ext/lpsolver-highs/highs/util/HSet.cpp +197 -0
- data/ext/lpsolver-highs/highs/util/HSet.h +89 -0
- data/ext/lpsolver-highs/highs/util/HVector.h +22 -0
- data/ext/lpsolver-highs/highs/util/HVectorBase.cpp +271 -0
- data/ext/lpsolver-highs/highs/util/HVectorBase.h +102 -0
- data/ext/lpsolver-highs/highs/util/HighsCDouble.h +323 -0
- data/ext/lpsolver-highs/highs/util/HighsComponent.h +53 -0
- data/ext/lpsolver-highs/highs/util/HighsDataStack.h +83 -0
- data/ext/lpsolver-highs/highs/util/HighsDisjointSets.h +107 -0
- data/ext/lpsolver-highs/highs/util/HighsHash.cpp +10 -0
- data/ext/lpsolver-highs/highs/util/HighsHash.h +1274 -0
- data/ext/lpsolver-highs/highs/util/HighsHashTree.h +1461 -0
- data/ext/lpsolver-highs/highs/util/HighsInt.h +36 -0
- data/ext/lpsolver-highs/highs/util/HighsIntegers.h +212 -0
- data/ext/lpsolver-highs/highs/util/HighsLinearSumBounds.cpp +267 -0
- data/ext/lpsolver-highs/highs/util/HighsLinearSumBounds.h +203 -0
- data/ext/lpsolver-highs/highs/util/HighsMatrixPic.cpp +146 -0
- data/ext/lpsolver-highs/highs/util/HighsMatrixPic.h +37 -0
- data/ext/lpsolver-highs/highs/util/HighsMatrixSlice.h +561 -0
- data/ext/lpsolver-highs/highs/util/HighsMatrixUtils.cpp +407 -0
- data/ext/lpsolver-highs/highs/util/HighsMatrixUtils.h +57 -0
- data/ext/lpsolver-highs/highs/util/HighsMemoryAllocation.h +63 -0
- data/ext/lpsolver-highs/highs/util/HighsRandom.h +242 -0
- data/ext/lpsolver-highs/highs/util/HighsRbTree.h +452 -0
- data/ext/lpsolver-highs/highs/util/HighsSort.cpp +364 -0
- data/ext/lpsolver-highs/highs/util/HighsSort.h +131 -0
- data/ext/lpsolver-highs/highs/util/HighsSparseMatrix.cpp +1746 -0
- data/ext/lpsolver-highs/highs/util/HighsSparseMatrix.h +151 -0
- data/ext/lpsolver-highs/highs/util/HighsSparseVectorSum.h +95 -0
- data/ext/lpsolver-highs/highs/util/HighsSplay.h +135 -0
- data/ext/lpsolver-highs/highs/util/HighsTimer.h +385 -0
- data/ext/lpsolver-highs/highs/util/HighsUtils.cpp +1259 -0
- data/ext/lpsolver-highs/highs/util/HighsUtils.h +272 -0
- data/ext/lpsolver-highs/highs/util/stringutil.cpp +131 -0
- data/ext/lpsolver-highs/highs/util/stringutil.h +46 -0
- data/ext/lpsolver-highs/highs.pc.in +12 -0
- data/ext/lpsolver-highs/meson.build +198 -0
- data/ext/lpsolver-highs/meson_options.txt +31 -0
- data/ext/lpsolver-highs/nuget/HiGHS_Logo.png +0 -0
- data/ext/lpsolver-highs/nuget/Highs.csproj +25 -0
- data/ext/lpsolver-highs/nuget/Highs.csproj.in +36 -0
- data/ext/lpsolver-highs/nuget/HowToAlternative.md +77 -0
- data/ext/lpsolver-highs/nuget/README.md +38 -0
- data/ext/lpsolver-highs/nuget/arm-toolchain.cmake +15 -0
- data/ext/lpsolver-highs/nuget/build_linux-arm.sh +13 -0
- data/ext/lpsolver-highs/nuget/build_linux.sh +10 -0
- data/ext/lpsolver-highs/nuget/build_windows.ps1 +27 -0
- data/ext/lpsolver-highs/nuget/generatePackage.ps1 +28 -0
- data/ext/lpsolver-highs/pyproject.toml +221 -0
- data/ext/lpsolver-highs/subprojects/pybind11.wrap +13 -0
- data/ext/lpsolver-highs/tests/test_highspy.py +2310 -0
- data/ext/lpsolver-highs/version.rc.in +50 -0
- data/lib/lpsolver/highs +0 -0
- data/lib/lpsolver/model.rb +28 -4
- data/lib/lpsolver/native.so +0 -0
- data/lib/lpsolver/native_model.rb +261 -0
- data/lib/lpsolver/solution.rb +72 -7
- data/lib/lpsolver/version.rb +1 -1
- data/lpsolver.gemspec +4 -1
- metadata +1176 -4
|
@@ -0,0 +1,2194 @@
|
|
|
1
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
2
|
+
/* */
|
|
3
|
+
/* This file is part of the HiGHS linear optimization suite */
|
|
4
|
+
/* */
|
|
5
|
+
/* Available as open-source under the MIT License */
|
|
6
|
+
/* */
|
|
7
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
8
|
+
/**@file lp_data/HighsSolution.cpp
|
|
9
|
+
* @brief Class-independent utilities for HiGHS
|
|
10
|
+
*/
|
|
11
|
+
#include "lp_data/HighsSolution.h"
|
|
12
|
+
|
|
13
|
+
#include <string>
|
|
14
|
+
#include <vector>
|
|
15
|
+
|
|
16
|
+
#include "io/HighsIO.h"
|
|
17
|
+
#include "ipm/IpxSolution.h"
|
|
18
|
+
#include "ipm/ipx/ipx_status.h"
|
|
19
|
+
#include "ipm/ipx/lp_solver.h"
|
|
20
|
+
#include "lp_data/HighsLpUtils.h"
|
|
21
|
+
#include "lp_data/HighsModelUtils.h"
|
|
22
|
+
#include "lp_data/HighsSolutionDebug.h"
|
|
23
|
+
|
|
24
|
+
const uint8_t kHighsSolutionLo = -1;
|
|
25
|
+
const uint8_t kHighsSolutionNo = 0;
|
|
26
|
+
const uint8_t kHighsSolutionUp = 1;
|
|
27
|
+
|
|
28
|
+
const bool printf_kkt = false; // true; //
|
|
29
|
+
|
|
30
|
+
void getKktFailures(const HighsOptions& options, const HighsModel& model,
|
|
31
|
+
const HighsSolution& solution, const HighsBasis& basis,
|
|
32
|
+
HighsInfo& highs_info) {
|
|
33
|
+
HighsPrimalDualErrors primal_dual_errors;
|
|
34
|
+
getKktFailures(options, model, solution, basis, highs_info,
|
|
35
|
+
primal_dual_errors);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
void getKktFailures(const HighsOptions& options, const HighsModel& model,
|
|
39
|
+
const HighsSolution& solution, const HighsBasis& basis,
|
|
40
|
+
HighsInfo& highs_info,
|
|
41
|
+
HighsPrimalDualErrors& primal_dual_errors,
|
|
42
|
+
const bool get_residuals) {
|
|
43
|
+
vector<double> gradient;
|
|
44
|
+
model.objectiveGradient(solution.col_value, gradient);
|
|
45
|
+
const HighsLp& lp = model.lp_;
|
|
46
|
+
getKktFailures(options, model.isQp(), lp, gradient, solution, highs_info,
|
|
47
|
+
get_residuals);
|
|
48
|
+
getPrimalDualBasisErrors(options, lp, solution, basis, primal_dual_errors);
|
|
49
|
+
getPrimalDualGlpsolErrors(options, lp, gradient, solution,
|
|
50
|
+
primal_dual_errors);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
void getLpKktFailures(const HighsOptions& options, const HighsLp& lp,
|
|
54
|
+
const HighsSolution& solution, const HighsBasis& basis,
|
|
55
|
+
HighsInfo& highs_info) {
|
|
56
|
+
HighsPrimalDualErrors primal_dual_errors;
|
|
57
|
+
getLpKktFailures(options, lp, solution, basis, highs_info,
|
|
58
|
+
primal_dual_errors);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
void getLpKktFailures(const HighsOptions& options, const HighsLp& lp,
|
|
62
|
+
const HighsSolution& solution, const HighsBasis& basis,
|
|
63
|
+
HighsInfo& highs_info,
|
|
64
|
+
HighsPrimalDualErrors& primal_dual_errors,
|
|
65
|
+
const bool get_residuals) {
|
|
66
|
+
getKktFailures(options, false, lp, lp.col_cost_, solution, highs_info,
|
|
67
|
+
get_residuals);
|
|
68
|
+
getPrimalDualBasisErrors(options, lp, solution, basis, primal_dual_errors);
|
|
69
|
+
getPrimalDualGlpsolErrors(options, lp, lp.col_cost_, solution,
|
|
70
|
+
primal_dual_errors);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
void getKktFailures(const HighsOptions& options, const bool is_qp,
|
|
74
|
+
const HighsLp& lp, const std::vector<double>& gradient,
|
|
75
|
+
const HighsSolution& solution, HighsInfo& highs_info,
|
|
76
|
+
const bool get_residuals) {
|
|
77
|
+
double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
|
|
78
|
+
double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
|
|
79
|
+
double primal_residual_tolerance = options.primal_residual_tolerance;
|
|
80
|
+
double dual_residual_tolerance = options.dual_residual_tolerance;
|
|
81
|
+
double optimality_tolerance = options.optimality_tolerance;
|
|
82
|
+
if (options.kkt_tolerance != kDefaultKktTolerance) {
|
|
83
|
+
primal_feasibility_tolerance = options.kkt_tolerance;
|
|
84
|
+
dual_feasibility_tolerance = options.kkt_tolerance;
|
|
85
|
+
primal_residual_tolerance = options.kkt_tolerance;
|
|
86
|
+
dual_residual_tolerance = options.kkt_tolerance;
|
|
87
|
+
optimality_tolerance = options.kkt_tolerance;
|
|
88
|
+
}
|
|
89
|
+
// highs_info are the values computed in this method
|
|
90
|
+
|
|
91
|
+
HighsInt& num_primal_infeasibility = highs_info.num_primal_infeasibilities;
|
|
92
|
+
double& max_primal_infeasibility = highs_info.max_primal_infeasibility;
|
|
93
|
+
double& sum_primal_infeasibility = highs_info.sum_primal_infeasibilities;
|
|
94
|
+
|
|
95
|
+
HighsInt& num_dual_infeasibility = highs_info.num_dual_infeasibilities;
|
|
96
|
+
double& max_dual_infeasibility = highs_info.max_dual_infeasibility;
|
|
97
|
+
double& sum_dual_infeasibility = highs_info.sum_dual_infeasibilities;
|
|
98
|
+
|
|
99
|
+
HighsInt& num_relative_primal_infeasibility =
|
|
100
|
+
highs_info.num_relative_primal_infeasibilities;
|
|
101
|
+
double& max_relative_primal_infeasibility =
|
|
102
|
+
highs_info.max_relative_primal_infeasibility;
|
|
103
|
+
|
|
104
|
+
HighsInt& num_relative_dual_infeasibility =
|
|
105
|
+
highs_info.num_relative_dual_infeasibilities;
|
|
106
|
+
double& max_relative_dual_infeasibility =
|
|
107
|
+
highs_info.max_relative_dual_infeasibility;
|
|
108
|
+
|
|
109
|
+
HighsInt& num_primal_residual_error = highs_info.num_primal_residual_errors;
|
|
110
|
+
double& max_primal_residual_error = highs_info.max_primal_residual_error;
|
|
111
|
+
|
|
112
|
+
HighsInt& num_dual_residual_error = highs_info.num_dual_residual_errors;
|
|
113
|
+
double& max_dual_residual_error = highs_info.max_dual_residual_error;
|
|
114
|
+
|
|
115
|
+
HighsInt& num_relative_primal_residual_error =
|
|
116
|
+
highs_info.num_relative_primal_residual_errors;
|
|
117
|
+
double& max_relative_primal_residual_error =
|
|
118
|
+
highs_info.max_relative_primal_residual_error;
|
|
119
|
+
|
|
120
|
+
HighsInt& num_relative_dual_residual_error =
|
|
121
|
+
highs_info.num_relative_dual_residual_errors;
|
|
122
|
+
double& max_relative_dual_residual_error =
|
|
123
|
+
highs_info.max_relative_dual_residual_error;
|
|
124
|
+
|
|
125
|
+
HighsInt& num_complementarity_violation =
|
|
126
|
+
highs_info.num_complementarity_violations;
|
|
127
|
+
double& max_complementarity_violation =
|
|
128
|
+
highs_info.max_complementarity_violation;
|
|
129
|
+
|
|
130
|
+
double& primal_dual_objective_error = highs_info.primal_dual_objective_error;
|
|
131
|
+
|
|
132
|
+
const bool& have_primal_solution = solution.value_valid;
|
|
133
|
+
const bool& have_dual_solution = solution.dual_valid;
|
|
134
|
+
const bool have_integrality = (lp.integrality_.size() != 0);
|
|
135
|
+
|
|
136
|
+
// Primal/dual solution status on entry can be feasible or
|
|
137
|
+
// infeasible, because it refers to the previous problem solved, so
|
|
138
|
+
// can't check whether something meaningful is being changed
|
|
139
|
+
highs_info.primal_solution_status = kSolutionStatusNone;
|
|
140
|
+
highs_info.dual_solution_status = kSolutionStatusNone;
|
|
141
|
+
|
|
142
|
+
// Check that there is no dual solution if there's no primal solution
|
|
143
|
+
assert(have_primal_solution || !have_dual_solution);
|
|
144
|
+
|
|
145
|
+
// Invalidate all the KKT measures
|
|
146
|
+
highs_info.invalidateKkt();
|
|
147
|
+
|
|
148
|
+
if (have_primal_solution) {
|
|
149
|
+
// There's a primal solution, so check its size and initialise the
|
|
150
|
+
// infeasibility counts
|
|
151
|
+
assert((int)solution.col_value.size() >= lp.num_col_);
|
|
152
|
+
assert((int)solution.row_value.size() >= lp.num_row_);
|
|
153
|
+
num_primal_infeasibility = 0;
|
|
154
|
+
max_primal_infeasibility = 0;
|
|
155
|
+
sum_primal_infeasibility = 0;
|
|
156
|
+
num_relative_primal_infeasibility = 0;
|
|
157
|
+
max_relative_primal_infeasibility = 0;
|
|
158
|
+
if (get_residuals) {
|
|
159
|
+
num_primal_residual_error = 0;
|
|
160
|
+
max_primal_residual_error = 0;
|
|
161
|
+
num_relative_primal_residual_error = 0;
|
|
162
|
+
max_relative_primal_residual_error = 0;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (have_dual_solution) {
|
|
166
|
+
// There's a dual solution, so check its size and initialise the
|
|
167
|
+
// infeasibility counts
|
|
168
|
+
assert((int)solution.col_dual.size() >= lp.num_col_);
|
|
169
|
+
assert((int)solution.row_dual.size() >= lp.num_row_);
|
|
170
|
+
num_dual_infeasibility = 0;
|
|
171
|
+
max_dual_infeasibility = 0;
|
|
172
|
+
sum_dual_infeasibility = 0;
|
|
173
|
+
num_relative_dual_infeasibility = 0;
|
|
174
|
+
max_relative_dual_infeasibility = 0;
|
|
175
|
+
if (get_residuals) {
|
|
176
|
+
num_dual_residual_error = 0;
|
|
177
|
+
max_dual_residual_error = 0;
|
|
178
|
+
num_relative_dual_residual_error = 0;
|
|
179
|
+
max_relative_dual_residual_error = 0;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Without a primal solution, nothing can be done!
|
|
183
|
+
if (!have_primal_solution) return;
|
|
184
|
+
|
|
185
|
+
// Possibly compute Ax and A^Ty (to form A^Ty-c) as residual check
|
|
186
|
+
// for solution.row_value and -solution.col_dual
|
|
187
|
+
std::vector<double> primal_activity;
|
|
188
|
+
std::vector<double> dual_activity;
|
|
189
|
+
if (get_residuals)
|
|
190
|
+
lp.a_matrix_.productQuad(primal_activity, solution.col_value);
|
|
191
|
+
if (get_residuals && have_dual_solution)
|
|
192
|
+
lp.a_matrix_.productTransposeQuad(dual_activity, solution.row_dual);
|
|
193
|
+
|
|
194
|
+
double max_col_primal_infeasibility = 0;
|
|
195
|
+
double max_col_dual_infeasibility = 0;
|
|
196
|
+
double max_relative_col_primal_infeasibility = 0;
|
|
197
|
+
double max_relative_col_dual_infeasibility = 0;
|
|
198
|
+
|
|
199
|
+
double primal_infeasibility;
|
|
200
|
+
double relative_primal_infeasibility;
|
|
201
|
+
double dual_infeasibility;
|
|
202
|
+
double cost = 0.0;
|
|
203
|
+
double lower;
|
|
204
|
+
double upper;
|
|
205
|
+
double value;
|
|
206
|
+
double dual = 0;
|
|
207
|
+
uint8_t at_status;
|
|
208
|
+
uint8_t mid_status;
|
|
209
|
+
HighsVarType integrality = HighsVarType::kContinuous;
|
|
210
|
+
HighsBasisStatus status;
|
|
211
|
+
// Compute the infinity norm of all near-active column and row
|
|
212
|
+
// bounds, since they contribute to the magnitude of the row values,
|
|
213
|
+
// and dividing their residual error by the norm gives a relative
|
|
214
|
+
// residual error: don't consider large inactive bounds, since they
|
|
215
|
+
// don't affect the model
|
|
216
|
+
//
|
|
217
|
+
// In IPM without crossover, the columns and rows with values close
|
|
218
|
+
// to their bounds are marginal in driving the algorithm so, by
|
|
219
|
+
// computing the norm as we do, we capture the active bounds of all
|
|
220
|
+
// these variables.
|
|
221
|
+
//
|
|
222
|
+
// In PDLP, only the constraint bounds contribute to the norm, but
|
|
223
|
+
// do the variable bounds not (also) drive the algorithm
|
|
224
|
+
//
|
|
225
|
+
// In simplex the values of the nonbasic variables would be used,
|
|
226
|
+
// since they determine the RHS of the system solved for the values
|
|
227
|
+
// of the basic variables values. That said, by computing the norm
|
|
228
|
+
// as we do, we capture the active bounds of all the nonbasic variables
|
|
229
|
+
double highs_norm_bounds = 0.0;
|
|
230
|
+
// Compute the infinity norm of all near-active column duals, since
|
|
231
|
+
// they contribute to the magnitude of the row values, and dividing
|
|
232
|
+
// their residual error by the norm gives a relative residual error:
|
|
233
|
+
// don't consider large inactive bounds, since they don't affect the
|
|
234
|
+
// model
|
|
235
|
+
double highs_norm_costs = 0.0;
|
|
236
|
+
|
|
237
|
+
// Pass twice through this loop, once to determine the bound and
|
|
238
|
+
// cost norms, and once to use them to assess relative
|
|
239
|
+
// infeasibilities and residual errors
|
|
240
|
+
for (HighsInt pass = 0; pass < 2; pass++) {
|
|
241
|
+
for (HighsInt iVar = 0; iVar < lp.num_col_ + lp.num_row_; iVar++) {
|
|
242
|
+
const bool is_col = iVar < lp.num_col_;
|
|
243
|
+
if (is_col) {
|
|
244
|
+
HighsInt iCol = iVar;
|
|
245
|
+
cost = gradient[iCol];
|
|
246
|
+
lower = lp.col_lower_[iCol];
|
|
247
|
+
upper = lp.col_upper_[iCol];
|
|
248
|
+
value = solution.col_value[iCol];
|
|
249
|
+
if (have_dual_solution) dual = solution.col_dual[iCol];
|
|
250
|
+
if (have_integrality) integrality = lp.integrality_[iCol];
|
|
251
|
+
if (pass == 0) {
|
|
252
|
+
if (dual * dual < dual_feasibility_tolerance) {
|
|
253
|
+
// Dual close to zero
|
|
254
|
+
highs_norm_costs = std::max(std::fabs(cost), highs_norm_costs);
|
|
255
|
+
}
|
|
256
|
+
if (get_residuals && have_dual_solution) {
|
|
257
|
+
// Subtract off the gradient value
|
|
258
|
+
HighsCDouble q_dual_activity = dual_activity[iCol];
|
|
259
|
+
q_dual_activity -= gradient[iCol];
|
|
260
|
+
dual_activity[iCol] = double(q_dual_activity);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
//
|
|
264
|
+
} else {
|
|
265
|
+
HighsInt iRow = iVar - lp.num_col_;
|
|
266
|
+
lower = lp.row_lower_[iRow];
|
|
267
|
+
upper = lp.row_upper_[iRow];
|
|
268
|
+
value = solution.row_value[iRow];
|
|
269
|
+
if (have_dual_solution) dual = solution.row_dual[iRow];
|
|
270
|
+
integrality = HighsVarType::kContinuous;
|
|
271
|
+
}
|
|
272
|
+
// Flip dual according to lp.sense_
|
|
273
|
+
dual *= (HighsInt)lp.sense_;
|
|
274
|
+
// Get the primal and dual infeasibility for this variable, and
|
|
275
|
+
//
|
|
276
|
+
// at_status: Indicates whether the variable is close to its
|
|
277
|
+
// lower bound, upper bound or not at all. Use this as a proxy
|
|
278
|
+
// for being non-basic, so the active bound contributes to
|
|
279
|
+
// highs_norm_bounds for calculating relative primal measures.
|
|
280
|
+
//
|
|
281
|
+
// mid_status: Indicates whether a variable with meaningful
|
|
282
|
+
// bound interval length is below the midpoint of its bound
|
|
283
|
+
// interval, or above the midpoint. The midpoint is infinite for
|
|
284
|
+
// one-sided variables. For free variables, fixed variables, or
|
|
285
|
+
// variables with small positive bound interval lengths,
|
|
286
|
+
// mid_status is returned as kHighsSolutionNo.
|
|
287
|
+
getVariableKktFailures(primal_feasibility_tolerance,
|
|
288
|
+
dual_feasibility_tolerance, lower, upper, value,
|
|
289
|
+
dual, integrality, primal_infeasibility,
|
|
290
|
+
dual_infeasibility, at_status, mid_status);
|
|
291
|
+
if (pass == 0) {
|
|
292
|
+
// If the primal value is close to a bound then include the bound
|
|
293
|
+
// in the active bound norm
|
|
294
|
+
if (at_status == kHighsSolutionLo) {
|
|
295
|
+
highs_norm_bounds = std::max(std::fabs(lower), highs_norm_bounds);
|
|
296
|
+
} else if (at_status == kHighsSolutionUp) {
|
|
297
|
+
highs_norm_bounds = std::max(std::fabs(upper), highs_norm_bounds);
|
|
298
|
+
}
|
|
299
|
+
} else {
|
|
300
|
+
if (primal_infeasibility > 0) {
|
|
301
|
+
// Accumulate primal infeasibilities
|
|
302
|
+
if (primal_infeasibility > primal_feasibility_tolerance)
|
|
303
|
+
num_primal_infeasibility++;
|
|
304
|
+
if (max_primal_infeasibility < primal_infeasibility)
|
|
305
|
+
max_primal_infeasibility = primal_infeasibility;
|
|
306
|
+
sum_primal_infeasibility += primal_infeasibility;
|
|
307
|
+
// Determine the denominator for the relative primal
|
|
308
|
+
// infeasibility
|
|
309
|
+
double relative_bound_measure = highs_norm_bounds;
|
|
310
|
+
if (at_status == kHighsSolutionNo) {
|
|
311
|
+
// Primal value is infeasible, but not close to a bound:
|
|
312
|
+
// unusual, but possible if absolute primal infeasibilities
|
|
313
|
+
// are not small. Bound has not been included in
|
|
314
|
+
// highs_norm_bounds, but should be used for local
|
|
315
|
+
// relative infeasibility
|
|
316
|
+
if (mid_status == kHighsSolutionNo ||
|
|
317
|
+
mid_status == kHighsSolutionLo) {
|
|
318
|
+
// Bound interval is short, or variable is below the
|
|
319
|
+
// midpoint (which is only possible if lower is finite)
|
|
320
|
+
relative_bound_measure =
|
|
321
|
+
std::max(std::fabs(lower), relative_bound_measure);
|
|
322
|
+
} else {
|
|
323
|
+
assert(mid_status == kHighsSolutionUp);
|
|
324
|
+
// Variable is above the midpoint of the bound interval
|
|
325
|
+
// (which is only possible if upper is finite)
|
|
326
|
+
relative_bound_measure =
|
|
327
|
+
std::max(std::fabs(upper), relative_bound_measure);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
double relative_primal_infeasibility =
|
|
331
|
+
primal_infeasibility / (1.0 + relative_bound_measure);
|
|
332
|
+
|
|
333
|
+
if (relative_primal_infeasibility > primal_feasibility_tolerance)
|
|
334
|
+
num_relative_primal_infeasibility++;
|
|
335
|
+
if (max_relative_primal_infeasibility < relative_primal_infeasibility)
|
|
336
|
+
max_relative_primal_infeasibility = relative_primal_infeasibility;
|
|
337
|
+
}
|
|
338
|
+
if (have_dual_solution) {
|
|
339
|
+
if (dual_infeasibility > 0) {
|
|
340
|
+
// Accumulate dual infeasibilities
|
|
341
|
+
if (dual_infeasibility > dual_feasibility_tolerance)
|
|
342
|
+
num_dual_infeasibility++;
|
|
343
|
+
if (max_dual_infeasibility < dual_infeasibility)
|
|
344
|
+
max_dual_infeasibility = dual_infeasibility;
|
|
345
|
+
sum_dual_infeasibility += dual_infeasibility;
|
|
346
|
+
|
|
347
|
+
// Determine the denominator for the relative dual
|
|
348
|
+
// infeasibility
|
|
349
|
+
double relative_cost_measure = highs_norm_costs;
|
|
350
|
+
if (is_col && cost && dual * dual >= dual_feasibility_tolerance) {
|
|
351
|
+
// Dual value is infeasible, but not close to zero:
|
|
352
|
+
// unusual, but possible if absolute dual infeasibilities
|
|
353
|
+
// are not small. Hence the cost has not been included in
|
|
354
|
+
// highs_norm_costs, but should be used for local relative
|
|
355
|
+
// infeasibility.
|
|
356
|
+
//
|
|
357
|
+
// updateRelativeMeasure(cost, relative_cost_measure);
|
|
358
|
+
relative_cost_measure =
|
|
359
|
+
std::max(std::fabs(cost), relative_cost_measure);
|
|
360
|
+
}
|
|
361
|
+
double relative_dual_infeasibility =
|
|
362
|
+
dual_infeasibility / (1.0 + relative_cost_measure);
|
|
363
|
+
|
|
364
|
+
if (relative_dual_infeasibility > dual_feasibility_tolerance)
|
|
365
|
+
num_relative_dual_infeasibility++;
|
|
366
|
+
if (max_relative_dual_infeasibility < relative_dual_infeasibility)
|
|
367
|
+
max_relative_dual_infeasibility = relative_dual_infeasibility;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (!is_col && get_residuals) {
|
|
371
|
+
HighsInt iRow = iVar - lp.num_col_;
|
|
372
|
+
assert(iRow >= 0);
|
|
373
|
+
double primal_residual_error =
|
|
374
|
+
std::fabs(primal_activity[iRow] - solution.row_value[iRow]);
|
|
375
|
+
double relative_primal_residual_error =
|
|
376
|
+
primal_residual_error / (1.0 + highs_norm_bounds);
|
|
377
|
+
|
|
378
|
+
if (primal_residual_error > primal_residual_tolerance)
|
|
379
|
+
num_primal_residual_error++;
|
|
380
|
+
if (max_primal_residual_error < primal_residual_error)
|
|
381
|
+
max_primal_residual_error = primal_residual_error;
|
|
382
|
+
|
|
383
|
+
if (relative_primal_residual_error > primal_residual_tolerance)
|
|
384
|
+
num_relative_primal_residual_error++;
|
|
385
|
+
if (max_relative_primal_residual_error <
|
|
386
|
+
relative_primal_residual_error)
|
|
387
|
+
max_relative_primal_residual_error = relative_primal_residual_error;
|
|
388
|
+
}
|
|
389
|
+
if (is_col && get_residuals && have_dual_solution) {
|
|
390
|
+
HighsInt iCol = iVar;
|
|
391
|
+
assert(iCol < lp.num_col_);
|
|
392
|
+
double dual_residual_error =
|
|
393
|
+
std::fabs(dual_activity[iCol] + solution.col_dual[iCol]);
|
|
394
|
+
double relative_dual_residual_error =
|
|
395
|
+
dual_residual_error / (1.0 + highs_norm_costs);
|
|
396
|
+
|
|
397
|
+
if (dual_residual_error > dual_residual_tolerance)
|
|
398
|
+
num_dual_residual_error++;
|
|
399
|
+
if (max_dual_residual_error < dual_residual_error)
|
|
400
|
+
max_dual_residual_error = dual_residual_error;
|
|
401
|
+
|
|
402
|
+
if (relative_dual_residual_error > dual_residual_tolerance)
|
|
403
|
+
num_relative_dual_residual_error++;
|
|
404
|
+
if (max_relative_dual_residual_error < relative_dual_residual_error)
|
|
405
|
+
max_relative_dual_residual_error = relative_dual_residual_error;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (pass == 1 && iVar == lp.num_col_ - 1) {
|
|
409
|
+
max_col_primal_infeasibility = max_primal_infeasibility;
|
|
410
|
+
max_col_dual_infeasibility = max_dual_infeasibility;
|
|
411
|
+
|
|
412
|
+
max_relative_col_primal_infeasibility =
|
|
413
|
+
max_relative_primal_infeasibility;
|
|
414
|
+
max_relative_col_dual_infeasibility = max_relative_dual_infeasibility;
|
|
415
|
+
|
|
416
|
+
max_primal_infeasibility = 0;
|
|
417
|
+
max_dual_infeasibility = 0;
|
|
418
|
+
|
|
419
|
+
max_relative_primal_infeasibility = 0;
|
|
420
|
+
max_relative_dual_infeasibility = 0;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
double max_row_primal_infeasibility = max_primal_infeasibility;
|
|
426
|
+
double max_row_dual_infeasibility = max_dual_infeasibility;
|
|
427
|
+
|
|
428
|
+
double max_relative_row_primal_infeasibility =
|
|
429
|
+
max_relative_primal_infeasibility;
|
|
430
|
+
double max_relative_row_dual_infeasibility = max_relative_dual_infeasibility;
|
|
431
|
+
|
|
432
|
+
max_primal_infeasibility =
|
|
433
|
+
std::max(max_col_primal_infeasibility, max_row_primal_infeasibility);
|
|
434
|
+
max_dual_infeasibility =
|
|
435
|
+
std::max(max_col_dual_infeasibility, max_row_dual_infeasibility);
|
|
436
|
+
|
|
437
|
+
max_relative_primal_infeasibility =
|
|
438
|
+
std::max(max_relative_col_primal_infeasibility,
|
|
439
|
+
max_relative_row_primal_infeasibility);
|
|
440
|
+
max_relative_dual_infeasibility = std::max(
|
|
441
|
+
max_relative_col_dual_infeasibility, max_relative_row_dual_infeasibility);
|
|
442
|
+
|
|
443
|
+
if (have_dual_solution) {
|
|
444
|
+
// Determine the sum of complementarity violations
|
|
445
|
+
const bool have_values = getComplementarityViolations(
|
|
446
|
+
lp, solution, optimality_tolerance, num_complementarity_violation,
|
|
447
|
+
max_complementarity_violation);
|
|
448
|
+
assert(have_values);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (have_dual_solution) {
|
|
452
|
+
// Determine the primal-dual objective error
|
|
453
|
+
//
|
|
454
|
+
// IPX computes objective_gap = (pobjective-dobjective) / (1.0 +
|
|
455
|
+
// 0.5*std::fabs(pobjective+dobjective));
|
|
456
|
+
//
|
|
457
|
+
// PDLP computes dRelObjGap = fabs(dPrimalObj - dDualObj) / (1.0 +
|
|
458
|
+
// fabs(dPrimalObj) + fabs(dDualObj));
|
|
459
|
+
//
|
|
460
|
+
// Use the PDLP relative primal-dual objective error
|
|
461
|
+
//
|
|
462
|
+
// The dual objective for a QP has a -(1/2)x^TQx term, and this
|
|
463
|
+
// can be computed from the gradient (g = Qx + c) as
|
|
464
|
+
// -(1/2)(g-c)^Tx = (1/2)(c-g)^Tx, so pass a pointer to the
|
|
465
|
+
// gradient data if this is necessary
|
|
466
|
+
const double* gradient_p = is_qp ? gradient.data() : nullptr;
|
|
467
|
+
double dual_objective_value;
|
|
468
|
+
bool dual_objective_status = computeDualObjectiveValue(
|
|
469
|
+
gradient_p, lp, solution, dual_objective_value);
|
|
470
|
+
assert(dual_objective_status);
|
|
471
|
+
const double abs_objective_difference =
|
|
472
|
+
std::fabs(highs_info.objective_function_value - dual_objective_value);
|
|
473
|
+
primal_dual_objective_error = abs_objective_difference;
|
|
474
|
+
const double denominator = 1.0 +
|
|
475
|
+
std::fabs(highs_info.objective_function_value) +
|
|
476
|
+
std::fabs(dual_objective_value);
|
|
477
|
+
primal_dual_objective_error = primal_dual_objective_error / denominator;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
if (printf_kkt || options.log_dev_level > 0) {
|
|
481
|
+
highsLogDev(options.log_options, HighsLogType::kInfo,
|
|
482
|
+
"getKktFailures:: cost norm = %8.3g; bound norm = %8.3g\n",
|
|
483
|
+
highs_norm_costs, highs_norm_bounds);
|
|
484
|
+
highsLogDev(options.log_options, HighsLogType::kInfo,
|
|
485
|
+
"getKktFailures: LP (abs / rel) "
|
|
486
|
+
" Col (abs / rel) Row (abs / rel)\n");
|
|
487
|
+
|
|
488
|
+
highsLogDev(
|
|
489
|
+
options.log_options, HighsLogType::kInfo,
|
|
490
|
+
"getKktFailures: primal infeasibility %8.3g / %8.3g %8.3g / "
|
|
491
|
+
"%8.3g %8.3g / %8.3g\n",
|
|
492
|
+
highs_info.max_primal_infeasibility,
|
|
493
|
+
highs_info.max_relative_primal_infeasibility,
|
|
494
|
+
max_col_primal_infeasibility, max_relative_col_primal_infeasibility,
|
|
495
|
+
max_row_primal_infeasibility, max_relative_row_primal_infeasibility);
|
|
496
|
+
if (have_dual_solution)
|
|
497
|
+
highsLogDev(
|
|
498
|
+
options.log_options, HighsLogType::kInfo,
|
|
499
|
+
"getKktFailures: dual infeasibility %8.3g / %8.3g %8.3g / "
|
|
500
|
+
"%8.3g %8.3g / %8.3g\n",
|
|
501
|
+
highs_info.max_dual_infeasibility,
|
|
502
|
+
highs_info.max_relative_dual_infeasibility,
|
|
503
|
+
max_col_dual_infeasibility, max_relative_col_dual_infeasibility,
|
|
504
|
+
max_row_dual_infeasibility, max_relative_row_dual_infeasibility);
|
|
505
|
+
if (get_residuals) {
|
|
506
|
+
highsLogDev(options.log_options, HighsLogType::kInfo,
|
|
507
|
+
"getKktFailures: primal residual %8.3g / %8.3g\n",
|
|
508
|
+
highs_info.max_primal_residual_error,
|
|
509
|
+
highs_info.max_relative_primal_residual_error);
|
|
510
|
+
if (have_dual_solution)
|
|
511
|
+
highsLogDev(options.log_options, HighsLogType::kInfo,
|
|
512
|
+
"getKktFailures: dual residual %8.3g / %8.3g\n",
|
|
513
|
+
highs_info.max_dual_residual_error,
|
|
514
|
+
highs_info.max_relative_dual_residual_error);
|
|
515
|
+
}
|
|
516
|
+
if (!is_qp && have_dual_solution)
|
|
517
|
+
highsLogDev(options.log_options, HighsLogType::kInfo,
|
|
518
|
+
"getKktFailures: objective gap %8.3g\n",
|
|
519
|
+
highs_info.primal_dual_objective_error);
|
|
520
|
+
}
|
|
521
|
+
// Assign primal (and possibly dual) solution status according to
|
|
522
|
+
// existence of primal and dual feasibilities
|
|
523
|
+
//
|
|
524
|
+
// For LP this may mean that primal/dual feasibility of the solution
|
|
525
|
+
// is claimed when there are residual errors, or denied when PDLP or
|
|
526
|
+
// IPX without crossover are used, since they are deemed feasible
|
|
527
|
+
// according to relative tolerances. This will be cleaned up in
|
|
528
|
+
// Highs::callLpKktCheck, when the existence of a basis determines
|
|
529
|
+
// whether absolute or relative measures are used.
|
|
530
|
+
|
|
531
|
+
if (num_primal_infeasibility) {
|
|
532
|
+
highs_info.primal_solution_status = kSolutionStatusInfeasible;
|
|
533
|
+
} else {
|
|
534
|
+
highs_info.primal_solution_status = kSolutionStatusFeasible;
|
|
535
|
+
}
|
|
536
|
+
if (have_dual_solution) {
|
|
537
|
+
if (num_dual_infeasibility) {
|
|
538
|
+
highs_info.dual_solution_status = kSolutionStatusInfeasible;
|
|
539
|
+
} else {
|
|
540
|
+
highs_info.dual_solution_status = kSolutionStatusFeasible;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Gets the KKT failures for a variable.
|
|
546
|
+
//
|
|
547
|
+
// Value and dual are used compute the primal and dual infeasibility
|
|
548
|
+
// It's up to the calling method to ignore these if the value or dual
|
|
549
|
+
// are not valid.
|
|
550
|
+
void getVariableKktFailures(const double primal_feasibility_tolerance,
|
|
551
|
+
const double dual_feasibility_tolerance,
|
|
552
|
+
const double lower, const double upper,
|
|
553
|
+
const double value, const double dual,
|
|
554
|
+
const HighsVarType integrality,
|
|
555
|
+
double& primal_infeasibility,
|
|
556
|
+
double& dual_infeasibility, uint8_t& at_status,
|
|
557
|
+
uint8_t& mid_status, const HighsInt index) {
|
|
558
|
+
// Return the primal residual (ie infeasibility with zero tolerance)
|
|
559
|
+
// as the primal infeasibility, ensuring (cf #2653) that it doesn't
|
|
560
|
+
// exceed the primal feasibility tolerance if the standard primal
|
|
561
|
+
// infeasibility (ie infeasibility exceeding the tolerance) is zero
|
|
562
|
+
auto infeasibility_residual =
|
|
563
|
+
infeasibility(lower, value, upper, primal_feasibility_tolerance);
|
|
564
|
+
primal_infeasibility = infeasibility_residual.second;
|
|
565
|
+
// Determine whether this value is close to a bound
|
|
566
|
+
at_status = kHighsSolutionNo;
|
|
567
|
+
double bound_residual = std::fabs(lower - value);
|
|
568
|
+
if (bound_residual * bound_residual <= primal_feasibility_tolerance) {
|
|
569
|
+
// Close to lower bound
|
|
570
|
+
at_status = kHighsSolutionLo;
|
|
571
|
+
} else {
|
|
572
|
+
// Not close to lower bound: maybe close to upper bound
|
|
573
|
+
bound_residual = std::fabs(value - upper);
|
|
574
|
+
if (bound_residual * bound_residual <= primal_feasibility_tolerance)
|
|
575
|
+
at_status = kHighsSolutionUp;
|
|
576
|
+
}
|
|
577
|
+
// Look for dual sign errors that exceed the tolerance. For boxed
|
|
578
|
+
// variables the test is discontinuous at the midpoint, but any
|
|
579
|
+
// meaningful dual value on a meaningful interval will show up as a
|
|
580
|
+
// large complementarity error
|
|
581
|
+
mid_status = kHighsSolutionNo;
|
|
582
|
+
if (lower < upper) {
|
|
583
|
+
double length = upper - lower;
|
|
584
|
+
// Non-fixed variable
|
|
585
|
+
if (lower <= -kHighsInf && upper >= kHighsInf) {
|
|
586
|
+
// Free variable
|
|
587
|
+
dual_infeasibility = fabs(dual);
|
|
588
|
+
} else if (length * length > primal_feasibility_tolerance) {
|
|
589
|
+
// Interval length is meaningful
|
|
590
|
+
//
|
|
591
|
+
// Compute the mid-point of the bound interval. This will be
|
|
592
|
+
// +infinity for LB variables; -infinity for UB variables;
|
|
593
|
+
// finite for boxed and fixed variables
|
|
594
|
+
const double middle = (lower + upper) * 0.5;
|
|
595
|
+
if (value < middle) {
|
|
596
|
+
// Below the mid-point, so use lower bound optimality condition:
|
|
597
|
+
// feasibility is dual >= -tolerance
|
|
598
|
+
mid_status = kHighsSolutionLo;
|
|
599
|
+
dual_infeasibility = std::max(-dual, 0.);
|
|
600
|
+
} else {
|
|
601
|
+
// Below the mid-point, so use upper bound optimality condition:
|
|
602
|
+
// feasibility is dual <= tolerance
|
|
603
|
+
mid_status = kHighsSolutionUp;
|
|
604
|
+
dual_infeasibility = std::max(dual, 0.);
|
|
605
|
+
}
|
|
606
|
+
} else {
|
|
607
|
+
// Interval length is less than
|
|
608
|
+
// sqrt(primal_feasibility_tolerance) so dual infeasibility is
|
|
609
|
+
// hard to define
|
|
610
|
+
dual_infeasibility = 0;
|
|
611
|
+
}
|
|
612
|
+
} else {
|
|
613
|
+
// Fixed variable
|
|
614
|
+
dual_infeasibility = 0;
|
|
615
|
+
}
|
|
616
|
+
// Account for semi-variables
|
|
617
|
+
const bool semi_variable = integrality == HighsVarType::kSemiContinuous ||
|
|
618
|
+
integrality == HighsVarType::kSemiInteger;
|
|
619
|
+
if (semi_variable && std::fabs(value) < primal_feasibility_tolerance)
|
|
620
|
+
primal_infeasibility = 0;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
void getPrimalDualGlpsolErrors(const HighsOptions& options, const HighsLp& lp,
|
|
624
|
+
const std::vector<double>& gradient,
|
|
625
|
+
const HighsSolution& solution,
|
|
626
|
+
HighsPrimalDualErrors& primal_dual_errors) {
|
|
627
|
+
double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
|
|
628
|
+
double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
|
|
629
|
+
double primal_residual_tolerance = options.primal_residual_tolerance;
|
|
630
|
+
double dual_residual_tolerance = options.dual_residual_tolerance;
|
|
631
|
+
double optimality_tolerance = options.optimality_tolerance;
|
|
632
|
+
|
|
633
|
+
// clang-format off
|
|
634
|
+
HighsInt& num_primal_residual_error = primal_dual_errors.glpsol_num_primal_residual_errors;
|
|
635
|
+
|
|
636
|
+
HighsInt& num_dual_residual_error = primal_dual_errors.glpsol_num_dual_residual_errors;
|
|
637
|
+
|
|
638
|
+
double& max_primal_residual_error = primal_dual_errors.glpsol_max_primal_residual.absolute_value;
|
|
639
|
+
HighsInt& max_primal_residual_index = primal_dual_errors.glpsol_max_primal_residual.absolute_index;
|
|
640
|
+
|
|
641
|
+
double& max_relative_primal_residual_error = primal_dual_errors.glpsol_max_primal_residual.relative_value;
|
|
642
|
+
HighsInt& max_relative_primal_residual_index = primal_dual_errors.glpsol_max_primal_residual.relative_index;
|
|
643
|
+
|
|
644
|
+
double& max_primal_infeasibility = primal_dual_errors.glpsol_max_primal_infeasibility.absolute_value;
|
|
645
|
+
HighsInt& max_primal_infeasibility_index = primal_dual_errors.glpsol_max_primal_infeasibility.absolute_index;
|
|
646
|
+
|
|
647
|
+
double& max_relative_primal_infeasibility = primal_dual_errors.glpsol_max_primal_infeasibility.relative_value;
|
|
648
|
+
HighsInt& max_relative_primal_infeasibility_index = primal_dual_errors.glpsol_max_primal_infeasibility.relative_index;
|
|
649
|
+
|
|
650
|
+
double& max_dual_residual_error = primal_dual_errors.glpsol_max_dual_residual.absolute_value;
|
|
651
|
+
HighsInt& max_dual_residual_index = primal_dual_errors.glpsol_max_dual_residual.absolute_index;
|
|
652
|
+
|
|
653
|
+
double& max_relative_dual_residual_error = primal_dual_errors.glpsol_max_dual_residual.relative_value;
|
|
654
|
+
HighsInt& max_relative_dual_residual_index = primal_dual_errors.glpsol_max_dual_residual.relative_index;
|
|
655
|
+
|
|
656
|
+
double& max_dual_infeasibility = primal_dual_errors.glpsol_max_dual_infeasibility.absolute_value;
|
|
657
|
+
HighsInt& max_dual_infeasibility_index = primal_dual_errors.glpsol_max_dual_infeasibility.absolute_index;
|
|
658
|
+
// clang-format on
|
|
659
|
+
|
|
660
|
+
// Relative dual infeasibilities are same as absolute
|
|
661
|
+
|
|
662
|
+
primal_dual_errors.glpsol_max_primal_infeasibility.invalidate();
|
|
663
|
+
primal_dual_errors.glpsol_max_dual_infeasibility.invalidate();
|
|
664
|
+
|
|
665
|
+
const bool have_primal_solution = solution.value_valid;
|
|
666
|
+
const bool have_dual_solution = solution.dual_valid;
|
|
667
|
+
const bool have_integrality = lp.integrality_.size() != 0;
|
|
668
|
+
|
|
669
|
+
// Check that there is no dual solution if there's no primal solution
|
|
670
|
+
assert(have_primal_solution || !have_dual_solution);
|
|
671
|
+
|
|
672
|
+
if (have_primal_solution) {
|
|
673
|
+
// There's a primal solution, so check its size and initialise the
|
|
674
|
+
// infeasibility counts
|
|
675
|
+
assert((int)solution.col_value.size() >= lp.num_col_);
|
|
676
|
+
assert((int)solution.row_value.size() >= lp.num_row_);
|
|
677
|
+
max_primal_infeasibility = 0;
|
|
678
|
+
primal_dual_errors.glpsol_max_primal_infeasibility.reset();
|
|
679
|
+
if (have_dual_solution) {
|
|
680
|
+
// There's a dual solution, so check its size and initialise the
|
|
681
|
+
// infeasibility counts
|
|
682
|
+
assert((int)solution.col_dual.size() >= lp.num_col_);
|
|
683
|
+
assert((int)solution.row_dual.size() >= lp.num_row_);
|
|
684
|
+
max_dual_infeasibility = 0;
|
|
685
|
+
primal_dual_errors.glpsol_max_dual_infeasibility.reset();
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
if (have_primal_solution) {
|
|
690
|
+
num_primal_residual_error = 0;
|
|
691
|
+
max_primal_residual_error = 0;
|
|
692
|
+
max_relative_primal_residual_error = 0;
|
|
693
|
+
primal_dual_errors.glpsol_max_primal_residual.reset();
|
|
694
|
+
|
|
695
|
+
} else {
|
|
696
|
+
num_primal_residual_error = kHighsIllegalResidualCount;
|
|
697
|
+
max_primal_residual_error = kHighsIllegalResidualMeasure;
|
|
698
|
+
max_relative_primal_residual_error = kHighsIllegalResidualMeasure;
|
|
699
|
+
primal_dual_errors.glpsol_max_primal_residual.invalidate();
|
|
700
|
+
}
|
|
701
|
+
if (have_dual_solution) {
|
|
702
|
+
num_dual_residual_error = 0;
|
|
703
|
+
max_dual_residual_error = 0;
|
|
704
|
+
max_relative_dual_residual_error = 0;
|
|
705
|
+
primal_dual_errors.glpsol_max_dual_residual.reset();
|
|
706
|
+
} else {
|
|
707
|
+
num_dual_residual_error = kHighsIllegalResidualCount;
|
|
708
|
+
max_dual_residual_error = kHighsIllegalResidualMeasure;
|
|
709
|
+
max_relative_dual_residual_error = kHighsIllegalResidualMeasure;
|
|
710
|
+
primal_dual_errors.glpsol_max_dual_residual.invalidate();
|
|
711
|
+
}
|
|
712
|
+
// Without a primal solution, nothing can be done!
|
|
713
|
+
if (!have_primal_solution) return;
|
|
714
|
+
|
|
715
|
+
// Residuals are formed for Glpsol via their positive and negative
|
|
716
|
+
// terms so that meaningful relative values can be computed
|
|
717
|
+
std::vector<double> primal_positive_sum;
|
|
718
|
+
std::vector<double> primal_negative_sum;
|
|
719
|
+
std::vector<double> dual_positive_sum;
|
|
720
|
+
std::vector<double> dual_negative_sum;
|
|
721
|
+
primal_positive_sum.assign(lp.num_row_, 0);
|
|
722
|
+
primal_negative_sum.assign(lp.num_row_, 0);
|
|
723
|
+
if (have_dual_solution) {
|
|
724
|
+
dual_positive_sum.resize(lp.num_col_);
|
|
725
|
+
dual_negative_sum.resize(lp.num_col_);
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
double primal_infeasibility;
|
|
729
|
+
double relative_primal_infeasibility;
|
|
730
|
+
double dual_infeasibility;
|
|
731
|
+
double lower;
|
|
732
|
+
double upper;
|
|
733
|
+
double value;
|
|
734
|
+
double dual = 0;
|
|
735
|
+
uint8_t at_status;
|
|
736
|
+
uint8_t mid_status;
|
|
737
|
+
HighsVarType integrality = HighsVarType::kContinuous;
|
|
738
|
+
for (HighsInt iVar = 0; iVar < lp.num_col_ + lp.num_row_; iVar++) {
|
|
739
|
+
if (iVar < lp.num_col_) {
|
|
740
|
+
HighsInt iCol = iVar;
|
|
741
|
+
lower = lp.col_lower_[iCol];
|
|
742
|
+
upper = lp.col_upper_[iCol];
|
|
743
|
+
value = solution.col_value[iCol];
|
|
744
|
+
if (have_dual_solution) dual = solution.col_dual[iCol];
|
|
745
|
+
if (have_integrality) integrality = lp.integrality_[iCol];
|
|
746
|
+
} else {
|
|
747
|
+
HighsInt iRow = iVar - lp.num_col_;
|
|
748
|
+
lower = lp.row_lower_[iRow];
|
|
749
|
+
upper = lp.row_upper_[iRow];
|
|
750
|
+
value = solution.row_value[iRow];
|
|
751
|
+
if (have_dual_solution) dual = solution.row_dual[iRow];
|
|
752
|
+
integrality = HighsVarType::kContinuous;
|
|
753
|
+
}
|
|
754
|
+
// Flip dual according to lp.sense_
|
|
755
|
+
dual *= (HighsInt)lp.sense_;
|
|
756
|
+
|
|
757
|
+
getVariableKktFailures(primal_feasibility_tolerance,
|
|
758
|
+
dual_feasibility_tolerance, lower, upper, value,
|
|
759
|
+
dual, integrality, primal_infeasibility,
|
|
760
|
+
dual_infeasibility, at_status, mid_status);
|
|
761
|
+
|
|
762
|
+
relative_primal_infeasibility = 0;
|
|
763
|
+
if (mid_status == kHighsSolutionLo) {
|
|
764
|
+
relative_primal_infeasibility =
|
|
765
|
+
primal_infeasibility / (1 + std::fabs(lower));
|
|
766
|
+
} else if (mid_status == kHighsSolutionUp) {
|
|
767
|
+
relative_primal_infeasibility =
|
|
768
|
+
primal_infeasibility / (1 + std::fabs(upper));
|
|
769
|
+
} else if (lower > -kHighsInf) {
|
|
770
|
+
// Variable has small bound length
|
|
771
|
+
relative_primal_infeasibility =
|
|
772
|
+
primal_infeasibility / (1 + std::fabs(lower));
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
if (max_primal_infeasibility < primal_infeasibility) {
|
|
776
|
+
max_primal_infeasibility = primal_infeasibility;
|
|
777
|
+
max_primal_infeasibility_index = iVar;
|
|
778
|
+
}
|
|
779
|
+
if (max_relative_primal_infeasibility < relative_primal_infeasibility) {
|
|
780
|
+
max_relative_primal_infeasibility = relative_primal_infeasibility;
|
|
781
|
+
max_relative_primal_infeasibility_index = iVar;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (have_dual_solution) {
|
|
785
|
+
// Accumulate dual infeasibilities
|
|
786
|
+
if (max_dual_infeasibility < dual_infeasibility) {
|
|
787
|
+
max_dual_infeasibility = dual_infeasibility;
|
|
788
|
+
max_dual_infeasibility_index = iVar;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
if (iVar < lp.num_col_) {
|
|
792
|
+
HighsInt iCol = iVar;
|
|
793
|
+
if (have_dual_solution) {
|
|
794
|
+
if (gradient[iCol] > 0) {
|
|
795
|
+
dual_positive_sum[iCol] = gradient[iCol];
|
|
796
|
+
} else {
|
|
797
|
+
dual_negative_sum[iCol] = -gradient[iCol];
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
for (HighsInt el = lp.a_matrix_.start_[iCol];
|
|
801
|
+
el < lp.a_matrix_.start_[iCol + 1]; el++) {
|
|
802
|
+
HighsInt iRow = lp.a_matrix_.index_[el];
|
|
803
|
+
double Avalue = lp.a_matrix_.value_[el];
|
|
804
|
+
double term = value * Avalue;
|
|
805
|
+
if (term > 0) {
|
|
806
|
+
primal_positive_sum[iRow] += term;
|
|
807
|
+
} else {
|
|
808
|
+
primal_negative_sum[iRow] -= term;
|
|
809
|
+
}
|
|
810
|
+
// @FlipRowDual += became -=
|
|
811
|
+
if (have_dual_solution) {
|
|
812
|
+
double term = -solution.row_dual[iRow] * Avalue;
|
|
813
|
+
if (term > 0) {
|
|
814
|
+
dual_positive_sum[iCol] += term;
|
|
815
|
+
} else {
|
|
816
|
+
dual_negative_sum[iCol] -= term;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// Relative dual infeasibilities are same as absolute
|
|
824
|
+
primal_dual_errors.glpsol_max_dual_infeasibility.relative_value =
|
|
825
|
+
primal_dual_errors.glpsol_max_dual_infeasibility.absolute_value;
|
|
826
|
+
|
|
827
|
+
primal_dual_errors.glpsol_max_dual_infeasibility.relative_index =
|
|
828
|
+
primal_dual_errors.glpsol_max_dual_infeasibility.absolute_index;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
void getPrimalDualBasisErrors(const HighsOptions& options, const HighsLp& lp,
|
|
832
|
+
const HighsSolution& solution,
|
|
833
|
+
const HighsBasis& basis,
|
|
834
|
+
HighsPrimalDualErrors& primal_dual_errors) {
|
|
835
|
+
double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
|
|
836
|
+
double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
|
|
837
|
+
const bool& have_primal_solution = solution.value_valid;
|
|
838
|
+
const bool& have_dual_solution = solution.dual_valid;
|
|
839
|
+
const bool& have_basis = basis.valid;
|
|
840
|
+
|
|
841
|
+
// Check that there is no dual solution if there's no primal solution
|
|
842
|
+
assert(have_primal_solution || !have_dual_solution);
|
|
843
|
+
|
|
844
|
+
// Check that there is no basis if there's no dual solution
|
|
845
|
+
assert(have_dual_solution || !have_basis);
|
|
846
|
+
|
|
847
|
+
HighsInt& num_nonzero_basic_dual = primal_dual_errors.num_nonzero_basic_duals;
|
|
848
|
+
double& max_nonzero_basic_dual = primal_dual_errors.max_nonzero_basic_dual;
|
|
849
|
+
double& sum_nonzero_basic_dual = primal_dual_errors.sum_nonzero_basic_duals;
|
|
850
|
+
|
|
851
|
+
HighsInt& num_off_bound_nonbasic = primal_dual_errors.num_off_bound_nonbasic;
|
|
852
|
+
double& max_off_bound_nonbasic = primal_dual_errors.max_off_bound_nonbasic;
|
|
853
|
+
double& sum_off_bound_nonbasic = primal_dual_errors.sum_off_bound_nonbasic;
|
|
854
|
+
|
|
855
|
+
if (have_basis) {
|
|
856
|
+
num_nonzero_basic_dual = 0;
|
|
857
|
+
max_nonzero_basic_dual = 0;
|
|
858
|
+
sum_nonzero_basic_dual = 0;
|
|
859
|
+
|
|
860
|
+
num_off_bound_nonbasic = 0;
|
|
861
|
+
max_off_bound_nonbasic = 0;
|
|
862
|
+
sum_off_bound_nonbasic = 0;
|
|
863
|
+
} else {
|
|
864
|
+
num_nonzero_basic_dual = kHighsIllegalInfeasibilityCount;
|
|
865
|
+
max_nonzero_basic_dual = kHighsIllegalInfeasibilityMeasure;
|
|
866
|
+
sum_nonzero_basic_dual = kHighsIllegalInfeasibilityMeasure;
|
|
867
|
+
|
|
868
|
+
num_off_bound_nonbasic = kHighsIllegalInfeasibilityCount;
|
|
869
|
+
max_off_bound_nonbasic = kHighsIllegalInfeasibilityMeasure;
|
|
870
|
+
sum_off_bound_nonbasic = kHighsIllegalInfeasibilityMeasure;
|
|
871
|
+
}
|
|
872
|
+
// Without a primal solution or a basis, nothing can be done!
|
|
873
|
+
if (!have_primal_solution || !have_basis) return;
|
|
874
|
+
// Makes no sense to get primal dual basis failures without a primal
|
|
875
|
+
// solution, dual solution and basis
|
|
876
|
+
assert(have_primal_solution && have_dual_solution && have_basis);
|
|
877
|
+
double primal_infeasibility;
|
|
878
|
+
double relative_primal_infeasibility;
|
|
879
|
+
double dual_infeasibility;
|
|
880
|
+
double value_residual;
|
|
881
|
+
double lower;
|
|
882
|
+
double upper;
|
|
883
|
+
double value;
|
|
884
|
+
double dual = 0;
|
|
885
|
+
HighsBasisStatus status;
|
|
886
|
+
bool status_value_ok;
|
|
887
|
+
for (HighsInt iVar = 0; iVar < lp.num_col_ + lp.num_row_; iVar++) {
|
|
888
|
+
if (iVar < lp.num_col_) {
|
|
889
|
+
HighsInt iCol = iVar;
|
|
890
|
+
lower = lp.col_lower_[iCol];
|
|
891
|
+
upper = lp.col_upper_[iCol];
|
|
892
|
+
value = solution.col_value[iCol];
|
|
893
|
+
dual = solution.col_dual[iCol];
|
|
894
|
+
status = basis.col_status[iCol];
|
|
895
|
+
} else {
|
|
896
|
+
HighsInt iRow = iVar - lp.num_col_;
|
|
897
|
+
lower = lp.row_lower_[iRow];
|
|
898
|
+
upper = lp.row_upper_[iRow];
|
|
899
|
+
value = solution.row_value[iRow];
|
|
900
|
+
dual = solution.row_dual[iRow];
|
|
901
|
+
status = basis.row_status[iRow];
|
|
902
|
+
}
|
|
903
|
+
value_residual =
|
|
904
|
+
std::min(std::fabs(lower - value), std::fabs(value - upper));
|
|
905
|
+
// Flip dual according to lp.sense_
|
|
906
|
+
dual *= (HighsInt)lp.sense_;
|
|
907
|
+
status_value_ok = true;
|
|
908
|
+
// Check that kLower and kUpper are consistent with value and
|
|
909
|
+
// bounds - for debugging QP basis errors
|
|
910
|
+
//
|
|
911
|
+
// With very large values, accuracy is lost in adding/subtracting
|
|
912
|
+
// the feasibility tolerance from the bounds, so skip if this may
|
|
913
|
+
// occur
|
|
914
|
+
if (status == HighsBasisStatus::kLower) {
|
|
915
|
+
if (std::fabs(lower) / primal_feasibility_tolerance < 1e-16)
|
|
916
|
+
status_value_ok = value >= lower - primal_feasibility_tolerance &&
|
|
917
|
+
value <= lower + primal_feasibility_tolerance;
|
|
918
|
+
} else if (status == HighsBasisStatus::kUpper) {
|
|
919
|
+
if (std::fabs(upper) / primal_feasibility_tolerance < 1e-16)
|
|
920
|
+
status_value_ok = value >= upper - primal_feasibility_tolerance &&
|
|
921
|
+
value <= upper + primal_feasibility_tolerance;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
if (!status_value_ok)
|
|
925
|
+
highsLogUser(
|
|
926
|
+
options.log_options, HighsLogType::kError,
|
|
927
|
+
"getPrimalDualBasisErrors: %s %d status-value error: [%23.18g; "
|
|
928
|
+
"%23.18g; %23.18g] has "
|
|
929
|
+
"residual %g\n",
|
|
930
|
+
iVar < lp.num_col_ ? "Column" : "Row ",
|
|
931
|
+
iVar < lp.num_col_ ? int(iVar) : int(iVar - lp.num_col_), lower,
|
|
932
|
+
value, upper, value_residual);
|
|
933
|
+
assert(status_value_ok);
|
|
934
|
+
|
|
935
|
+
if (status == HighsBasisStatus::kBasic) {
|
|
936
|
+
double abs_basic_dual = std::fabs(dual);
|
|
937
|
+
if (abs_basic_dual > 0) {
|
|
938
|
+
num_nonzero_basic_dual++;
|
|
939
|
+
max_nonzero_basic_dual =
|
|
940
|
+
std::max(abs_basic_dual, max_nonzero_basic_dual);
|
|
941
|
+
sum_nonzero_basic_dual += abs_basic_dual;
|
|
942
|
+
}
|
|
943
|
+
} else {
|
|
944
|
+
double off_bound_nonbasic = value_residual;
|
|
945
|
+
if (off_bound_nonbasic > 0) num_off_bound_nonbasic++;
|
|
946
|
+
max_off_bound_nonbasic =
|
|
947
|
+
std::max(off_bound_nonbasic, max_off_bound_nonbasic);
|
|
948
|
+
sum_off_bound_nonbasic += off_bound_nonbasic;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
bool getComplementarityViolations(const HighsLp& lp,
|
|
954
|
+
const HighsSolution& solution,
|
|
955
|
+
const double optimality_tolerance,
|
|
956
|
+
HighsInt& num_complementarity_violation,
|
|
957
|
+
double& max_complementarity_violation) {
|
|
958
|
+
num_complementarity_violation = kHighsIllegalComplementarityCount;
|
|
959
|
+
max_complementarity_violation = kHighsIllegalComplementarityViolation;
|
|
960
|
+
if (!solution.dual_valid) return false;
|
|
961
|
+
|
|
962
|
+
num_complementarity_violation = 0;
|
|
963
|
+
max_complementarity_violation = 0;
|
|
964
|
+
double primal_residual = 0;
|
|
965
|
+
for (HighsInt iVar = 0; iVar < lp.num_col_ + lp.num_row_; iVar++) {
|
|
966
|
+
const bool is_col = iVar < lp.num_col_;
|
|
967
|
+
const HighsInt iRow = iVar - lp.num_col_;
|
|
968
|
+
const double primal =
|
|
969
|
+
is_col ? solution.col_value[iVar] : solution.row_value[iRow];
|
|
970
|
+
const double dual =
|
|
971
|
+
is_col ? solution.col_dual[iVar] : solution.row_dual[iRow];
|
|
972
|
+
const double lower = is_col ? lp.col_lower_[iVar] : lp.row_lower_[iRow];
|
|
973
|
+
const double upper = is_col ? lp.col_upper_[iVar] : lp.row_upper_[iRow];
|
|
974
|
+
if (lower <= -kHighsInf && upper >= kHighsInf) {
|
|
975
|
+
// Free
|
|
976
|
+
primal_residual = 1;
|
|
977
|
+
} else {
|
|
978
|
+
const double mid = (lower + upper) * 0.5;
|
|
979
|
+
primal_residual =
|
|
980
|
+
primal < mid ? std::fabs(lower - primal) : std::fabs(upper - primal);
|
|
981
|
+
}
|
|
982
|
+
const double dual_residual = std::fabs(dual);
|
|
983
|
+
const double complementarity_violation = primal_residual * dual_residual;
|
|
984
|
+
if (complementarity_violation > optimality_tolerance)
|
|
985
|
+
num_complementarity_violation++;
|
|
986
|
+
max_complementarity_violation =
|
|
987
|
+
std::max(complementarity_violation, max_complementarity_violation);
|
|
988
|
+
}
|
|
989
|
+
return true;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
void lpNoBasisKktCheck(HighsModelStatus& model_status, HighsInfo& info,
|
|
993
|
+
const HighsLp& lp, const HighsSolution& solution,
|
|
994
|
+
const HighsOptions& options,
|
|
995
|
+
const std::string& message) {
|
|
996
|
+
HighsBasis basis;
|
|
997
|
+
lpKktCheck(model_status, info, lp, solution, basis, options, message);
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
void lpKktCheck(HighsModelStatus& model_status, HighsInfo& info,
|
|
1001
|
+
const HighsLp& lp, const HighsSolution& solution,
|
|
1002
|
+
const HighsBasis& basis, const HighsOptions& options,
|
|
1003
|
+
const std::string& message) {
|
|
1004
|
+
if (!solution.value_valid) return;
|
|
1005
|
+
const bool has_dual_values = solution.dual_valid;
|
|
1006
|
+
const HighsLogOptions& log_options = options.log_options;
|
|
1007
|
+
double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
|
|
1008
|
+
double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
|
|
1009
|
+
double primal_residual_tolerance = options.primal_residual_tolerance;
|
|
1010
|
+
double dual_residual_tolerance = options.dual_residual_tolerance;
|
|
1011
|
+
double optimality_tolerance = options.optimality_tolerance;
|
|
1012
|
+
if (options.kkt_tolerance != kDefaultKktTolerance) {
|
|
1013
|
+
primal_feasibility_tolerance = options.kkt_tolerance;
|
|
1014
|
+
dual_feasibility_tolerance = options.kkt_tolerance;
|
|
1015
|
+
primal_residual_tolerance = options.kkt_tolerance;
|
|
1016
|
+
dual_residual_tolerance = options.kkt_tolerance;
|
|
1017
|
+
optimality_tolerance = options.kkt_tolerance;
|
|
1018
|
+
}
|
|
1019
|
+
info.objective_function_value = lp.objectiveValue(solution.col_value);
|
|
1020
|
+
HighsPrimalDualErrors primal_dual_errors;
|
|
1021
|
+
const bool get_residuals = !basis.valid;
|
|
1022
|
+
getLpKktFailures(options, lp, solution, basis, info, primal_dual_errors,
|
|
1023
|
+
get_residuals);
|
|
1024
|
+
if (model_status == HighsModelStatus::kOptimal)
|
|
1025
|
+
reportKktFailures(lp, options, info, message);
|
|
1026
|
+
// get_residuals is false when there is a valid basis, since
|
|
1027
|
+
// residual errors are assumed to be small, so
|
|
1028
|
+
// info.num_primal_residual_errors = -1, since they aren't
|
|
1029
|
+
// known. Hence don't consider this in identifying unboundedness
|
|
1030
|
+
// from HighsModelStatus::kUnboundedOrInfeasible
|
|
1031
|
+
if (model_status == HighsModelStatus::kUnboundedOrInfeasible &&
|
|
1032
|
+
info.num_primal_infeasibilities == 0 &&
|
|
1033
|
+
(!get_residuals || info.num_primal_residual_errors == 0))
|
|
1034
|
+
model_status = HighsModelStatus::kUnbounded;
|
|
1035
|
+
bool was_optimal = model_status == HighsModelStatus::kOptimal;
|
|
1036
|
+
bool kkt_ok = true;
|
|
1037
|
+
bool written_optimality_error_header = false;
|
|
1038
|
+
|
|
1039
|
+
auto foundOptimalityError = [&]() {
|
|
1040
|
+
kkt_ok = false;
|
|
1041
|
+
if (!was_optimal || written_optimality_error_header) return;
|
|
1042
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1043
|
+
"LP solver claims optimality, but with\n");
|
|
1044
|
+
written_optimality_error_header = true;
|
|
1045
|
+
};
|
|
1046
|
+
|
|
1047
|
+
double max_primal_tolerance_relative_violation = 0;
|
|
1048
|
+
double max_dual_tolerance_relative_violation = 0;
|
|
1049
|
+
double primal_dual_objective_tolerance_relative_violation = 0;
|
|
1050
|
+
const double max_allowed_tolerance_relative_violation = 1e2;
|
|
1051
|
+
if (basis.valid) {
|
|
1052
|
+
if (info.num_primal_infeasibilities > 0) {
|
|
1053
|
+
max_primal_tolerance_relative_violation =
|
|
1054
|
+
std::max(info.max_primal_infeasibility / primal_feasibility_tolerance,
|
|
1055
|
+
max_primal_tolerance_relative_violation);
|
|
1056
|
+
foundOptimalityError();
|
|
1057
|
+
if (was_optimal)
|
|
1058
|
+
highsLogUser(
|
|
1059
|
+
log_options, HighsLogType::kWarning,
|
|
1060
|
+
" num/max/sum %6d / %8.3g / %8.3g primal "
|
|
1061
|
+
"infeasibilities (tolerance = %4.0e)\n",
|
|
1062
|
+
int(info.num_primal_infeasibilities), info.max_primal_infeasibility,
|
|
1063
|
+
info.sum_primal_infeasibilities, primal_feasibility_tolerance);
|
|
1064
|
+
}
|
|
1065
|
+
if (info.num_dual_infeasibilities > 0) {
|
|
1066
|
+
max_dual_tolerance_relative_violation =
|
|
1067
|
+
std::max(info.max_dual_infeasibility / dual_feasibility_tolerance,
|
|
1068
|
+
max_dual_tolerance_relative_violation);
|
|
1069
|
+
foundOptimalityError();
|
|
1070
|
+
if (was_optimal)
|
|
1071
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1072
|
+
" num/max/sum %6d / %8.3g / %8.3g dual "
|
|
1073
|
+
"infeasibilities (tolerance = %4.0e)\n",
|
|
1074
|
+
int(info.num_dual_infeasibilities),
|
|
1075
|
+
info.max_dual_infeasibility, info.sum_dual_infeasibilities,
|
|
1076
|
+
dual_feasibility_tolerance);
|
|
1077
|
+
}
|
|
1078
|
+
// An optimal basic solution has no complementarity violations
|
|
1079
|
+
// by construction, and can be assumed to have no relative
|
|
1080
|
+
// primal or dual residual errors or meaningful primal dual
|
|
1081
|
+
// objective error
|
|
1082
|
+
bool unexpected_error_if_optimal = info.num_complementarity_violations != 0;
|
|
1083
|
+
double local_dual_objective = 0;
|
|
1084
|
+
if (info.primal_dual_objective_error > optimality_tolerance) {
|
|
1085
|
+
// Ignore primal-dual objective errors if both objectives are small
|
|
1086
|
+
const bool ok_dual_objective = computeDualObjectiveValue(
|
|
1087
|
+
nullptr, lp, solution, local_dual_objective);
|
|
1088
|
+
assert(ok_dual_objective);
|
|
1089
|
+
if (info.objective_function_value * info.objective_function_value >
|
|
1090
|
+
optimality_tolerance &&
|
|
1091
|
+
local_dual_objective * local_dual_objective > optimality_tolerance)
|
|
1092
|
+
unexpected_error_if_optimal = true;
|
|
1093
|
+
}
|
|
1094
|
+
const bool have_residual_errors =
|
|
1095
|
+
info.num_primal_residual_errors != kHighsIllegalResidualCount;
|
|
1096
|
+
if (have_residual_errors) {
|
|
1097
|
+
unexpected_error_if_optimal =
|
|
1098
|
+
unexpected_error_if_optimal ||
|
|
1099
|
+
info.num_relative_primal_residual_errors != 0 ||
|
|
1100
|
+
info.num_relative_dual_residual_errors != 0;
|
|
1101
|
+
max_primal_tolerance_relative_violation = std::max(
|
|
1102
|
+
info.max_relative_primal_residual_error / primal_residual_tolerance,
|
|
1103
|
+
max_primal_tolerance_relative_violation);
|
|
1104
|
+
max_dual_tolerance_relative_violation = std::max(
|
|
1105
|
+
info.max_relative_dual_residual_error / dual_residual_tolerance,
|
|
1106
|
+
max_dual_tolerance_relative_violation);
|
|
1107
|
+
}
|
|
1108
|
+
primal_dual_objective_tolerance_relative_violation =
|
|
1109
|
+
info.primal_dual_objective_error / optimality_tolerance;
|
|
1110
|
+
|
|
1111
|
+
if (was_optimal && unexpected_error_if_optimal) {
|
|
1112
|
+
highsLogUser(
|
|
1113
|
+
log_options, HighsLogType::kWarning,
|
|
1114
|
+
"Optimal basic solution has %d complementarity violations and %g "
|
|
1115
|
+
"primal dual objective error from primal (dual) objective = %g "
|
|
1116
|
+
"(%g)\n",
|
|
1117
|
+
int(info.num_complementarity_violations),
|
|
1118
|
+
info.primal_dual_objective_error, info.objective_function_value,
|
|
1119
|
+
local_dual_objective);
|
|
1120
|
+
if (have_residual_errors) {
|
|
1121
|
+
highsLogUser(
|
|
1122
|
+
log_options, HighsLogType::kWarning,
|
|
1123
|
+
" num/max %6d / %8.3g relative primal residual errors "
|
|
1124
|
+
"(tolerance = %4.0e)\n",
|
|
1125
|
+
int(info.num_relative_primal_residual_errors),
|
|
1126
|
+
info.max_relative_primal_residual_error, primal_residual_tolerance);
|
|
1127
|
+
highsLogUser(
|
|
1128
|
+
log_options, HighsLogType::kWarning,
|
|
1129
|
+
" num/max %6d / %8.3g relative dual residual errors "
|
|
1130
|
+
"(tolerance = %4.0e)\n",
|
|
1131
|
+
int(info.num_relative_dual_residual_errors),
|
|
1132
|
+
info.max_relative_dual_residual_error, dual_residual_tolerance);
|
|
1133
|
+
}
|
|
1134
|
+
assert(info.num_complementarity_violations == 0);
|
|
1135
|
+
assert(info.primal_dual_objective_error <= optimality_tolerance);
|
|
1136
|
+
if (have_residual_errors) {
|
|
1137
|
+
assert(info.num_relative_primal_residual_errors == 0);
|
|
1138
|
+
assert(info.num_relative_dual_residual_errors == 0);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
// Infeasibility of the primal and dual solutions based on number
|
|
1142
|
+
// of primal/dual infeasibilities should have been set in
|
|
1143
|
+
// getKktFailures, but qualify this if the residuals are
|
|
1144
|
+
// meaningful
|
|
1145
|
+
if (info.num_primal_infeasibilities) {
|
|
1146
|
+
assert(info.primal_solution_status == kSolutionStatusInfeasible);
|
|
1147
|
+
} else {
|
|
1148
|
+
info.primal_solution_status = kSolutionStatusFeasible;
|
|
1149
|
+
}
|
|
1150
|
+
if (info.num_dual_infeasibilities) {
|
|
1151
|
+
assert(info.dual_solution_status == kSolutionStatusInfeasible);
|
|
1152
|
+
} else {
|
|
1153
|
+
info.dual_solution_status = kSolutionStatusFeasible;
|
|
1154
|
+
}
|
|
1155
|
+
// Overrule feasibility if large relative tolerance failures have
|
|
1156
|
+
// occurred - pretty inconceivable since absolute residuals should
|
|
1157
|
+
// be small with a basis
|
|
1158
|
+
if (max_primal_tolerance_relative_violation >
|
|
1159
|
+
max_allowed_tolerance_relative_violation)
|
|
1160
|
+
info.primal_solution_status = kSolutionStatusInfeasible;
|
|
1161
|
+
if (max_dual_tolerance_relative_violation >
|
|
1162
|
+
max_allowed_tolerance_relative_violation)
|
|
1163
|
+
info.dual_solution_status = kSolutionStatusInfeasible;
|
|
1164
|
+
} else {
|
|
1165
|
+
// A solution without a basis may have primal or dual residual
|
|
1166
|
+
// errors, and complementarity errors - due to the convergence
|
|
1167
|
+
// being based on relative primal-dual objective error, so test
|
|
1168
|
+
// the latter
|
|
1169
|
+
double tolerance_relative_violation =
|
|
1170
|
+
info.max_relative_primal_infeasibility / primal_feasibility_tolerance;
|
|
1171
|
+
max_primal_tolerance_relative_violation = std::max(
|
|
1172
|
+
tolerance_relative_violation, max_primal_tolerance_relative_violation);
|
|
1173
|
+
if (info.num_relative_primal_infeasibilities > 0) {
|
|
1174
|
+
foundOptimalityError();
|
|
1175
|
+
if (was_optimal)
|
|
1176
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1177
|
+
" num/max %6d / %8.3g relative primal infeasibilities "
|
|
1178
|
+
"(tolerance = %4.0e)\n",
|
|
1179
|
+
int(info.num_relative_primal_infeasibilities),
|
|
1180
|
+
info.max_relative_primal_infeasibility,
|
|
1181
|
+
primal_feasibility_tolerance);
|
|
1182
|
+
}
|
|
1183
|
+
tolerance_relative_violation =
|
|
1184
|
+
info.max_relative_dual_infeasibility / dual_feasibility_tolerance;
|
|
1185
|
+
max_dual_tolerance_relative_violation = std::max(
|
|
1186
|
+
tolerance_relative_violation, max_dual_tolerance_relative_violation);
|
|
1187
|
+
if (info.num_relative_dual_infeasibilities > 0) {
|
|
1188
|
+
foundOptimalityError();
|
|
1189
|
+
if (was_optimal)
|
|
1190
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1191
|
+
" num/max %6d / %8.3g relative dual infeasibilities "
|
|
1192
|
+
"(tolerance = %4.0e)\n",
|
|
1193
|
+
int(info.num_relative_dual_infeasibilities),
|
|
1194
|
+
info.max_relative_dual_infeasibility,
|
|
1195
|
+
dual_feasibility_tolerance);
|
|
1196
|
+
}
|
|
1197
|
+
tolerance_relative_violation =
|
|
1198
|
+
info.max_relative_primal_residual_error / primal_residual_tolerance;
|
|
1199
|
+
max_primal_tolerance_relative_violation = std::max(
|
|
1200
|
+
tolerance_relative_violation, max_primal_tolerance_relative_violation);
|
|
1201
|
+
if (info.num_relative_primal_residual_errors > 0) {
|
|
1202
|
+
foundOptimalityError();
|
|
1203
|
+
if (was_optimal)
|
|
1204
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1205
|
+
" num/max %6d / %8.3g relative primal residual errors "
|
|
1206
|
+
"(tolerance = %4.0e)\n",
|
|
1207
|
+
int(info.num_relative_primal_residual_errors),
|
|
1208
|
+
info.max_relative_primal_residual_error,
|
|
1209
|
+
primal_residual_tolerance);
|
|
1210
|
+
}
|
|
1211
|
+
tolerance_relative_violation =
|
|
1212
|
+
info.max_relative_dual_residual_error / dual_residual_tolerance;
|
|
1213
|
+
max_dual_tolerance_relative_violation = std::max(
|
|
1214
|
+
tolerance_relative_violation, max_dual_tolerance_relative_violation);
|
|
1215
|
+
if (info.num_relative_dual_residual_errors > 0) {
|
|
1216
|
+
foundOptimalityError();
|
|
1217
|
+
if (was_optimal)
|
|
1218
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1219
|
+
" num/max %6d / %8.3g relative dual residual errors "
|
|
1220
|
+
"(tolerance = %4.0e)\n",
|
|
1221
|
+
int(info.num_relative_dual_residual_errors),
|
|
1222
|
+
info.max_relative_dual_residual_error,
|
|
1223
|
+
dual_residual_tolerance);
|
|
1224
|
+
}
|
|
1225
|
+
if (info.primal_dual_objective_error > optimality_tolerance) {
|
|
1226
|
+
primal_dual_objective_tolerance_relative_violation =
|
|
1227
|
+
info.primal_dual_objective_error / optimality_tolerance;
|
|
1228
|
+
foundOptimalityError();
|
|
1229
|
+
if (was_optimal)
|
|
1230
|
+
highsLogUser(
|
|
1231
|
+
log_options, HighsLogType::kWarning,
|
|
1232
|
+
" %8.3g relative P-D objective error "
|
|
1233
|
+
"(tolerance = %4.0e)\n",
|
|
1234
|
+
info.primal_dual_objective_error, optimality_tolerance);
|
|
1235
|
+
}
|
|
1236
|
+
// Set the primal and dual solution status according to tolerance failure
|
|
1237
|
+
if (max_primal_tolerance_relative_violation >
|
|
1238
|
+
max_allowed_tolerance_relative_violation) {
|
|
1239
|
+
info.primal_solution_status = kSolutionStatusInfeasible;
|
|
1240
|
+
} else {
|
|
1241
|
+
info.primal_solution_status = kSolutionStatusFeasible;
|
|
1242
|
+
}
|
|
1243
|
+
if (max_dual_tolerance_relative_violation >
|
|
1244
|
+
max_allowed_tolerance_relative_violation) {
|
|
1245
|
+
info.dual_solution_status = kSolutionStatusInfeasible;
|
|
1246
|
+
} else {
|
|
1247
|
+
info.dual_solution_status = kSolutionStatusFeasible;
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
double max_tolerance_relative_violation =
|
|
1251
|
+
primal_dual_objective_tolerance_relative_violation;
|
|
1252
|
+
max_tolerance_relative_violation =
|
|
1253
|
+
std::max(max_primal_tolerance_relative_violation,
|
|
1254
|
+
max_tolerance_relative_violation);
|
|
1255
|
+
max_tolerance_relative_violation = std::max(
|
|
1256
|
+
max_dual_tolerance_relative_violation, max_tolerance_relative_violation);
|
|
1257
|
+
//
|
|
1258
|
+
// Now see whether optimality is compromised or permitted given the tolerance
|
|
1259
|
+
// failures
|
|
1260
|
+
if (model_status == HighsModelStatus::kOptimal) {
|
|
1261
|
+
if (max_tolerance_relative_violation >
|
|
1262
|
+
max_allowed_tolerance_relative_violation) {
|
|
1263
|
+
model_status = HighsModelStatus::kUnknown;
|
|
1264
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1265
|
+
"Model status changed from \"Optimal\" to \"Unknown\""
|
|
1266
|
+
" since relative violation of tolerances is %8.3g\n",
|
|
1267
|
+
max_tolerance_relative_violation);
|
|
1268
|
+
} else if (max_allowed_tolerance_relative_violation > 1 &&
|
|
1269
|
+
max_tolerance_relative_violation > 1) {
|
|
1270
|
+
highsLogUser(log_options, HighsLogType::kInfo,
|
|
1271
|
+
"Model status is \"Optimal\" since relative violation of "
|
|
1272
|
+
"tolerances is no more than %8.3g\n",
|
|
1273
|
+
max_tolerance_relative_violation);
|
|
1274
|
+
}
|
|
1275
|
+
} else if (model_status == HighsModelStatus::kUnknown &&
|
|
1276
|
+
max_tolerance_relative_violation <=
|
|
1277
|
+
max_allowed_tolerance_relative_violation) {
|
|
1278
|
+
model_status = HighsModelStatus::kOptimal;
|
|
1279
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1280
|
+
"Model status changed from \"Unknown\" to \"Optimal\"\n");
|
|
1281
|
+
}
|
|
1282
|
+
highsLogUser(log_options, HighsLogType::kInfo, "\n");
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
bool computeDualObjectiveValue(const HighsModel& model,
|
|
1287
|
+
const HighsSolution& solution,
|
|
1288
|
+
double& dual_objective_value) {
|
|
1289
|
+
const HighsLp& lp = model.lp_;
|
|
1290
|
+
if (!model.isQp())
|
|
1291
|
+
return computeDualObjectiveValue(nullptr, lp, solution,
|
|
1292
|
+
dual_objective_value);
|
|
1293
|
+
assert(solution.col_value.size() == static_cast<size_t>(lp.num_col_));
|
|
1294
|
+
// Model is QP, so compute gradient Qx + c so generic
|
|
1295
|
+
// computeDualObjectiveValue can be used
|
|
1296
|
+
std::vector<double> gradient;
|
|
1297
|
+
model.objectiveGradient(solution.col_value, gradient);
|
|
1298
|
+
return computeDualObjectiveValue(gradient.data(), lp, solution,
|
|
1299
|
+
dual_objective_value);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
bool computeDualObjectiveValue(const double* gradient, const HighsLp& lp,
|
|
1303
|
+
const HighsSolution& solution,
|
|
1304
|
+
double& dual_objective_value) {
|
|
1305
|
+
dual_objective_value = 0;
|
|
1306
|
+
if (!solution.dual_valid) return false;
|
|
1307
|
+
// #2184 Make sure that the solution corresponds to this LP
|
|
1308
|
+
assert(solution.col_value.size() == static_cast<size_t>(lp.num_col_));
|
|
1309
|
+
assert(solution.col_dual.size() == static_cast<size_t>(lp.num_col_));
|
|
1310
|
+
assert(solution.row_value.size() == static_cast<size_t>(lp.num_row_));
|
|
1311
|
+
assert(solution.row_dual.size() == static_cast<size_t>(lp.num_row_));
|
|
1312
|
+
|
|
1313
|
+
dual_objective_value = lp.offset_;
|
|
1314
|
+
if (gradient) {
|
|
1315
|
+
// The dual objective for a QP has a -(1/2)x^TQx term, and this
|
|
1316
|
+
// can be computed from the gradient (g = Qx + c) as
|
|
1317
|
+
// -(1/2)(g-c)^Tx = (1/2)(c-g)^Tx, a pointer to the gradient data
|
|
1318
|
+
// is passed if this is necessary
|
|
1319
|
+
double quad_value = 0;
|
|
1320
|
+
for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++) {
|
|
1321
|
+
quad_value +=
|
|
1322
|
+
(lp.col_cost_[iCol] - gradient[iCol]) * solution.col_value[iCol];
|
|
1323
|
+
}
|
|
1324
|
+
dual_objective_value += 0.5 * quad_value;
|
|
1325
|
+
}
|
|
1326
|
+
double bound = 0;
|
|
1327
|
+
for (HighsInt iVar = 0; iVar < lp.num_col_ + lp.num_row_; iVar++) {
|
|
1328
|
+
const bool is_col = iVar < lp.num_col_;
|
|
1329
|
+
const HighsInt iRow = iVar - lp.num_col_;
|
|
1330
|
+
const double primal =
|
|
1331
|
+
is_col ? solution.col_value[iVar] : solution.row_value[iRow];
|
|
1332
|
+
const double dual =
|
|
1333
|
+
is_col ? solution.col_dual[iVar] : solution.row_dual[iRow];
|
|
1334
|
+
const double lower = is_col ? lp.col_lower_[iVar] : lp.row_lower_[iRow];
|
|
1335
|
+
const double upper = is_col ? lp.col_upper_[iVar] : lp.row_upper_[iRow];
|
|
1336
|
+
if (lower <= -kHighsInf && upper >= kHighsInf) {
|
|
1337
|
+
// Free
|
|
1338
|
+
bound = 1;
|
|
1339
|
+
} else {
|
|
1340
|
+
const double mid = (lower + upper) * 0.5;
|
|
1341
|
+
bound = primal < mid ? lower : upper;
|
|
1342
|
+
}
|
|
1343
|
+
dual_objective_value += bound * dual;
|
|
1344
|
+
}
|
|
1345
|
+
return true;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
void HighsError::print(std::string message) {
|
|
1349
|
+
printf(
|
|
1350
|
+
"\n%s\nAbsolute value = %11.4g; index = %9d\nRelative value = %11.4g; "
|
|
1351
|
+
"index = %9d\n",
|
|
1352
|
+
message.c_str(), this->absolute_value, (int)this->absolute_index,
|
|
1353
|
+
this->relative_value, (int)this->relative_index);
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
void HighsError::reset() {
|
|
1357
|
+
this->absolute_value = 0;
|
|
1358
|
+
this->absolute_index = 0;
|
|
1359
|
+
this->relative_value = 0;
|
|
1360
|
+
this->relative_index = 0;
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
void HighsError::invalidate() {
|
|
1364
|
+
this->absolute_value = kHighsIllegalErrorValue;
|
|
1365
|
+
this->absolute_index = kHighsIllegalErrorIndex;
|
|
1366
|
+
this->relative_value = kHighsIllegalErrorValue;
|
|
1367
|
+
this->relative_index = kHighsIllegalErrorIndex;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
double computeObjectiveValue(const HighsLp& lp, const HighsSolution& solution) {
|
|
1371
|
+
double objective_value = 0;
|
|
1372
|
+
for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++)
|
|
1373
|
+
objective_value += lp.col_cost_[iCol] * solution.col_value[iCol];
|
|
1374
|
+
objective_value += lp.offset_;
|
|
1375
|
+
return objective_value;
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
// Refine any HighsBasisStatus::kNonbasic settings according to the LP
|
|
1379
|
+
// and any solution values
|
|
1380
|
+
void refineBasis(const HighsLp& lp, const HighsSolution& solution,
|
|
1381
|
+
HighsBasis& basis) {
|
|
1382
|
+
assert(basis.useful);
|
|
1383
|
+
assert(isBasisRightSize(lp, basis));
|
|
1384
|
+
const bool have_highs_solution = solution.value_valid;
|
|
1385
|
+
|
|
1386
|
+
const HighsInt num_col = lp.num_col_;
|
|
1387
|
+
const HighsInt num_row = lp.num_row_;
|
|
1388
|
+
for (HighsInt iCol = 0; iCol < num_col; iCol++) {
|
|
1389
|
+
if (basis.col_status[iCol] != HighsBasisStatus::kNonbasic) continue;
|
|
1390
|
+
const double lower = lp.col_lower_[iCol];
|
|
1391
|
+
const double upper = lp.col_upper_[iCol];
|
|
1392
|
+
HighsBasisStatus status = HighsBasisStatus::kNonbasic;
|
|
1393
|
+
if (lower == upper) {
|
|
1394
|
+
status = HighsBasisStatus::kLower;
|
|
1395
|
+
} else if (!highs_isInfinity(-lower)) {
|
|
1396
|
+
if (!highs_isInfinity(upper)) {
|
|
1397
|
+
if (have_highs_solution) {
|
|
1398
|
+
if (solution.col_value[iCol] < 0.5 * (lower + upper)) {
|
|
1399
|
+
status = HighsBasisStatus::kLower;
|
|
1400
|
+
} else {
|
|
1401
|
+
status = HighsBasisStatus::kUpper;
|
|
1402
|
+
}
|
|
1403
|
+
} else {
|
|
1404
|
+
if (fabs(lower) < fabs(upper)) {
|
|
1405
|
+
status = HighsBasisStatus::kLower;
|
|
1406
|
+
} else {
|
|
1407
|
+
status = HighsBasisStatus::kUpper;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
} else {
|
|
1411
|
+
status = HighsBasisStatus::kLower;
|
|
1412
|
+
}
|
|
1413
|
+
} else if (!highs_isInfinity(upper)) {
|
|
1414
|
+
status = HighsBasisStatus::kUpper;
|
|
1415
|
+
} else {
|
|
1416
|
+
status = HighsBasisStatus::kZero;
|
|
1417
|
+
}
|
|
1418
|
+
assert(status != HighsBasisStatus::kNonbasic);
|
|
1419
|
+
basis.col_status[iCol] = status;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
for (HighsInt iRow = 0; iRow < num_row; iRow++) {
|
|
1423
|
+
if (basis.row_status[iRow] != HighsBasisStatus::kNonbasic) continue;
|
|
1424
|
+
const double lower = lp.row_lower_[iRow];
|
|
1425
|
+
const double upper = lp.row_upper_[iRow];
|
|
1426
|
+
HighsBasisStatus status = HighsBasisStatus::kNonbasic;
|
|
1427
|
+
if (lower == upper) {
|
|
1428
|
+
status = HighsBasisStatus::kLower;
|
|
1429
|
+
} else if (!highs_isInfinity(-lower)) {
|
|
1430
|
+
if (!highs_isInfinity(upper)) {
|
|
1431
|
+
if (have_highs_solution) {
|
|
1432
|
+
if (solution.row_value[iRow] < 0.5 * (lower + upper)) {
|
|
1433
|
+
status = HighsBasisStatus::kLower;
|
|
1434
|
+
} else {
|
|
1435
|
+
status = HighsBasisStatus::kUpper;
|
|
1436
|
+
}
|
|
1437
|
+
} else {
|
|
1438
|
+
if (fabs(lower) < fabs(upper)) {
|
|
1439
|
+
status = HighsBasisStatus::kLower;
|
|
1440
|
+
} else {
|
|
1441
|
+
status = HighsBasisStatus::kUpper;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
} else {
|
|
1445
|
+
status = HighsBasisStatus::kLower;
|
|
1446
|
+
}
|
|
1447
|
+
} else if (!highs_isInfinity(upper)) {
|
|
1448
|
+
status = HighsBasisStatus::kUpper;
|
|
1449
|
+
} else {
|
|
1450
|
+
status = HighsBasisStatus::kZero;
|
|
1451
|
+
}
|
|
1452
|
+
assert(status != HighsBasisStatus::kNonbasic);
|
|
1453
|
+
basis.row_status[iRow] = status;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
HighsStatus ipxSolutionToHighsSolution(
|
|
1458
|
+
const HighsOptions& options, const HighsLp& lp,
|
|
1459
|
+
const std::vector<double>& rhs, const std::vector<char>& constraint_type,
|
|
1460
|
+
const HighsInt ipx_num_col, const HighsInt ipx_num_row,
|
|
1461
|
+
const std::vector<double>& ipx_x, const std::vector<double>& ipx_slack_vars,
|
|
1462
|
+
const std::vector<double>& ipx_y, const std::vector<double>& ipx_zl,
|
|
1463
|
+
const std::vector<double>& ipx_zu, HighsSolution& highs_solution) {
|
|
1464
|
+
// Resize the HighsSolution
|
|
1465
|
+
highs_solution.col_value.resize(lp.num_col_);
|
|
1466
|
+
highs_solution.row_value.resize(lp.num_row_);
|
|
1467
|
+
highs_solution.col_dual.resize(lp.num_col_);
|
|
1468
|
+
highs_solution.row_dual.resize(lp.num_row_);
|
|
1469
|
+
|
|
1470
|
+
const std::vector<double>& ipx_col_value = ipx_x;
|
|
1471
|
+
const std::vector<double>& ipx_row_value = ipx_slack_vars;
|
|
1472
|
+
|
|
1473
|
+
// Row activities are needed to set activity values of free rows -
|
|
1474
|
+
// which are ignored by IPX
|
|
1475
|
+
vector<double> row_activity;
|
|
1476
|
+
const bool get_row_activities = ipx_num_row < lp.num_row_;
|
|
1477
|
+
if (get_row_activities) row_activity.assign(lp.num_row_, 0);
|
|
1478
|
+
HighsInt ipx_slack = lp.num_col_;
|
|
1479
|
+
assert(ipx_num_row == lp.num_row_);
|
|
1480
|
+
HighsInt dual_infeasibility_count = 0;
|
|
1481
|
+
double primal_infeasibility;
|
|
1482
|
+
double relative_primal_infeasibility;
|
|
1483
|
+
double dual_infeasibility;
|
|
1484
|
+
double value_residual;
|
|
1485
|
+
uint8_t at_status; // Not used
|
|
1486
|
+
uint8_t mid_status; // Not used
|
|
1487
|
+
for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++) {
|
|
1488
|
+
double value = ipx_col_value[iCol];
|
|
1489
|
+
if (get_row_activities) {
|
|
1490
|
+
// Accumulate row activities to assign value to free rows
|
|
1491
|
+
for (HighsInt el = lp.a_matrix_.start_[iCol];
|
|
1492
|
+
el < lp.a_matrix_.start_[iCol + 1]; el++) {
|
|
1493
|
+
HighsInt row = lp.a_matrix_.index_[el];
|
|
1494
|
+
row_activity[row] += value * lp.a_matrix_.value_[el];
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
double dual = ipx_zl[iCol] - ipx_zu[iCol];
|
|
1498
|
+
highs_solution.col_value[iCol] = value;
|
|
1499
|
+
highs_solution.col_dual[iCol] = dual;
|
|
1500
|
+
}
|
|
1501
|
+
HighsInt ipx_row = 0;
|
|
1502
|
+
ipx_slack = lp.num_col_;
|
|
1503
|
+
for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++) {
|
|
1504
|
+
double lower = lp.row_lower_[iRow];
|
|
1505
|
+
double upper = lp.row_upper_[iRow];
|
|
1506
|
+
if (lower <= -kHighsInf && upper >= kHighsInf) {
|
|
1507
|
+
// Free row - removed by IPX so set it to its row activity
|
|
1508
|
+
highs_solution.row_value[iRow] = row_activity[iRow];
|
|
1509
|
+
highs_solution.row_dual[iRow] = 0;
|
|
1510
|
+
continue;
|
|
1511
|
+
}
|
|
1512
|
+
// Non-free row, so IPX will have it
|
|
1513
|
+
double value = 0;
|
|
1514
|
+
double dual = 0;
|
|
1515
|
+
if ((lower > -kHighsInf && upper < kHighsInf) && (lower < upper)) {
|
|
1516
|
+
assert(constraint_type[ipx_row] == '=');
|
|
1517
|
+
// Boxed row - look at its slack
|
|
1518
|
+
value = ipx_col_value[ipx_slack];
|
|
1519
|
+
dual = ipx_zl[ipx_slack] - ipx_zu[ipx_slack];
|
|
1520
|
+
// Update the slack to be used for boxed rows
|
|
1521
|
+
ipx_slack++;
|
|
1522
|
+
} else {
|
|
1523
|
+
value = rhs[ipx_row] - ipx_row_value[ipx_row];
|
|
1524
|
+
dual = ipx_y[ipx_row];
|
|
1525
|
+
}
|
|
1526
|
+
highs_solution.row_value[iRow] = value;
|
|
1527
|
+
highs_solution.row_dual[iRow] = dual;
|
|
1528
|
+
// Update the IPX row index
|
|
1529
|
+
ipx_row++;
|
|
1530
|
+
}
|
|
1531
|
+
assert(ipx_row == ipx_num_row);
|
|
1532
|
+
assert(ipx_slack == ipx_num_col);
|
|
1533
|
+
if (lp.sense_ == ObjSense::kMaximize) {
|
|
1534
|
+
// Flip dual values since original LP is maximization
|
|
1535
|
+
for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++)
|
|
1536
|
+
highs_solution.col_dual[iCol] *= -1;
|
|
1537
|
+
for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++)
|
|
1538
|
+
highs_solution.row_dual[iRow] *= -1;
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
// Indicate that the primal and dual solution are known
|
|
1542
|
+
highs_solution.value_valid = true;
|
|
1543
|
+
highs_solution.dual_valid = true;
|
|
1544
|
+
return HighsStatus::kOk;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
HighsStatus ipxBasicSolutionToHighsBasicSolution(
|
|
1548
|
+
const HighsLogOptions& log_options, const HighsLp& lp,
|
|
1549
|
+
const std::vector<double>& rhs, const std::vector<char>& constraint_type,
|
|
1550
|
+
const IpxSolution& ipx_solution, HighsBasis& highs_basis,
|
|
1551
|
+
HighsSolution& highs_solution) {
|
|
1552
|
+
// Resize the HighsSolution and HighsBasis
|
|
1553
|
+
highs_solution.col_value.resize(lp.num_col_);
|
|
1554
|
+
highs_solution.row_value.resize(lp.num_row_);
|
|
1555
|
+
highs_solution.col_dual.resize(lp.num_col_);
|
|
1556
|
+
highs_solution.row_dual.resize(lp.num_row_);
|
|
1557
|
+
highs_basis.col_status.resize(lp.num_col_);
|
|
1558
|
+
highs_basis.row_status.resize(lp.num_row_);
|
|
1559
|
+
|
|
1560
|
+
const std::vector<double>& ipx_col_value = ipx_solution.ipx_col_value;
|
|
1561
|
+
const std::vector<double>& ipx_row_value = ipx_solution.ipx_row_value;
|
|
1562
|
+
const std::vector<double>& ipx_col_dual = ipx_solution.ipx_col_dual;
|
|
1563
|
+
const std::vector<double>& ipx_row_dual = ipx_solution.ipx_row_dual;
|
|
1564
|
+
const std::vector<ipx::Int>& ipx_col_status = ipx_solution.ipx_col_status;
|
|
1565
|
+
const std::vector<ipx::Int>& ipx_row_status = ipx_solution.ipx_row_status;
|
|
1566
|
+
|
|
1567
|
+
// Set up meaningful names for values of ipx_col_status and ipx_row_status to
|
|
1568
|
+
// be used later in comparisons
|
|
1569
|
+
const ipx::Int ipx_basic = 0;
|
|
1570
|
+
const ipx::Int ipx_nonbasic_at_lb = -1;
|
|
1571
|
+
const ipx::Int ipx_nonbasic_at_ub = -2;
|
|
1572
|
+
const ipx::Int ipx_superbasic = -3;
|
|
1573
|
+
// Row activities are needed to set activity values of free rows -
|
|
1574
|
+
// which are ignored by IPX
|
|
1575
|
+
vector<double> row_activity;
|
|
1576
|
+
bool get_row_activities = ipx_solution.num_row < lp.num_row_;
|
|
1577
|
+
if (get_row_activities) row_activity.assign(lp.num_row_, 0);
|
|
1578
|
+
HighsInt num_basic_variables = 0;
|
|
1579
|
+
for (HighsInt col = 0; col < lp.num_col_; col++) {
|
|
1580
|
+
bool unrecognised = false;
|
|
1581
|
+
if (ipx_col_status[col] == ipx_basic) {
|
|
1582
|
+
// Column is basic
|
|
1583
|
+
highs_basis.col_status[col] = HighsBasisStatus::kBasic;
|
|
1584
|
+
highs_solution.col_value[col] = ipx_col_value[col];
|
|
1585
|
+
highs_solution.col_dual[col] = 0;
|
|
1586
|
+
} else {
|
|
1587
|
+
// Column is nonbasic. Setting of ipx_col_status is consistent
|
|
1588
|
+
// with dual value for fixed columns
|
|
1589
|
+
if (ipx_col_status[col] == ipx_nonbasic_at_lb) {
|
|
1590
|
+
// Column is at lower bound
|
|
1591
|
+
highs_basis.col_status[col] = HighsBasisStatus::kLower;
|
|
1592
|
+
highs_solution.col_value[col] = ipx_col_value[col];
|
|
1593
|
+
highs_solution.col_dual[col] = ipx_col_dual[col];
|
|
1594
|
+
} else if (ipx_col_status[col] == ipx_nonbasic_at_ub) {
|
|
1595
|
+
// Column is at upper bound
|
|
1596
|
+
highs_basis.col_status[col] = HighsBasisStatus::kUpper;
|
|
1597
|
+
highs_solution.col_value[col] = ipx_col_value[col];
|
|
1598
|
+
highs_solution.col_dual[col] = ipx_col_dual[col];
|
|
1599
|
+
} else if (ipx_col_status[col] == ipx_superbasic) {
|
|
1600
|
+
// Column is superbasic
|
|
1601
|
+
highs_basis.col_status[col] = HighsBasisStatus::kZero;
|
|
1602
|
+
highs_solution.col_value[col] = ipx_col_value[col];
|
|
1603
|
+
highs_solution.col_dual[col] = ipx_col_dual[col];
|
|
1604
|
+
} else {
|
|
1605
|
+
unrecognised = true;
|
|
1606
|
+
highsLogDev(log_options, HighsLogType::kError,
|
|
1607
|
+
"\nError in IPX conversion: Unrecognised value "
|
|
1608
|
+
"ipx_col_status[%2" HIGHSINT_FORMAT
|
|
1609
|
+
"] = "
|
|
1610
|
+
"%" HIGHSINT_FORMAT "\n",
|
|
1611
|
+
col, (HighsInt)ipx_col_status[col]);
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
if (unrecognised) {
|
|
1615
|
+
highsLogDev(log_options, HighsLogType::kError,
|
|
1616
|
+
"Bounds [%11.4g, %11.4g]\n", lp.col_lower_[col],
|
|
1617
|
+
lp.col_upper_[col]);
|
|
1618
|
+
highsLogDev(log_options, HighsLogType::kError,
|
|
1619
|
+
"Col %2" HIGHSINT_FORMAT " ipx_col_status[%2" HIGHSINT_FORMAT
|
|
1620
|
+
"] = %2" HIGHSINT_FORMAT "; x[%2" HIGHSINT_FORMAT
|
|
1621
|
+
"] = %11.4g; z[%2" HIGHSINT_FORMAT
|
|
1622
|
+
"] = "
|
|
1623
|
+
"%11.4g\n",
|
|
1624
|
+
col, col, (HighsInt)ipx_col_status[col], col,
|
|
1625
|
+
ipx_col_value[col], col, ipx_col_dual[col]);
|
|
1626
|
+
assert(!unrecognised);
|
|
1627
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1628
|
+
"Unrecognised ipx_col_status value from IPX\n");
|
|
1629
|
+
return HighsStatus::kError;
|
|
1630
|
+
}
|
|
1631
|
+
if (get_row_activities) {
|
|
1632
|
+
// Accumulate row activities to assign value to free rows
|
|
1633
|
+
for (HighsInt el = lp.a_matrix_.start_[col];
|
|
1634
|
+
el < lp.a_matrix_.start_[col + 1]; el++) {
|
|
1635
|
+
HighsInt row = lp.a_matrix_.index_[el];
|
|
1636
|
+
row_activity[row] +=
|
|
1637
|
+
highs_solution.col_value[col] * lp.a_matrix_.value_[el];
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
if (highs_basis.col_status[col] == HighsBasisStatus::kBasic)
|
|
1641
|
+
num_basic_variables++;
|
|
1642
|
+
}
|
|
1643
|
+
HighsInt ipx_row = 0;
|
|
1644
|
+
HighsInt ipx_slack = lp.num_col_;
|
|
1645
|
+
HighsInt num_boxed_rows = 0;
|
|
1646
|
+
HighsInt num_boxed_rows_basic = 0;
|
|
1647
|
+
HighsInt num_boxed_row_slacks_basic = 0;
|
|
1648
|
+
for (HighsInt row = 0; row < lp.num_row_; row++) {
|
|
1649
|
+
bool unrecognised = false;
|
|
1650
|
+
double lower = lp.row_lower_[row];
|
|
1651
|
+
double upper = lp.row_upper_[row];
|
|
1652
|
+
HighsInt this_ipx_row = ipx_row;
|
|
1653
|
+
if (lower <= -kHighsInf && upper >= kHighsInf) {
|
|
1654
|
+
// Free row - removed by IPX so make it basic at its row activity
|
|
1655
|
+
highs_basis.row_status[row] = HighsBasisStatus::kBasic;
|
|
1656
|
+
highs_solution.row_value[row] = row_activity[row];
|
|
1657
|
+
highs_solution.row_dual[row] = 0;
|
|
1658
|
+
} else {
|
|
1659
|
+
// Non-free row, so IPX will have it
|
|
1660
|
+
if ((lower > -kHighsInf && upper < kHighsInf) && (lower < upper)) {
|
|
1661
|
+
// Boxed row - look at its slack
|
|
1662
|
+
num_boxed_rows++;
|
|
1663
|
+
double slack_value = ipx_col_value[ipx_slack];
|
|
1664
|
+
double slack_dual = ipx_col_dual[ipx_slack];
|
|
1665
|
+
double value = slack_value;
|
|
1666
|
+
// @FlipRowDual -slack_dual became slack_dual
|
|
1667
|
+
double dual = slack_dual;
|
|
1668
|
+
if (ipx_row_status[ipx_row] == ipx_basic) {
|
|
1669
|
+
// Row is basic
|
|
1670
|
+
num_boxed_rows_basic++;
|
|
1671
|
+
highs_basis.row_status[row] = HighsBasisStatus::kBasic;
|
|
1672
|
+
highs_solution.row_value[row] = value;
|
|
1673
|
+
highs_solution.row_dual[row] = 0;
|
|
1674
|
+
} else if (ipx_col_status[ipx_slack] == ipx_basic) {
|
|
1675
|
+
// Slack is basic
|
|
1676
|
+
num_boxed_row_slacks_basic++;
|
|
1677
|
+
highs_basis.row_status[row] = HighsBasisStatus::kBasic;
|
|
1678
|
+
highs_solution.row_value[row] = value;
|
|
1679
|
+
highs_solution.row_dual[row] = 0;
|
|
1680
|
+
} else if (ipx_col_status[ipx_slack] == ipx_nonbasic_at_lb) {
|
|
1681
|
+
// Slack at lower bound
|
|
1682
|
+
highs_basis.row_status[row] = HighsBasisStatus::kLower;
|
|
1683
|
+
highs_solution.row_value[row] = value;
|
|
1684
|
+
highs_solution.row_dual[row] = dual;
|
|
1685
|
+
} else if (ipx_col_status[ipx_slack] == ipx_nonbasic_at_ub) {
|
|
1686
|
+
// Slack is at its upper bound
|
|
1687
|
+
assert(ipx_col_status[ipx_slack] == ipx_nonbasic_at_ub);
|
|
1688
|
+
highs_basis.row_status[row] = HighsBasisStatus::kUpper;
|
|
1689
|
+
highs_solution.row_value[row] = value;
|
|
1690
|
+
highs_solution.row_dual[row] = dual;
|
|
1691
|
+
} else {
|
|
1692
|
+
unrecognised = true;
|
|
1693
|
+
highsLogDev(log_options, HighsLogType::kError,
|
|
1694
|
+
"Error in IPX conversion: Row %2" HIGHSINT_FORMAT
|
|
1695
|
+
" (IPX row %2" HIGHSINT_FORMAT
|
|
1696
|
+
") has "
|
|
1697
|
+
"unrecognised value ipx_col_status[%2" HIGHSINT_FORMAT
|
|
1698
|
+
"] = %" HIGHSINT_FORMAT "\n",
|
|
1699
|
+
row, ipx_row, ipx_slack,
|
|
1700
|
+
(HighsInt)ipx_col_status[ipx_slack]);
|
|
1701
|
+
}
|
|
1702
|
+
// Update the slack to be used for boxed rows
|
|
1703
|
+
ipx_slack++;
|
|
1704
|
+
} else if (ipx_row_status[ipx_row] == ipx_basic) {
|
|
1705
|
+
// Row is basic
|
|
1706
|
+
highs_basis.row_status[row] = HighsBasisStatus::kBasic;
|
|
1707
|
+
highs_solution.row_value[row] = rhs[ipx_row] - ipx_row_value[ipx_row];
|
|
1708
|
+
highs_solution.row_dual[row] = 0;
|
|
1709
|
+
} else {
|
|
1710
|
+
// Nonbasic row at fixed value, lower bound or upper bound
|
|
1711
|
+
assert(ipx_row_status[ipx_row] ==
|
|
1712
|
+
-1); // const ipx::Int ipx_nonbasic_row = -1;
|
|
1713
|
+
double value = rhs[ipx_row] - ipx_row_value[ipx_row];
|
|
1714
|
+
// @FlipRowDual -ipx_row_dual[ipx_row]; became ipx_row_dual[ipx_row];
|
|
1715
|
+
double dual = ipx_row_dual[ipx_row];
|
|
1716
|
+
if (constraint_type[ipx_row] == '>') {
|
|
1717
|
+
// Row is at its lower bound
|
|
1718
|
+
highs_basis.row_status[row] = HighsBasisStatus::kLower;
|
|
1719
|
+
highs_solution.row_value[row] = value;
|
|
1720
|
+
highs_solution.row_dual[row] = dual;
|
|
1721
|
+
} else if (constraint_type[ipx_row] == '<') {
|
|
1722
|
+
// Row is at its upper bound
|
|
1723
|
+
highs_basis.row_status[row] = HighsBasisStatus::kUpper;
|
|
1724
|
+
highs_solution.row_value[row] = value;
|
|
1725
|
+
highs_solution.row_dual[row] = dual;
|
|
1726
|
+
} else if (constraint_type[ipx_row] == '=') {
|
|
1727
|
+
// Row is at its fixed value: set HighsBasisStatus according
|
|
1728
|
+
// to sign of dual.
|
|
1729
|
+
//
|
|
1730
|
+
// Don't worry about maximization problems. IPX solves them
|
|
1731
|
+
// as minimizations with negated costs, so a negative dual
|
|
1732
|
+
// yields HighsBasisStatus::kUpper here, and dual signs are
|
|
1733
|
+
// then flipped below, so HighsBasisStatus::kUpper will have
|
|
1734
|
+
// corresponding positive dual.
|
|
1735
|
+
highs_basis.row_status[row] =
|
|
1736
|
+
dual >= 0 ? HighsBasisStatus::kLower : HighsBasisStatus::kUpper;
|
|
1737
|
+
highs_solution.row_value[row] = value;
|
|
1738
|
+
highs_solution.row_dual[row] = dual;
|
|
1739
|
+
} else {
|
|
1740
|
+
unrecognised = true;
|
|
1741
|
+
highsLogDev(log_options, HighsLogType::kError,
|
|
1742
|
+
"Error in IPX conversion: Row %2" HIGHSINT_FORMAT
|
|
1743
|
+
": cannot handle "
|
|
1744
|
+
"constraint_type[%2" HIGHSINT_FORMAT
|
|
1745
|
+
"] = %" HIGHSINT_FORMAT "\n",
|
|
1746
|
+
row, ipx_row, constraint_type[ipx_row]);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
// Update the IPX row index
|
|
1750
|
+
ipx_row++;
|
|
1751
|
+
}
|
|
1752
|
+
if (unrecognised) {
|
|
1753
|
+
highsLogDev(log_options, HighsLogType::kError,
|
|
1754
|
+
"Bounds [%11.4g, %11.4g]\n", lp.row_lower_[row],
|
|
1755
|
+
lp.row_upper_[row]);
|
|
1756
|
+
highsLogDev(log_options, HighsLogType::kError,
|
|
1757
|
+
"Row %2" HIGHSINT_FORMAT " ipx_row_status[%2" HIGHSINT_FORMAT
|
|
1758
|
+
"] = %2" HIGHSINT_FORMAT "; s[%2" HIGHSINT_FORMAT
|
|
1759
|
+
"] = %11.4g; y[%2" HIGHSINT_FORMAT
|
|
1760
|
+
"] = "
|
|
1761
|
+
"%11.4g\n",
|
|
1762
|
+
row, this_ipx_row, (HighsInt)ipx_row_status[this_ipx_row],
|
|
1763
|
+
this_ipx_row, ipx_row_value[this_ipx_row], this_ipx_row,
|
|
1764
|
+
ipx_row_dual[this_ipx_row]);
|
|
1765
|
+
assert(!unrecognised);
|
|
1766
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1767
|
+
"Unrecognised ipx_row_status value from IPX\n");
|
|
1768
|
+
return HighsStatus::kError;
|
|
1769
|
+
}
|
|
1770
|
+
if (highs_basis.row_status[row] == HighsBasisStatus::kBasic)
|
|
1771
|
+
num_basic_variables++;
|
|
1772
|
+
}
|
|
1773
|
+
assert(num_basic_variables == lp.num_row_);
|
|
1774
|
+
assert(ipx_row == ipx_solution.num_row);
|
|
1775
|
+
assert(ipx_slack == ipx_solution.num_col);
|
|
1776
|
+
|
|
1777
|
+
if (lp.sense_ == ObjSense::kMaximize) {
|
|
1778
|
+
// Flip dual values since original LP is maximization
|
|
1779
|
+
for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++)
|
|
1780
|
+
highs_solution.col_dual[iCol] *= -1;
|
|
1781
|
+
for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++)
|
|
1782
|
+
highs_solution.row_dual[iRow] *= -1;
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
if (num_boxed_rows)
|
|
1786
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
1787
|
+
"Of %" HIGHSINT_FORMAT " boxed rows: %" HIGHSINT_FORMAT
|
|
1788
|
+
" are basic and %" HIGHSINT_FORMAT " have basic slacks\n",
|
|
1789
|
+
num_boxed_rows, num_boxed_rows_basic,
|
|
1790
|
+
num_boxed_row_slacks_basic);
|
|
1791
|
+
// Indicate that the primal solution, dual solution and basis are valid
|
|
1792
|
+
highs_solution.value_valid = true;
|
|
1793
|
+
highs_solution.dual_valid = true;
|
|
1794
|
+
highs_basis.valid = true;
|
|
1795
|
+
highs_basis.useful = true;
|
|
1796
|
+
return HighsStatus::kOk;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
HighsStatus formSimplexLpBasisAndFactorReturn(
|
|
1800
|
+
const HighsStatus return_status, HighsLpSolverObject& solver_object) {
|
|
1801
|
+
HighsLp& lp = solver_object.lp_;
|
|
1802
|
+
HighsLp& ekk_lp = solver_object.ekk_instance_.lp_;
|
|
1803
|
+
if (lp.is_moved_) lp.moveBackLpAndUnapplyScaling(ekk_lp);
|
|
1804
|
+
return return_status;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
HighsStatus formSimplexLpBasisAndFactor(HighsLpSolverObject& solver_object,
|
|
1808
|
+
const bool only_from_known_basis) {
|
|
1809
|
+
// Ideally, forms a SimplexBasis from the HighsBasis in the
|
|
1810
|
+
// HighsLpSolverObject
|
|
1811
|
+
//
|
|
1812
|
+
// If only_from_known_basis is true and
|
|
1813
|
+
// initialiseSimplexLpBasisAndFactor finds that there is no simplex
|
|
1814
|
+
// basis, then its error return is passed down
|
|
1815
|
+
//
|
|
1816
|
+
// If only_from_known_basis is false, then the basis is completed
|
|
1817
|
+
// with logicals if it is rank deficient (from singularity or being
|
|
1818
|
+
// incomplete)
|
|
1819
|
+
//
|
|
1820
|
+
HighsStatus return_status = HighsStatus::kOk;
|
|
1821
|
+
HighsStatus call_status;
|
|
1822
|
+
HighsLp& lp = solver_object.lp_;
|
|
1823
|
+
HighsBasis& basis = solver_object.basis_;
|
|
1824
|
+
HighsOptions& options = solver_object.options_;
|
|
1825
|
+
HEkk& ekk_instance = solver_object.ekk_instance_;
|
|
1826
|
+
HighsSimplexStatus& ekk_status = ekk_instance.status_;
|
|
1827
|
+
lp.ensureColwise();
|
|
1828
|
+
const bool passed_scaled = lp.is_scaled_;
|
|
1829
|
+
// Consider scaling the LP
|
|
1830
|
+
if (!passed_scaled) considerScaling(options, lp);
|
|
1831
|
+
const bool check_basis = basis.alien || (!basis.valid && basis.useful);
|
|
1832
|
+
if (check_basis) {
|
|
1833
|
+
// The basis needs to be checked for rank deficiency, and possibly
|
|
1834
|
+
// completed if it is rectangular
|
|
1835
|
+
//
|
|
1836
|
+
// If it's not valid but useful, but not alien,
|
|
1837
|
+
// accommodateAlienBasis will assert, so make the basis alien
|
|
1838
|
+
basis.alien = true;
|
|
1839
|
+
assert(!only_from_known_basis);
|
|
1840
|
+
accommodateAlienBasis(solver_object);
|
|
1841
|
+
basis.alien = false;
|
|
1842
|
+
// Unapply any scaling used only for factorization to check and
|
|
1843
|
+
// complete the basis
|
|
1844
|
+
if (!passed_scaled) lp.unapplyScale();
|
|
1845
|
+
// Check that any scaling the LP arrived with has not been removed
|
|
1846
|
+
assert(lp.is_scaled_ == passed_scaled);
|
|
1847
|
+
return HighsStatus::kOk;
|
|
1848
|
+
}
|
|
1849
|
+
// Move the HighsLpSolverObject's LP to EKK
|
|
1850
|
+
ekk_instance.moveLp(solver_object);
|
|
1851
|
+
if (!ekk_status.has_basis) {
|
|
1852
|
+
// The Ekk instance has no simplex basis, so pass the HiGHS basis
|
|
1853
|
+
HighsStatus call_status = ekk_instance.setBasis(basis);
|
|
1854
|
+
return_status = interpretCallStatus(options.log_options, call_status,
|
|
1855
|
+
return_status, "setBasis");
|
|
1856
|
+
if (return_status == HighsStatus::kError)
|
|
1857
|
+
return formSimplexLpBasisAndFactorReturn(return_status, solver_object);
|
|
1858
|
+
}
|
|
1859
|
+
// Now form the invert
|
|
1860
|
+
assert(ekk_status.has_basis);
|
|
1861
|
+
call_status =
|
|
1862
|
+
ekk_instance.initialiseSimplexLpBasisAndFactor(only_from_known_basis);
|
|
1863
|
+
// If the current basis cannot be inverted, return an error
|
|
1864
|
+
if (call_status != HighsStatus::kOk)
|
|
1865
|
+
return formSimplexLpBasisAndFactorReturn(HighsStatus::kError,
|
|
1866
|
+
solver_object);
|
|
1867
|
+
// Once the invert is formed, move back the LP and remove any scaling.
|
|
1868
|
+
return formSimplexLpBasisAndFactorReturn(HighsStatus::kOk, solver_object);
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
void accommodateAlienBasis(HighsLpSolverObject& solver_object) {
|
|
1872
|
+
HighsLp& lp = solver_object.lp_;
|
|
1873
|
+
HighsBasis& basis = solver_object.basis_;
|
|
1874
|
+
HighsOptions& options = solver_object.options_;
|
|
1875
|
+
assert(basis.alien);
|
|
1876
|
+
HighsInt num_row = lp.num_row_;
|
|
1877
|
+
HighsInt num_col = lp.num_col_;
|
|
1878
|
+
assert((int)basis.col_status.size() >= num_col);
|
|
1879
|
+
assert((int)basis.row_status.size() >= num_row);
|
|
1880
|
+
std::vector<HighsInt> basic_index;
|
|
1881
|
+
for (HighsInt iCol = 0; iCol < num_col; iCol++) {
|
|
1882
|
+
if (basis.col_status[iCol] == HighsBasisStatus::kBasic)
|
|
1883
|
+
basic_index.push_back(iCol);
|
|
1884
|
+
}
|
|
1885
|
+
for (HighsInt iRow = 0; iRow < num_row; iRow++) {
|
|
1886
|
+
if (basis.row_status[iRow] == HighsBasisStatus::kBasic)
|
|
1887
|
+
basic_index.push_back(num_col + iRow);
|
|
1888
|
+
}
|
|
1889
|
+
HighsInt num_basic_variables = basic_index.size();
|
|
1890
|
+
HFactor factor;
|
|
1891
|
+
factor.setupGeneral(&lp.a_matrix_, num_basic_variables, basic_index.data(),
|
|
1892
|
+
kDefaultPivotThreshold, kDefaultPivotTolerance,
|
|
1893
|
+
kHighsDebugLevelMin, &options.log_options);
|
|
1894
|
+
HighsInt rank_deficiency = factor.build();
|
|
1895
|
+
// Must not have timed out
|
|
1896
|
+
assert(rank_deficiency >= 0);
|
|
1897
|
+
// Deduce the basis from basic_index
|
|
1898
|
+
//
|
|
1899
|
+
// Set all basic variables to nonbasic
|
|
1900
|
+
for (HighsInt iCol = 0; iCol < num_col; iCol++) {
|
|
1901
|
+
if (basis.col_status[iCol] == HighsBasisStatus::kBasic)
|
|
1902
|
+
basis.col_status[iCol] = HighsBasisStatus::kNonbasic;
|
|
1903
|
+
}
|
|
1904
|
+
for (HighsInt iRow = 0; iRow < num_row; iRow++) {
|
|
1905
|
+
if (basis.row_status[iRow] == HighsBasisStatus::kBasic)
|
|
1906
|
+
basis.row_status[iRow] = HighsBasisStatus::kNonbasic;
|
|
1907
|
+
}
|
|
1908
|
+
// Set at most the first num_row variables in basic_index to basic
|
|
1909
|
+
const HighsInt use_basic_variables = std::min(num_row, num_basic_variables);
|
|
1910
|
+
// num_basic_variables is no longer needed, so can be used as a check
|
|
1911
|
+
num_basic_variables = 0;
|
|
1912
|
+
for (HighsInt iRow = 0; iRow < use_basic_variables; iRow++) {
|
|
1913
|
+
HighsInt iVar = basic_index[iRow];
|
|
1914
|
+
if (iVar < num_col) {
|
|
1915
|
+
basis.col_status[iVar] = HighsBasisStatus::kBasic;
|
|
1916
|
+
} else {
|
|
1917
|
+
basis.row_status[iVar - num_col] = HighsBasisStatus::kBasic;
|
|
1918
|
+
}
|
|
1919
|
+
num_basic_variables++;
|
|
1920
|
+
}
|
|
1921
|
+
// Complete the assignment of basic variables using the logicals of
|
|
1922
|
+
// non-pivotal rows
|
|
1923
|
+
const HighsInt num_missing = num_row - num_basic_variables;
|
|
1924
|
+
for (HighsInt k = 0; k < num_missing; k++) {
|
|
1925
|
+
HighsInt iRow = factor.row_with_no_pivot[rank_deficiency + k];
|
|
1926
|
+
basis.row_status[iRow] = HighsBasisStatus::kBasic;
|
|
1927
|
+
num_basic_variables++;
|
|
1928
|
+
}
|
|
1929
|
+
assert(num_basic_variables == num_row);
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
void resetModelStatusAndHighsInfo(HighsLpSolverObject& solver_object) {
|
|
1933
|
+
resetModelStatusAndHighsInfo(solver_object.model_status_,
|
|
1934
|
+
solver_object.highs_info_);
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1937
|
+
void resetModelStatusAndHighsInfo(HighsModelStatus& model_status,
|
|
1938
|
+
HighsInfo& highs_info) {
|
|
1939
|
+
model_status = HighsModelStatus::kNotset;
|
|
1940
|
+
highs_info.objective_function_value = 0;
|
|
1941
|
+
highs_info.primal_solution_status = kSolutionStatusNone;
|
|
1942
|
+
highs_info.dual_solution_status = kSolutionStatusNone;
|
|
1943
|
+
highs_info.invalidateKkt();
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
bool isBasisConsistent(const HighsLp& lp, const HighsBasis& basis) {
|
|
1947
|
+
if (!isBasisRightSize(lp, basis)) return false;
|
|
1948
|
+
|
|
1949
|
+
HighsInt num_basic_variables = 0;
|
|
1950
|
+
for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++) {
|
|
1951
|
+
if (basis.col_status[iCol] == HighsBasisStatus::kBasic)
|
|
1952
|
+
num_basic_variables++;
|
|
1953
|
+
}
|
|
1954
|
+
for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++) {
|
|
1955
|
+
if (basis.row_status[iRow] == HighsBasisStatus::kBasic)
|
|
1956
|
+
num_basic_variables++;
|
|
1957
|
+
}
|
|
1958
|
+
return num_basic_variables == lp.num_row_;
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
bool isColPrimalSolutionRightSize(const HighsLp& lp,
|
|
1962
|
+
const HighsSolution& solution) {
|
|
1963
|
+
return solution.col_value.size() == static_cast<size_t>(lp.num_col_);
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
bool isRowPrimalSolutionRightSize(const HighsLp& lp,
|
|
1967
|
+
const HighsSolution& solution) {
|
|
1968
|
+
return solution.row_value.size() == static_cast<size_t>(lp.num_row_);
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
bool isPrimalSolutionRightSize(const HighsLp& lp,
|
|
1972
|
+
const HighsSolution& solution) {
|
|
1973
|
+
return isColPrimalSolutionRightSize(lp, solution) &&
|
|
1974
|
+
isRowPrimalSolutionRightSize(lp, solution);
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
bool isColDualSolutionRightSize(const HighsLp& lp,
|
|
1978
|
+
const HighsSolution& solution) {
|
|
1979
|
+
return solution.col_dual.size() == static_cast<size_t>(lp.num_col_);
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
bool isRowDualSolutionRightSize(const HighsLp& lp,
|
|
1983
|
+
const HighsSolution& solution) {
|
|
1984
|
+
return solution.row_dual.size() == static_cast<size_t>(lp.num_row_);
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
bool isDualSolutionRightSize(const HighsLp& lp, const HighsSolution& solution) {
|
|
1988
|
+
return isColDualSolutionRightSize(lp, solution) &&
|
|
1989
|
+
isRowDualSolutionRightSize(lp, solution);
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
bool isSolutionRightSize(const HighsLp& lp, const HighsSolution& solution) {
|
|
1993
|
+
return isPrimalSolutionRightSize(lp, solution) &&
|
|
1994
|
+
isDualSolutionRightSize(lp, solution);
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
bool isBasisRightSize(const HighsLp& lp, const HighsBasis& basis) {
|
|
1998
|
+
return basis.col_status.size() == static_cast<size_t>(lp.num_col_) &&
|
|
1999
|
+
basis.row_status.size() == static_cast<size_t>(lp.num_row_);
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
bool reportKktFailures(const HighsLp& lp, const HighsOptions& options,
|
|
2003
|
+
const HighsInfo& info, const std::string& message) {
|
|
2004
|
+
const HighsLogOptions& log_options = options.log_options;
|
|
2005
|
+
double mip_feasibility_tolerance = options.mip_feasibility_tolerance;
|
|
2006
|
+
double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
|
|
2007
|
+
double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
|
|
2008
|
+
double primal_residual_tolerance = options.primal_residual_tolerance;
|
|
2009
|
+
double dual_residual_tolerance = options.dual_residual_tolerance;
|
|
2010
|
+
double optimality_tolerance = options.optimality_tolerance;
|
|
2011
|
+
const bool is_mip = lp.isMip();
|
|
2012
|
+
if (is_mip) {
|
|
2013
|
+
primal_feasibility_tolerance = mip_feasibility_tolerance;
|
|
2014
|
+
} else if (options.kkt_tolerance != kDefaultKktTolerance) {
|
|
2015
|
+
mip_feasibility_tolerance = options.kkt_tolerance;
|
|
2016
|
+
primal_feasibility_tolerance = options.kkt_tolerance;
|
|
2017
|
+
dual_feasibility_tolerance = options.kkt_tolerance;
|
|
2018
|
+
primal_residual_tolerance = options.kkt_tolerance;
|
|
2019
|
+
dual_residual_tolerance = options.kkt_tolerance;
|
|
2020
|
+
optimality_tolerance = options.kkt_tolerance;
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
const bool force_report = options.log_dev_level >= kHighsLogDevLevelInfo;
|
|
2024
|
+
const bool complementarity_error =
|
|
2025
|
+
!is_mip && info.primal_dual_objective_error > optimality_tolerance;
|
|
2026
|
+
const bool integrality_error =
|
|
2027
|
+
is_mip && info.max_integrality_violation >= mip_feasibility_tolerance;
|
|
2028
|
+
const bool has_kkt_failures =
|
|
2029
|
+
integrality_error || info.num_primal_infeasibilities > 0 ||
|
|
2030
|
+
info.num_dual_infeasibilities > 0 ||
|
|
2031
|
+
info.num_primal_residual_errors > 0 ||
|
|
2032
|
+
info.num_dual_residual_errors > 0 || complementarity_error;
|
|
2033
|
+
if (!has_kkt_failures && !force_report) return has_kkt_failures;
|
|
2034
|
+
|
|
2035
|
+
HighsLogType log_type =
|
|
2036
|
+
has_kkt_failures ? HighsLogType::kWarning : HighsLogType::kInfo;
|
|
2037
|
+
|
|
2038
|
+
highsLogUser(log_options, log_type, "Solution optimality conditions%s%s\n",
|
|
2039
|
+
message == "" ? "" : ": ", message == "" ? "" : message.c_str());
|
|
2040
|
+
if (is_mip && info.max_integrality_violation >= 0)
|
|
2041
|
+
highsLogUser(log_options, HighsLogType::kInfo,
|
|
2042
|
+
" max %8.3g "
|
|
2043
|
+
"integrality violations"
|
|
2044
|
+
" (tolerance = %4.0e)\n",
|
|
2045
|
+
info.max_integrality_violation, mip_feasibility_tolerance);
|
|
2046
|
+
if (info.num_primal_infeasibilities >= 0)
|
|
2047
|
+
highsLogUser(
|
|
2048
|
+
log_options, HighsLogType::kInfo,
|
|
2049
|
+
"num/max %6d / %8.3g (relative %6d / %8.3g) primal "
|
|
2050
|
+
"infeasibilities (tolerance = %4.0e)\n",
|
|
2051
|
+
int(info.num_primal_infeasibilities), info.max_primal_infeasibility,
|
|
2052
|
+
int(info.num_relative_primal_infeasibilities),
|
|
2053
|
+
info.max_relative_primal_infeasibility, primal_feasibility_tolerance);
|
|
2054
|
+
if (info.num_dual_infeasibilities >= 0)
|
|
2055
|
+
highsLogUser(
|
|
2056
|
+
log_options, HighsLogType::kInfo,
|
|
2057
|
+
"num/max %6d / %8.3g (relative %6d / %8.3g) dual "
|
|
2058
|
+
"infeasibilities (tolerance = %4.0e)\n",
|
|
2059
|
+
int(info.num_dual_infeasibilities), info.max_dual_infeasibility,
|
|
2060
|
+
int(info.num_relative_dual_infeasibilities),
|
|
2061
|
+
info.max_relative_dual_infeasibility, dual_feasibility_tolerance);
|
|
2062
|
+
if (info.num_primal_residual_errors >= 0)
|
|
2063
|
+
highsLogUser(
|
|
2064
|
+
log_options, HighsLogType::kInfo,
|
|
2065
|
+
"num/max %6d / %8.3g (relative %6d / %8.3g) primal residual "
|
|
2066
|
+
"errors (tolerance = %4.0e)\n",
|
|
2067
|
+
int(info.num_primal_residual_errors), info.max_primal_residual_error,
|
|
2068
|
+
int(info.num_relative_primal_residual_errors),
|
|
2069
|
+
info.max_relative_primal_residual_error, primal_residual_tolerance);
|
|
2070
|
+
if (info.num_dual_residual_errors >= 0)
|
|
2071
|
+
highsLogUser(
|
|
2072
|
+
log_options, HighsLogType::kInfo,
|
|
2073
|
+
"num/max %6d / %8.3g (relative %6d / %8.3g) dual residual "
|
|
2074
|
+
"errors (tolerance = %4.0e)\n",
|
|
2075
|
+
int(info.num_dual_residual_errors), info.max_dual_residual_error,
|
|
2076
|
+
int(info.num_relative_dual_residual_errors),
|
|
2077
|
+
info.max_relative_dual_residual_error, dual_residual_tolerance);
|
|
2078
|
+
if (info.primal_dual_objective_error !=
|
|
2079
|
+
kHighsIllegalComplementarityViolation) {
|
|
2080
|
+
highsLogUser(
|
|
2081
|
+
log_options, HighsLogType::kInfo,
|
|
2082
|
+
" "
|
|
2083
|
+
" %1d / %8.3g P-D objective error "
|
|
2084
|
+
"(tolerance = %4.0e)\n",
|
|
2085
|
+
info.primal_dual_objective_error > optimality_tolerance ? 1 : 0,
|
|
2086
|
+
info.primal_dual_objective_error, optimality_tolerance);
|
|
2087
|
+
}
|
|
2088
|
+
if (printf_kkt) {
|
|
2089
|
+
printf("grepKktFailures,%s,%s,%s,%g,%d,%d,%d,%d,%d,%d,%d,%d,%g\n",
|
|
2090
|
+
options.solver.c_str(), lp.model_name_.c_str(),
|
|
2091
|
+
lp.origin_name_.c_str(), info.max_integrality_violation,
|
|
2092
|
+
int(info.num_primal_infeasibilities),
|
|
2093
|
+
int(info.num_dual_infeasibilities),
|
|
2094
|
+
int(info.num_primal_residual_errors),
|
|
2095
|
+
int(info.num_dual_residual_errors),
|
|
2096
|
+
int(info.num_relative_primal_infeasibilities),
|
|
2097
|
+
int(info.num_relative_dual_infeasibilities),
|
|
2098
|
+
int(info.num_relative_primal_residual_errors),
|
|
2099
|
+
int(info.num_relative_dual_residual_errors),
|
|
2100
|
+
info.primal_dual_objective_error);
|
|
2101
|
+
}
|
|
2102
|
+
return has_kkt_failures;
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
bool HighsSolution::hasUndefined() const {
|
|
2106
|
+
for (double value : this->col_value)
|
|
2107
|
+
if (value == kHighsUndefined) return true;
|
|
2108
|
+
return false;
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
void HighsSolution::invalidate() {
|
|
2112
|
+
this->value_valid = false;
|
|
2113
|
+
this->dual_valid = false;
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
void HighsSolution::clear() {
|
|
2117
|
+
this->invalidate();
|
|
2118
|
+
this->col_value.clear();
|
|
2119
|
+
this->row_value.clear();
|
|
2120
|
+
this->col_dual.clear();
|
|
2121
|
+
this->row_dual.clear();
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
void HighsSolution::print(const std::string& prefix,
|
|
2125
|
+
const std::string& message) const {
|
|
2126
|
+
HighsInt num_col = this->col_value.size();
|
|
2127
|
+
HighsInt num_row = this->row_value.size();
|
|
2128
|
+
printf("%s HighsSolution(num_col = %d, num_row = %d): %s\n", prefix.c_str(),
|
|
2129
|
+
int(num_col), int(num_row), message.c_str());
|
|
2130
|
+
for (HighsInt iCol = 0; iCol < num_col; iCol++)
|
|
2131
|
+
printf("%s col_value[%3d] = %11.4g\n", prefix.c_str(), int(iCol),
|
|
2132
|
+
this->col_value[iCol]);
|
|
2133
|
+
for (HighsInt iRow = 0; iRow < num_row; iRow++)
|
|
2134
|
+
printf("%s row_value[%3d] = %11.4g\n", prefix.c_str(), int(iRow),
|
|
2135
|
+
this->row_value[iRow]);
|
|
2136
|
+
|
|
2137
|
+
num_col = this->col_dual.size();
|
|
2138
|
+
num_row = this->row_dual.size();
|
|
2139
|
+
printf("%s HighsSolution(num_col = %d, num_row = %d): %s\n", prefix.c_str(),
|
|
2140
|
+
int(num_col), int(num_row), message.c_str());
|
|
2141
|
+
for (HighsInt iCol = 0; iCol < num_col; iCol++)
|
|
2142
|
+
printf("%s col_dual[%3d] = %11.4g\n", prefix.c_str(), int(iCol),
|
|
2143
|
+
this->col_dual[iCol]);
|
|
2144
|
+
for (HighsInt iRow = 0; iRow < num_row; iRow++)
|
|
2145
|
+
printf("%s row_dual[%3d] = %11.4g\n", prefix.c_str(), int(iRow),
|
|
2146
|
+
this->row_dual[iRow]);
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2149
|
+
void HighsObjectiveSolution::clear() { this->col_value.clear(); }
|
|
2150
|
+
|
|
2151
|
+
void HighsBasis::print(const std::string& prefix,
|
|
2152
|
+
const std::string& message) const {
|
|
2153
|
+
this->printScalars(prefix, message);
|
|
2154
|
+
if (!this->useful) return;
|
|
2155
|
+
for (HighsInt iCol = 0; iCol < HighsInt(this->col_status.size()); iCol++)
|
|
2156
|
+
printf("%s HighsBasis: col_status[%2d] = %d\n", prefix.c_str(), int(iCol),
|
|
2157
|
+
int(this->col_status[iCol]));
|
|
2158
|
+
for (HighsInt iRow = 0; iRow < HighsInt(this->row_status.size()); iRow++)
|
|
2159
|
+
printf("%s HighsBasis: row_status[%2d] = %d\n", prefix.c_str(), int(iRow),
|
|
2160
|
+
int(this->row_status[iRow]));
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
void HighsBasis::printScalars(const std::string& prefix,
|
|
2164
|
+
const std::string& message) const {
|
|
2165
|
+
HighsInt num_col = this->col_status.size();
|
|
2166
|
+
HighsInt num_row = this->row_status.size();
|
|
2167
|
+
printf("\n%s HighsBasis(num_col = %d, num_row = %d): %s\n", prefix.c_str(),
|
|
2168
|
+
int(num_col), int(num_row), message.c_str());
|
|
2169
|
+
printf("%s valid = %d\n", prefix.c_str(), this->valid);
|
|
2170
|
+
printf("%s alien = %d\n", prefix.c_str(), this->alien);
|
|
2171
|
+
printf("%s useful = %d\n", prefix.c_str(), this->useful);
|
|
2172
|
+
printf("%s was_alien = %d\n", prefix.c_str(), this->was_alien);
|
|
2173
|
+
printf("%s debug_id = %d\n", prefix.c_str(), int(this->debug_id));
|
|
2174
|
+
printf("%s debug_update_count = %d\n", prefix.c_str(),
|
|
2175
|
+
int(this->debug_update_count));
|
|
2176
|
+
printf("%s debug_origin_name = %s\n", prefix.c_str(),
|
|
2177
|
+
this->debug_origin_name.c_str());
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
void HighsBasis::invalidate() {
|
|
2181
|
+
this->valid = false;
|
|
2182
|
+
this->alien = true;
|
|
2183
|
+
this->useful = false;
|
|
2184
|
+
this->was_alien = true;
|
|
2185
|
+
this->debug_id = -1;
|
|
2186
|
+
this->debug_update_count = -1;
|
|
2187
|
+
this->debug_origin_name = "None";
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
void HighsBasis::clear() {
|
|
2191
|
+
this->invalidate();
|
|
2192
|
+
this->row_status.clear();
|
|
2193
|
+
this->col_status.clear();
|
|
2194
|
+
}
|