lpsolver 0.1.0 → 0.2.1
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 +104 -26
- data/ext/lpsolver/Makefile +269 -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 +35 -7
- data/lib/lpsolver/native.so +0 -0
- data/lib/lpsolver/native_model.rb +261 -0
- data/lib/lpsolver/solution.rb +93 -8
- data/lib/lpsolver/version.rb +1 -1
- data/lpsolver.gemspec +4 -1
- metadata +1176 -4
|
@@ -0,0 +1,2113 @@
|
|
|
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
|
+
|
|
9
|
+
#include "io/HMpsFF.h"
|
|
10
|
+
|
|
11
|
+
#include "lp_data/HighsModelUtils.h"
|
|
12
|
+
|
|
13
|
+
#ifdef ZLIB_FOUND
|
|
14
|
+
#include "../extern/zstr/zstr.hpp"
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
namespace free_format_parser {
|
|
18
|
+
|
|
19
|
+
const bool kNoClockCalls = false;
|
|
20
|
+
|
|
21
|
+
FreeFormatParserReturnCode HMpsFF::loadProblem(
|
|
22
|
+
const HighsLogOptions& log_options, const std::string filename,
|
|
23
|
+
HighsModel& model) {
|
|
24
|
+
// Keep track of any warnings that are issued so that
|
|
25
|
+
// Highs::readModel can return HighsStatus::kWarning
|
|
26
|
+
warning_issued_ = false;
|
|
27
|
+
HighsLp& lp = model.lp_;
|
|
28
|
+
HighsHessian& hessian = model.hessian_;
|
|
29
|
+
FreeFormatParserReturnCode result = parse(log_options, filename);
|
|
30
|
+
if (result != FreeFormatParserReturnCode::kSuccess) return result;
|
|
31
|
+
|
|
32
|
+
if (!qrows_entries.empty()) {
|
|
33
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
34
|
+
"Quadratic rows not supported by HiGHS\n");
|
|
35
|
+
return FreeFormatParserReturnCode::kParserError;
|
|
36
|
+
}
|
|
37
|
+
if (!sos_entries.empty()) {
|
|
38
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
39
|
+
"SOS not supported by HiGHS\n");
|
|
40
|
+
return FreeFormatParserReturnCode::kParserError;
|
|
41
|
+
}
|
|
42
|
+
if (!cone_entries.empty()) {
|
|
43
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
44
|
+
"Cones not supported by HiGHS\n");
|
|
45
|
+
return FreeFormatParserReturnCode::kParserError;
|
|
46
|
+
}
|
|
47
|
+
// Duplicate row and column names in MPS files occur if the same row
|
|
48
|
+
// name appears twice in the ROWS section, or if a column name
|
|
49
|
+
// reoccurs in the COLUMNS section after another column has been
|
|
50
|
+
// defined. They are anomalies, but are only handled by a warning in
|
|
51
|
+
// some solvers. Hence, rather than fail, HiGHS does the same.
|
|
52
|
+
//
|
|
53
|
+
// If there are duplicate row (column) names, then they are treated
|
|
54
|
+
// as distinct rows (columns), so the row (column) names array is
|
|
55
|
+
// not valid. Report this for the first instance, and clear the row
|
|
56
|
+
// (column) names array.
|
|
57
|
+
//
|
|
58
|
+
// Note that rowname2idx and colname2idx will return the index
|
|
59
|
+
// corresponding to the first occurrence of the name, so values for
|
|
60
|
+
// rows in the COLUMNS, RHS and RANGES sections, and columns in the
|
|
61
|
+
// BOUNDS and other sections can only be defined for the first
|
|
62
|
+
// occurrence
|
|
63
|
+
if (has_duplicate_row_name_) {
|
|
64
|
+
warning_issued_ = true;
|
|
65
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
66
|
+
"Linear constraints %d and %d have the same name \"%s\"\n",
|
|
67
|
+
(int)duplicate_row_name_index0_,
|
|
68
|
+
(int)duplicate_row_name_index1_, duplicate_row_name_.c_str());
|
|
69
|
+
row_names.clear();
|
|
70
|
+
}
|
|
71
|
+
if (has_duplicate_col_name_) {
|
|
72
|
+
warning_issued_ = true;
|
|
73
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
74
|
+
"Variables %d and %d have the same name \"%s\"\n",
|
|
75
|
+
(int)duplicate_col_name_index0_,
|
|
76
|
+
(int)duplicate_col_name_index1_, duplicate_col_name_.c_str());
|
|
77
|
+
col_names.clear();
|
|
78
|
+
}
|
|
79
|
+
col_cost.assign(num_col, 0);
|
|
80
|
+
for (auto i : coeffobj) col_cost[i.first] = i.second;
|
|
81
|
+
HighsInt status = fillMatrix(log_options);
|
|
82
|
+
if (status) return FreeFormatParserReturnCode::kParserError;
|
|
83
|
+
status = fillHessian(log_options);
|
|
84
|
+
if (status) return FreeFormatParserReturnCode::kParserError;
|
|
85
|
+
|
|
86
|
+
lp.num_row_ = num_row;
|
|
87
|
+
lp.num_col_ = num_col;
|
|
88
|
+
|
|
89
|
+
lp.sense_ = obj_sense;
|
|
90
|
+
lp.offset_ = obj_offset;
|
|
91
|
+
|
|
92
|
+
lp.a_matrix_.format_ = MatrixFormat::kColwise;
|
|
93
|
+
lp.a_matrix_.start_ = std::move(a_start);
|
|
94
|
+
lp.a_matrix_.index_ = std::move(a_index);
|
|
95
|
+
lp.a_matrix_.value_ = std::move(a_value);
|
|
96
|
+
// a must have at least start_[0]=0 for the fictitious column
|
|
97
|
+
// 0
|
|
98
|
+
if (lp.a_matrix_.start_.size() == 0) lp.a_matrix_.clear();
|
|
99
|
+
lp.col_cost_ = std::move(col_cost);
|
|
100
|
+
lp.col_lower_ = std::move(col_lower);
|
|
101
|
+
lp.col_upper_ = std::move(col_upper);
|
|
102
|
+
lp.row_lower_ = std::move(row_lower);
|
|
103
|
+
lp.row_upper_ = std::move(row_upper);
|
|
104
|
+
|
|
105
|
+
lp.objective_name_ = objective_name;
|
|
106
|
+
lp.row_names_ = std::move(row_names);
|
|
107
|
+
lp.col_names_ = std::move(col_names);
|
|
108
|
+
|
|
109
|
+
// Only set up lp.integrality_ if non-continuous
|
|
110
|
+
bool is_mip = false;
|
|
111
|
+
for (const auto& var_type : col_integrality) {
|
|
112
|
+
if (var_type != HighsVarType::kContinuous) {
|
|
113
|
+
is_mip = true;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (is_mip) lp.integrality_ = std::move(col_integrality);
|
|
118
|
+
|
|
119
|
+
hessian.dim_ = q_dim;
|
|
120
|
+
hessian.format_ = q_format;
|
|
121
|
+
hessian.start_ = std::move(q_start);
|
|
122
|
+
hessian.index_ = std::move(q_index);
|
|
123
|
+
hessian.value_ = std::move(q_value);
|
|
124
|
+
// hessian must have at least start_[0]=0 for the fictitious column
|
|
125
|
+
// 0
|
|
126
|
+
if (hessian.start_.size() == 0) hessian.clear();
|
|
127
|
+
|
|
128
|
+
// Set the objective name, creating one if necessary
|
|
129
|
+
lp.objective_name_ = findModelObjectiveName(&lp, &hessian);
|
|
130
|
+
lp.cost_row_location_ = cost_row_location;
|
|
131
|
+
|
|
132
|
+
return FreeFormatParserReturnCode::kSuccess;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
HighsInt HMpsFF::fillMatrix(const HighsLogOptions& log_options) {
|
|
136
|
+
size_t num_entries = entries.size();
|
|
137
|
+
if (num_entries != static_cast<size_t>(num_nz)) return 1;
|
|
138
|
+
|
|
139
|
+
a_value.resize(num_nz);
|
|
140
|
+
a_index.resize(num_nz);
|
|
141
|
+
a_start.assign(num_col + 1, 0);
|
|
142
|
+
// Nothing to do if there are no entries in the matrix
|
|
143
|
+
if (!num_entries) return 0;
|
|
144
|
+
|
|
145
|
+
HighsInt newColIndex = std::get<0>(entries.at(0));
|
|
146
|
+
|
|
147
|
+
for (HighsInt k = 0; k < num_nz; k++) {
|
|
148
|
+
a_value.at(k) = std::get<2>(entries.at(k));
|
|
149
|
+
a_index.at(k) = std::get<1>(entries.at(k));
|
|
150
|
+
|
|
151
|
+
if (std::get<0>(entries.at(k)) != newColIndex) {
|
|
152
|
+
HighsInt nEmptyCols = std::get<0>(entries.at(k)) - newColIndex;
|
|
153
|
+
newColIndex = std::get<0>(entries.at(k));
|
|
154
|
+
if (newColIndex >= num_col) return 1;
|
|
155
|
+
|
|
156
|
+
a_start.at(newColIndex) = k;
|
|
157
|
+
for (HighsInt i = 1; i < nEmptyCols; i++) {
|
|
158
|
+
a_start.at(newColIndex - i) = k;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
for (HighsInt col = newColIndex + 1; col <= num_col; col++)
|
|
164
|
+
a_start[col] = num_nz;
|
|
165
|
+
|
|
166
|
+
for (HighsInt i = 0; i < num_col; i++) {
|
|
167
|
+
if (a_start[i] > a_start[i + 1]) {
|
|
168
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
169
|
+
"Non-monotonic starts in MPS file reader\n");
|
|
170
|
+
return 1;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return 0;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
HighsInt HMpsFF::fillHessian(const HighsLogOptions& log_options) {
|
|
178
|
+
size_t num_entries = q_entries.size();
|
|
179
|
+
if (!num_entries) {
|
|
180
|
+
q_dim = 0;
|
|
181
|
+
return 0;
|
|
182
|
+
} else {
|
|
183
|
+
q_dim = num_col;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
q_start.resize(q_dim + 1);
|
|
187
|
+
q_index.resize(num_entries);
|
|
188
|
+
q_value.resize(num_entries);
|
|
189
|
+
|
|
190
|
+
// Use q_length to determine the number of entries in each column,
|
|
191
|
+
// and then as workspace to point to the next entry to be filled in
|
|
192
|
+
// each column
|
|
193
|
+
std::vector<HighsInt> q_length;
|
|
194
|
+
q_length.assign(q_dim, 0);
|
|
195
|
+
|
|
196
|
+
for (size_t iEl = 0; iEl < num_entries; iEl++) {
|
|
197
|
+
HighsInt iCol = std::get<1>(q_entries[iEl]);
|
|
198
|
+
q_length[iCol]++;
|
|
199
|
+
}
|
|
200
|
+
q_start[0] = 0;
|
|
201
|
+
for (HighsInt iCol = 0; iCol < num_col; iCol++) {
|
|
202
|
+
q_start[iCol + 1] = q_start[iCol] + q_length[iCol];
|
|
203
|
+
q_length[iCol] = q_start[iCol];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
for (size_t iEl = 0; iEl < num_entries; iEl++) {
|
|
207
|
+
HighsInt iRow = std::get<0>(q_entries[iEl]);
|
|
208
|
+
HighsInt iCol = std::get<1>(q_entries[iEl]);
|
|
209
|
+
double value = std::get<2>(q_entries[iEl]);
|
|
210
|
+
q_index[q_length[iCol]] = iRow;
|
|
211
|
+
q_value[q_length[iCol]] = value;
|
|
212
|
+
q_length[iCol]++;
|
|
213
|
+
}
|
|
214
|
+
q_format = HessianFormat::kSquare;
|
|
215
|
+
return 0;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
bool HMpsFF::timeout() {
|
|
219
|
+
return time_limit_ > 0 && getWallTime() - start_time > time_limit_;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
bool HMpsFF::getMpsLine(std::istream& file, std::string& strline, bool& skip) {
|
|
223
|
+
const bool remove_trailing_comments = false;
|
|
224
|
+
skip = false;
|
|
225
|
+
if (!getline(file, strline)) return false;
|
|
226
|
+
if (is_empty(strline) || strline[0] == '*') {
|
|
227
|
+
skip = true;
|
|
228
|
+
} else {
|
|
229
|
+
if (remove_trailing_comments) {
|
|
230
|
+
// Remove any trailing comment
|
|
231
|
+
const size_t p = strline.find_first_of(mps_comment_chars);
|
|
232
|
+
if (p <= strline.length()) {
|
|
233
|
+
// A comment character has been found, so erase from it to the end
|
|
234
|
+
// of the line and check whether the line is now empty
|
|
235
|
+
strline.erase(p);
|
|
236
|
+
skip = is_empty(strline);
|
|
237
|
+
if (skip) return true;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
strline = trim(strline);
|
|
241
|
+
skip = is_empty(strline);
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
FreeFormatParserReturnCode HMpsFF::parse(const HighsLogOptions& log_options,
|
|
247
|
+
const std::string& filename) {
|
|
248
|
+
HMpsFF::Parsekey keyword = HMpsFF::Parsekey::kNone;
|
|
249
|
+
|
|
250
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
251
|
+
"readMPS: Trying to open file %s\n", filename.c_str());
|
|
252
|
+
#ifdef ZLIB_FOUND
|
|
253
|
+
zstr::ifstream f;
|
|
254
|
+
try {
|
|
255
|
+
f.open(filename.c_str(), std::ios::in);
|
|
256
|
+
} catch (const strict_fstream::Exception& e) {
|
|
257
|
+
highsLogDev(log_options, HighsLogType::kInfo, e.what());
|
|
258
|
+
return FreeFormatParserReturnCode::kFileNotFound;
|
|
259
|
+
}
|
|
260
|
+
#else
|
|
261
|
+
std::ifstream f;
|
|
262
|
+
f.open(filename.c_str(), std::ios::in);
|
|
263
|
+
#endif
|
|
264
|
+
if (f.is_open()) {
|
|
265
|
+
start_time = getWallTime();
|
|
266
|
+
num_row = 0;
|
|
267
|
+
num_col = 0;
|
|
268
|
+
num_nz = 0;
|
|
269
|
+
cost_row_location = -1;
|
|
270
|
+
// Indicate that no duplicate rows or columns have been found
|
|
271
|
+
has_duplicate_row_name_ = false;
|
|
272
|
+
has_duplicate_col_name_ = false;
|
|
273
|
+
// parsing loop
|
|
274
|
+
while (keyword != HMpsFF::Parsekey::kFail &&
|
|
275
|
+
keyword != HMpsFF::Parsekey::kEnd &&
|
|
276
|
+
keyword != HMpsFF::Parsekey::kTimeout) {
|
|
277
|
+
if (cannotParseSection(log_options, keyword)) {
|
|
278
|
+
f.close();
|
|
279
|
+
return FreeFormatParserReturnCode::kParserError;
|
|
280
|
+
}
|
|
281
|
+
switch (keyword) {
|
|
282
|
+
case HMpsFF::Parsekey::kObjsense:
|
|
283
|
+
keyword = parseObjsense(log_options, f);
|
|
284
|
+
break;
|
|
285
|
+
case HMpsFF::Parsekey::kRows:
|
|
286
|
+
keyword = parseRows(log_options, f);
|
|
287
|
+
break;
|
|
288
|
+
case HMpsFF::Parsekey::kCols:
|
|
289
|
+
keyword = parseCols(log_options, f);
|
|
290
|
+
break;
|
|
291
|
+
case HMpsFF::Parsekey::kRhs:
|
|
292
|
+
keyword = parseRhs(log_options, f);
|
|
293
|
+
break;
|
|
294
|
+
case HMpsFF::Parsekey::kBounds:
|
|
295
|
+
keyword = parseBounds(log_options, f);
|
|
296
|
+
break;
|
|
297
|
+
case HMpsFF::Parsekey::kRanges:
|
|
298
|
+
keyword = parseRanges(log_options, f);
|
|
299
|
+
break;
|
|
300
|
+
case HMpsFF::Parsekey::kQmatrix:
|
|
301
|
+
case HMpsFF::Parsekey::kQuadobj:
|
|
302
|
+
keyword = parseHessian(log_options, f, keyword);
|
|
303
|
+
break;
|
|
304
|
+
case HMpsFF::Parsekey::kQsection:
|
|
305
|
+
case HMpsFF::Parsekey::kQcmatrix:
|
|
306
|
+
keyword = parseQuadRows(log_options, f, keyword);
|
|
307
|
+
break;
|
|
308
|
+
case HMpsFF::Parsekey::kCsection:
|
|
309
|
+
keyword = parseCones(log_options, f);
|
|
310
|
+
break;
|
|
311
|
+
case HMpsFF::Parsekey::kSets:
|
|
312
|
+
case HMpsFF::Parsekey::kSos:
|
|
313
|
+
keyword = parseSos(log_options, f, keyword);
|
|
314
|
+
break;
|
|
315
|
+
case HMpsFF::Parsekey::kFail:
|
|
316
|
+
f.close();
|
|
317
|
+
return FreeFormatParserReturnCode::kParserError;
|
|
318
|
+
case HMpsFF::Parsekey::kFixedFormat:
|
|
319
|
+
f.close();
|
|
320
|
+
return FreeFormatParserReturnCode::kFixedFormat;
|
|
321
|
+
default:
|
|
322
|
+
keyword = parseDefault(log_options, f);
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Assign bounds to columns that remain binary by default
|
|
328
|
+
for (HighsInt colidx = 0; colidx < num_col; colidx++) {
|
|
329
|
+
if (col_binary[colidx]) {
|
|
330
|
+
col_lower[colidx] = 0.0;
|
|
331
|
+
col_upper[colidx] = 1.0;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (keyword == HMpsFF::Parsekey::kFail) {
|
|
336
|
+
f.close();
|
|
337
|
+
return FreeFormatParserReturnCode::kParserError;
|
|
338
|
+
}
|
|
339
|
+
} else {
|
|
340
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
341
|
+
"readMPS: Not opened file OK\n");
|
|
342
|
+
f.close();
|
|
343
|
+
return FreeFormatParserReturnCode::kFileNotFound;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
f.close();
|
|
347
|
+
|
|
348
|
+
if (keyword == HMpsFF::Parsekey::kTimeout)
|
|
349
|
+
return FreeFormatParserReturnCode::kTimeout;
|
|
350
|
+
|
|
351
|
+
assert(col_lower.size() == static_cast<size_t>(num_col));
|
|
352
|
+
assert(row_lower.size() == static_cast<size_t>(num_row));
|
|
353
|
+
return FreeFormatParserReturnCode::kSuccess;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
bool HMpsFF::cannotParseSection(const HighsLogOptions& log_options,
|
|
357
|
+
const HMpsFF::Parsekey keyword) {
|
|
358
|
+
switch (keyword) {
|
|
359
|
+
// Identify the sections that cannot be parsed
|
|
360
|
+
case HMpsFF::Parsekey::kDelayedrows:
|
|
361
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
362
|
+
"MPS file reader cannot parse DELAYEDROWS section\n");
|
|
363
|
+
break;
|
|
364
|
+
case HMpsFF::Parsekey::kModelcuts:
|
|
365
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
366
|
+
"MPS file reader cannot parse MODELCUTS section\n");
|
|
367
|
+
break;
|
|
368
|
+
case HMpsFF::Parsekey::kUsercuts:
|
|
369
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
370
|
+
"MPS file reader cannot parse USERCUTS section\n");
|
|
371
|
+
break;
|
|
372
|
+
case HMpsFF::Parsekey::kIndicators:
|
|
373
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
374
|
+
"MPS file reader cannot parse INDICATORS section\n");
|
|
375
|
+
break;
|
|
376
|
+
case HMpsFF::Parsekey::kGencons:
|
|
377
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
378
|
+
"MPS file reader cannot parse GENCONS section\n");
|
|
379
|
+
break;
|
|
380
|
+
case HMpsFF::Parsekey::kPwlobj:
|
|
381
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
382
|
+
"MPS file reader cannot parse PWLOBJ section\n");
|
|
383
|
+
break;
|
|
384
|
+
case HMpsFF::Parsekey::kPwlnam:
|
|
385
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
386
|
+
"MPS file reader cannot parse PWLNAM section\n");
|
|
387
|
+
break;
|
|
388
|
+
case HMpsFF::Parsekey::kPwlcon:
|
|
389
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
390
|
+
"MPS file reader cannot parse PWLCON section\n");
|
|
391
|
+
break;
|
|
392
|
+
default:
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Assuming string is not empty.
|
|
399
|
+
HMpsFF::Parsekey HMpsFF::checkFirstWord(std::string& strline, size_t& start,
|
|
400
|
+
size_t& end, std::string& word) const {
|
|
401
|
+
start = strline.find_first_not_of(" ");
|
|
402
|
+
if ((start + 1 == strline.size()) || is_empty(strline[start + 1])) {
|
|
403
|
+
end = start + 1;
|
|
404
|
+
word = strline[start];
|
|
405
|
+
return HMpsFF::Parsekey::kNone;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
end = first_word_end(strline, start + 1);
|
|
409
|
+
|
|
410
|
+
word = strline.substr(start, end - start);
|
|
411
|
+
|
|
412
|
+
// Create an upper-case version of WORD, so that keywords are
|
|
413
|
+
// read as if they were in lower or mixed case
|
|
414
|
+
std::string upper_word = word;
|
|
415
|
+
toupper(upper_word);
|
|
416
|
+
|
|
417
|
+
// store rest of strline for keywords that have arguments
|
|
418
|
+
if (upper_word == "QCMATRIX" || upper_word == "QSECTION" ||
|
|
419
|
+
upper_word == "CSECTION")
|
|
420
|
+
section_args = strline.substr(end, strline.length());
|
|
421
|
+
|
|
422
|
+
HMpsFF::Parsekey key;
|
|
423
|
+
|
|
424
|
+
if (upper_word == "NAME")
|
|
425
|
+
key = HMpsFF::Parsekey::kName;
|
|
426
|
+
else if (upper_word == "OBJSENSE")
|
|
427
|
+
key = HMpsFF::Parsekey::kObjsense;
|
|
428
|
+
else if (upper_word.substr(0, 3) == "MAX")
|
|
429
|
+
key = HMpsFF::Parsekey::kMax;
|
|
430
|
+
else if (upper_word.substr(0, 3) == "MIN")
|
|
431
|
+
key = HMpsFF::Parsekey::kMin;
|
|
432
|
+
else if (upper_word == "ROWS")
|
|
433
|
+
key = HMpsFF::Parsekey::kRows;
|
|
434
|
+
else if (upper_word == "COLUMNS")
|
|
435
|
+
key = HMpsFF::Parsekey::kCols;
|
|
436
|
+
else if (upper_word == "RHS")
|
|
437
|
+
key = HMpsFF::Parsekey::kRhs;
|
|
438
|
+
else if (upper_word == "BOUNDS")
|
|
439
|
+
key = HMpsFF::Parsekey::kBounds;
|
|
440
|
+
else if (upper_word == "RANGES")
|
|
441
|
+
key = HMpsFF::Parsekey::kRanges;
|
|
442
|
+
else if (upper_word == "QSECTION")
|
|
443
|
+
key = HMpsFF::Parsekey::kQsection;
|
|
444
|
+
else if (upper_word == "QMATRIX")
|
|
445
|
+
key = HMpsFF::Parsekey::kQmatrix;
|
|
446
|
+
else if (upper_word == "QUADOBJ")
|
|
447
|
+
key = HMpsFF::Parsekey::kQuadobj;
|
|
448
|
+
else if (upper_word == "QCMATRIX")
|
|
449
|
+
key = HMpsFF::Parsekey::kQcmatrix;
|
|
450
|
+
else if (upper_word == "CSECTION")
|
|
451
|
+
key = HMpsFF::Parsekey::kCsection;
|
|
452
|
+
else if (upper_word == "DELAYEDROWS")
|
|
453
|
+
key = HMpsFF::Parsekey::kDelayedrows;
|
|
454
|
+
else if (upper_word == "MODELCUTS")
|
|
455
|
+
key = HMpsFF::Parsekey::kModelcuts;
|
|
456
|
+
else if (upper_word == "USERCUTS")
|
|
457
|
+
key = HMpsFF::Parsekey::kUsercuts;
|
|
458
|
+
else if (upper_word == "INDICATORS")
|
|
459
|
+
key = HMpsFF::Parsekey::kIndicators;
|
|
460
|
+
else if (upper_word == "SETS")
|
|
461
|
+
key = HMpsFF::Parsekey::kSets;
|
|
462
|
+
else if (upper_word == "SOS")
|
|
463
|
+
key = HMpsFF::Parsekey::kSos;
|
|
464
|
+
else if (upper_word == "GENCONS")
|
|
465
|
+
key = HMpsFF::Parsekey::kGencons;
|
|
466
|
+
else if (upper_word == "PWLOBJ")
|
|
467
|
+
key = HMpsFF::Parsekey::kPwlobj;
|
|
468
|
+
else if (upper_word == "PWLNAM")
|
|
469
|
+
key = HMpsFF::Parsekey::kPwlnam;
|
|
470
|
+
else if (upper_word == "PWLCON")
|
|
471
|
+
key = HMpsFF::Parsekey::kPwlcon;
|
|
472
|
+
else if (upper_word == "ENDATA")
|
|
473
|
+
key = HMpsFF::Parsekey::kEnd;
|
|
474
|
+
else
|
|
475
|
+
return HMpsFF::Parsekey::kNone;
|
|
476
|
+
// Can have keywords used as column names or names of RHS, BOUND,
|
|
477
|
+
// RANGES etc, so assume this if there are non-blanks after the
|
|
478
|
+
// apparent keyword. Only cases that don't work are NAME, OBJSENSE,
|
|
479
|
+
// QCMATRIX, QSECTION, and CSECTION since they can be followed by text
|
|
480
|
+
if (key == HMpsFF::Parsekey::kName || key == HMpsFF::Parsekey::kObjsense ||
|
|
481
|
+
key == HMpsFF::Parsekey::kQcmatrix ||
|
|
482
|
+
key == HMpsFF::Parsekey::kQsection || key == HMpsFF::Parsekey::kCsection)
|
|
483
|
+
return key;
|
|
484
|
+
assert(key != HMpsFF::Parsekey::kNone);
|
|
485
|
+
|
|
486
|
+
if (is_end(strline, end)) return key;
|
|
487
|
+
|
|
488
|
+
return HMpsFF::Parsekey::kNone;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
HighsInt HMpsFF::getColIdx(const std::string& colname, const bool add_if_new) {
|
|
492
|
+
// look up column name
|
|
493
|
+
auto mit = colname2idx.find(colname);
|
|
494
|
+
if (mit != colname2idx.end()) return mit->second;
|
|
495
|
+
|
|
496
|
+
if (!add_if_new) return -1;
|
|
497
|
+
// add new continuous column with default bounds
|
|
498
|
+
colname2idx.emplace(colname, num_col++);
|
|
499
|
+
col_names.push_back(colname);
|
|
500
|
+
col_integrality.push_back(HighsVarType::kContinuous);
|
|
501
|
+
col_binary.push_back(false);
|
|
502
|
+
col_lower.push_back(0.0);
|
|
503
|
+
col_upper.push_back(kHighsInf);
|
|
504
|
+
|
|
505
|
+
return num_col - 1;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
HMpsFF::Parsekey HMpsFF::parseDefault(const HighsLogOptions& log_options,
|
|
509
|
+
std::istream& file) {
|
|
510
|
+
std::string strline, word;
|
|
511
|
+
bool skip;
|
|
512
|
+
if (getMpsLine(file, strline, skip)) {
|
|
513
|
+
if (skip) return HMpsFF::Parsekey::kComment;
|
|
514
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
515
|
+
|
|
516
|
+
size_t s, e;
|
|
517
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, s, e, word);
|
|
518
|
+
if (key == HMpsFF::Parsekey::kName) {
|
|
519
|
+
// Save name of the MPS file
|
|
520
|
+
if (e < strline.length()) {
|
|
521
|
+
mps_name = first_word(strline, e);
|
|
522
|
+
}
|
|
523
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
524
|
+
"readMPS: Read NAME OK\n");
|
|
525
|
+
return HMpsFF::Parsekey::kNone;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
if (key == HMpsFF::Parsekey::kObjsense) {
|
|
529
|
+
// Look for Gurobi-style definition of MAX/MIN on OBJSENSE line
|
|
530
|
+
if (e < strline.length()) {
|
|
531
|
+
std::string sense = first_word(strline, e);
|
|
532
|
+
// Convert to upper case
|
|
533
|
+
toupper(sense);
|
|
534
|
+
if (sense.compare("MAX") == 0) {
|
|
535
|
+
// Found MAX sense on OBJSENSE line
|
|
536
|
+
obj_sense = ObjSense::kMaximize;
|
|
537
|
+
} else if (sense.compare("MIN") == 0) {
|
|
538
|
+
// Found MIN sense on OBJSENSE line
|
|
539
|
+
obj_sense = ObjSense::kMinimize;
|
|
540
|
+
}
|
|
541
|
+
// Don't return HMpsFF::Parsekey::kNone; in case there's a
|
|
542
|
+
// redefinition of OBJSENSE on the "proper" line. If there's
|
|
543
|
+
// no such line, the ROWS keyword is read OK
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
return key;
|
|
548
|
+
}
|
|
549
|
+
return HMpsFF::Parsekey::kFail;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
double getWallTime() {
|
|
553
|
+
using namespace std::chrono;
|
|
554
|
+
const double wall_time = kNoClockCalls
|
|
555
|
+
? 0
|
|
556
|
+
: duration_cast<duration<double> >(
|
|
557
|
+
wall_clock::now().time_since_epoch())
|
|
558
|
+
.count();
|
|
559
|
+
return wall_time;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
HMpsFF::Parsekey HMpsFF::parseObjsense(const HighsLogOptions& log_options,
|
|
563
|
+
std::istream& file) {
|
|
564
|
+
std::string strline, word;
|
|
565
|
+
|
|
566
|
+
bool skip;
|
|
567
|
+
while (getMpsLine(file, strline, skip)) {
|
|
568
|
+
if (skip) continue;
|
|
569
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
570
|
+
|
|
571
|
+
size_t start = 0;
|
|
572
|
+
size_t end = 0;
|
|
573
|
+
|
|
574
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, start, end, word);
|
|
575
|
+
|
|
576
|
+
// Interpret key being MAX or MIN
|
|
577
|
+
if (key == HMpsFF::Parsekey::kMax) {
|
|
578
|
+
obj_sense = ObjSense::kMaximize;
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
if (key == HMpsFF::Parsekey::kMin) {
|
|
582
|
+
obj_sense = ObjSense::kMinimize;
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
586
|
+
"readMPS: Read OBJSENSE OK\n");
|
|
587
|
+
// start of new section?
|
|
588
|
+
if (key != HMpsFF::Parsekey::kNone) {
|
|
589
|
+
return key;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
return HMpsFF::Parsekey::kFail;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
HMpsFF::Parsekey HMpsFF::parseRows(const HighsLogOptions& log_options,
|
|
596
|
+
std::istream& file) {
|
|
597
|
+
std::string strline, word;
|
|
598
|
+
bool hasobj = false;
|
|
599
|
+
// Assign a default objective name
|
|
600
|
+
objective_name = "Objective";
|
|
601
|
+
|
|
602
|
+
assert(num_row == 0);
|
|
603
|
+
assert(row_lower.size() == 0);
|
|
604
|
+
assert(row_upper.size() == 0);
|
|
605
|
+
bool skip;
|
|
606
|
+
while (getMpsLine(file, strline, skip)) {
|
|
607
|
+
if (skip) continue;
|
|
608
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
609
|
+
|
|
610
|
+
bool isobj = false;
|
|
611
|
+
bool isFreeRow = false;
|
|
612
|
+
|
|
613
|
+
size_t start = 0;
|
|
614
|
+
size_t end = 0;
|
|
615
|
+
|
|
616
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, start, end, word);
|
|
617
|
+
|
|
618
|
+
// start of new section?
|
|
619
|
+
if (key != HMpsFF::Parsekey::kNone) {
|
|
620
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
621
|
+
"readMPS: Read ROWS OK\n");
|
|
622
|
+
if (!hasobj) {
|
|
623
|
+
warning_issued_ = true;
|
|
624
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
625
|
+
"No objective row found\n");
|
|
626
|
+
rowname2idx.emplace("artificial_empty_objective", HighsInt{-1});
|
|
627
|
+
};
|
|
628
|
+
return key;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
if (strline[start] == 'G') {
|
|
632
|
+
row_lower.push_back(0.0);
|
|
633
|
+
row_upper.push_back(kHighsInf);
|
|
634
|
+
row_type.push_back(Boundtype::kGe);
|
|
635
|
+
} else if (strline[start] == 'E') {
|
|
636
|
+
row_lower.push_back(0.0);
|
|
637
|
+
row_upper.push_back(0.0);
|
|
638
|
+
row_type.push_back(Boundtype::kEq);
|
|
639
|
+
} else if (strline[start] == 'L') {
|
|
640
|
+
row_lower.push_back(-kHighsInf);
|
|
641
|
+
row_upper.push_back(0.0);
|
|
642
|
+
row_type.push_back(Boundtype::kLe);
|
|
643
|
+
} else if (strline[start] == 'N') {
|
|
644
|
+
if (!hasobj) {
|
|
645
|
+
isobj = true;
|
|
646
|
+
hasobj = true;
|
|
647
|
+
cost_row_location = num_row;
|
|
648
|
+
} else {
|
|
649
|
+
isFreeRow = true;
|
|
650
|
+
}
|
|
651
|
+
} else {
|
|
652
|
+
std::string unidentified = strline.substr(start);
|
|
653
|
+
trim(unidentified);
|
|
654
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
655
|
+
"Entry \"%s\" in ROWS section of MPS file is unidentified\n",
|
|
656
|
+
unidentified.c_str());
|
|
657
|
+
return HMpsFF::Parsekey::kFail;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
std::string rowname = first_word(strline, start + 1);
|
|
661
|
+
size_t rowname_end = first_word_end(strline, start + 1);
|
|
662
|
+
|
|
663
|
+
// Detect if file is in fixed format.
|
|
664
|
+
if (!is_end(strline, rowname_end)) {
|
|
665
|
+
std::string name = strline.substr(start + 1);
|
|
666
|
+
name = trim(name);
|
|
667
|
+
if (name.size() > 8)
|
|
668
|
+
return HMpsFF::Parsekey::kFail;
|
|
669
|
+
else
|
|
670
|
+
return HMpsFF::Parsekey::kFixedFormat;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Do not add to matrix if row is free.
|
|
674
|
+
if (isFreeRow) {
|
|
675
|
+
rowname2idx.emplace(rowname, HighsInt{-2});
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// so in rowname2idx -1 is the objective, -2 is all the free rows
|
|
680
|
+
auto ret = rowname2idx.emplace(rowname, isobj ? HighsInt{-1} : (num_row++));
|
|
681
|
+
// ret is a pair consisting of an iterator to the inserted
|
|
682
|
+
// element (or the already-existing element if no insertion
|
|
683
|
+
// happened) and a bool denoting whether the insertion took place
|
|
684
|
+
|
|
685
|
+
// Else is enough here because all free rows are ignored.
|
|
686
|
+
if (!isobj)
|
|
687
|
+
row_names.push_back(rowname);
|
|
688
|
+
else
|
|
689
|
+
objective_name = rowname;
|
|
690
|
+
|
|
691
|
+
if (!ret.second) {
|
|
692
|
+
// Duplicate row name
|
|
693
|
+
if (!has_duplicate_row_name_) {
|
|
694
|
+
// This is the first so record it
|
|
695
|
+
has_duplicate_row_name_ = true;
|
|
696
|
+
auto mit = rowname2idx.find(rowname);
|
|
697
|
+
assert(mit != rowname2idx.end());
|
|
698
|
+
duplicate_row_name_ = rowname;
|
|
699
|
+
duplicate_row_name_index0_ = mit->second;
|
|
700
|
+
duplicate_row_name_index1_ = num_row - 1;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// Hard to imagine how the following lines are executed
|
|
706
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
707
|
+
"Anomalous exit when parsing BOUNDS section of MPS file\n");
|
|
708
|
+
assert(1 == 0);
|
|
709
|
+
// Update num_row in case there is free rows. They won't be added to the
|
|
710
|
+
// constraint matrix.
|
|
711
|
+
num_row = row_lower.size();
|
|
712
|
+
return HMpsFF::Parsekey::kFail;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
typename HMpsFF::Parsekey HMpsFF::parseCols(const HighsLogOptions& log_options,
|
|
716
|
+
std::istream& file) {
|
|
717
|
+
std::string colname = "";
|
|
718
|
+
std::string strline, word;
|
|
719
|
+
HighsInt rowidx;
|
|
720
|
+
size_t start, end;
|
|
721
|
+
bool integral_cols = false;
|
|
722
|
+
assert(num_col == 0);
|
|
723
|
+
// Define the scattered value vector, index vector and count
|
|
724
|
+
std::vector<double> col_value;
|
|
725
|
+
std::vector<HighsInt> col_index;
|
|
726
|
+
HighsInt col_count = 0;
|
|
727
|
+
double col_cost = 0;
|
|
728
|
+
col_value.assign(num_row, 0);
|
|
729
|
+
col_index.resize(num_row);
|
|
730
|
+
|
|
731
|
+
auto parseName = [&rowidx, this](std::string name) {
|
|
732
|
+
auto mit = rowname2idx.find(name);
|
|
733
|
+
|
|
734
|
+
assert(mit != rowname2idx.end());
|
|
735
|
+
rowidx = mit->second;
|
|
736
|
+
|
|
737
|
+
if (rowidx >= 0)
|
|
738
|
+
this->num_nz++;
|
|
739
|
+
else
|
|
740
|
+
assert(-1 == rowidx || -2 == rowidx);
|
|
741
|
+
};
|
|
742
|
+
|
|
743
|
+
bool skip;
|
|
744
|
+
size_t num_ignored_row_name = 0;
|
|
745
|
+
size_t report_ignored_row_name_frequency = 1;
|
|
746
|
+
size_t num_ignored_duplicate_cost_nz = 0;
|
|
747
|
+
size_t report_ignored_duplicate_cost_nz_frequency = 1;
|
|
748
|
+
size_t num_ignored_duplicate_matrix_nz = 0;
|
|
749
|
+
size_t report_ignored_duplicate_matrix_nz_frequency = 1;
|
|
750
|
+
while (getMpsLine(file, strline, skip)) {
|
|
751
|
+
if (skip) continue;
|
|
752
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
753
|
+
|
|
754
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, start, end, word);
|
|
755
|
+
|
|
756
|
+
// start of new section?
|
|
757
|
+
if (key != Parsekey::kNone) {
|
|
758
|
+
if (num_col) {
|
|
759
|
+
if (col_cost) {
|
|
760
|
+
coeffobj.push_back(std::make_pair(num_col - 1, col_cost));
|
|
761
|
+
col_cost = 0;
|
|
762
|
+
}
|
|
763
|
+
for (HighsInt iEl = 0; iEl < col_count; iEl++) {
|
|
764
|
+
const HighsInt iRow = col_index[iEl];
|
|
765
|
+
assert(col_value[iRow]);
|
|
766
|
+
entries.push_back(
|
|
767
|
+
std::make_tuple(num_col - 1, iRow, col_value[iRow]));
|
|
768
|
+
col_value[iRow] = 0;
|
|
769
|
+
}
|
|
770
|
+
col_count = 0;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
warning_issued_ = num_ignored_row_name > 0 ||
|
|
774
|
+
num_ignored_duplicate_cost_nz > 0 ||
|
|
775
|
+
num_ignored_duplicate_matrix_nz > 0;
|
|
776
|
+
if (warning_issued_)
|
|
777
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
778
|
+
"COLUMNS section: ignored %d undefined rows %d duplicate "
|
|
779
|
+
"cost values and %d duplicate matrix values\n",
|
|
780
|
+
int(num_ignored_row_name),
|
|
781
|
+
int(num_ignored_duplicate_cost_nz),
|
|
782
|
+
int(num_ignored_duplicate_matrix_nz));
|
|
783
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
784
|
+
"readMPS: Read COLUMNS OK\n");
|
|
785
|
+
return key;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
// check for integrality marker
|
|
789
|
+
std::string marker = first_word(strline, end);
|
|
790
|
+
size_t end_marker = first_word_end(strline, end);
|
|
791
|
+
|
|
792
|
+
if (marker == "'MARKER'") {
|
|
793
|
+
marker = first_word(strline, end_marker);
|
|
794
|
+
|
|
795
|
+
if ((integral_cols && marker != "'INTEND'") ||
|
|
796
|
+
(!integral_cols && marker != "'INTORG'")) {
|
|
797
|
+
highsLogUser(
|
|
798
|
+
log_options, HighsLogType::kError,
|
|
799
|
+
"Integrality marker error in COLUMNS section of MPS file\n");
|
|
800
|
+
return Parsekey::kFail;
|
|
801
|
+
}
|
|
802
|
+
integral_cols = !integral_cols;
|
|
803
|
+
|
|
804
|
+
continue;
|
|
805
|
+
}
|
|
806
|
+
// Detect whether the file is in fixed format with spaces in
|
|
807
|
+
// names, even if there are no known examples!
|
|
808
|
+
//
|
|
809
|
+
// end_marker should be the end index of the row name:
|
|
810
|
+
//
|
|
811
|
+
// If the names are at least 8 characters, end_marker should be
|
|
812
|
+
// more than 13 minus the 4 whitespaces we have trimmed from the
|
|
813
|
+
// start so more than 9
|
|
814
|
+
//
|
|
815
|
+
// However, free format MPS can have names with only one character
|
|
816
|
+
// (pyomo.mps). Have to distinguish this from 8-character names
|
|
817
|
+
// with spaces. Best bet is to see whether "marker" is in the set
|
|
818
|
+
// of row names. If it is, then assume that the names are short
|
|
819
|
+
if (end_marker < 9) {
|
|
820
|
+
auto mit = rowname2idx.find(marker);
|
|
821
|
+
if (mit == rowname2idx.end()) {
|
|
822
|
+
// marker is not a row name, so continue to look at name
|
|
823
|
+
std::string name = strline.substr(0, 10);
|
|
824
|
+
// Delete trailing spaces
|
|
825
|
+
name = trim(name);
|
|
826
|
+
if (name.size() > 8) {
|
|
827
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
828
|
+
"Row name \"%s\" with spaces exceeds fixed format name "
|
|
829
|
+
"length of 8\n",
|
|
830
|
+
name.c_str());
|
|
831
|
+
return HMpsFF::Parsekey::kFail;
|
|
832
|
+
} else {
|
|
833
|
+
warning_issued_ = true;
|
|
834
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
835
|
+
"Row name \"%s\" with spaces has length %d, so assume "
|
|
836
|
+
"fixed format\n",
|
|
837
|
+
name.c_str(), (int)name.size());
|
|
838
|
+
return HMpsFF::Parsekey::kFixedFormat;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
// Test for new column
|
|
844
|
+
if (!(word == colname)) {
|
|
845
|
+
// Record the nonzeros in any previous column
|
|
846
|
+
if (num_col) {
|
|
847
|
+
if (col_cost) {
|
|
848
|
+
coeffobj.push_back(std::make_pair(num_col - 1, col_cost));
|
|
849
|
+
col_cost = 0;
|
|
850
|
+
}
|
|
851
|
+
for (HighsInt iEl = 0; iEl < col_count; iEl++) {
|
|
852
|
+
const HighsInt iRow = col_index[iEl];
|
|
853
|
+
assert(col_value[iRow]);
|
|
854
|
+
entries.push_back(
|
|
855
|
+
std::make_tuple(num_col - 1, iRow, col_value[iRow]));
|
|
856
|
+
col_value[iRow] = 0;
|
|
857
|
+
}
|
|
858
|
+
col_count = 0;
|
|
859
|
+
}
|
|
860
|
+
assert(!col_cost);
|
|
861
|
+
colname = word;
|
|
862
|
+
auto ret = colname2idx.emplace(colname, num_col++);
|
|
863
|
+
col_names.push_back(colname);
|
|
864
|
+
if (!ret.second) {
|
|
865
|
+
// Duplicate col name
|
|
866
|
+
if (!has_duplicate_col_name_) {
|
|
867
|
+
// This is the first so record it
|
|
868
|
+
has_duplicate_col_name_ = true;
|
|
869
|
+
auto mit = colname2idx.find(colname);
|
|
870
|
+
assert(mit != colname2idx.end());
|
|
871
|
+
duplicate_col_name_ = colname;
|
|
872
|
+
duplicate_col_name_index0_ = mit->second;
|
|
873
|
+
duplicate_col_name_index1_ = num_col - 1;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
// Mark the column as integer, according to whether
|
|
878
|
+
// the integral_cols flag is set
|
|
879
|
+
col_integrality.push_back(integral_cols ? HighsVarType::kInteger
|
|
880
|
+
: HighsVarType::kContinuous);
|
|
881
|
+
// Mark the column as binary as well
|
|
882
|
+
col_binary.push_back(integral_cols && kintegerVarsInColumnsAreBinary);
|
|
883
|
+
|
|
884
|
+
// initialize with default bounds
|
|
885
|
+
col_lower.push_back(0.0);
|
|
886
|
+
col_upper.push_back(kHighsInf);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
assert(num_col > 0);
|
|
890
|
+
|
|
891
|
+
// here marker is the row name and end marks its end
|
|
892
|
+
word = "";
|
|
893
|
+
word = first_word(strline, end_marker);
|
|
894
|
+
end = first_word_end(strline, end_marker);
|
|
895
|
+
|
|
896
|
+
if (word == "") {
|
|
897
|
+
trim(marker);
|
|
898
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
899
|
+
"No coefficient given for column \"%s\"\n", marker.c_str());
|
|
900
|
+
return HMpsFF::Parsekey::kFail;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
auto mit = rowname2idx.find(marker);
|
|
904
|
+
if (mit == rowname2idx.end()) {
|
|
905
|
+
num_ignored_row_name++;
|
|
906
|
+
if (num_ignored_row_name % report_ignored_row_name_frequency == 0) {
|
|
907
|
+
highsLogUser(
|
|
908
|
+
log_options, HighsLogType::kWarning,
|
|
909
|
+
"Row name \"%s\" in COLUMNS section is not defined: ignored\n",
|
|
910
|
+
marker.c_str());
|
|
911
|
+
report_ignored_row_name_frequency *= 2;
|
|
912
|
+
}
|
|
913
|
+
} else {
|
|
914
|
+
bool is_nan = false;
|
|
915
|
+
double value = getValue(word, is_nan); // atof(word.c_str());
|
|
916
|
+
if (is_nan) {
|
|
917
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
918
|
+
"Coefficient for column \"%s\" is NaN\n", marker.c_str());
|
|
919
|
+
return HMpsFF::Parsekey::kFail;
|
|
920
|
+
}
|
|
921
|
+
if (value) {
|
|
922
|
+
parseName(marker); // rowidx set and num_nz incremented
|
|
923
|
+
if (rowidx >= 0) {
|
|
924
|
+
if (col_value[rowidx]) {
|
|
925
|
+
// Ignore duplicate entry
|
|
926
|
+
num_nz--;
|
|
927
|
+
num_ignored_duplicate_matrix_nz++;
|
|
928
|
+
if (num_ignored_duplicate_matrix_nz %
|
|
929
|
+
report_ignored_duplicate_matrix_nz_frequency ==
|
|
930
|
+
0) {
|
|
931
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
932
|
+
"Column \"%s\" has duplicate nonzero %g in row "
|
|
933
|
+
"\"%s\": ignored\n",
|
|
934
|
+
colname.c_str(), value, marker.c_str());
|
|
935
|
+
report_ignored_duplicate_matrix_nz_frequency *= 2;
|
|
936
|
+
}
|
|
937
|
+
} else {
|
|
938
|
+
col_value[rowidx] = value;
|
|
939
|
+
col_index[col_count++] = rowidx;
|
|
940
|
+
}
|
|
941
|
+
} else if (rowidx == -1) {
|
|
942
|
+
// Ignore duplicate entry
|
|
943
|
+
if (col_cost) {
|
|
944
|
+
num_ignored_duplicate_cost_nz++;
|
|
945
|
+
if (num_ignored_duplicate_cost_nz %
|
|
946
|
+
report_ignored_duplicate_cost_nz_frequency ==
|
|
947
|
+
0) {
|
|
948
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
949
|
+
"Column \"%s\" has duplicate nonzero %g in "
|
|
950
|
+
"objective row \"%s\": ignored\n",
|
|
951
|
+
colname.c_str(), value, marker.c_str());
|
|
952
|
+
report_ignored_duplicate_cost_nz_frequency *= 2;
|
|
953
|
+
}
|
|
954
|
+
} else {
|
|
955
|
+
col_cost = value;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
if (!is_end(strline, end)) {
|
|
962
|
+
// parse second coefficient
|
|
963
|
+
marker = first_word(strline, end);
|
|
964
|
+
if (word == "") {
|
|
965
|
+
trim(marker);
|
|
966
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
967
|
+
"No coefficient given for column \"%s\"\n",
|
|
968
|
+
marker.c_str());
|
|
969
|
+
return HMpsFF::Parsekey::kFail;
|
|
970
|
+
}
|
|
971
|
+
end_marker = first_word_end(strline, end);
|
|
972
|
+
|
|
973
|
+
// here marker is the row name and end marks its end
|
|
974
|
+
word = "";
|
|
975
|
+
end_marker++;
|
|
976
|
+
word = first_word(strline, end_marker);
|
|
977
|
+
end = first_word_end(strline, end_marker);
|
|
978
|
+
|
|
979
|
+
assert(is_end(strline, end));
|
|
980
|
+
|
|
981
|
+
auto mit = rowname2idx.find(marker);
|
|
982
|
+
if (mit == rowname2idx.end()) {
|
|
983
|
+
num_ignored_row_name++;
|
|
984
|
+
if (num_ignored_row_name % report_ignored_row_name_frequency == 0) {
|
|
985
|
+
highsLogUser(
|
|
986
|
+
log_options, HighsLogType::kWarning,
|
|
987
|
+
"Row name \"%s\" in COLUMNS section is not defined: ignored\n",
|
|
988
|
+
marker.c_str());
|
|
989
|
+
report_ignored_row_name_frequency *= 2;
|
|
990
|
+
}
|
|
991
|
+
continue;
|
|
992
|
+
};
|
|
993
|
+
bool is_nan = false;
|
|
994
|
+
double value = getValue(word, is_nan); // atof(word.c_str());
|
|
995
|
+
if (is_nan) {
|
|
996
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
997
|
+
"Coefficient for column \"%s\" is NaN\n", marker.c_str());
|
|
998
|
+
return HMpsFF::Parsekey::kFail;
|
|
999
|
+
}
|
|
1000
|
+
if (value) {
|
|
1001
|
+
parseName(marker); // rowidx set and num_nz incremented
|
|
1002
|
+
if (rowidx >= 0) {
|
|
1003
|
+
if (col_value[rowidx]) {
|
|
1004
|
+
// Ignore duplicate entry
|
|
1005
|
+
num_nz--;
|
|
1006
|
+
num_ignored_duplicate_matrix_nz++;
|
|
1007
|
+
if (num_ignored_duplicate_matrix_nz %
|
|
1008
|
+
report_ignored_duplicate_matrix_nz_frequency ==
|
|
1009
|
+
0) {
|
|
1010
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1011
|
+
"Column \"%s\" has duplicate nonzero %g in row "
|
|
1012
|
+
"\"%s\": ignored\n",
|
|
1013
|
+
colname.c_str(), value, marker.c_str());
|
|
1014
|
+
report_ignored_duplicate_matrix_nz_frequency *= 2;
|
|
1015
|
+
}
|
|
1016
|
+
} else {
|
|
1017
|
+
col_value[rowidx] = value;
|
|
1018
|
+
col_index[col_count++] = rowidx;
|
|
1019
|
+
}
|
|
1020
|
+
} else if (rowidx == -1) {
|
|
1021
|
+
// Ignore duplicate entry
|
|
1022
|
+
if (col_cost) {
|
|
1023
|
+
num_ignored_duplicate_cost_nz++;
|
|
1024
|
+
if (num_ignored_duplicate_cost_nz %
|
|
1025
|
+
report_ignored_duplicate_cost_nz_frequency ==
|
|
1026
|
+
0) {
|
|
1027
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1028
|
+
"Column \"%s\" has duplicate nonzero %g in "
|
|
1029
|
+
"objective row \"%s\": ignored\n",
|
|
1030
|
+
colname.c_str(), value, objective_name.c_str());
|
|
1031
|
+
report_ignored_duplicate_cost_nz_frequency *= 2;
|
|
1032
|
+
}
|
|
1033
|
+
} else {
|
|
1034
|
+
col_cost = value;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
return Parsekey::kFail;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
HMpsFF::Parsekey HMpsFF::parseRhs(const HighsLogOptions& log_options,
|
|
1045
|
+
std::istream& file) {
|
|
1046
|
+
std::string strline;
|
|
1047
|
+
|
|
1048
|
+
auto parseName = [this](const std::string& name, HighsInt& rowidx,
|
|
1049
|
+
bool& has_entry) {
|
|
1050
|
+
auto mit = rowname2idx.find(name);
|
|
1051
|
+
|
|
1052
|
+
assert(mit != rowname2idx.end());
|
|
1053
|
+
rowidx = mit->second;
|
|
1054
|
+
|
|
1055
|
+
assert(rowidx < num_row);
|
|
1056
|
+
|
|
1057
|
+
if (rowidx > -1) {
|
|
1058
|
+
has_entry = has_row_entry_[rowidx];
|
|
1059
|
+
} else {
|
|
1060
|
+
assert(rowidx == -1);
|
|
1061
|
+
has_entry = has_obj_entry_;
|
|
1062
|
+
}
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
auto addRhs = [this](double val, HighsInt rowidx) {
|
|
1066
|
+
if (rowidx > -1) {
|
|
1067
|
+
if (row_type[rowidx] == Boundtype::kEq ||
|
|
1068
|
+
row_type[rowidx] == Boundtype::kLe) {
|
|
1069
|
+
assert(size_t(rowidx) < row_upper.size());
|
|
1070
|
+
row_upper[rowidx] = val;
|
|
1071
|
+
}
|
|
1072
|
+
if (row_type[rowidx] == Boundtype::kEq ||
|
|
1073
|
+
row_type[rowidx] == Boundtype::kGe) {
|
|
1074
|
+
assert(size_t(rowidx) < row_lower.size());
|
|
1075
|
+
row_lower[rowidx] = val;
|
|
1076
|
+
}
|
|
1077
|
+
has_row_entry_[rowidx] = true;
|
|
1078
|
+
} else {
|
|
1079
|
+
// objective shift
|
|
1080
|
+
assert(rowidx == -1);
|
|
1081
|
+
obj_offset = -val;
|
|
1082
|
+
has_obj_entry_ = true;
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
// Initialise tracking for duplicate entries
|
|
1087
|
+
has_row_entry_.assign(num_row, false);
|
|
1088
|
+
has_obj_entry_ = false;
|
|
1089
|
+
bool has_entry = false;
|
|
1090
|
+
|
|
1091
|
+
bool skip;
|
|
1092
|
+
size_t num_ignored_row_name = 0;
|
|
1093
|
+
size_t report_ignored_row_name_frequency = 1;
|
|
1094
|
+
size_t num_ignored_duplicate_rhs = 0;
|
|
1095
|
+
size_t report_ignored_duplicate_rhs_frequency = 1;
|
|
1096
|
+
while (getMpsLine(file, strline, skip)) {
|
|
1097
|
+
if (skip) continue;
|
|
1098
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
1099
|
+
|
|
1100
|
+
size_t begin = 0;
|
|
1101
|
+
size_t end = 0;
|
|
1102
|
+
std::string word;
|
|
1103
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, begin, end, word);
|
|
1104
|
+
|
|
1105
|
+
// start of new section?
|
|
1106
|
+
if (key != Parsekey::kNone && key != Parsekey::kRhs) {
|
|
1107
|
+
warning_issued_ =
|
|
1108
|
+
num_ignored_row_name > 0 || num_ignored_duplicate_rhs > 0;
|
|
1109
|
+
if (warning_issued_)
|
|
1110
|
+
highsLogUser(
|
|
1111
|
+
log_options, HighsLogType::kWarning,
|
|
1112
|
+
"RHS section: ignored %d undefined rows and %d duplicate values\n",
|
|
1113
|
+
int(num_ignored_row_name), int(num_ignored_duplicate_rhs));
|
|
1114
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
1115
|
+
"readMPS: Read RHS OK\n");
|
|
1116
|
+
return key;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
// Ignore lack of name for SIF format;
|
|
1120
|
+
// we know we have this case when "word" is a row name
|
|
1121
|
+
if ((key == Parsekey::kNone) && (key != Parsekey::kRhs) &&
|
|
1122
|
+
(rowname2idx.find(word) != rowname2idx.end())) {
|
|
1123
|
+
end = begin;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
HighsInt rowidx;
|
|
1127
|
+
|
|
1128
|
+
std::string marker = first_word(strline, end);
|
|
1129
|
+
size_t end_marker = first_word_end(strline, end);
|
|
1130
|
+
|
|
1131
|
+
// here marker is the row name and end marks its end
|
|
1132
|
+
word = "";
|
|
1133
|
+
word = first_word(strline, end_marker);
|
|
1134
|
+
end = first_word_end(strline, end_marker);
|
|
1135
|
+
|
|
1136
|
+
if (word == "") {
|
|
1137
|
+
trim(marker);
|
|
1138
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1139
|
+
"No bound given for row \"%s\"\n", marker.c_str());
|
|
1140
|
+
return HMpsFF::Parsekey::kFail;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
auto mit = rowname2idx.find(marker);
|
|
1144
|
+
|
|
1145
|
+
// SIF format sometimes has the name of the MPS file
|
|
1146
|
+
// prepended to the RHS entry; remove it here if
|
|
1147
|
+
// that's the case. "word" will then hold the marker,
|
|
1148
|
+
// so also get new "word" and "end" values
|
|
1149
|
+
if (mit == rowname2idx.end()) {
|
|
1150
|
+
if (marker == mps_name) {
|
|
1151
|
+
marker = word;
|
|
1152
|
+
end_marker = end;
|
|
1153
|
+
word = "";
|
|
1154
|
+
word = first_word(strline, end_marker);
|
|
1155
|
+
end = first_word_end(strline, end_marker);
|
|
1156
|
+
if (word == "") {
|
|
1157
|
+
trim(marker);
|
|
1158
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1159
|
+
"No bound given for SIF row \"%s\"\n", marker.c_str());
|
|
1160
|
+
return HMpsFF::Parsekey::kFail;
|
|
1161
|
+
}
|
|
1162
|
+
mit = rowname2idx.find(marker);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
if (mit == rowname2idx.end()) {
|
|
1167
|
+
num_ignored_row_name++;
|
|
1168
|
+
if (num_ignored_row_name % report_ignored_row_name_frequency == 0) {
|
|
1169
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1170
|
+
"Row name \"%s\" in RHS section is not defined: ignored\n",
|
|
1171
|
+
marker.c_str());
|
|
1172
|
+
report_ignored_row_name_frequency *= 2;
|
|
1173
|
+
}
|
|
1174
|
+
} else {
|
|
1175
|
+
bool is_nan = false;
|
|
1176
|
+
double value = getValue(word, is_nan); // atof(word.c_str());
|
|
1177
|
+
parseName(marker, rowidx, has_entry);
|
|
1178
|
+
if (has_entry) {
|
|
1179
|
+
num_ignored_duplicate_rhs++;
|
|
1180
|
+
if (num_ignored_duplicate_rhs %
|
|
1181
|
+
report_ignored_duplicate_rhs_frequency ==
|
|
1182
|
+
0) {
|
|
1183
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1184
|
+
"Row name \"%s\" in RHS section has duplicate value %g: "
|
|
1185
|
+
"ignored\n",
|
|
1186
|
+
marker.c_str(), value);
|
|
1187
|
+
report_ignored_duplicate_rhs_frequency *= 2;
|
|
1188
|
+
}
|
|
1189
|
+
} else {
|
|
1190
|
+
if (is_nan) {
|
|
1191
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1192
|
+
"RHS for row \"%s\" is NaN\n", marker.c_str());
|
|
1193
|
+
return HMpsFF::Parsekey::kFail;
|
|
1194
|
+
}
|
|
1195
|
+
addRhs(value, rowidx);
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
if (!is_end(strline, end)) {
|
|
1200
|
+
// parse second coefficient
|
|
1201
|
+
marker = first_word(strline, end);
|
|
1202
|
+
if (word == "") {
|
|
1203
|
+
trim(marker);
|
|
1204
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1205
|
+
"No coefficient given for rhs of row \"%s\"\n",
|
|
1206
|
+
marker.c_str());
|
|
1207
|
+
return HMpsFF::Parsekey::kFail;
|
|
1208
|
+
}
|
|
1209
|
+
end_marker = first_word_end(strline, end);
|
|
1210
|
+
|
|
1211
|
+
// here marker is the row name and end marks its end
|
|
1212
|
+
word = "";
|
|
1213
|
+
end_marker++;
|
|
1214
|
+
word = first_word(strline, end_marker);
|
|
1215
|
+
end = first_word_end(strline, end_marker);
|
|
1216
|
+
|
|
1217
|
+
assert(is_end(strline, end));
|
|
1218
|
+
|
|
1219
|
+
auto mit = rowname2idx.find(marker);
|
|
1220
|
+
if (mit == rowname2idx.end()) {
|
|
1221
|
+
num_ignored_row_name++;
|
|
1222
|
+
if (num_ignored_row_name % report_ignored_row_name_frequency == 0) {
|
|
1223
|
+
highsLogUser(
|
|
1224
|
+
log_options, HighsLogType::kWarning,
|
|
1225
|
+
"Row name \"%s\" in RHS section is not defined: ignored\n",
|
|
1226
|
+
marker.c_str());
|
|
1227
|
+
report_ignored_row_name_frequency *= 2;
|
|
1228
|
+
}
|
|
1229
|
+
continue;
|
|
1230
|
+
};
|
|
1231
|
+
|
|
1232
|
+
parseName(marker, rowidx, has_entry);
|
|
1233
|
+
bool is_nan = false;
|
|
1234
|
+
double value = getValue(word, is_nan); // atof(word.c_str());
|
|
1235
|
+
if (has_entry) {
|
|
1236
|
+
num_ignored_duplicate_rhs++;
|
|
1237
|
+
if (num_ignored_duplicate_rhs %
|
|
1238
|
+
report_ignored_duplicate_rhs_frequency ==
|
|
1239
|
+
0) {
|
|
1240
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1241
|
+
"Row name \"%s\" in RHS section has duplicate value %g: "
|
|
1242
|
+
"ignored\n",
|
|
1243
|
+
marker.c_str(), value);
|
|
1244
|
+
report_ignored_duplicate_rhs_frequency *= 2;
|
|
1245
|
+
}
|
|
1246
|
+
} else {
|
|
1247
|
+
if (is_nan) {
|
|
1248
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1249
|
+
"RHS for row \"%s\" is NaN\n", marker.c_str());
|
|
1250
|
+
return HMpsFF::Parsekey::kFail;
|
|
1251
|
+
}
|
|
1252
|
+
addRhs(value, rowidx);
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
return Parsekey::kFail;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
HMpsFF::Parsekey HMpsFF::parseBounds(const HighsLogOptions& log_options,
|
|
1261
|
+
std::istream& file) {
|
|
1262
|
+
std::string strline, word;
|
|
1263
|
+
|
|
1264
|
+
HighsInt num_mi = 0;
|
|
1265
|
+
HighsInt num_pl = 0;
|
|
1266
|
+
HighsInt num_bv = 0;
|
|
1267
|
+
HighsInt num_li = 0;
|
|
1268
|
+
HighsInt num_ui = 0;
|
|
1269
|
+
HighsInt num_si = 0;
|
|
1270
|
+
HighsInt num_sc = 0;
|
|
1271
|
+
|
|
1272
|
+
std::vector<bool> has_lower;
|
|
1273
|
+
std::vector<bool> has_upper;
|
|
1274
|
+
has_lower.assign(num_col, false);
|
|
1275
|
+
has_upper.assign(num_col, false);
|
|
1276
|
+
|
|
1277
|
+
bool skip;
|
|
1278
|
+
size_t num_ignored_duplicate_bound = 0;
|
|
1279
|
+
size_t report_ignored_duplicate_bound_frequency = 1;
|
|
1280
|
+
size_t num_fractional_integer_bound = 0;
|
|
1281
|
+
size_t report_fractional_integer_bound_frequency = 1;
|
|
1282
|
+
while (getMpsLine(file, strline, skip)) {
|
|
1283
|
+
if (skip) continue;
|
|
1284
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
1285
|
+
|
|
1286
|
+
size_t begin = 0;
|
|
1287
|
+
size_t end = 0;
|
|
1288
|
+
std::string word;
|
|
1289
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, begin, end, word);
|
|
1290
|
+
|
|
1291
|
+
// start of new section?
|
|
1292
|
+
if (key != Parsekey::kNone) {
|
|
1293
|
+
if (num_mi)
|
|
1294
|
+
highsLogUser(
|
|
1295
|
+
log_options, HighsLogType::kInfo,
|
|
1296
|
+
"Number of MI entries in BOUNDS section is %" HIGHSINT_FORMAT "\n",
|
|
1297
|
+
num_mi);
|
|
1298
|
+
if (num_pl)
|
|
1299
|
+
highsLogUser(
|
|
1300
|
+
log_options, HighsLogType::kInfo,
|
|
1301
|
+
"Number of PL entries in BOUNDS section is %" HIGHSINT_FORMAT "\n",
|
|
1302
|
+
num_pl);
|
|
1303
|
+
if (num_bv)
|
|
1304
|
+
highsLogUser(
|
|
1305
|
+
log_options, HighsLogType::kInfo,
|
|
1306
|
+
"Number of BV entries in BOUNDS section is %" HIGHSINT_FORMAT "\n",
|
|
1307
|
+
num_bv);
|
|
1308
|
+
if (num_li)
|
|
1309
|
+
highsLogUser(
|
|
1310
|
+
log_options, HighsLogType::kInfo,
|
|
1311
|
+
"Number of LI entries in BOUNDS section is %" HIGHSINT_FORMAT "\n",
|
|
1312
|
+
num_li);
|
|
1313
|
+
if (num_ui)
|
|
1314
|
+
highsLogUser(
|
|
1315
|
+
log_options, HighsLogType::kInfo,
|
|
1316
|
+
"Number of UI entries in BOUNDS section is %" HIGHSINT_FORMAT "\n",
|
|
1317
|
+
num_ui);
|
|
1318
|
+
if (num_si)
|
|
1319
|
+
highsLogUser(
|
|
1320
|
+
log_options, HighsLogType::kInfo,
|
|
1321
|
+
"Number of SI entries in BOUNDS section is %" HIGHSINT_FORMAT "\n",
|
|
1322
|
+
num_si);
|
|
1323
|
+
if (num_sc)
|
|
1324
|
+
highsLogUser(
|
|
1325
|
+
log_options, HighsLogType::kInfo,
|
|
1326
|
+
"Number of SC entries in BOUNDS section is %" HIGHSINT_FORMAT "\n",
|
|
1327
|
+
num_sc);
|
|
1328
|
+
warning_issued_ =
|
|
1329
|
+
num_ignored_duplicate_bound || num_fractional_integer_bound > 0;
|
|
1330
|
+
if (warning_issued_)
|
|
1331
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1332
|
+
"BOUNDS section: ignored %d duplicate values and %d "
|
|
1333
|
+
"fractional integer bounds\n",
|
|
1334
|
+
int(num_ignored_duplicate_bound),
|
|
1335
|
+
int(num_fractional_integer_bound));
|
|
1336
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
1337
|
+
"readMPS: Read BOUNDS OK\n");
|
|
1338
|
+
return key;
|
|
1339
|
+
}
|
|
1340
|
+
bool is_lb = false;
|
|
1341
|
+
bool is_ub = false;
|
|
1342
|
+
bool is_integral = false;
|
|
1343
|
+
bool is_semi = false;
|
|
1344
|
+
bool is_defaultbound = false;
|
|
1345
|
+
const std::string bound_type = word;
|
|
1346
|
+
if (word == "UP") // lower bound
|
|
1347
|
+
is_ub = true;
|
|
1348
|
+
else if (word == "LO") // upper bound
|
|
1349
|
+
is_lb = true;
|
|
1350
|
+
else if (word == "FX") // fixed
|
|
1351
|
+
{
|
|
1352
|
+
is_lb = true;
|
|
1353
|
+
is_ub = true;
|
|
1354
|
+
} else if (word == "MI") // infinite lower bound
|
|
1355
|
+
{
|
|
1356
|
+
is_lb = true;
|
|
1357
|
+
is_defaultbound = true;
|
|
1358
|
+
num_mi++;
|
|
1359
|
+
} else if (word == "PL") // infinite upper bound (redundant)
|
|
1360
|
+
{
|
|
1361
|
+
is_ub = true;
|
|
1362
|
+
is_defaultbound = true;
|
|
1363
|
+
num_pl++;
|
|
1364
|
+
} else if (word == "BV") // binary
|
|
1365
|
+
{
|
|
1366
|
+
is_lb = true;
|
|
1367
|
+
is_ub = true;
|
|
1368
|
+
is_integral = true;
|
|
1369
|
+
is_defaultbound = true;
|
|
1370
|
+
num_bv++;
|
|
1371
|
+
} else if (word == "LI") // integer lower bound
|
|
1372
|
+
{
|
|
1373
|
+
is_lb = true;
|
|
1374
|
+
is_integral = true;
|
|
1375
|
+
num_li++;
|
|
1376
|
+
} else if (word == "UI") // integer upper bound
|
|
1377
|
+
{
|
|
1378
|
+
is_ub = true;
|
|
1379
|
+
is_integral = true;
|
|
1380
|
+
num_ui++;
|
|
1381
|
+
} else if (word == "FR") // free variable
|
|
1382
|
+
{
|
|
1383
|
+
is_lb = true;
|
|
1384
|
+
is_ub = true;
|
|
1385
|
+
is_defaultbound = true;
|
|
1386
|
+
} else if (word == "SI") // semi-integer variable
|
|
1387
|
+
{
|
|
1388
|
+
is_ub = true;
|
|
1389
|
+
is_integral = true;
|
|
1390
|
+
is_semi = true;
|
|
1391
|
+
num_si++;
|
|
1392
|
+
} else if (word == "SC") // semi-continuous variable
|
|
1393
|
+
{
|
|
1394
|
+
is_ub = true;
|
|
1395
|
+
is_semi = true;
|
|
1396
|
+
num_sc++;
|
|
1397
|
+
} else {
|
|
1398
|
+
trim(word);
|
|
1399
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1400
|
+
"Entry in BOUNDS section of MPS file is of type \"%s\"\n",
|
|
1401
|
+
word.c_str());
|
|
1402
|
+
return HMpsFF::Parsekey::kFail;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
std::string bound_name = first_word(strline, end);
|
|
1406
|
+
size_t end_bound_name = first_word_end(strline, end);
|
|
1407
|
+
|
|
1408
|
+
std::string marker;
|
|
1409
|
+
size_t end_marker;
|
|
1410
|
+
if (colname2idx.find(bound_name) != colname2idx.end()) {
|
|
1411
|
+
// SIF format might not have the bound name, so skip
|
|
1412
|
+
// it here if we found the marker instead
|
|
1413
|
+
marker = bound_name;
|
|
1414
|
+
end_marker = end_bound_name;
|
|
1415
|
+
} else {
|
|
1416
|
+
// The first word is the bound name, which should be ignored.
|
|
1417
|
+
marker = first_word(strline, end_bound_name);
|
|
1418
|
+
end_marker = first_word_end(strline, end_bound_name);
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
// BOUNDS: get column index from name, without adding new column
|
|
1422
|
+
// if not existing yet
|
|
1423
|
+
HighsInt colidx = getColIdx(marker, false);
|
|
1424
|
+
if (colidx < 0) {
|
|
1425
|
+
// add new column if did not exist yet
|
|
1426
|
+
colidx = getColIdx(marker, true);
|
|
1427
|
+
assert(colidx == num_col - 1);
|
|
1428
|
+
has_lower.push_back(false);
|
|
1429
|
+
has_upper.push_back(false);
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
// Determine whether this entry yields a duplicate bound
|
|
1433
|
+
// definition
|
|
1434
|
+
if ((is_lb && has_lower[colidx]) || (is_ub && has_upper[colidx])) {
|
|
1435
|
+
num_ignored_duplicate_bound++;
|
|
1436
|
+
if (num_ignored_duplicate_bound %
|
|
1437
|
+
report_ignored_duplicate_bound_frequency ==
|
|
1438
|
+
0) {
|
|
1439
|
+
highsLogUser(
|
|
1440
|
+
log_options, HighsLogType::kWarning,
|
|
1441
|
+
"Column name \"%s\" in BOUNDS section has duplicate %s bound "
|
|
1442
|
+
"definition: ignored\n",
|
|
1443
|
+
marker.c_str(), is_lb ? "lower" : "upper");
|
|
1444
|
+
report_ignored_duplicate_bound_frequency *= 2;
|
|
1445
|
+
}
|
|
1446
|
+
continue;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
if (is_defaultbound) {
|
|
1450
|
+
// MI, PL, BV or FR
|
|
1451
|
+
if (is_integral)
|
|
1452
|
+
// binary: BV
|
|
1453
|
+
{
|
|
1454
|
+
if (!is_lb || !is_ub) {
|
|
1455
|
+
trim(marker);
|
|
1456
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1457
|
+
"BV row %s but [is_lb, is_ub] = [%1" HIGHSINT_FORMAT
|
|
1458
|
+
", %1" HIGHSINT_FORMAT "]\n",
|
|
1459
|
+
marker.c_str(), is_lb, is_ub);
|
|
1460
|
+
assert(is_lb && is_ub);
|
|
1461
|
+
return HMpsFF::Parsekey::kFail;
|
|
1462
|
+
}
|
|
1463
|
+
assert(is_lb && is_ub);
|
|
1464
|
+
// Mark the column as integer and binary
|
|
1465
|
+
col_integrality[colidx] = HighsVarType::kInteger;
|
|
1466
|
+
col_binary[colidx] = true;
|
|
1467
|
+
assert(col_lower[colidx] == 0.0);
|
|
1468
|
+
col_upper[colidx] = 1.0;
|
|
1469
|
+
} else {
|
|
1470
|
+
// continuous: MI, PL or FR
|
|
1471
|
+
col_binary[colidx] = false;
|
|
1472
|
+
if (is_lb) col_lower[colidx] = -kHighsInf;
|
|
1473
|
+
if (is_ub) col_upper[colidx] = kHighsInf;
|
|
1474
|
+
}
|
|
1475
|
+
if (is_lb) has_lower[colidx] = true;
|
|
1476
|
+
if (is_ub) has_upper[colidx] = true;
|
|
1477
|
+
continue;
|
|
1478
|
+
}
|
|
1479
|
+
// Bounds now are UP, LO, FX, LI, UI, SI or SC
|
|
1480
|
+
// here marker is the col name and end marks its end
|
|
1481
|
+
word = "";
|
|
1482
|
+
word = first_word(strline, end_marker);
|
|
1483
|
+
end = first_word_end(strline, end_marker);
|
|
1484
|
+
|
|
1485
|
+
if (word == "") {
|
|
1486
|
+
trim(marker);
|
|
1487
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1488
|
+
"No bound given for %s row \"%s\"\n", bound_type.c_str(),
|
|
1489
|
+
marker.c_str());
|
|
1490
|
+
return HMpsFF::Parsekey::kFail;
|
|
1491
|
+
}
|
|
1492
|
+
bool is_nan = false;
|
|
1493
|
+
double value = getValue(word, is_nan); // atof(word.c_str());
|
|
1494
|
+
if (is_nan) {
|
|
1495
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1496
|
+
"Bound for column \"%s\" is NaN\n", marker.c_str());
|
|
1497
|
+
return HMpsFF::Parsekey::kFail;
|
|
1498
|
+
}
|
|
1499
|
+
if (is_integral) {
|
|
1500
|
+
assert(is_lb || is_ub || is_semi);
|
|
1501
|
+
// Must be LI, UI or SI, and value should be integer
|
|
1502
|
+
HighsInt i_value = static_cast<HighsInt>(value);
|
|
1503
|
+
double dl = value - i_value;
|
|
1504
|
+
if (dl) {
|
|
1505
|
+
num_fractional_integer_bound++;
|
|
1506
|
+
if (num_fractional_integer_bound %
|
|
1507
|
+
report_fractional_integer_bound_frequency ==
|
|
1508
|
+
0) {
|
|
1509
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1510
|
+
"Bound for LI/UI/SI column \"%s\" is %g: not integer\n",
|
|
1511
|
+
marker.c_str(), value);
|
|
1512
|
+
report_fractional_integer_bound_frequency *= 2;
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
if (is_semi) {
|
|
1516
|
+
// Bound marker SI defines the column as semi-integer
|
|
1517
|
+
col_integrality[colidx] = HighsVarType::kSemiInteger;
|
|
1518
|
+
} else {
|
|
1519
|
+
// Bound marker LI or UI defines the column as integer
|
|
1520
|
+
col_integrality[colidx] = HighsVarType::kInteger;
|
|
1521
|
+
}
|
|
1522
|
+
} else if (is_semi) {
|
|
1523
|
+
// Bound marker SC defines the column as semi-continuous
|
|
1524
|
+
col_integrality[colidx] = HighsVarType::kSemiContinuous;
|
|
1525
|
+
}
|
|
1526
|
+
// Assign the bounds that have been read
|
|
1527
|
+
if (is_lb) {
|
|
1528
|
+
col_lower[colidx] = value;
|
|
1529
|
+
has_lower[colidx] = true;
|
|
1530
|
+
}
|
|
1531
|
+
if (is_ub) {
|
|
1532
|
+
col_upper[colidx] = value;
|
|
1533
|
+
has_upper[colidx] = true;
|
|
1534
|
+
}
|
|
1535
|
+
// Column is not binary by default
|
|
1536
|
+
col_binary[colidx] = false;
|
|
1537
|
+
}
|
|
1538
|
+
return Parsekey::kFail;
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
HMpsFF::Parsekey HMpsFF::parseRanges(const HighsLogOptions& log_options,
|
|
1542
|
+
std::istream& file) {
|
|
1543
|
+
std::string strline, word;
|
|
1544
|
+
|
|
1545
|
+
auto parseName = [this](const std::string& name, HighsInt& rowidx) {
|
|
1546
|
+
auto mit = rowname2idx.find(name);
|
|
1547
|
+
|
|
1548
|
+
assert(mit != rowname2idx.end());
|
|
1549
|
+
rowidx = mit->second;
|
|
1550
|
+
|
|
1551
|
+
assert(rowidx < num_row);
|
|
1552
|
+
};
|
|
1553
|
+
|
|
1554
|
+
auto addRhs = [this](double val, HighsInt& rowidx) {
|
|
1555
|
+
if ((row_type[rowidx] == Boundtype::kEq && val < 0) ||
|
|
1556
|
+
row_type[rowidx] == Boundtype::kLe) {
|
|
1557
|
+
assert(row_upper.at(rowidx) < kHighsInf);
|
|
1558
|
+
row_lower.at(rowidx) = row_upper.at(rowidx) - fabs(val);
|
|
1559
|
+
} else if ((row_type[rowidx] == Boundtype::kEq && val > 0) ||
|
|
1560
|
+
row_type[rowidx] == Boundtype::kGe) {
|
|
1561
|
+
assert(row_lower.at(rowidx) > (-kHighsInf));
|
|
1562
|
+
row_upper.at(rowidx) = row_lower.at(rowidx) + fabs(val);
|
|
1563
|
+
}
|
|
1564
|
+
has_row_entry_[rowidx] = true;
|
|
1565
|
+
};
|
|
1566
|
+
|
|
1567
|
+
// Initialise tracking for duplicate entries
|
|
1568
|
+
has_row_entry_.assign(num_row, false);
|
|
1569
|
+
|
|
1570
|
+
bool skip;
|
|
1571
|
+
size_t num_ignored_row_name = 0;
|
|
1572
|
+
size_t report_ignored_row_name_frequency = 1;
|
|
1573
|
+
size_t num_ignored_duplicate_range = 0;
|
|
1574
|
+
size_t report_ignored_duplicate_range_frequency = 1;
|
|
1575
|
+
while (getMpsLine(file, strline, skip)) {
|
|
1576
|
+
if (skip) continue;
|
|
1577
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
1578
|
+
|
|
1579
|
+
size_t begin, end;
|
|
1580
|
+
std::string word;
|
|
1581
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, begin, end, word);
|
|
1582
|
+
|
|
1583
|
+
if (key != Parsekey::kNone) {
|
|
1584
|
+
warning_issued_ =
|
|
1585
|
+
num_ignored_row_name > 0 || num_ignored_duplicate_range > 0;
|
|
1586
|
+
if (warning_issued_)
|
|
1587
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1588
|
+
"RANGES section: ignored %d undefined/illegal rows and %d "
|
|
1589
|
+
"duplicate values\n",
|
|
1590
|
+
int(num_ignored_row_name),
|
|
1591
|
+
int(num_ignored_duplicate_range));
|
|
1592
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
1593
|
+
"readMPS: Read RANGES OK\n");
|
|
1594
|
+
return key;
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
HighsInt rowidx;
|
|
1598
|
+
|
|
1599
|
+
std::string marker = first_word(strline, end);
|
|
1600
|
+
size_t end_marker = first_word_end(strline, end);
|
|
1601
|
+
|
|
1602
|
+
// here marker is the row name and end marks its end
|
|
1603
|
+
word = "";
|
|
1604
|
+
word = first_word(strline, end_marker);
|
|
1605
|
+
end = first_word_end(strline, end_marker);
|
|
1606
|
+
|
|
1607
|
+
if (word == "") {
|
|
1608
|
+
trim(marker);
|
|
1609
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1610
|
+
"No range given for row \"%s\"\n", marker.c_str());
|
|
1611
|
+
return HMpsFF::Parsekey::kFail;
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
auto mit = rowname2idx.find(marker);
|
|
1615
|
+
if (mit == rowname2idx.end()) {
|
|
1616
|
+
num_ignored_row_name++;
|
|
1617
|
+
if (num_ignored_row_name % report_ignored_row_name_frequency == 0) {
|
|
1618
|
+
highsLogUser(
|
|
1619
|
+
log_options, HighsLogType::kWarning,
|
|
1620
|
+
"Row name \"%s\" in RANGES section is not defined: ignored\n",
|
|
1621
|
+
marker.c_str());
|
|
1622
|
+
report_ignored_row_name_frequency *= 2;
|
|
1623
|
+
}
|
|
1624
|
+
} else {
|
|
1625
|
+
parseName(marker, rowidx);
|
|
1626
|
+
if (rowidx < 0) {
|
|
1627
|
+
num_ignored_row_name++;
|
|
1628
|
+
if (num_ignored_row_name % report_ignored_row_name_frequency == 0) {
|
|
1629
|
+
highsLogUser(
|
|
1630
|
+
log_options, HighsLogType::kWarning,
|
|
1631
|
+
"Row name \"%s\" in RANGES section is not valid: ignored\n",
|
|
1632
|
+
marker.c_str());
|
|
1633
|
+
report_ignored_row_name_frequency *= 2;
|
|
1634
|
+
}
|
|
1635
|
+
} else {
|
|
1636
|
+
bool is_nan = false;
|
|
1637
|
+
double value = getValue(word, is_nan); // atof(word.c_str());
|
|
1638
|
+
if (has_row_entry_[rowidx]) {
|
|
1639
|
+
num_ignored_duplicate_range++;
|
|
1640
|
+
if (num_ignored_duplicate_range %
|
|
1641
|
+
report_ignored_duplicate_range_frequency ==
|
|
1642
|
+
0) {
|
|
1643
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1644
|
+
"Row name \"%s\" in RANGES section has duplicate "
|
|
1645
|
+
"value %g: ignored\n",
|
|
1646
|
+
marker.c_str(), value);
|
|
1647
|
+
report_ignored_duplicate_range_frequency *= 2;
|
|
1648
|
+
}
|
|
1649
|
+
} else {
|
|
1650
|
+
if (is_nan) {
|
|
1651
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1652
|
+
"Range for row \"%s\" is NaN\n", marker.c_str());
|
|
1653
|
+
return HMpsFF::Parsekey::kFail;
|
|
1654
|
+
}
|
|
1655
|
+
addRhs(value, rowidx);
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
if (!is_end(strline, end)) {
|
|
1661
|
+
std::string marker = first_word(strline, end);
|
|
1662
|
+
size_t end_marker = first_word_end(strline, end);
|
|
1663
|
+
|
|
1664
|
+
// here marker is the row name and end marks its end
|
|
1665
|
+
word = "";
|
|
1666
|
+
word = first_word(strline, end_marker);
|
|
1667
|
+
end = first_word_end(strline, end_marker);
|
|
1668
|
+
|
|
1669
|
+
if (word == "") {
|
|
1670
|
+
trim(marker);
|
|
1671
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1672
|
+
"No range given for row \"%s\"\n", marker.c_str());
|
|
1673
|
+
return HMpsFF::Parsekey::kFail;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
auto mit = rowname2idx.find(marker);
|
|
1677
|
+
if (mit == rowname2idx.end()) {
|
|
1678
|
+
num_ignored_row_name++;
|
|
1679
|
+
if (num_ignored_row_name % report_ignored_row_name_frequency == 0) {
|
|
1680
|
+
highsLogUser(
|
|
1681
|
+
log_options, HighsLogType::kWarning,
|
|
1682
|
+
"Row name \"%s\" in RANGES section is not defined: ignored\n",
|
|
1683
|
+
marker.c_str());
|
|
1684
|
+
report_ignored_row_name_frequency *= 2;
|
|
1685
|
+
}
|
|
1686
|
+
} else {
|
|
1687
|
+
parseName(marker, rowidx);
|
|
1688
|
+
if (rowidx < 0) {
|
|
1689
|
+
num_ignored_row_name++;
|
|
1690
|
+
if (num_ignored_row_name % report_ignored_row_name_frequency == 0) {
|
|
1691
|
+
highsLogUser(
|
|
1692
|
+
log_options, HighsLogType::kWarning,
|
|
1693
|
+
"Row name \"%s\" in RANGES section is not valid: ignored\n",
|
|
1694
|
+
marker.c_str());
|
|
1695
|
+
report_ignored_row_name_frequency *= 2;
|
|
1696
|
+
}
|
|
1697
|
+
} else {
|
|
1698
|
+
bool is_nan = false;
|
|
1699
|
+
double value = getValue(word, is_nan); // atof(word.c_str());
|
|
1700
|
+
if (has_row_entry_[rowidx]) {
|
|
1701
|
+
num_ignored_duplicate_range++;
|
|
1702
|
+
if (num_ignored_duplicate_range %
|
|
1703
|
+
report_ignored_duplicate_range_frequency ==
|
|
1704
|
+
0) {
|
|
1705
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1706
|
+
"Row name \"%s\" in RANGES section has duplicate "
|
|
1707
|
+
"value %g: ignored\n",
|
|
1708
|
+
marker.c_str(), value);
|
|
1709
|
+
report_ignored_duplicate_range_frequency *= 2;
|
|
1710
|
+
}
|
|
1711
|
+
} else {
|
|
1712
|
+
if (is_nan) {
|
|
1713
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1714
|
+
"Range for row \"%s\" is NaN\n", marker.c_str());
|
|
1715
|
+
return HMpsFF::Parsekey::kFail;
|
|
1716
|
+
}
|
|
1717
|
+
addRhs(value, rowidx);
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
if (!is_end(strline, end)) {
|
|
1723
|
+
trim(marker);
|
|
1724
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1725
|
+
"Unknown specifiers in RANGES section for row \"%s\"\n",
|
|
1726
|
+
marker.c_str());
|
|
1727
|
+
return HMpsFF::Parsekey::kFail;
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
return HMpsFF::Parsekey::kFail;
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
typename HMpsFF::Parsekey HMpsFF::parseHessian(
|
|
1736
|
+
const HighsLogOptions& log_options, std::istream& file,
|
|
1737
|
+
const HMpsFF::Parsekey keyword) {
|
|
1738
|
+
assert(keyword == HMpsFF::Parsekey::kQuadobj ||
|
|
1739
|
+
keyword == HMpsFF::Parsekey::kQmatrix);
|
|
1740
|
+
const std::string section_name =
|
|
1741
|
+
keyword == HMpsFF::Parsekey::kQuadobj ? "QUADOBJ" : "QMATRIX";
|
|
1742
|
+
return parseQuadMatrix(log_options, file, section_name, q_entries);
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
typename HMpsFF::Parsekey HMpsFF::parseQuadRows(
|
|
1746
|
+
const HighsLogOptions& log_options, std::istream& file,
|
|
1747
|
+
const HMpsFF::Parsekey keyword) {
|
|
1748
|
+
assert(keyword == HMpsFF::Parsekey::kQsection ||
|
|
1749
|
+
keyword == HMpsFF::Parsekey::kQcmatrix);
|
|
1750
|
+
const std::string section_name =
|
|
1751
|
+
keyword == HMpsFF::Parsekey::kQsection ? "QSECTION" : "QCMATRIX";
|
|
1752
|
+
std::string strline;
|
|
1753
|
+
std::string col_name;
|
|
1754
|
+
HighsInt rowidx; // index of quadratic row
|
|
1755
|
+
|
|
1756
|
+
// Get row name from section argument
|
|
1757
|
+
std::string rowname = first_word(section_args, 0);
|
|
1758
|
+
if (rowname.empty()) {
|
|
1759
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1760
|
+
"No row name given in argument of %s\n", section_name.c_str());
|
|
1761
|
+
return HMpsFF::Parsekey::kFail;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
auto mit = rowname2idx.find(rowname);
|
|
1765
|
+
// if row of section does not exist or is free (index -2), then skip
|
|
1766
|
+
if (mit == rowname2idx.end() || mit->second == HighsInt{-2}) {
|
|
1767
|
+
if (mit == rowname2idx.end()) {
|
|
1768
|
+
warning_issued_ = true;
|
|
1769
|
+
highsLogUser(log_options, HighsLogType::kWarning,
|
|
1770
|
+
"Row name \"%s\" in %s section is not defined: ignored\n",
|
|
1771
|
+
rowname.c_str(), section_name.c_str());
|
|
1772
|
+
}
|
|
1773
|
+
// read lines until start of new section
|
|
1774
|
+
bool skip;
|
|
1775
|
+
while (getMpsLine(file, strline, skip)) {
|
|
1776
|
+
if (skip) continue;
|
|
1777
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
1778
|
+
|
|
1779
|
+
size_t begin = 0;
|
|
1780
|
+
size_t end = 0;
|
|
1781
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, begin, end, col_name);
|
|
1782
|
+
|
|
1783
|
+
// start of new section?
|
|
1784
|
+
if (key != Parsekey::kNone) {
|
|
1785
|
+
highsLogDev(log_options, HighsLogType::kInfo, "readMPS: Read %s OK\n",
|
|
1786
|
+
section_name.c_str());
|
|
1787
|
+
return key;
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
return Parsekey::kFail; // unexpected end of file
|
|
1791
|
+
}
|
|
1792
|
+
rowidx = mit->second;
|
|
1793
|
+
assert(rowidx >= -1);
|
|
1794
|
+
assert(rowidx < num_row);
|
|
1795
|
+
|
|
1796
|
+
if (rowidx >= 0) qrows_entries.resize(num_row);
|
|
1797
|
+
assert(rowidx == -1 || qrows_entries.size() == static_cast<size_t>(num_row));
|
|
1798
|
+
|
|
1799
|
+
auto& qentries = (rowidx == -1 ? q_entries : qrows_entries[rowidx]);
|
|
1800
|
+
return parseQuadMatrix(log_options, file, section_name, qentries);
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
typename HMpsFF::Parsekey HMpsFF::parseQuadMatrix(
|
|
1804
|
+
const HighsLogOptions& log_options, std::istream& file,
|
|
1805
|
+
const std::string& section_name, std::vector<Triplet>& q_entries) {
|
|
1806
|
+
// Store all nonzeros in the section. QMATRIX/QCMATRIX should have
|
|
1807
|
+
// all entries, whereas every off-diagonal QUADOBJ/QSECTION entry
|
|
1808
|
+
// also defines its entry in the opposite triangle, so add this
|
|
1809
|
+
// explicitly to unify the record regardless of section
|
|
1810
|
+
const bool triangular =
|
|
1811
|
+
section_name == "QUADOBJ" || section_name == "QSECTION";
|
|
1812
|
+
std::string strline;
|
|
1813
|
+
std::string col_name;
|
|
1814
|
+
std::string row_name;
|
|
1815
|
+
std::string coeff_name;
|
|
1816
|
+
size_t end_row_name;
|
|
1817
|
+
size_t end_coeff_name;
|
|
1818
|
+
HighsInt colidx, rowidx;
|
|
1819
|
+
|
|
1820
|
+
bool skip;
|
|
1821
|
+
while (getMpsLine(file, strline, skip)) {
|
|
1822
|
+
if (skip) continue;
|
|
1823
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
1824
|
+
|
|
1825
|
+
size_t begin = 0;
|
|
1826
|
+
size_t end = 0;
|
|
1827
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, begin, end, col_name);
|
|
1828
|
+
|
|
1829
|
+
// start of new section?
|
|
1830
|
+
if (key != Parsekey::kNone) {
|
|
1831
|
+
highsLogDev(log_options, HighsLogType::kInfo, "readMPS: Read %s OK\n",
|
|
1832
|
+
section_name.c_str());
|
|
1833
|
+
return key;
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
// Get the column index from the name
|
|
1837
|
+
colidx = getColIdx(col_name);
|
|
1838
|
+
assert(colidx >= 0 && colidx < num_col);
|
|
1839
|
+
|
|
1840
|
+
// Loop over the maximum of two entries per row of the file
|
|
1841
|
+
for (int entry = 0; entry < 2; entry++) {
|
|
1842
|
+
// Get the row name
|
|
1843
|
+
row_name = "";
|
|
1844
|
+
row_name = first_word(strline, end);
|
|
1845
|
+
end_row_name = first_word_end(strline, end);
|
|
1846
|
+
|
|
1847
|
+
if (row_name == "") break;
|
|
1848
|
+
|
|
1849
|
+
coeff_name = "";
|
|
1850
|
+
coeff_name = first_word(strline, end_row_name);
|
|
1851
|
+
end_coeff_name = first_word_end(strline, end_row_name);
|
|
1852
|
+
|
|
1853
|
+
if (coeff_name == "") {
|
|
1854
|
+
trim(row_name);
|
|
1855
|
+
trim(col_name);
|
|
1856
|
+
highsLogUser(
|
|
1857
|
+
log_options, HighsLogType::kError,
|
|
1858
|
+
"%s has no coefficient for entry \"%s\" in column \"%s\"\n",
|
|
1859
|
+
section_name.c_str(), row_name.c_str(), col_name.c_str());
|
|
1860
|
+
return HMpsFF::Parsekey::kFail;
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
rowidx = getColIdx(row_name);
|
|
1864
|
+
assert(rowidx >= 0 && rowidx < num_col);
|
|
1865
|
+
|
|
1866
|
+
bool is_nan = false;
|
|
1867
|
+
double coeff = getValue(coeff_name, is_nan); // atof(word.c_str());
|
|
1868
|
+
if (is_nan) {
|
|
1869
|
+
highsLogUser(
|
|
1870
|
+
log_options, HighsLogType::kError,
|
|
1871
|
+
"Hessian coefficient for entry \"%s\" in column \"%s\" is NaN\n",
|
|
1872
|
+
row_name.c_str(), col_name.c_str());
|
|
1873
|
+
return HMpsFF::Parsekey::kFail;
|
|
1874
|
+
}
|
|
1875
|
+
if (coeff) {
|
|
1876
|
+
q_entries.push_back(std::make_tuple(rowidx, colidx, coeff));
|
|
1877
|
+
// For a triangular section (QUADOBJ/QSECTION), make a
|
|
1878
|
+
// separate record of the entry in the opposite triangle
|
|
1879
|
+
if (triangular && rowidx != colidx)
|
|
1880
|
+
q_entries.push_back(std::make_tuple(colidx, rowidx, coeff));
|
|
1881
|
+
}
|
|
1882
|
+
end = end_coeff_name;
|
|
1883
|
+
// Don't read more if end of line reached
|
|
1884
|
+
if (end == strline.length()) break;
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
return HMpsFF::Parsekey::kFail;
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
typename HMpsFF::Parsekey HMpsFF::parseCones(const HighsLogOptions& log_options,
|
|
1892
|
+
std::istream& file) {
|
|
1893
|
+
size_t end = 0;
|
|
1894
|
+
|
|
1895
|
+
// first argument should be cone name
|
|
1896
|
+
std::string conename = first_word(section_args, end);
|
|
1897
|
+
end = first_word_end(section_args, end);
|
|
1898
|
+
|
|
1899
|
+
if (conename.empty()) {
|
|
1900
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1901
|
+
"Cone name missing in CSECTION\n");
|
|
1902
|
+
return HMpsFF::Parsekey::kFail;
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
// second argument is cone parameter, but is optional
|
|
1906
|
+
// third argument is cone type
|
|
1907
|
+
std::string secondarg = first_word(section_args, end);
|
|
1908
|
+
end = first_word_end(section_args, end);
|
|
1909
|
+
|
|
1910
|
+
std::string thirdarg = first_word(section_args, end);
|
|
1911
|
+
end = first_word_end(section_args, end);
|
|
1912
|
+
|
|
1913
|
+
std::string coneparam = "0.0";
|
|
1914
|
+
std::string conetypestr;
|
|
1915
|
+
if (thirdarg.empty()) {
|
|
1916
|
+
conetypestr = secondarg;
|
|
1917
|
+
} else {
|
|
1918
|
+
coneparam = secondarg;
|
|
1919
|
+
conetypestr = thirdarg;
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
if (conetypestr.empty()) {
|
|
1923
|
+
trim(section_args);
|
|
1924
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1925
|
+
"Cone type missing in CSECTION %s\n", section_args.c_str());
|
|
1926
|
+
return HMpsFF::Parsekey::kFail;
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
ConeType conetype;
|
|
1930
|
+
if (conetypestr == "ZERO")
|
|
1931
|
+
conetype = ConeType::kZero;
|
|
1932
|
+
else if (conetypestr == "QUAD")
|
|
1933
|
+
conetype = ConeType::kQuad;
|
|
1934
|
+
else if (conetypestr == "RQUAD")
|
|
1935
|
+
conetype = ConeType::kRQuad;
|
|
1936
|
+
else if (conetypestr == "PEXP")
|
|
1937
|
+
conetype = ConeType::kPExp;
|
|
1938
|
+
else if (conetypestr == "PPOW")
|
|
1939
|
+
conetype = ConeType::kPPow;
|
|
1940
|
+
else if (conetypestr == "DEXP")
|
|
1941
|
+
conetype = ConeType::kDExp;
|
|
1942
|
+
else if (conetypestr == "DPOW")
|
|
1943
|
+
conetype = ConeType::kDPow;
|
|
1944
|
+
else {
|
|
1945
|
+
trim(conetypestr);
|
|
1946
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
1947
|
+
"Unrecognized cone type %s\n", conetypestr.c_str());
|
|
1948
|
+
return HMpsFF::Parsekey::kFail;
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
cone_name.push_back(conename);
|
|
1952
|
+
cone_type.push_back(conetype);
|
|
1953
|
+
cone_param.push_back(atof(coneparam.c_str()));
|
|
1954
|
+
cone_entries.push_back(std::vector<HighsInt>());
|
|
1955
|
+
|
|
1956
|
+
// now parse the cone entries: one column per line
|
|
1957
|
+
std::string strline;
|
|
1958
|
+
bool skip;
|
|
1959
|
+
while (getMpsLine(file, strline, skip)) {
|
|
1960
|
+
if (skip) continue;
|
|
1961
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
1962
|
+
|
|
1963
|
+
size_t begin;
|
|
1964
|
+
std::string colname;
|
|
1965
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, begin, end, colname);
|
|
1966
|
+
|
|
1967
|
+
if (key != Parsekey::kNone) {
|
|
1968
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
1969
|
+
"readMPS: Read CSECTION OK\n");
|
|
1970
|
+
return key;
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
// colname -> colidx
|
|
1974
|
+
HighsInt colidx = getColIdx(colname);
|
|
1975
|
+
assert(colidx >= 0);
|
|
1976
|
+
assert(colidx < num_col);
|
|
1977
|
+
|
|
1978
|
+
cone_entries.back().push_back(colidx);
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
return HMpsFF::Parsekey::kFail;
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
typename HMpsFF::Parsekey HMpsFF::parseSos(const HighsLogOptions& log_options,
|
|
1985
|
+
std::istream& file,
|
|
1986
|
+
const HMpsFF::Parsekey keyword) {
|
|
1987
|
+
std::string strline, word;
|
|
1988
|
+
|
|
1989
|
+
bool skip;
|
|
1990
|
+
while (getMpsLine(file, strline, skip)) {
|
|
1991
|
+
if (skip) continue;
|
|
1992
|
+
if (timeout()) return HMpsFF::Parsekey::kTimeout;
|
|
1993
|
+
|
|
1994
|
+
size_t begin, end;
|
|
1995
|
+
std::string word;
|
|
1996
|
+
HMpsFF::Parsekey key = checkFirstWord(strline, begin, end, word);
|
|
1997
|
+
|
|
1998
|
+
if (key != Parsekey::kNone) {
|
|
1999
|
+
highsLogDev(log_options, HighsLogType::kInfo,
|
|
2000
|
+
"readMPS: Read SETS OK\n");
|
|
2001
|
+
return key;
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
if (word == "S1" || word == "S2") {
|
|
2005
|
+
/* a new SOS is starting */
|
|
2006
|
+
std::string sosname = first_word(strline, end);
|
|
2007
|
+
|
|
2008
|
+
if (sosname.empty()) {
|
|
2009
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
2010
|
+
"No name given for SOS\n");
|
|
2011
|
+
return HMpsFF::Parsekey::kFail;
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
sos_type.push_back(word[1] == '1' ? 1 : 2);
|
|
2015
|
+
sos_name.push_back(sosname);
|
|
2016
|
+
sos_entries.push_back(std::vector<std::pair<HighsInt, double> >());
|
|
2017
|
+
continue;
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
/* a SOS is continuing
|
|
2021
|
+
* word is currently the column name and there may be a weight following
|
|
2022
|
+
*/
|
|
2023
|
+
if (sos_entries.empty()) {
|
|
2024
|
+
trim(strline);
|
|
2025
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
2026
|
+
"SOS type specification missing before %s.\n",
|
|
2027
|
+
strline.c_str());
|
|
2028
|
+
return HMpsFF::Parsekey::kFail;
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
std::string colname;
|
|
2032
|
+
|
|
2033
|
+
if (keyword == HMpsFF::Parsekey::kSos) {
|
|
2034
|
+
// first word is column index
|
|
2035
|
+
colname = word;
|
|
2036
|
+
} else {
|
|
2037
|
+
// first word is SOS name, second word is colname, third word is weight
|
|
2038
|
+
// we expect SOS definitions to be contiguous for now
|
|
2039
|
+
if (word != sos_name.back()) {
|
|
2040
|
+
trim(word);
|
|
2041
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
2042
|
+
"SOS specification for SOS %s mixed with SOS %s. This is "
|
|
2043
|
+
"currently not supported.\n",
|
|
2044
|
+
sos_name.back().c_str(), word.c_str());
|
|
2045
|
+
return HMpsFF::Parsekey::kFail;
|
|
2046
|
+
}
|
|
2047
|
+
if (is_end(strline, end)) {
|
|
2048
|
+
trim(strline);
|
|
2049
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
2050
|
+
"Missing variable in SOS specification line %s.\n",
|
|
2051
|
+
strline.c_str());
|
|
2052
|
+
return HMpsFF::Parsekey::kFail;
|
|
2053
|
+
}
|
|
2054
|
+
colname = first_word(strline, end);
|
|
2055
|
+
end = first_word_end(strline, end);
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
// colname -> colidx
|
|
2059
|
+
HighsInt colidx = getColIdx(colname);
|
|
2060
|
+
assert(colidx >= 0);
|
|
2061
|
+
assert(colidx < num_col);
|
|
2062
|
+
|
|
2063
|
+
// last word is weight, allow to omit
|
|
2064
|
+
double weight = 0.0;
|
|
2065
|
+
if (!is_end(strline, end)) {
|
|
2066
|
+
word = first_word(strline, end);
|
|
2067
|
+
bool is_nan = false;
|
|
2068
|
+
weight = getValue(word, is_nan); // atof(word.c_str());
|
|
2069
|
+
if (is_nan) {
|
|
2070
|
+
highsLogUser(log_options, HighsLogType::kError,
|
|
2071
|
+
"Weight for column \"%s\" is NaN\n", colname.c_str());
|
|
2072
|
+
return HMpsFF::Parsekey::kFail;
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
sos_entries.back().push_back(std::make_pair(colidx, weight));
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
return HMpsFF::Parsekey::kFail;
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
bool HMpsFF::allZeroed(const std::vector<double>& value) {
|
|
2083
|
+
for (HighsInt iRow = 0; iRow < num_row; iRow++)
|
|
2084
|
+
if (value[iRow]) return false;
|
|
2085
|
+
return true;
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2088
|
+
double HMpsFF::getValue(const std::string& word, bool& is_nan,
|
|
2089
|
+
const HighsInt id) const {
|
|
2090
|
+
// Lambda to replace any d or D by E
|
|
2091
|
+
auto dD2e = [&](std::string& word) {
|
|
2092
|
+
size_t ix = word.find("D");
|
|
2093
|
+
if (ix != std::string::npos) {
|
|
2094
|
+
word.replace(ix, 1, "E");
|
|
2095
|
+
} else {
|
|
2096
|
+
ix = word.find("d");
|
|
2097
|
+
if (ix != std::string::npos) word.replace(ix, 1, "E");
|
|
2098
|
+
}
|
|
2099
|
+
};
|
|
2100
|
+
|
|
2101
|
+
std::string local_word = word;
|
|
2102
|
+
dD2e(local_word);
|
|
2103
|
+
const double value = atof(local_word.c_str());
|
|
2104
|
+
is_nan = false;
|
|
2105
|
+
// printf("value(%d) = %g\n", int(id), value);
|
|
2106
|
+
// if (std::isnan(value)) return true;
|
|
2107
|
+
// // atof('nan') yields 0 with some Windows compilers, so try a string
|
|
2108
|
+
// // comparison
|
|
2109
|
+
// std::string lower_word = word;
|
|
2110
|
+
// if (str_tolower(lower_word) == "nan") return true;
|
|
2111
|
+
return value;
|
|
2112
|
+
}
|
|
2113
|
+
} // namespace free_format_parser
|