lpsolver 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1165) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/README.md +70 -26
  4. data/ext/lpsolver/Makefile +273 -0
  5. data/ext/lpsolver/ext.c +353 -0
  6. data/ext/lpsolver/ext.o +0 -0
  7. data/ext/lpsolver/extconf.rb +79 -0
  8. data/ext/lpsolver/native.so +0 -0
  9. data/ext/lpsolver-highs/AUTHORS +7 -0
  10. data/ext/lpsolver-highs/BUILD.bazel +243 -0
  11. data/ext/lpsolver-highs/CITATION.cff +29 -0
  12. data/ext/lpsolver-highs/CMakeCache.txt +406 -0
  13. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeCCompiler.cmake +81 -0
  14. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeCXXCompiler.cmake +101 -0
  15. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeDetermineCompilerABI_C.bin +0 -0
  16. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeDetermineCompilerABI_CXX.bin +0 -0
  17. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeSystem.cmake +15 -0
  18. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdC/CMakeCCompilerId.c +904 -0
  19. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdC/a.out +0 -0
  20. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdCXX/CMakeCXXCompilerId.cpp +919 -0
  21. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdCXX/a.out +0 -0
  22. data/ext/lpsolver-highs/CMakeFiles/CMakeConfigureLog.yaml +576 -0
  23. data/ext/lpsolver-highs/CMakeFiles/cmake.check_cache +1 -0
  24. data/ext/lpsolver-highs/CMakeLists.txt +983 -0
  25. data/ext/lpsolver-highs/CODE_OF_CONDUCT.md +128 -0
  26. data/ext/lpsolver-highs/CONTRIBUTING.md +31 -0
  27. data/ext/lpsolver-highs/FEATURES.md +61 -0
  28. data/ext/lpsolver-highs/LICENSE.txt +21 -0
  29. data/ext/lpsolver-highs/MODULE.bazel +38 -0
  30. data/ext/lpsolver-highs/README.md +281 -0
  31. data/ext/lpsolver-highs/THIRD_PARTY_NOTICES.md +78 -0
  32. data/ext/lpsolver-highs/Version.txt +4 -0
  33. data/ext/lpsolver-highs/WORKSPACE +33 -0
  34. data/ext/lpsolver-highs/app/CMakeLists.txt +110 -0
  35. data/ext/lpsolver-highs/app/HighsRuntimeOptions.h +292 -0
  36. data/ext/lpsolver-highs/app/RunHighs.cpp +147 -0
  37. data/ext/lpsolver-highs/app/highs_webdemo_shell.html +73 -0
  38. data/ext/lpsolver-highs/build/bin/highs +0 -0
  39. data/ext/lpsolver-highs/build/include/highs/HConfig.h +22 -0
  40. data/ext/lpsolver-highs/build/include/highs/Highs.h +1812 -0
  41. data/ext/lpsolver-highs/build/include/highs/interfaces/highs_c_api.h +2651 -0
  42. data/ext/lpsolver-highs/build/include/highs/io/Filereader.h +45 -0
  43. data/ext/lpsolver-highs/build/include/highs/io/FilereaderLp.h +49 -0
  44. data/ext/lpsolver-highs/build/include/highs/io/FilereaderMps.h +27 -0
  45. data/ext/lpsolver-highs/build/include/highs/io/HMPSIO.h +78 -0
  46. data/ext/lpsolver-highs/build/include/highs/io/HMpsFF.h +245 -0
  47. data/ext/lpsolver-highs/build/include/highs/io/HighsIO.h +118 -0
  48. data/ext/lpsolver-highs/build/include/highs/io/LoadOptions.h +24 -0
  49. data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/builder.hpp +25 -0
  50. data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/def.hpp +19 -0
  51. data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/model.hpp +68 -0
  52. data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/reader.hpp +10 -0
  53. data/ext/lpsolver-highs/build/include/highs/ipm/IpxSolution.h +32 -0
  54. data/ext/lpsolver-highs/build/include/highs/ipm/IpxWrapper.h +106 -0
  55. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu.h +161 -0
  56. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_factorize.h +247 -0
  57. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_get_factors.h +108 -0
  58. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_initialize.h +119 -0
  59. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_factorize.h +34 -0
  60. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_free.h +19 -0
  61. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_get_factors.h +34 -0
  62. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_initialize.h +46 -0
  63. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_solve_dense.h +29 -0
  64. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_solve_for_update.h +42 -0
  65. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_solve_sparse.h +32 -0
  66. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_update.h +31 -0
  67. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_object.h +30 -0
  68. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_solve_dense.h +75 -0
  69. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_solve_for_update.h +169 -0
  70. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_solve_sparse.h +112 -0
  71. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_update.h +125 -0
  72. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_def.h +39 -0
  73. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_file.h +21 -0
  74. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_internal.h +220 -0
  75. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_list.h +173 -0
  76. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/basiclu_kernel.h +20 -0
  77. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/basiclu_wrapper.h +47 -0
  78. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/basis.h +350 -0
  79. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/conjugate_residuals.h +74 -0
  80. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/control.h +167 -0
  81. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/crossover.h +157 -0
  82. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/diagonal_precond.h +45 -0
  83. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/forrest_tomlin.h +102 -0
  84. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/guess_basis.h +21 -0
  85. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/indexed_vector.h +113 -0
  86. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/info.h +27 -0
  87. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipm.h +94 -0
  88. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_c.h +47 -0
  89. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_config.h +9 -0
  90. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_info.h +111 -0
  91. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_internal.h +89 -0
  92. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_parameters.h +76 -0
  93. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_status.h +57 -0
  94. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/iterate.h +331 -0
  95. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/kkt_solver.h +70 -0
  96. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/kkt_solver_basis.h +66 -0
  97. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/kkt_solver_diag.h +48 -0
  98. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/linear_operator.h +26 -0
  99. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/lp_solver.h +204 -0
  100. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/lu_factorization.h +79 -0
  101. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/lu_update.h +129 -0
  102. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/maxvolume.h +54 -0
  103. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/model.h +413 -0
  104. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/multistream.h +52 -0
  105. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/normal_matrix.h +44 -0
  106. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/power_method.h +44 -0
  107. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/sparse_matrix.h +195 -0
  108. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/sparse_utils.h +58 -0
  109. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/splitted_normal_matrix.h +63 -0
  110. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/starting_basis.h +39 -0
  111. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/symbolic_invert.h +29 -0
  112. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/timer.h +25 -0
  113. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/utils.h +37 -0
  114. data/ext/lpsolver-highs/build/include/highs/lp_data/HConst.h +430 -0
  115. data/ext/lpsolver-highs/build/include/highs/lp_data/HStruct.h +213 -0
  116. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsAnalysis.h +23 -0
  117. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsCallback.h +104 -0
  118. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsCallbackStruct.h +70 -0
  119. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsDebug.h +34 -0
  120. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsIis.h +139 -0
  121. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsInfo.h +421 -0
  122. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsInfoDebug.h +27 -0
  123. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsLp.h +97 -0
  124. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsLpSolverObject.h +47 -0
  125. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsLpUtils.h +330 -0
  126. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsModelUtils.h +129 -0
  127. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsOptions.h +1715 -0
  128. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsRanging.h +43 -0
  129. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsSolution.h +179 -0
  130. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsSolutionDebug.h +87 -0
  131. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsSolve.h +29 -0
  132. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsStatus.h +29 -0
  133. data/ext/lpsolver-highs/build/include/highs/mip/HighsCliqueTable.h +329 -0
  134. data/ext/lpsolver-highs/build/include/highs/mip/HighsConflictPool.h +109 -0
  135. data/ext/lpsolver-highs/build/include/highs/mip/HighsCutGeneration.h +108 -0
  136. data/ext/lpsolver-highs/build/include/highs/mip/HighsCutPool.h +168 -0
  137. data/ext/lpsolver-highs/build/include/highs/mip/HighsDebugSol.h +133 -0
  138. data/ext/lpsolver-highs/build/include/highs/mip/HighsDomain.h +657 -0
  139. data/ext/lpsolver-highs/build/include/highs/mip/HighsDomainChange.h +48 -0
  140. data/ext/lpsolver-highs/build/include/highs/mip/HighsDynamicRowMatrix.h +104 -0
  141. data/ext/lpsolver-highs/build/include/highs/mip/HighsGFkSolve.h +439 -0
  142. data/ext/lpsolver-highs/build/include/highs/mip/HighsImplications.h +194 -0
  143. data/ext/lpsolver-highs/build/include/highs/mip/HighsLpAggregator.h +50 -0
  144. data/ext/lpsolver-highs/build/include/highs/mip/HighsLpRelaxation.h +361 -0
  145. data/ext/lpsolver-highs/build/include/highs/mip/HighsMipAnalysis.h +71 -0
  146. data/ext/lpsolver-highs/build/include/highs/mip/HighsMipSolver.h +159 -0
  147. data/ext/lpsolver-highs/build/include/highs/mip/HighsMipSolverData.h +313 -0
  148. data/ext/lpsolver-highs/build/include/highs/mip/HighsModkSeparator.h +60 -0
  149. data/ext/lpsolver-highs/build/include/highs/mip/HighsNodeQueue.h +312 -0
  150. data/ext/lpsolver-highs/build/include/highs/mip/HighsObjectiveFunction.h +71 -0
  151. data/ext/lpsolver-highs/build/include/highs/mip/HighsPathSeparator.h +39 -0
  152. data/ext/lpsolver-highs/build/include/highs/mip/HighsPrimalHeuristics.h +75 -0
  153. data/ext/lpsolver-highs/build/include/highs/mip/HighsPseudocost.h +366 -0
  154. data/ext/lpsolver-highs/build/include/highs/mip/HighsRedcostFixing.h +42 -0
  155. data/ext/lpsolver-highs/build/include/highs/mip/HighsSearch.h +241 -0
  156. data/ext/lpsolver-highs/build/include/highs/mip/HighsSeparation.h +41 -0
  157. data/ext/lpsolver-highs/build/include/highs/mip/HighsSeparator.h +60 -0
  158. data/ext/lpsolver-highs/build/include/highs/mip/HighsTableauSeparator.h +34 -0
  159. data/ext/lpsolver-highs/build/include/highs/mip/HighsTransformedLp.h +63 -0
  160. data/ext/lpsolver-highs/build/include/highs/mip/MipTimer.h +544 -0
  161. data/ext/lpsolver-highs/build/include/highs/mip/feasibilityjump.hh +800 -0
  162. data/ext/lpsolver-highs/build/include/highs/model/HighsHessian.h +54 -0
  163. data/ext/lpsolver-highs/build/include/highs/model/HighsHessianUtils.h +47 -0
  164. data/ext/lpsolver-highs/build/include/highs/model/HighsModel.h +42 -0
  165. data/ext/lpsolver-highs/build/include/highs/parallel/HighsBinarySemaphore.h +108 -0
  166. data/ext/lpsolver-highs/build/include/highs/parallel/HighsCacheAlign.h +82 -0
  167. data/ext/lpsolver-highs/build/include/highs/parallel/HighsCombinable.h +116 -0
  168. data/ext/lpsolver-highs/build/include/highs/parallel/HighsMutex.h +124 -0
  169. data/ext/lpsolver-highs/build/include/highs/parallel/HighsParallel.h +128 -0
  170. data/ext/lpsolver-highs/build/include/highs/parallel/HighsRaceTimer.h +38 -0
  171. data/ext/lpsolver-highs/build/include/highs/parallel/HighsSchedulerConstants.h +19 -0
  172. data/ext/lpsolver-highs/build/include/highs/parallel/HighsSpinMutex.h +48 -0
  173. data/ext/lpsolver-highs/build/include/highs/parallel/HighsSplitDeque.h +606 -0
  174. data/ext/lpsolver-highs/build/include/highs/parallel/HighsTask.h +170 -0
  175. data/ext/lpsolver-highs/build/include/highs/parallel/HighsTaskExecutor.h +217 -0
  176. data/ext/lpsolver-highs/build/include/highs/pdlp/CupdlpWrapper.h +108 -0
  177. data/ext/lpsolver-highs/build/include/highs/pdlp/HiPdlpTimer.h +155 -0
  178. data/ext/lpsolver-highs/build/include/highs/pdlp/HiPdlpWrapper.h +26 -0
  179. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_cs.h +40 -0
  180. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_defs.h +447 -0
  181. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_linalg.h +189 -0
  182. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_proj.h +19 -0
  183. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_restart.h +31 -0
  184. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_scaling.h +26 -0
  185. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_solver.h +105 -0
  186. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_step.h +37 -0
  187. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_utils.c +1850 -0
  188. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/defs.hpp +222 -0
  189. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/linalg.hpp +61 -0
  190. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/logger.hpp +80 -0
  191. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/pdhg.hpp +358 -0
  192. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/restart.hpp +96 -0
  193. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/scaling.hpp +74 -0
  194. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/solver_results.hpp +65 -0
  195. data/ext/lpsolver-highs/build/include/highs/pdqsort/pdqsort.h +532 -0
  196. data/ext/lpsolver-highs/build/include/highs/presolve/HPresolve.h +505 -0
  197. data/ext/lpsolver-highs/build/include/highs/presolve/HPresolveAnalysis.h +52 -0
  198. data/ext/lpsolver-highs/build/include/highs/presolve/HighsPostsolveStack.h +943 -0
  199. data/ext/lpsolver-highs/build/include/highs/presolve/HighsSymmetry.h +284 -0
  200. data/ext/lpsolver-highs/build/include/highs/presolve/ICrash.h +124 -0
  201. data/ext/lpsolver-highs/build/include/highs/presolve/ICrashUtil.h +62 -0
  202. data/ext/lpsolver-highs/build/include/highs/presolve/ICrashX.h +23 -0
  203. data/ext/lpsolver-highs/build/include/highs/presolve/PresolveComponent.h +90 -0
  204. data/ext/lpsolver-highs/build/include/highs/qpsolver/a_asm.hpp +77 -0
  205. data/ext/lpsolver-highs/build/include/highs/qpsolver/a_quass.hpp +22 -0
  206. data/ext/lpsolver-highs/build/include/highs/qpsolver/basis.hpp +159 -0
  207. data/ext/lpsolver-highs/build/include/highs/qpsolver/crashsolution.hpp +20 -0
  208. data/ext/lpsolver-highs/build/include/highs/qpsolver/dantzigpricing.hpp +80 -0
  209. data/ext/lpsolver-highs/build/include/highs/qpsolver/devexpricing.hpp +108 -0
  210. data/ext/lpsolver-highs/build/include/highs/qpsolver/eventhandler.hpp +30 -0
  211. data/ext/lpsolver-highs/build/include/highs/qpsolver/factor.hpp +408 -0
  212. data/ext/lpsolver-highs/build/include/highs/qpsolver/feasibility_bounded.hpp +114 -0
  213. data/ext/lpsolver-highs/build/include/highs/qpsolver/feasibility_highs.hpp +301 -0
  214. data/ext/lpsolver-highs/build/include/highs/qpsolver/gradient.hpp +46 -0
  215. data/ext/lpsolver-highs/build/include/highs/qpsolver/instance.hpp +70 -0
  216. data/ext/lpsolver-highs/build/include/highs/qpsolver/matrix.hpp +342 -0
  217. data/ext/lpsolver-highs/build/include/highs/qpsolver/perturbation.hpp +15 -0
  218. data/ext/lpsolver-highs/build/include/highs/qpsolver/pricing.hpp +22 -0
  219. data/ext/lpsolver-highs/build/include/highs/qpsolver/qpconst.hpp +34 -0
  220. data/ext/lpsolver-highs/build/include/highs/qpsolver/qpvector.hpp +242 -0
  221. data/ext/lpsolver-highs/build/include/highs/qpsolver/quass.hpp +27 -0
  222. data/ext/lpsolver-highs/build/include/highs/qpsolver/ratiotest.hpp +26 -0
  223. data/ext/lpsolver-highs/build/include/highs/qpsolver/runtime.hpp +45 -0
  224. data/ext/lpsolver-highs/build/include/highs/qpsolver/scaling.hpp +15 -0
  225. data/ext/lpsolver-highs/build/include/highs/qpsolver/settings.hpp +84 -0
  226. data/ext/lpsolver-highs/build/include/highs/qpsolver/snippets.hpp +36 -0
  227. data/ext/lpsolver-highs/build/include/highs/qpsolver/statistics.hpp +30 -0
  228. data/ext/lpsolver-highs/build/include/highs/qpsolver/steepestedgepricing.hpp +173 -0
  229. data/ext/lpsolver-highs/build/include/highs/simplex/HApp.h +550 -0
  230. data/ext/lpsolver-highs/build/include/highs/simplex/HEkk.h +419 -0
  231. data/ext/lpsolver-highs/build/include/highs/simplex/HEkkDual.h +513 -0
  232. data/ext/lpsolver-highs/build/include/highs/simplex/HEkkDualRHS.h +134 -0
  233. data/ext/lpsolver-highs/build/include/highs/simplex/HEkkDualRow.h +201 -0
  234. data/ext/lpsolver-highs/build/include/highs/simplex/HEkkPrimal.h +191 -0
  235. data/ext/lpsolver-highs/build/include/highs/simplex/HSimplex.h +42 -0
  236. data/ext/lpsolver-highs/build/include/highs/simplex/HSimplexDebug.h +48 -0
  237. data/ext/lpsolver-highs/build/include/highs/simplex/HSimplexNla.h +158 -0
  238. data/ext/lpsolver-highs/build/include/highs/simplex/HSimplexReport.h +21 -0
  239. data/ext/lpsolver-highs/build/include/highs/simplex/HighsSimplexAnalysis.h +500 -0
  240. data/ext/lpsolver-highs/build/include/highs/simplex/SimplexConst.h +273 -0
  241. data/ext/lpsolver-highs/build/include/highs/simplex/SimplexStruct.h +263 -0
  242. data/ext/lpsolver-highs/build/include/highs/simplex/SimplexTimer.h +414 -0
  243. data/ext/lpsolver-highs/build/include/highs/test_kkt/DevKkt.h +143 -0
  244. data/ext/lpsolver-highs/build/include/highs/test_kkt/KktCh2.h +79 -0
  245. data/ext/lpsolver-highs/build/include/highs/util/FactorTimer.h +199 -0
  246. data/ext/lpsolver-highs/build/include/highs/util/HFactor.h +587 -0
  247. data/ext/lpsolver-highs/build/include/highs/util/HFactorConst.h +81 -0
  248. data/ext/lpsolver-highs/build/include/highs/util/HFactorDebug.h +55 -0
  249. data/ext/lpsolver-highs/build/include/highs/util/HSet.h +89 -0
  250. data/ext/lpsolver-highs/build/include/highs/util/HVector.h +22 -0
  251. data/ext/lpsolver-highs/build/include/highs/util/HVectorBase.h +102 -0
  252. data/ext/lpsolver-highs/build/include/highs/util/HighsCDouble.h +323 -0
  253. data/ext/lpsolver-highs/build/include/highs/util/HighsComponent.h +53 -0
  254. data/ext/lpsolver-highs/build/include/highs/util/HighsDataStack.h +83 -0
  255. data/ext/lpsolver-highs/build/include/highs/util/HighsDisjointSets.h +107 -0
  256. data/ext/lpsolver-highs/build/include/highs/util/HighsHash.h +1274 -0
  257. data/ext/lpsolver-highs/build/include/highs/util/HighsHashTree.h +1461 -0
  258. data/ext/lpsolver-highs/build/include/highs/util/HighsInt.h +36 -0
  259. data/ext/lpsolver-highs/build/include/highs/util/HighsIntegers.h +212 -0
  260. data/ext/lpsolver-highs/build/include/highs/util/HighsLinearSumBounds.h +203 -0
  261. data/ext/lpsolver-highs/build/include/highs/util/HighsMatrixPic.h +37 -0
  262. data/ext/lpsolver-highs/build/include/highs/util/HighsMatrixSlice.h +561 -0
  263. data/ext/lpsolver-highs/build/include/highs/util/HighsMatrixUtils.h +57 -0
  264. data/ext/lpsolver-highs/build/include/highs/util/HighsMemoryAllocation.h +63 -0
  265. data/ext/lpsolver-highs/build/include/highs/util/HighsRandom.h +242 -0
  266. data/ext/lpsolver-highs/build/include/highs/util/HighsRbTree.h +452 -0
  267. data/ext/lpsolver-highs/build/include/highs/util/HighsSort.h +131 -0
  268. data/ext/lpsolver-highs/build/include/highs/util/HighsSparseMatrix.h +151 -0
  269. data/ext/lpsolver-highs/build/include/highs/util/HighsSparseVectorSum.h +95 -0
  270. data/ext/lpsolver-highs/build/include/highs/util/HighsSplay.h +135 -0
  271. data/ext/lpsolver-highs/build/include/highs/util/HighsTimer.h +385 -0
  272. data/ext/lpsolver-highs/build/include/highs/util/HighsUtils.h +272 -0
  273. data/ext/lpsolver-highs/build/include/highs/util/stringutil.h +46 -0
  274. data/ext/lpsolver-highs/build/include/highs/zstr/strict_fstream.hpp +237 -0
  275. data/ext/lpsolver-highs/build/include/highs/zstr/zstr.hpp +473 -0
  276. data/ext/lpsolver-highs/build/include/highs_export.h +43 -0
  277. data/ext/lpsolver-highs/build/lib/cmake/highs/highs-config-version.cmake +65 -0
  278. data/ext/lpsolver-highs/build/lib/cmake/highs/highs-config.cmake +36 -0
  279. data/ext/lpsolver-highs/build/lib/cmake/highs/highs-targets-release.cmake +19 -0
  280. data/ext/lpsolver-highs/build/lib/cmake/highs/highs-targets.cmake +111 -0
  281. data/ext/lpsolver-highs/build/lib/libhighs.a +0 -0
  282. data/ext/lpsolver-highs/build/lib/pkgconfig/highs.pc +12 -0
  283. data/ext/lpsolver-highs/build/share/doc/HIGHS/AUTHORS +7 -0
  284. data/ext/lpsolver-highs/build/share/doc/HIGHS/CITATION.cff +29 -0
  285. data/ext/lpsolver-highs/build/share/doc/HIGHS/CODE_OF_CONDUCT.md +128 -0
  286. data/ext/lpsolver-highs/build/share/doc/HIGHS/CONTRIBUTING.md +31 -0
  287. data/ext/lpsolver-highs/build/share/doc/HIGHS/FEATURES.md +61 -0
  288. data/ext/lpsolver-highs/build/share/doc/HIGHS/LICENSE.txt +21 -0
  289. data/ext/lpsolver-highs/build/share/doc/HIGHS/README.md +281 -0
  290. data/ext/lpsolver-highs/build_webdemo.sh +46 -0
  291. data/ext/lpsolver-highs/check/Avgas.cpp +245 -0
  292. data/ext/lpsolver-highs/check/Avgas.h +44 -0
  293. data/ext/lpsolver-highs/check/CMakeLists.txt +573 -0
  294. data/ext/lpsolver-highs/check/HCheckConfig.h.bazel.in +6 -0
  295. data/ext/lpsolver-highs/check/HCheckConfig.h.in +12 -0
  296. data/ext/lpsolver-highs/check/HCheckConfig.h.meson.in +6 -0
  297. data/ext/lpsolver-highs/check/SpecialLps.h +405 -0
  298. data/ext/lpsolver-highs/check/TestAlienBasis.cpp +720 -0
  299. data/ext/lpsolver-highs/check/TestBasis.cpp +359 -0
  300. data/ext/lpsolver-highs/check/TestBasisSolves.cpp +669 -0
  301. data/ext/lpsolver-highs/check/TestCAPI.c +2513 -0
  302. data/ext/lpsolver-highs/check/TestCallbacks.cpp +608 -0
  303. data/ext/lpsolver-highs/check/TestCheckSolution.cpp +740 -0
  304. data/ext/lpsolver-highs/check/TestCrossover.cpp +111 -0
  305. data/ext/lpsolver-highs/check/TestDualize.cpp +172 -0
  306. data/ext/lpsolver-highs/check/TestEkk.cpp +100 -0
  307. data/ext/lpsolver-highs/check/TestFactor.cpp +389 -0
  308. data/ext/lpsolver-highs/check/TestFilereader.cpp +568 -0
  309. data/ext/lpsolver-highs/check/TestFortranAPI.f90 +65 -0
  310. data/ext/lpsolver-highs/check/TestHSet.cpp +80 -0
  311. data/ext/lpsolver-highs/check/TestHighsCDouble.cpp +109 -0
  312. data/ext/lpsolver-highs/check/TestHighsGFkSolve.cpp +102 -0
  313. data/ext/lpsolver-highs/check/TestHighsHash.cpp +126 -0
  314. data/ext/lpsolver-highs/check/TestHighsHessian.cpp +329 -0
  315. data/ext/lpsolver-highs/check/TestHighsIntegers.cpp +42 -0
  316. data/ext/lpsolver-highs/check/TestHighsModel.cpp +134 -0
  317. data/ext/lpsolver-highs/check/TestHighsParallel.cpp +277 -0
  318. data/ext/lpsolver-highs/check/TestHighsRbTree.cpp +109 -0
  319. data/ext/lpsolver-highs/check/TestHighsSparseMatrix.cpp +126 -0
  320. data/ext/lpsolver-highs/check/TestHighsVersion.cpp +61 -0
  321. data/ext/lpsolver-highs/check/TestHipo.cpp +122 -0
  322. data/ext/lpsolver-highs/check/TestICrash.cpp +46 -0
  323. data/ext/lpsolver-highs/check/TestIO.cpp +163 -0
  324. data/ext/lpsolver-highs/check/TestIis.cpp +1063 -0
  325. data/ext/lpsolver-highs/check/TestInfo.cpp +116 -0
  326. data/ext/lpsolver-highs/check/TestIpm.cpp +226 -0
  327. data/ext/lpsolver-highs/check/TestIpx.cpp +96 -0
  328. data/ext/lpsolver-highs/check/TestLPFileFormat.cpp +22 -0
  329. data/ext/lpsolver-highs/check/TestLogging.cpp +69 -0
  330. data/ext/lpsolver-highs/check/TestLpModification.cpp +2497 -0
  331. data/ext/lpsolver-highs/check/TestLpOrientation.cpp +121 -0
  332. data/ext/lpsolver-highs/check/TestLpSolvers.cpp +555 -0
  333. data/ext/lpsolver-highs/check/TestLpValidation.cpp +689 -0
  334. data/ext/lpsolver-highs/check/TestMain.cpp +6 -0
  335. data/ext/lpsolver-highs/check/TestMipSolver.cpp +1406 -0
  336. data/ext/lpsolver-highs/check/TestModelProperties.cpp +143 -0
  337. data/ext/lpsolver-highs/check/TestMultiObjective.cpp +198 -0
  338. data/ext/lpsolver-highs/check/TestNames.cpp +187 -0
  339. data/ext/lpsolver-highs/check/TestOptions.cpp +544 -0
  340. data/ext/lpsolver-highs/check/TestPdlp.cpp +327 -0
  341. data/ext/lpsolver-highs/check/TestPdlpHi.cpp +40 -0
  342. data/ext/lpsolver-highs/check/TestPresolve.cpp +912 -0
  343. data/ext/lpsolver-highs/check/TestQpSolver.cpp +1345 -0
  344. data/ext/lpsolver-highs/check/TestRanging.cpp +558 -0
  345. data/ext/lpsolver-highs/check/TestRays.cpp +1010 -0
  346. data/ext/lpsolver-highs/check/TestSemiVariables.cpp +329 -0
  347. data/ext/lpsolver-highs/check/TestSetup.cpp +12 -0
  348. data/ext/lpsolver-highs/check/TestSort.cpp +247 -0
  349. data/ext/lpsolver-highs/check/TestSpecialLps.cpp +775 -0
  350. data/ext/lpsolver-highs/check/TestThrow.cpp +83 -0
  351. data/ext/lpsolver-highs/check/TestTspSolver.cpp +19 -0
  352. data/ext/lpsolver-highs/check/TestUserScale.cpp +444 -0
  353. data/ext/lpsolver-highs/check/cublas_example.cpp +76 -0
  354. data/ext/lpsolver-highs/check/cublas_gpu_start.cpp +88 -0
  355. data/ext/lpsolver-highs/check/hipo_test_option_files/hipo_options_0 +1 -0
  356. data/ext/lpsolver-highs/check/instances/1448.lp +1 -0
  357. data/ext/lpsolver-highs/check/instances/1449a.lp +1 -0
  358. data/ext/lpsolver-highs/check/instances/1449b.lp +1 -0
  359. data/ext/lpsolver-highs/check/instances/1451.lp +8 -0
  360. data/ext/lpsolver-highs/check/instances/2122.lp +1822 -0
  361. data/ext/lpsolver-highs/check/instances/2171.mps +717 -0
  362. data/ext/lpsolver-highs/check/instances/25fv47.mps +6919 -0
  363. data/ext/lpsolver-highs/check/instances/2821-duplicate.mps +31 -0
  364. data/ext/lpsolver-highs/check/instances/2821-qmatrix.mps +31 -0
  365. data/ext/lpsolver-highs/check/instances/2821-quadobj.mps +29 -0
  366. data/ext/lpsolver-highs/check/instances/2821-summation.mps +30 -0
  367. data/ext/lpsolver-highs/check/instances/2821.mps +29 -0
  368. data/ext/lpsolver-highs/check/instances/2894.mps +89 -0
  369. data/ext/lpsolver-highs/check/instances/80bau3b.mps +23732 -0
  370. data/ext/lpsolver-highs/check/instances/WithInf.set +3 -0
  371. data/ext/lpsolver-highs/check/instances/adlittle.mps +335 -0
  372. data/ext/lpsolver-highs/check/instances/afiro.mps +83 -0
  373. data/ext/lpsolver-highs/check/instances/avgas.mps +51 -0
  374. data/ext/lpsolver-highs/check/instances/bell5.mps +384 -0
  375. data/ext/lpsolver-highs/check/instances/bgetam.mps +2112 -0
  376. data/ext/lpsolver-highs/check/instances/blending.mps +13 -0
  377. data/ext/lpsolver-highs/check/instances/box1.mps +1085 -0
  378. data/ext/lpsolver-highs/check/instances/chip.mps +13 -0
  379. data/ext/lpsolver-highs/check/instances/comment.mps +23 -0
  380. data/ext/lpsolver-highs/check/instances/cplex1.mps +9674 -0
  381. data/ext/lpsolver-highs/check/instances/dD2e.mps +10 -0
  382. data/ext/lpsolver-highs/check/instances/dcmulti.mps +2310 -0
  383. data/ext/lpsolver-highs/check/instances/e226.mps +1733 -0
  384. data/ext/lpsolver-highs/check/instances/egout-ac.mps +473 -0
  385. data/ext/lpsolver-highs/check/instances/egout.mps +403 -0
  386. data/ext/lpsolver-highs/check/instances/etamacro.mps +2084 -0
  387. data/ext/lpsolver-highs/check/instances/ex72a.mps +849 -0
  388. data/ext/lpsolver-highs/check/instances/fixed-binary.lp +11 -0
  389. data/ext/lpsolver-highs/check/instances/flugpl.mps +111 -0
  390. data/ext/lpsolver-highs/check/instances/flugpl_illegal_integer.sol +24 -0
  391. data/ext/lpsolver-highs/check/instances/flugpl_integer.sol +25 -0
  392. data/ext/lpsolver-highs/check/instances/forest6.mps +261 -0
  393. data/ext/lpsolver-highs/check/instances/galenet.mps +34 -0
  394. data/ext/lpsolver-highs/check/instances/gams10am.mps +478 -0
  395. data/ext/lpsolver-highs/check/instances/garbage.ems +3 -0
  396. data/ext/lpsolver-highs/check/instances/garbage.lp +3 -0
  397. data/ext/lpsolver-highs/check/instances/garbage.mps +3 -0
  398. data/ext/lpsolver-highs/check/instances/gas11.mps +2924 -0
  399. data/ext/lpsolver-highs/check/instances/gesa2.mps +5459 -0
  400. data/ext/lpsolver-highs/check/instances/greenbea.mps +19215 -0
  401. data/ext/lpsolver-highs/check/instances/gt2.mps +534 -0
  402. data/ext/lpsolver-highs/check/instances/infeasible-mip0.mps +140 -0
  403. data/ext/lpsolver-highs/check/instances/infeasible-mip1.mps +371 -0
  404. data/ext/lpsolver-highs/check/instances/israel.mps +1490 -0
  405. data/ext/lpsolver-highs/check/instances/issue-2095.mps +836 -0
  406. data/ext/lpsolver-highs/check/instances/issue-2173.mps +3331 -0
  407. data/ext/lpsolver-highs/check/instances/issue-2204.mps +143 -0
  408. data/ext/lpsolver-highs/check/instances/issue-2290.mps +158 -0
  409. data/ext/lpsolver-highs/check/instances/issue-2388.lp +76 -0
  410. data/ext/lpsolver-highs/check/instances/issue-2402.mps +435 -0
  411. data/ext/lpsolver-highs/check/instances/issue-2446.mps +9154 -0
  412. data/ext/lpsolver-highs/check/instances/issue-2585.lp +16 -0
  413. data/ext/lpsolver-highs/check/instances/issue-2874-3.mps +97 -0
  414. data/ext/lpsolver-highs/check/instances/klein1.mps +422 -0
  415. data/ext/lpsolver-highs/check/instances/lseu.mps +371 -0
  416. data/ext/lpsolver-highs/check/instances/model.xyz +1 -0
  417. data/ext/lpsolver-highs/check/instances/nan0.mps +13 -0
  418. data/ext/lpsolver-highs/check/instances/nan1.mps +13 -0
  419. data/ext/lpsolver-highs/check/instances/nan2.mps +13 -0
  420. data/ext/lpsolver-highs/check/instances/no-newline-eof.lp +5 -0
  421. data/ext/lpsolver-highs/check/instances/p01.mps +909 -0
  422. data/ext/lpsolver-highs/check/instances/p0548.mps +1992 -0
  423. data/ext/lpsolver-highs/check/instances/primal1.mps +3909 -0
  424. data/ext/lpsolver-highs/check/instances/qap04.mps +606 -0
  425. data/ext/lpsolver-highs/check/instances/qcqp.lp +8 -0
  426. data/ext/lpsolver-highs/check/instances/qjh.lp +9 -0
  427. data/ext/lpsolver-highs/check/instances/qjh.mps +18 -0
  428. data/ext/lpsolver-highs/check/instances/qjh_qmatrix.mps +19 -0
  429. data/ext/lpsolver-highs/check/instances/qjh_quadobj.mps +18 -0
  430. data/ext/lpsolver-highs/check/instances/qjh_quadobj_qmatrix.mps +25 -0
  431. data/ext/lpsolver-highs/check/instances/qjh_uncon.lp +10 -0
  432. data/ext/lpsolver-highs/check/instances/qjh_uncon.mps +17 -0
  433. data/ext/lpsolver-highs/check/instances/qpinfeasible.lp +8 -0
  434. data/ext/lpsolver-highs/check/instances/qptestnw.lp +7 -0
  435. data/ext/lpsolver-highs/check/instances/qpunbounded.lp +5 -0
  436. data/ext/lpsolver-highs/check/instances/refinery.mps +1882 -0
  437. data/ext/lpsolver-highs/check/instances/rgn.mps +559 -0
  438. data/ext/lpsolver-highs/check/instances/scrs8.mps +2717 -0
  439. data/ext/lpsolver-highs/check/instances/sctest.mps +66 -0
  440. data/ext/lpsolver-highs/check/instances/semi-continuous.lp +13 -0
  441. data/ext/lpsolver-highs/check/instances/semi-continuous.mps +24 -0
  442. data/ext/lpsolver-highs/check/instances/semi-integer.lp +15 -0
  443. data/ext/lpsolver-highs/check/instances/semi-integer.mps +22 -0
  444. data/ext/lpsolver-highs/check/instances/shell.mps +4039 -0
  445. data/ext/lpsolver-highs/check/instances/silly-names.mps +14 -0
  446. data/ext/lpsolver-highs/check/instances/small_mip.mps +87 -0
  447. data/ext/lpsolver-highs/check/instances/smalllp.mps +21 -0
  448. data/ext/lpsolver-highs/check/instances/sp150x300d.mps +1983 -0
  449. data/ext/lpsolver-highs/check/instances/stair.mps +2499 -0
  450. data/ext/lpsolver-highs/check/instances/standata.mps +2317 -0
  451. data/ext/lpsolver-highs/check/instances/standgub.mps +2428 -0
  452. data/ext/lpsolver-highs/check/instances/standmps.mps +2695 -0
  453. data/ext/lpsolver-highs/check/instances/test.mps +53 -0
  454. data/ext/lpsolver-highs/check/instances/vol1.mps +1895 -0
  455. data/ext/lpsolver-highs/check/instances/warnings.mps +68 -0
  456. data/ext/lpsolver-highs/check/instances/woodinfe.mps +216 -0
  457. data/ext/lpsolver-highs/check/matrix_multiplication.hpp +49 -0
  458. data/ext/lpsolver-highs/check/meson.build +92 -0
  459. data/ext/lpsolver-highs/check/pythontest.py +11 -0
  460. data/ext/lpsolver-highs/check/sample_options_file +8 -0
  461. data/ext/lpsolver-highs/cmake/CheckAtomic.cmake +74 -0
  462. data/ext/lpsolver-highs/cmake/FindCUDAConf.cmake +44 -0
  463. data/ext/lpsolver-highs/cmake/FindHipoDeps.cmake +351 -0
  464. data/ext/lpsolver-highs/cmake/README.md +243 -0
  465. data/ext/lpsolver-highs/cmake/cpp-highs.cmake +243 -0
  466. data/ext/lpsolver-highs/cmake/dotnet.cmake +94 -0
  467. data/ext/lpsolver-highs/cmake/highs-config.cmake.in +22 -0
  468. data/ext/lpsolver-highs/cmake/python-highs.cmake +74 -0
  469. data/ext/lpsolver-highs/cmake/set-version.cmake +26 -0
  470. data/ext/lpsolver-highs/cmake/sources-python.cmake +461 -0
  471. data/ext/lpsolver-highs/cmake/sources.cmake +618 -0
  472. data/ext/lpsolver-highs/docs/HiGHS_CopyrightHeader.pl +78 -0
  473. data/ext/lpsolver-highs/docs/HiGHS_CopyrightHeaderUpdateAll +32 -0
  474. data/ext/lpsolver-highs/docs/Project.toml +7 -0
  475. data/ext/lpsolver-highs/docs/README.md +27 -0
  476. data/ext/lpsolver-highs/docs/c_api_gen/HConfig.h +1 -0
  477. data/ext/lpsolver-highs/docs/c_api_gen/build.jl +48 -0
  478. data/ext/lpsolver-highs/docs/make.jl +115 -0
  479. data/ext/lpsolver-highs/docs/src/assets/logo.png +0 -0
  480. data/ext/lpsolver-highs/docs/src/callbacks.md +171 -0
  481. data/ext/lpsolver-highs/docs/src/executable.md +88 -0
  482. data/ext/lpsolver-highs/docs/src/guide/advanced.md +66 -0
  483. data/ext/lpsolver-highs/docs/src/guide/basic.md +116 -0
  484. data/ext/lpsolver-highs/docs/src/guide/further.md +193 -0
  485. data/ext/lpsolver-highs/docs/src/guide/gpu.md +58 -0
  486. data/ext/lpsolver-highs/docs/src/guide/index.md +18 -0
  487. data/ext/lpsolver-highs/docs/src/guide/kkt.md +219 -0
  488. data/ext/lpsolver-highs/docs/src/guide/numerics.md +55 -0
  489. data/ext/lpsolver-highs/docs/src/index.md +86 -0
  490. data/ext/lpsolver-highs/docs/src/installation.md +130 -0
  491. data/ext/lpsolver-highs/docs/src/interfaces/c_api.md +6 -0
  492. data/ext/lpsolver-highs/docs/src/interfaces/cpp/examples.md +1 -0
  493. data/ext/lpsolver-highs/docs/src/interfaces/cpp/index.md +29 -0
  494. data/ext/lpsolver-highs/docs/src/interfaces/cpp/library.md +107 -0
  495. data/ext/lpsolver-highs/docs/src/interfaces/csharp.md +55 -0
  496. data/ext/lpsolver-highs/docs/src/interfaces/fortran.md +11 -0
  497. data/ext/lpsolver-highs/docs/src/interfaces/julia/index.md +130 -0
  498. data/ext/lpsolver-highs/docs/src/interfaces/other.md +41 -0
  499. data/ext/lpsolver-highs/docs/src/interfaces/python/example-py.md +275 -0
  500. data/ext/lpsolver-highs/docs/src/interfaces/python/index.md +91 -0
  501. data/ext/lpsolver-highs/docs/src/interfaces/python/model-py.md +90 -0
  502. data/ext/lpsolver-highs/docs/src/options/definitions.md +529 -0
  503. data/ext/lpsolver-highs/docs/src/options/intro.md +46 -0
  504. data/ext/lpsolver-highs/docs/src/parallel.md +88 -0
  505. data/ext/lpsolver-highs/docs/src/solvers.md +168 -0
  506. data/ext/lpsolver-highs/docs/src/structures/classes/HighsHessian.md +9 -0
  507. data/ext/lpsolver-highs/docs/src/structures/classes/HighsIis.md +16 -0
  508. data/ext/lpsolver-highs/docs/src/structures/classes/HighsLp.md +19 -0
  509. data/ext/lpsolver-highs/docs/src/structures/classes/HighsModel.md +6 -0
  510. data/ext/lpsolver-highs/docs/src/structures/classes/HighsSparseMatrix.md +10 -0
  511. data/ext/lpsolver-highs/docs/src/structures/classes/index.md +11 -0
  512. data/ext/lpsolver-highs/docs/src/structures/enums.md +114 -0
  513. data/ext/lpsolver-highs/docs/src/structures/index.md +12 -0
  514. data/ext/lpsolver-highs/docs/src/structures/structs/HighsBasis.md +8 -0
  515. data/ext/lpsolver-highs/docs/src/structures/structs/HighsInfo.md +148 -0
  516. data/ext/lpsolver-highs/docs/src/structures/structs/HighsLinearObjective.md +11 -0
  517. data/ext/lpsolver-highs/docs/src/structures/structs/HighsSolution.md +10 -0
  518. data/ext/lpsolver-highs/docs/src/structures/structs/index.md +10 -0
  519. data/ext/lpsolver-highs/docs/src/terminology.md +163 -0
  520. data/ext/lpsolver-highs/examples/CMakeLists.txt +26 -0
  521. data/ext/lpsolver-highs/examples/Docs.py +104 -0
  522. data/ext/lpsolver-highs/examples/branch-and-price.py +465 -0
  523. data/ext/lpsolver-highs/examples/call_highs_from_c.c +685 -0
  524. data/ext/lpsolver-highs/examples/call_highs_from_c_minimal.c +659 -0
  525. data/ext/lpsolver-highs/examples/call_highs_from_cpp.cpp +178 -0
  526. data/ext/lpsolver-highs/examples/call_highs_from_csharp.cs +83 -0
  527. data/ext/lpsolver-highs/examples/call_highs_from_fortran.f90 +579 -0
  528. data/ext/lpsolver-highs/examples/call_highs_from_python.py +448 -0
  529. data/ext/lpsolver-highs/examples/call_highs_from_python_highspy.py +71 -0
  530. data/ext/lpsolver-highs/examples/call_highs_from_python_mps.py +59 -0
  531. data/ext/lpsolver-highs/examples/callback_gap.py +71 -0
  532. data/ext/lpsolver-highs/examples/chip.py +43 -0
  533. data/ext/lpsolver-highs/examples/chip0.py +29 -0
  534. data/ext/lpsolver-highs/examples/distillation.py +77 -0
  535. data/ext/lpsolver-highs/examples/knapsack.py +43 -0
  536. data/ext/lpsolver-highs/examples/minimal.py +11 -0
  537. data/ext/lpsolver-highs/examples/multi_objective.py +139 -0
  538. data/ext/lpsolver-highs/examples/multiple_objective.py +120 -0
  539. data/ext/lpsolver-highs/examples/network_flow.py +37 -0
  540. data/ext/lpsolver-highs/examples/nqueens.py +29 -0
  541. data/ext/lpsolver-highs/examples/plot_highs_log.py +134 -0
  542. data/ext/lpsolver-highs/extern/CLI11.hpp +11546 -0
  543. data/ext/lpsolver-highs/extern/LICENCE_1_0.txt +23 -0
  544. data/ext/lpsolver-highs/extern/amd/License.txt +35 -0
  545. data/ext/lpsolver-highs/extern/amd/SuiteSparse_config.c +54 -0
  546. data/ext/lpsolver-highs/extern/amd/SuiteSparse_config.h +56 -0
  547. data/ext/lpsolver-highs/extern/amd/amd.h +357 -0
  548. data/ext/lpsolver-highs/extern/amd/amd_1.c +172 -0
  549. data/ext/lpsolver-highs/extern/amd/amd_2.c +1761 -0
  550. data/ext/lpsolver-highs/extern/amd/amd_aat.c +179 -0
  551. data/ext/lpsolver-highs/extern/amd/amd_control.c +65 -0
  552. data/ext/lpsolver-highs/extern/amd/amd_defaults.c +37 -0
  553. data/ext/lpsolver-highs/extern/amd/amd_info.c +120 -0
  554. data/ext/lpsolver-highs/extern/amd/amd_internal.h +137 -0
  555. data/ext/lpsolver-highs/extern/amd/amd_order.c +195 -0
  556. data/ext/lpsolver-highs/extern/amd/amd_post_tree.c +105 -0
  557. data/ext/lpsolver-highs/extern/amd/amd_postorder.c +140 -0
  558. data/ext/lpsolver-highs/extern/amd/amd_preprocess.c +107 -0
  559. data/ext/lpsolver-highs/extern/amd/amd_valid.c +93 -0
  560. data/ext/lpsolver-highs/extern/amd/changes.txt +8 -0
  561. data/ext/lpsolver-highs/extern/catch.hpp +18861 -0
  562. data/ext/lpsolver-highs/extern/metis/Changes.txt +31 -0
  563. data/ext/lpsolver-highs/extern/metis/GKlib/GKlib.h +62 -0
  564. data/ext/lpsolver-highs/extern/metis/GKlib/error.c +21 -0
  565. data/ext/lpsolver-highs/extern/metis/GKlib/gk_arch.h +64 -0
  566. data/ext/lpsolver-highs/extern/metis/GKlib/gk_defs.h +19 -0
  567. data/ext/lpsolver-highs/extern/metis/GKlib/gk_macros.h +50 -0
  568. data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkblas.h +51 -0
  569. data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkmemory.h +80 -0
  570. data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkpqueue.h +329 -0
  571. data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkrandom.h +89 -0
  572. data/ext/lpsolver-highs/extern/metis/GKlib/gk_mksort.h +271 -0
  573. data/ext/lpsolver-highs/extern/metis/GKlib/gk_ms_inttypes.h +41 -0
  574. data/ext/lpsolver-highs/extern/metis/GKlib/gk_ms_stat.h +22 -0
  575. data/ext/lpsolver-highs/extern/metis/GKlib/gk_ms_stdint.h +41 -0
  576. data/ext/lpsolver-highs/extern/metis/GKlib/gk_proto.h +50 -0
  577. data/ext/lpsolver-highs/extern/metis/GKlib/gk_struct.h +66 -0
  578. data/ext/lpsolver-highs/extern/metis/GKlib/gk_types.h +15 -0
  579. data/ext/lpsolver-highs/extern/metis/GKlib/mcore.c +176 -0
  580. data/ext/lpsolver-highs/extern/metis/GKlib/memory.c +23 -0
  581. data/ext/lpsolver-highs/extern/metis/GKlib/random.c +37 -0
  582. data/ext/lpsolver-highs/extern/metis/LICENSE.txt +18 -0
  583. data/ext/lpsolver-highs/extern/metis/libmetis/auxapi.c +27 -0
  584. data/ext/lpsolver-highs/extern/metis/libmetis/balance.c +491 -0
  585. data/ext/lpsolver-highs/extern/metis/libmetis/bucketsort.c +44 -0
  586. data/ext/lpsolver-highs/extern/metis/libmetis/coarsen.c +895 -0
  587. data/ext/lpsolver-highs/extern/metis/libmetis/compress.c +231 -0
  588. data/ext/lpsolver-highs/extern/metis/libmetis/contig.c +83 -0
  589. data/ext/lpsolver-highs/extern/metis/libmetis/defs.h +39 -0
  590. data/ext/lpsolver-highs/extern/metis/libmetis/fm.c +527 -0
  591. data/ext/lpsolver-highs/extern/metis/libmetis/gklib.c +55 -0
  592. data/ext/lpsolver-highs/extern/metis/libmetis/gklib_defs.h +33 -0
  593. data/ext/lpsolver-highs/extern/metis/libmetis/graph.c +268 -0
  594. data/ext/lpsolver-highs/extern/metis/libmetis/initpart.c +385 -0
  595. data/ext/lpsolver-highs/extern/metis/libmetis/macros.h +59 -0
  596. data/ext/lpsolver-highs/extern/metis/libmetis/mcutil.c +162 -0
  597. data/ext/lpsolver-highs/extern/metis/libmetis/metislib.h +35 -0
  598. data/ext/lpsolver-highs/extern/metis/libmetis/mmd.c +598 -0
  599. data/ext/lpsolver-highs/extern/metis/libmetis/ometis.c +661 -0
  600. data/ext/lpsolver-highs/extern/metis/libmetis/options.c +260 -0
  601. data/ext/lpsolver-highs/extern/metis/libmetis/proto.h +172 -0
  602. data/ext/lpsolver-highs/extern/metis/libmetis/refine.c +99 -0
  603. data/ext/lpsolver-highs/extern/metis/libmetis/separator.c +57 -0
  604. data/ext/lpsolver-highs/extern/metis/libmetis/sfm.c +581 -0
  605. data/ext/lpsolver-highs/extern/metis/libmetis/srefine.c +152 -0
  606. data/ext/lpsolver-highs/extern/metis/libmetis/stdheaders.h +29 -0
  607. data/ext/lpsolver-highs/extern/metis/libmetis/struct.h +117 -0
  608. data/ext/lpsolver-highs/extern/metis/libmetis/util.c +59 -0
  609. data/ext/lpsolver-highs/extern/metis/libmetis/wspace.c +91 -0
  610. data/ext/lpsolver-highs/extern/metis/metis.h +271 -0
  611. data/ext/lpsolver-highs/extern/pdqsort/license.txt +16 -0
  612. data/ext/lpsolver-highs/extern/pdqsort/pdqsort.h +532 -0
  613. data/ext/lpsolver-highs/extern/rcm/LICENSE +19 -0
  614. data/ext/lpsolver-highs/extern/rcm/rcm.cpp +873 -0
  615. data/ext/lpsolver-highs/extern/rcm/rcm.h +22 -0
  616. data/ext/lpsolver-highs/extern/zstr/LICENSE +21 -0
  617. data/ext/lpsolver-highs/extern/zstr/strict_fstream.hpp +237 -0
  618. data/ext/lpsolver-highs/extern/zstr/zstr.hpp +473 -0
  619. data/ext/lpsolver-highs/flake.lock +61 -0
  620. data/ext/lpsolver-highs/flake.nix +73 -0
  621. data/ext/lpsolver-highs/highs/CMakeLists.txt +499 -0
  622. data/ext/lpsolver-highs/highs/HConfig.h.bazel.in +25 -0
  623. data/ext/lpsolver-highs/highs/HConfig.h.in +22 -0
  624. data/ext/lpsolver-highs/highs/HConfig.h.meson.in +17 -0
  625. data/ext/lpsolver-highs/highs/Highs.h +1812 -0
  626. data/ext/lpsolver-highs/highs/HighsRun.md +143 -0
  627. data/ext/lpsolver-highs/highs/highs_bindings.cpp +1826 -0
  628. data/ext/lpsolver-highs/highs/highspy/__init__.py +93 -0
  629. data/ext/lpsolver-highs/highs/highspy/__init__.pyi +91 -0
  630. data/ext/lpsolver-highs/highs/highspy/_core/__init__.pyi +1058 -0
  631. data/ext/lpsolver-highs/highs/highspy/_core/cb.pyi +118 -0
  632. data/ext/lpsolver-highs/highs/highspy/_core/simplex_constants.pyi +472 -0
  633. data/ext/lpsolver-highs/highs/highspy/highs.py +2430 -0
  634. data/ext/lpsolver-highs/highs/interfaces/highs_c_api.cpp +1812 -0
  635. data/ext/lpsolver-highs/highs/interfaces/highs_c_api.h +2651 -0
  636. data/ext/lpsolver-highs/highs/interfaces/highs_csharp_api.cs +1142 -0
  637. data/ext/lpsolver-highs/highs/interfaces/highs_fortran_api.f90 +873 -0
  638. data/ext/lpsolver-highs/highs/io/Filereader.cpp +87 -0
  639. data/ext/lpsolver-highs/highs/io/Filereader.h +45 -0
  640. data/ext/lpsolver-highs/highs/io/FilereaderLp.cpp +539 -0
  641. data/ext/lpsolver-highs/highs/io/FilereaderLp.h +49 -0
  642. data/ext/lpsolver-highs/highs/io/FilereaderMps.cpp +86 -0
  643. data/ext/lpsolver-highs/highs/io/FilereaderMps.h +27 -0
  644. data/ext/lpsolver-highs/highs/io/HMPSIO.cpp +1001 -0
  645. data/ext/lpsolver-highs/highs/io/HMPSIO.h +78 -0
  646. data/ext/lpsolver-highs/highs/io/HMpsFF.cpp +2113 -0
  647. data/ext/lpsolver-highs/highs/io/HMpsFF.h +245 -0
  648. data/ext/lpsolver-highs/highs/io/HighsIO.cpp +371 -0
  649. data/ext/lpsolver-highs/highs/io/HighsIO.h +118 -0
  650. data/ext/lpsolver-highs/highs/io/LoadOptions.cpp +60 -0
  651. data/ext/lpsolver-highs/highs/io/LoadOptions.h +24 -0
  652. data/ext/lpsolver-highs/highs/io/filereaderlp/LICENSE +19 -0
  653. data/ext/lpsolver-highs/highs/io/filereaderlp/builder.hpp +25 -0
  654. data/ext/lpsolver-highs/highs/io/filereaderlp/def.hpp +19 -0
  655. data/ext/lpsolver-highs/highs/io/filereaderlp/model.hpp +68 -0
  656. data/ext/lpsolver-highs/highs/io/filereaderlp/reader.cpp +1375 -0
  657. data/ext/lpsolver-highs/highs/io/filereaderlp/reader.hpp +10 -0
  658. data/ext/lpsolver-highs/highs/ipm/IpxSolution.h +32 -0
  659. data/ext/lpsolver-highs/highs/ipm/IpxWrapper.cpp +1526 -0
  660. data/ext/lpsolver-highs/highs/ipm/IpxWrapper.h +106 -0
  661. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu.h +161 -0
  662. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_factorize.c +132 -0
  663. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_factorize.h +247 -0
  664. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_get_factors.c +148 -0
  665. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_get_factors.h +108 -0
  666. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_initialize.c +24 -0
  667. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_initialize.h +119 -0
  668. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_factorize.h +34 -0
  669. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_free.h +19 -0
  670. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_get_factors.h +34 -0
  671. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_initialize.h +46 -0
  672. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_solve_dense.h +29 -0
  673. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_solve_for_update.h +42 -0
  674. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_solve_sparse.h +32 -0
  675. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_update.h +31 -0
  676. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_object.c +325 -0
  677. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_object.h +30 -0
  678. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_dense.c +46 -0
  679. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_dense.h +75 -0
  680. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_for_update.c +79 -0
  681. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_for_update.h +169 -0
  682. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_sparse.c +63 -0
  683. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_sparse.h +112 -0
  684. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_update.c +44 -0
  685. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_update.h +125 -0
  686. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_build_factors.c +441 -0
  687. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_condest.c +124 -0
  688. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_def.h +39 -0
  689. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_dfs.c +141 -0
  690. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_factorize_bump.c +56 -0
  691. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_file.c +184 -0
  692. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_file.h +21 -0
  693. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_garbage_perm.c +53 -0
  694. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_initialize.c +56 -0
  695. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_internal.c +352 -0
  696. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_internal.h +220 -0
  697. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_list.h +173 -0
  698. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_markowitz.c +188 -0
  699. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_matrix_norm.c +51 -0
  700. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_pivot.c +1247 -0
  701. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_residual_test.c +155 -0
  702. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_setup_bump.c +198 -0
  703. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_singletons.c +511 -0
  704. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_dense.c +129 -0
  705. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_for_update.c +360 -0
  706. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_sparse.c +284 -0
  707. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_symbolic.c +48 -0
  708. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_triangular.c +140 -0
  709. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_update.c +908 -0
  710. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Auxiliary.cpp +301 -0
  711. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Auxiliary.h +104 -0
  712. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/IntConfig.h +27 -0
  713. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/KrylovMethods.cpp +193 -0
  714. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/KrylovMethods.h +30 -0
  715. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Log.cpp +60 -0
  716. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Log.h +62 -0
  717. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/OrderingPrint.h +10 -0
  718. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/VectorOperations.cpp +117 -0
  719. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/VectorOperations.h +59 -0
  720. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/mycblas.h +85 -0
  721. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Analyse.cpp +1367 -0
  722. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Analyse.h +122 -0
  723. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CallAndTimeBlas.cpp +114 -0
  724. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CallAndTimeBlas.h +46 -0
  725. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CliqueStack.cpp +82 -0
  726. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CliqueStack.h +83 -0
  727. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DataCollector.cpp +326 -0
  728. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DataCollector.h +86 -0
  729. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DenseFact.h +48 -0
  730. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DenseFactHybrid.cpp +279 -0
  731. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DenseFactKernel.cpp +284 -0
  732. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DgemmParallel.cpp +38 -0
  733. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DgemmParallel.h +32 -0
  734. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FactorHiGHS.cpp +57 -0
  735. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FactorHiGHS.h +112 -0
  736. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FactorHiGHSSettings.h +63 -0
  737. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Factorise.cpp +405 -0
  738. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Factorise.h +85 -0
  739. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FormatHandler.cpp +46 -0
  740. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FormatHandler.h +95 -0
  741. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridHybridFormatHandler.cpp +238 -0
  742. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridHybridFormatHandler.h +31 -0
  743. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridSolveHandler.cpp +272 -0
  744. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridSolveHandler.h +26 -0
  745. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/KrylovMethodsIpm.cpp +83 -0
  746. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/KrylovMethodsIpm.h +45 -0
  747. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Numeric.cpp +54 -0
  748. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Numeric.h +46 -0
  749. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/ReturnValues.h +19 -0
  750. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/SolveHandler.cpp +10 -0
  751. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/SolveHandler.h +48 -0
  752. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Swaps.cpp +70 -0
  753. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Swaps.h +19 -0
  754. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Symbolic.cpp +101 -0
  755. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Symbolic.h +220 -0
  756. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Timing.h +114 -0
  757. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Control.cpp +38 -0
  758. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Control.h +41 -0
  759. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/FactorHiGHSSolver.cpp +887 -0
  760. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/FactorHiGHSSolver.h +92 -0
  761. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Info.h +58 -0
  762. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/IpmData.cpp +8 -0
  763. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/IpmData.h +37 -0
  764. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Iterate.cpp +640 -0
  765. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Iterate.h +172 -0
  766. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/LinearSolver.h +81 -0
  767. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/LogHighs.cpp +71 -0
  768. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/LogHighs.h +33 -0
  769. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Model.cpp +403 -0
  770. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Model.h +136 -0
  771. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Options.h +35 -0
  772. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Parameters.h +63 -0
  773. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/PreProcess.cpp +646 -0
  774. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/PreProcess.h +94 -0
  775. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Refine.cpp +214 -0
  776. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Solver.cpp +1346 -0
  777. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Solver.h +338 -0
  778. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Status.h +88 -0
  779. data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_kernel.cc +71 -0
  780. data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_kernel.h +20 -0
  781. data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_wrapper.cc +299 -0
  782. data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_wrapper.h +47 -0
  783. data/ext/lpsolver-highs/highs/ipm/ipx/basis.cc +966 -0
  784. data/ext/lpsolver-highs/highs/ipm/ipx/basis.h +350 -0
  785. data/ext/lpsolver-highs/highs/ipm/ipx/conjugate_residuals.cc +217 -0
  786. data/ext/lpsolver-highs/highs/ipm/ipx/conjugate_residuals.h +74 -0
  787. data/ext/lpsolver-highs/highs/ipm/ipx/control.cc +151 -0
  788. data/ext/lpsolver-highs/highs/ipm/ipx/control.h +167 -0
  789. data/ext/lpsolver-highs/highs/ipm/ipx/crossover.cc +479 -0
  790. data/ext/lpsolver-highs/highs/ipm/ipx/crossover.h +157 -0
  791. data/ext/lpsolver-highs/highs/ipm/ipx/diagonal_precond.cc +70 -0
  792. data/ext/lpsolver-highs/highs/ipm/ipx/diagonal_precond.h +45 -0
  793. data/ext/lpsolver-highs/highs/ipm/ipx/forrest_tomlin.cc +360 -0
  794. data/ext/lpsolver-highs/highs/ipm/ipx/forrest_tomlin.h +102 -0
  795. data/ext/lpsolver-highs/highs/ipm/ipx/guess_basis.cc +233 -0
  796. data/ext/lpsolver-highs/highs/ipm/ipx/guess_basis.h +21 -0
  797. data/ext/lpsolver-highs/highs/ipm/ipx/indexed_vector.cc +30 -0
  798. data/ext/lpsolver-highs/highs/ipm/ipx/indexed_vector.h +113 -0
  799. data/ext/lpsolver-highs/highs/ipm/ipx/info.cc +124 -0
  800. data/ext/lpsolver-highs/highs/ipm/ipx/info.h +27 -0
  801. data/ext/lpsolver-highs/highs/ipm/ipx/ipm.cc +897 -0
  802. data/ext/lpsolver-highs/highs/ipm/ipx/ipm.h +94 -0
  803. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_c.cc +83 -0
  804. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_c.h +47 -0
  805. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_config.h +9 -0
  806. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_info.h +111 -0
  807. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_internal.h +89 -0
  808. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_parameters.h +76 -0
  809. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_status.h +57 -0
  810. data/ext/lpsolver-highs/highs/ipm/ipx/iterate.cc +683 -0
  811. data/ext/lpsolver-highs/highs/ipm/ipx/iterate.h +331 -0
  812. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver.cc +23 -0
  813. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver.h +70 -0
  814. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_basis.cc +387 -0
  815. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_basis.h +66 -0
  816. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_diag.cc +120 -0
  817. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_diag.h +48 -0
  818. data/ext/lpsolver-highs/highs/ipm/ipx/linear_operator.cc +10 -0
  819. data/ext/lpsolver-highs/highs/ipm/ipx/linear_operator.h +26 -0
  820. data/ext/lpsolver-highs/highs/ipm/ipx/lp_solver.cc +686 -0
  821. data/ext/lpsolver-highs/highs/ipm/ipx/lp_solver.h +204 -0
  822. data/ext/lpsolver-highs/highs/ipm/ipx/lu_factorization.cc +131 -0
  823. data/ext/lpsolver-highs/highs/ipm/ipx/lu_factorization.h +79 -0
  824. data/ext/lpsolver-highs/highs/ipm/ipx/lu_update.cc +62 -0
  825. data/ext/lpsolver-highs/highs/ipm/ipx/lu_update.h +129 -0
  826. data/ext/lpsolver-highs/highs/ipm/ipx/maxvolume.cc +337 -0
  827. data/ext/lpsolver-highs/highs/ipm/ipx/maxvolume.h +54 -0
  828. data/ext/lpsolver-highs/highs/ipm/ipx/model.cc +1528 -0
  829. data/ext/lpsolver-highs/highs/ipm/ipx/model.h +413 -0
  830. data/ext/lpsolver-highs/highs/ipm/ipx/multistream.h +52 -0
  831. data/ext/lpsolver-highs/highs/ipm/ipx/normal_matrix.cc +126 -0
  832. data/ext/lpsolver-highs/highs/ipm/ipx/normal_matrix.h +44 -0
  833. data/ext/lpsolver-highs/highs/ipm/ipx/power_method.h +44 -0
  834. data/ext/lpsolver-highs/highs/ipm/ipx/sparse_matrix.cc +382 -0
  835. data/ext/lpsolver-highs/highs/ipm/ipx/sparse_matrix.h +195 -0
  836. data/ext/lpsolver-highs/highs/ipm/ipx/sparse_utils.cc +92 -0
  837. data/ext/lpsolver-highs/highs/ipm/ipx/sparse_utils.h +58 -0
  838. data/ext/lpsolver-highs/highs/ipm/ipx/splitted_normal_matrix.cc +117 -0
  839. data/ext/lpsolver-highs/highs/ipm/ipx/splitted_normal_matrix.h +63 -0
  840. data/ext/lpsolver-highs/highs/ipm/ipx/starting_basis.cc +182 -0
  841. data/ext/lpsolver-highs/highs/ipm/ipx/starting_basis.h +39 -0
  842. data/ext/lpsolver-highs/highs/ipm/ipx/symbolic_invert.cc +183 -0
  843. data/ext/lpsolver-highs/highs/ipm/ipx/symbolic_invert.h +29 -0
  844. data/ext/lpsolver-highs/highs/ipm/ipx/timer.cc +16 -0
  845. data/ext/lpsolver-highs/highs/ipm/ipx/timer.h +25 -0
  846. data/ext/lpsolver-highs/highs/ipm/ipx/utils.cc +95 -0
  847. data/ext/lpsolver-highs/highs/ipm/ipx/utils.h +37 -0
  848. data/ext/lpsolver-highs/highs/lp_data/HConst.h +430 -0
  849. data/ext/lpsolver-highs/highs/lp_data/HStruct.h +213 -0
  850. data/ext/lpsolver-highs/highs/lp_data/Highs.cpp +4949 -0
  851. data/ext/lpsolver-highs/highs/lp_data/HighsAnalysis.h +23 -0
  852. data/ext/lpsolver-highs/highs/lp_data/HighsCallback.cpp +323 -0
  853. data/ext/lpsolver-highs/highs/lp_data/HighsCallback.h +104 -0
  854. data/ext/lpsolver-highs/highs/lp_data/HighsCallbackStruct.h +70 -0
  855. data/ext/lpsolver-highs/highs/lp_data/HighsDebug.cpp +54 -0
  856. data/ext/lpsolver-highs/highs/lp_data/HighsDebug.h +34 -0
  857. data/ext/lpsolver-highs/highs/lp_data/HighsDeprecated.cpp +181 -0
  858. data/ext/lpsolver-highs/highs/lp_data/HighsIis.cpp +1290 -0
  859. data/ext/lpsolver-highs/highs/lp_data/HighsIis.h +139 -0
  860. data/ext/lpsolver-highs/highs/lp_data/HighsInfo.cpp +426 -0
  861. data/ext/lpsolver-highs/highs/lp_data/HighsInfo.h +421 -0
  862. data/ext/lpsolver-highs/highs/lp_data/HighsInfoDebug.cpp +175 -0
  863. data/ext/lpsolver-highs/highs/lp_data/HighsInfoDebug.h +27 -0
  864. data/ext/lpsolver-highs/highs/lp_data/HighsInterface.cpp +4344 -0
  865. data/ext/lpsolver-highs/highs/lp_data/HighsLp.cpp +564 -0
  866. data/ext/lpsolver-highs/highs/lp_data/HighsLp.h +97 -0
  867. data/ext/lpsolver-highs/highs/lp_data/HighsLpSolverObject.h +47 -0
  868. data/ext/lpsolver-highs/highs/lp_data/HighsLpUtils.cpp +3794 -0
  869. data/ext/lpsolver-highs/highs/lp_data/HighsLpUtils.h +330 -0
  870. data/ext/lpsolver-highs/highs/lp_data/HighsModelUtils.cpp +1650 -0
  871. data/ext/lpsolver-highs/highs/lp_data/HighsModelUtils.h +129 -0
  872. data/ext/lpsolver-highs/highs/lp_data/HighsOptions.cpp +1176 -0
  873. data/ext/lpsolver-highs/highs/lp_data/HighsOptions.h +1715 -0
  874. data/ext/lpsolver-highs/highs/lp_data/HighsRanging.cpp +733 -0
  875. data/ext/lpsolver-highs/highs/lp_data/HighsRanging.h +43 -0
  876. data/ext/lpsolver-highs/highs/lp_data/HighsSolution.cpp +2194 -0
  877. data/ext/lpsolver-highs/highs/lp_data/HighsSolution.h +179 -0
  878. data/ext/lpsolver-highs/highs/lp_data/HighsSolutionDebug.cpp +490 -0
  879. data/ext/lpsolver-highs/highs/lp_data/HighsSolutionDebug.h +87 -0
  880. data/ext/lpsolver-highs/highs/lp_data/HighsSolve.cpp +747 -0
  881. data/ext/lpsolver-highs/highs/lp_data/HighsSolve.h +29 -0
  882. data/ext/lpsolver-highs/highs/lp_data/HighsStatus.cpp +48 -0
  883. data/ext/lpsolver-highs/highs/lp_data/HighsStatus.h +29 -0
  884. data/ext/lpsolver-highs/highs/lp_data/Iis.md +113 -0
  885. data/ext/lpsolver-highs/highs/meson.build +433 -0
  886. data/ext/lpsolver-highs/highs/mip/HighsCliqueTable.cpp +2236 -0
  887. data/ext/lpsolver-highs/highs/mip/HighsCliqueTable.h +329 -0
  888. data/ext/lpsolver-highs/highs/mip/HighsConflictPool.cpp +201 -0
  889. data/ext/lpsolver-highs/highs/mip/HighsConflictPool.h +109 -0
  890. data/ext/lpsolver-highs/highs/mip/HighsCutGeneration.cpp +1491 -0
  891. data/ext/lpsolver-highs/highs/mip/HighsCutGeneration.h +108 -0
  892. data/ext/lpsolver-highs/highs/mip/HighsCutPool.cpp +526 -0
  893. data/ext/lpsolver-highs/highs/mip/HighsCutPool.h +168 -0
  894. data/ext/lpsolver-highs/highs/mip/HighsDebugSol.cpp +313 -0
  895. data/ext/lpsolver-highs/highs/mip/HighsDebugSol.h +133 -0
  896. data/ext/lpsolver-highs/highs/mip/HighsDomain.cpp +3861 -0
  897. data/ext/lpsolver-highs/highs/mip/HighsDomain.h +657 -0
  898. data/ext/lpsolver-highs/highs/mip/HighsDomainChange.h +48 -0
  899. data/ext/lpsolver-highs/highs/mip/HighsDynamicRowMatrix.cpp +199 -0
  900. data/ext/lpsolver-highs/highs/mip/HighsDynamicRowMatrix.h +104 -0
  901. data/ext/lpsolver-highs/highs/mip/HighsFeasibilityJump.cpp +139 -0
  902. data/ext/lpsolver-highs/highs/mip/HighsGFkSolve.cpp +106 -0
  903. data/ext/lpsolver-highs/highs/mip/HighsGFkSolve.h +439 -0
  904. data/ext/lpsolver-highs/highs/mip/HighsImplications.cpp +915 -0
  905. data/ext/lpsolver-highs/highs/mip/HighsImplications.h +194 -0
  906. data/ext/lpsolver-highs/highs/mip/HighsLpAggregator.cpp +56 -0
  907. data/ext/lpsolver-highs/highs/mip/HighsLpAggregator.h +50 -0
  908. data/ext/lpsolver-highs/highs/mip/HighsLpRelaxation.cpp +1609 -0
  909. data/ext/lpsolver-highs/highs/mip/HighsLpRelaxation.h +361 -0
  910. data/ext/lpsolver-highs/highs/mip/HighsMipAnalysis.cpp +313 -0
  911. data/ext/lpsolver-highs/highs/mip/HighsMipAnalysis.h +71 -0
  912. data/ext/lpsolver-highs/highs/mip/HighsMipSolver.cpp +1002 -0
  913. data/ext/lpsolver-highs/highs/mip/HighsMipSolver.h +159 -0
  914. data/ext/lpsolver-highs/highs/mip/HighsMipSolverData.cpp +2936 -0
  915. data/ext/lpsolver-highs/highs/mip/HighsMipSolverData.h +313 -0
  916. data/ext/lpsolver-highs/highs/mip/HighsModkSeparator.cpp +267 -0
  917. data/ext/lpsolver-highs/highs/mip/HighsModkSeparator.h +60 -0
  918. data/ext/lpsolver-highs/highs/mip/HighsNodeQueue.cpp +443 -0
  919. data/ext/lpsolver-highs/highs/mip/HighsNodeQueue.h +312 -0
  920. data/ext/lpsolver-highs/highs/mip/HighsObjectiveFunction.cpp +124 -0
  921. data/ext/lpsolver-highs/highs/mip/HighsObjectiveFunction.h +71 -0
  922. data/ext/lpsolver-highs/highs/mip/HighsPathSeparator.cpp +549 -0
  923. data/ext/lpsolver-highs/highs/mip/HighsPathSeparator.h +39 -0
  924. data/ext/lpsolver-highs/highs/mip/HighsPrimalHeuristics.cpp +1673 -0
  925. data/ext/lpsolver-highs/highs/mip/HighsPrimalHeuristics.h +75 -0
  926. data/ext/lpsolver-highs/highs/mip/HighsPseudocost.cpp +129 -0
  927. data/ext/lpsolver-highs/highs/mip/HighsPseudocost.h +366 -0
  928. data/ext/lpsolver-highs/highs/mip/HighsRedcostFixing.cpp +316 -0
  929. data/ext/lpsolver-highs/highs/mip/HighsRedcostFixing.h +42 -0
  930. data/ext/lpsolver-highs/highs/mip/HighsSearch.cpp +1881 -0
  931. data/ext/lpsolver-highs/highs/mip/HighsSearch.h +241 -0
  932. data/ext/lpsolver-highs/highs/mip/HighsSeparation.cpp +186 -0
  933. data/ext/lpsolver-highs/highs/mip/HighsSeparation.h +41 -0
  934. data/ext/lpsolver-highs/highs/mip/HighsSeparator.cpp +39 -0
  935. data/ext/lpsolver-highs/highs/mip/HighsSeparator.h +60 -0
  936. data/ext/lpsolver-highs/highs/mip/HighsTableauSeparator.cpp +244 -0
  937. data/ext/lpsolver-highs/highs/mip/HighsTableauSeparator.h +34 -0
  938. data/ext/lpsolver-highs/highs/mip/HighsTransformedLp.cpp +563 -0
  939. data/ext/lpsolver-highs/highs/mip/HighsTransformedLp.h +63 -0
  940. data/ext/lpsolver-highs/highs/mip/MipTimer.h +544 -0
  941. data/ext/lpsolver-highs/highs/mip/feasibilityjump.hh +800 -0
  942. data/ext/lpsolver-highs/highs/model/HighsHessian.cpp +263 -0
  943. data/ext/lpsolver-highs/highs/model/HighsHessian.h +54 -0
  944. data/ext/lpsolver-highs/highs/model/HighsHessianUtils.cpp +584 -0
  945. data/ext/lpsolver-highs/highs/model/HighsHessianUtils.h +47 -0
  946. data/ext/lpsolver-highs/highs/model/HighsModel.cpp +46 -0
  947. data/ext/lpsolver-highs/highs/model/HighsModel.h +42 -0
  948. data/ext/lpsolver-highs/highs/parallel/HighsBinarySemaphore.h +108 -0
  949. data/ext/lpsolver-highs/highs/parallel/HighsCacheAlign.h +82 -0
  950. data/ext/lpsolver-highs/highs/parallel/HighsCombinable.h +116 -0
  951. data/ext/lpsolver-highs/highs/parallel/HighsMutex.h +124 -0
  952. data/ext/lpsolver-highs/highs/parallel/HighsParallel.h +128 -0
  953. data/ext/lpsolver-highs/highs/parallel/HighsRaceTimer.h +38 -0
  954. data/ext/lpsolver-highs/highs/parallel/HighsSchedulerConstants.h +19 -0
  955. data/ext/lpsolver-highs/highs/parallel/HighsSpinMutex.h +48 -0
  956. data/ext/lpsolver-highs/highs/parallel/HighsSplitDeque.h +606 -0
  957. data/ext/lpsolver-highs/highs/parallel/HighsTask.h +170 -0
  958. data/ext/lpsolver-highs/highs/parallel/HighsTaskExecutor.cpp +43 -0
  959. data/ext/lpsolver-highs/highs/parallel/HighsTaskExecutor.h +217 -0
  960. data/ext/lpsolver-highs/highs/pdlp/CupdlpWrapper.cpp +848 -0
  961. data/ext/lpsolver-highs/highs/pdlp/CupdlpWrapper.h +108 -0
  962. data/ext/lpsolver-highs/highs/pdlp/HiPdlpTimer.h +155 -0
  963. data/ext/lpsolver-highs/highs/pdlp/HiPdlpWrapper.cpp +141 -0
  964. data/ext/lpsolver-highs/highs/pdlp/HiPdlpWrapper.h +26 -0
  965. data/ext/lpsolver-highs/highs/pdlp/cupdlp/Diff +12 -0
  966. data/ext/lpsolver-highs/highs/pdlp/cupdlp/Meld +7 -0
  967. data/ext/lpsolver-highs/highs/pdlp/cupdlp/Merge +2 -0
  968. data/ext/lpsolver-highs/highs/pdlp/cupdlp/README.md +95 -0
  969. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/CMakeLists.txt +58 -0
  970. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cuda_kernels.cu +338 -0
  971. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cuda_kernels.cuh +319 -0
  972. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cudalinalg.cu +386 -0
  973. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cudalinalg.cuh +149 -0
  974. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/test_cublas.c +154 -0
  975. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/test_cuda_linalg.c +79 -0
  976. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp.h +16 -0
  977. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_cs.c +214 -0
  978. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_cs.h +40 -0
  979. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_defs.h +447 -0
  980. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_linalg.c +802 -0
  981. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_linalg.h +189 -0
  982. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_proj.c +148 -0
  983. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_proj.h +19 -0
  984. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_restart.c +124 -0
  985. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_restart.h +31 -0
  986. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_scaling.c +425 -0
  987. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_scaling.h +26 -0
  988. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_solver.c +1498 -0
  989. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_solver.h +105 -0
  990. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_step.c +478 -0
  991. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_step.h +37 -0
  992. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_utils.c +1850 -0
  993. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_utils.h +212 -0
  994. data/ext/lpsolver-highs/highs/pdlp/cupdlp/glbopts.h +342 -0
  995. data/ext/lpsolver-highs/highs/pdlp/hipdlp/defs.hpp +222 -0
  996. data/ext/lpsolver-highs/highs/pdlp/hipdlp/linalg.cc +231 -0
  997. data/ext/lpsolver-highs/highs/pdlp/hipdlp/linalg.hpp +61 -0
  998. data/ext/lpsolver-highs/highs/pdlp/hipdlp/logger.cc +225 -0
  999. data/ext/lpsolver-highs/highs/pdlp/hipdlp/logger.hpp +80 -0
  1000. data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg.cc +2798 -0
  1001. data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg.cu +497 -0
  1002. data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg.hpp +358 -0
  1003. data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg_kernels.hpp +77 -0
  1004. data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdlp_gpu_debug.hpp +62 -0
  1005. data/ext/lpsolver-highs/highs/pdlp/hipdlp/restart.cc +132 -0
  1006. data/ext/lpsolver-highs/highs/pdlp/hipdlp/restart.hpp +96 -0
  1007. data/ext/lpsolver-highs/highs/pdlp/hipdlp/scaling.cc +307 -0
  1008. data/ext/lpsolver-highs/highs/pdlp/hipdlp/scaling.hpp +74 -0
  1009. data/ext/lpsolver-highs/highs/pdlp/hipdlp/solver_results.hpp +65 -0
  1010. data/ext/lpsolver-highs/highs/presolve/HPresolve.cpp +8511 -0
  1011. data/ext/lpsolver-highs/highs/presolve/HPresolve.h +505 -0
  1012. data/ext/lpsolver-highs/highs/presolve/HPresolveAnalysis.cpp +239 -0
  1013. data/ext/lpsolver-highs/highs/presolve/HPresolveAnalysis.h +52 -0
  1014. data/ext/lpsolver-highs/highs/presolve/HighsPostsolveStack.cpp +1368 -0
  1015. data/ext/lpsolver-highs/highs/presolve/HighsPostsolveStack.h +943 -0
  1016. data/ext/lpsolver-highs/highs/presolve/HighsSymmetry.cpp +1921 -0
  1017. data/ext/lpsolver-highs/highs/presolve/HighsSymmetry.h +284 -0
  1018. data/ext/lpsolver-highs/highs/presolve/ICrash.cpp +474 -0
  1019. data/ext/lpsolver-highs/highs/presolve/ICrash.h +124 -0
  1020. data/ext/lpsolver-highs/highs/presolve/ICrashUtil.cpp +267 -0
  1021. data/ext/lpsolver-highs/highs/presolve/ICrashUtil.h +62 -0
  1022. data/ext/lpsolver-highs/highs/presolve/ICrashX.cpp +173 -0
  1023. data/ext/lpsolver-highs/highs/presolve/ICrashX.h +23 -0
  1024. data/ext/lpsolver-highs/highs/presolve/PresolveComponent.cpp +45 -0
  1025. data/ext/lpsolver-highs/highs/presolve/PresolveComponent.h +90 -0
  1026. data/ext/lpsolver-highs/highs/qpsolver/README.md +185 -0
  1027. data/ext/lpsolver-highs/highs/qpsolver/a_asm.cpp +139 -0
  1028. data/ext/lpsolver-highs/highs/qpsolver/a_asm.hpp +77 -0
  1029. data/ext/lpsolver-highs/highs/qpsolver/a_quass.cpp +194 -0
  1030. data/ext/lpsolver-highs/highs/qpsolver/a_quass.hpp +22 -0
  1031. data/ext/lpsolver-highs/highs/qpsolver/basis.cpp +443 -0
  1032. data/ext/lpsolver-highs/highs/qpsolver/basis.hpp +159 -0
  1033. data/ext/lpsolver-highs/highs/qpsolver/crashsolution.hpp +20 -0
  1034. data/ext/lpsolver-highs/highs/qpsolver/dantzigpricing.hpp +80 -0
  1035. data/ext/lpsolver-highs/highs/qpsolver/devexharrispricing.hpp +98 -0
  1036. data/ext/lpsolver-highs/highs/qpsolver/devexpricing.hpp +108 -0
  1037. data/ext/lpsolver-highs/highs/qpsolver/eventhandler.hpp +30 -0
  1038. data/ext/lpsolver-highs/highs/qpsolver/factor.hpp +408 -0
  1039. data/ext/lpsolver-highs/highs/qpsolver/feasibility_bounded.hpp +114 -0
  1040. data/ext/lpsolver-highs/highs/qpsolver/feasibility_highs.hpp +301 -0
  1041. data/ext/lpsolver-highs/highs/qpsolver/gradient.hpp +46 -0
  1042. data/ext/lpsolver-highs/highs/qpsolver/instance.hpp +70 -0
  1043. data/ext/lpsolver-highs/highs/qpsolver/matrix.hpp +342 -0
  1044. data/ext/lpsolver-highs/highs/qpsolver/perturbation.cpp +41 -0
  1045. data/ext/lpsolver-highs/highs/qpsolver/perturbation.hpp +15 -0
  1046. data/ext/lpsolver-highs/highs/qpsolver/pricing.hpp +22 -0
  1047. data/ext/lpsolver-highs/highs/qpsolver/qpconst.hpp +34 -0
  1048. data/ext/lpsolver-highs/highs/qpsolver/qpvector.hpp +242 -0
  1049. data/ext/lpsolver-highs/highs/qpsolver/quass.cpp +551 -0
  1050. data/ext/lpsolver-highs/highs/qpsolver/quass.hpp +27 -0
  1051. data/ext/lpsolver-highs/highs/qpsolver/ratiotest.cpp +146 -0
  1052. data/ext/lpsolver-highs/highs/qpsolver/ratiotest.hpp +26 -0
  1053. data/ext/lpsolver-highs/highs/qpsolver/reducedcosts.hpp +46 -0
  1054. data/ext/lpsolver-highs/highs/qpsolver/reducedgradient.hpp +95 -0
  1055. data/ext/lpsolver-highs/highs/qpsolver/runtime.hpp +45 -0
  1056. data/ext/lpsolver-highs/highs/qpsolver/scaling.cpp +123 -0
  1057. data/ext/lpsolver-highs/highs/qpsolver/scaling.hpp +15 -0
  1058. data/ext/lpsolver-highs/highs/qpsolver/settings.hpp +84 -0
  1059. data/ext/lpsolver-highs/highs/qpsolver/snippets.hpp +36 -0
  1060. data/ext/lpsolver-highs/highs/qpsolver/statistics.hpp +30 -0
  1061. data/ext/lpsolver-highs/highs/qpsolver/steepestedgepricing.hpp +173 -0
  1062. data/ext/lpsolver-highs/highs/simplex/HApp.h +550 -0
  1063. data/ext/lpsolver-highs/highs/simplex/HEkk.cpp +4404 -0
  1064. data/ext/lpsolver-highs/highs/simplex/HEkk.h +419 -0
  1065. data/ext/lpsolver-highs/highs/simplex/HEkkControl.cpp +146 -0
  1066. data/ext/lpsolver-highs/highs/simplex/HEkkDebug.cpp +1722 -0
  1067. data/ext/lpsolver-highs/highs/simplex/HEkkDual.cpp +3003 -0
  1068. data/ext/lpsolver-highs/highs/simplex/HEkkDual.h +513 -0
  1069. data/ext/lpsolver-highs/highs/simplex/HEkkDualMulti.cpp +1020 -0
  1070. data/ext/lpsolver-highs/highs/simplex/HEkkDualRHS.cpp +535 -0
  1071. data/ext/lpsolver-highs/highs/simplex/HEkkDualRHS.h +134 -0
  1072. data/ext/lpsolver-highs/highs/simplex/HEkkDualRow.cpp +697 -0
  1073. data/ext/lpsolver-highs/highs/simplex/HEkkDualRow.h +201 -0
  1074. data/ext/lpsolver-highs/highs/simplex/HEkkInterface.cpp +26 -0
  1075. data/ext/lpsolver-highs/highs/simplex/HEkkPrimal.cpp +2984 -0
  1076. data/ext/lpsolver-highs/highs/simplex/HEkkPrimal.h +191 -0
  1077. data/ext/lpsolver-highs/highs/simplex/HSimplex.cpp +330 -0
  1078. data/ext/lpsolver-highs/highs/simplex/HSimplex.h +42 -0
  1079. data/ext/lpsolver-highs/highs/simplex/HSimplexDebug.cpp +145 -0
  1080. data/ext/lpsolver-highs/highs/simplex/HSimplexDebug.h +48 -0
  1081. data/ext/lpsolver-highs/highs/simplex/HSimplexNla.cpp +517 -0
  1082. data/ext/lpsolver-highs/highs/simplex/HSimplexNla.h +158 -0
  1083. data/ext/lpsolver-highs/highs/simplex/HSimplexNlaDebug.cpp +373 -0
  1084. data/ext/lpsolver-highs/highs/simplex/HSimplexNlaFreeze.cpp +28 -0
  1085. data/ext/lpsolver-highs/highs/simplex/HSimplexNlaProductForm.cpp +113 -0
  1086. data/ext/lpsolver-highs/highs/simplex/HSimplexReport.cpp +77 -0
  1087. data/ext/lpsolver-highs/highs/simplex/HSimplexReport.h +21 -0
  1088. data/ext/lpsolver-highs/highs/simplex/HighsSimplexAnalysis.cpp +1495 -0
  1089. data/ext/lpsolver-highs/highs/simplex/HighsSimplexAnalysis.h +500 -0
  1090. data/ext/lpsolver-highs/highs/simplex/SimplexConst.h +273 -0
  1091. data/ext/lpsolver-highs/highs/simplex/SimplexStruct.h +263 -0
  1092. data/ext/lpsolver-highs/highs/simplex/SimplexTimer.h +414 -0
  1093. data/ext/lpsolver-highs/highs/test_kkt/DevKkt.cpp +469 -0
  1094. data/ext/lpsolver-highs/highs/test_kkt/DevKkt.h +143 -0
  1095. data/ext/lpsolver-highs/highs/test_kkt/KktCh2.cpp +305 -0
  1096. data/ext/lpsolver-highs/highs/test_kkt/KktCh2.h +79 -0
  1097. data/ext/lpsolver-highs/highs/util/FactorTimer.h +199 -0
  1098. data/ext/lpsolver-highs/highs/util/HFactor.cpp +2597 -0
  1099. data/ext/lpsolver-highs/highs/util/HFactor.h +587 -0
  1100. data/ext/lpsolver-highs/highs/util/HFactorConst.h +81 -0
  1101. data/ext/lpsolver-highs/highs/util/HFactorDebug.cpp +231 -0
  1102. data/ext/lpsolver-highs/highs/util/HFactorDebug.h +55 -0
  1103. data/ext/lpsolver-highs/highs/util/HFactorExtend.cpp +229 -0
  1104. data/ext/lpsolver-highs/highs/util/HFactorRefactor.cpp +304 -0
  1105. data/ext/lpsolver-highs/highs/util/HFactorUtils.cpp +122 -0
  1106. data/ext/lpsolver-highs/highs/util/HSet.cpp +197 -0
  1107. data/ext/lpsolver-highs/highs/util/HSet.h +89 -0
  1108. data/ext/lpsolver-highs/highs/util/HVector.h +22 -0
  1109. data/ext/lpsolver-highs/highs/util/HVectorBase.cpp +271 -0
  1110. data/ext/lpsolver-highs/highs/util/HVectorBase.h +102 -0
  1111. data/ext/lpsolver-highs/highs/util/HighsCDouble.h +323 -0
  1112. data/ext/lpsolver-highs/highs/util/HighsComponent.h +53 -0
  1113. data/ext/lpsolver-highs/highs/util/HighsDataStack.h +83 -0
  1114. data/ext/lpsolver-highs/highs/util/HighsDisjointSets.h +107 -0
  1115. data/ext/lpsolver-highs/highs/util/HighsHash.cpp +10 -0
  1116. data/ext/lpsolver-highs/highs/util/HighsHash.h +1274 -0
  1117. data/ext/lpsolver-highs/highs/util/HighsHashTree.h +1461 -0
  1118. data/ext/lpsolver-highs/highs/util/HighsInt.h +36 -0
  1119. data/ext/lpsolver-highs/highs/util/HighsIntegers.h +212 -0
  1120. data/ext/lpsolver-highs/highs/util/HighsLinearSumBounds.cpp +267 -0
  1121. data/ext/lpsolver-highs/highs/util/HighsLinearSumBounds.h +203 -0
  1122. data/ext/lpsolver-highs/highs/util/HighsMatrixPic.cpp +146 -0
  1123. data/ext/lpsolver-highs/highs/util/HighsMatrixPic.h +37 -0
  1124. data/ext/lpsolver-highs/highs/util/HighsMatrixSlice.h +561 -0
  1125. data/ext/lpsolver-highs/highs/util/HighsMatrixUtils.cpp +407 -0
  1126. data/ext/lpsolver-highs/highs/util/HighsMatrixUtils.h +57 -0
  1127. data/ext/lpsolver-highs/highs/util/HighsMemoryAllocation.h +63 -0
  1128. data/ext/lpsolver-highs/highs/util/HighsRandom.h +242 -0
  1129. data/ext/lpsolver-highs/highs/util/HighsRbTree.h +452 -0
  1130. data/ext/lpsolver-highs/highs/util/HighsSort.cpp +364 -0
  1131. data/ext/lpsolver-highs/highs/util/HighsSort.h +131 -0
  1132. data/ext/lpsolver-highs/highs/util/HighsSparseMatrix.cpp +1746 -0
  1133. data/ext/lpsolver-highs/highs/util/HighsSparseMatrix.h +151 -0
  1134. data/ext/lpsolver-highs/highs/util/HighsSparseVectorSum.h +95 -0
  1135. data/ext/lpsolver-highs/highs/util/HighsSplay.h +135 -0
  1136. data/ext/lpsolver-highs/highs/util/HighsTimer.h +385 -0
  1137. data/ext/lpsolver-highs/highs/util/HighsUtils.cpp +1259 -0
  1138. data/ext/lpsolver-highs/highs/util/HighsUtils.h +272 -0
  1139. data/ext/lpsolver-highs/highs/util/stringutil.cpp +131 -0
  1140. data/ext/lpsolver-highs/highs/util/stringutil.h +46 -0
  1141. data/ext/lpsolver-highs/highs.pc.in +12 -0
  1142. data/ext/lpsolver-highs/meson.build +198 -0
  1143. data/ext/lpsolver-highs/meson_options.txt +31 -0
  1144. data/ext/lpsolver-highs/nuget/HiGHS_Logo.png +0 -0
  1145. data/ext/lpsolver-highs/nuget/Highs.csproj +25 -0
  1146. data/ext/lpsolver-highs/nuget/Highs.csproj.in +36 -0
  1147. data/ext/lpsolver-highs/nuget/HowToAlternative.md +77 -0
  1148. data/ext/lpsolver-highs/nuget/README.md +38 -0
  1149. data/ext/lpsolver-highs/nuget/arm-toolchain.cmake +15 -0
  1150. data/ext/lpsolver-highs/nuget/build_linux-arm.sh +13 -0
  1151. data/ext/lpsolver-highs/nuget/build_linux.sh +10 -0
  1152. data/ext/lpsolver-highs/nuget/build_windows.ps1 +27 -0
  1153. data/ext/lpsolver-highs/nuget/generatePackage.ps1 +28 -0
  1154. data/ext/lpsolver-highs/pyproject.toml +221 -0
  1155. data/ext/lpsolver-highs/subprojects/pybind11.wrap +13 -0
  1156. data/ext/lpsolver-highs/tests/test_highspy.py +2310 -0
  1157. data/ext/lpsolver-highs/version.rc.in +50 -0
  1158. data/lib/lpsolver/highs +0 -0
  1159. data/lib/lpsolver/model.rb +28 -4
  1160. data/lib/lpsolver/native.so +0 -0
  1161. data/lib/lpsolver/native_model.rb +261 -0
  1162. data/lib/lpsolver/solution.rb +72 -7
  1163. data/lib/lpsolver/version.rb +1 -1
  1164. data/lpsolver.gemspec +4 -1
  1165. metadata +1176 -4
@@ -0,0 +1,1881 @@
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
+ #include "mip/HighsSearch.h"
9
+
10
+ #include <numeric>
11
+
12
+ #include "lp_data/HConst.h"
13
+ #include "mip/HighsCutGeneration.h"
14
+ #include "mip/HighsDomainChange.h"
15
+ #include "mip/HighsMipSolverData.h"
16
+
17
+ HighsSearch::HighsSearch(HighsMipSolver& mipsolver, HighsPseudocost& pseudocost)
18
+ : mipsolver(mipsolver),
19
+ lp(nullptr),
20
+ localdom(mipsolver.mipdata_->domain),
21
+ pseudocost(pseudocost) {
22
+ nnodes = 0;
23
+ treeweight = 0.0;
24
+ depthoffset = 0;
25
+ lpiterations = 0;
26
+ heurlpiterations = 0;
27
+ sblpiterations = 0;
28
+ upper_limit = kHighsInf;
29
+ inheuristic = false;
30
+ inbranching = false;
31
+ countTreeWeight = true;
32
+ childselrule = mipsolver.submip ? ChildSelectionRule::kHybridInferenceCost
33
+ : ChildSelectionRule::kRootSol;
34
+ // the infeasibility flag is overwritten and lost when setDomainChangeStack is
35
+ // called. therefore, assert that localdom is not infeasible here.
36
+ assert(!this->localdom.infeasible());
37
+ this->localdom.setDomainChangeStack(std::vector<HighsDomainChange>());
38
+ }
39
+
40
+ double HighsSearch::checkSol(const std::vector<double>& sol,
41
+ bool& integerfeasible) const {
42
+ HighsCDouble objval = 0.0;
43
+ integerfeasible = true;
44
+ for (HighsInt i = 0; i != mipsolver.numCol(); ++i) {
45
+ objval += sol[i] * mipsolver.colCost(i);
46
+ assert(std::isfinite(sol[i]));
47
+
48
+ if (!integerfeasible || !mipsolver.isColInteger(i)) continue;
49
+
50
+ if (fractionality(sol[i]) > mipsolver.mipdata_->feastol) {
51
+ integerfeasible = false;
52
+ }
53
+ }
54
+
55
+ return double(objval);
56
+ }
57
+
58
+ bool HighsSearch::orbitsValidInChildNode(
59
+ const HighsDomainChange& branchChg) const {
60
+ HighsInt branchCol = branchChg.column;
61
+ // if the variable is integral or we are in an up branch the stabilizer only
62
+ // stays valid if the column has been stabilized
63
+ const NodeData& currNode = nodestack.back();
64
+ if (!currNode.stabilizerOrbits ||
65
+ currNode.stabilizerOrbits->orbitCols.empty() ||
66
+ currNode.stabilizerOrbits->isStabilized(branchCol))
67
+ return true;
68
+
69
+ // a down branch stays valid if the variable is binary
70
+ if (branchChg.boundtype == HighsBoundType::kUpper &&
71
+ localdom.isGlobalBinary(branchChg.column))
72
+ return true;
73
+
74
+ return false;
75
+ }
76
+
77
+ double HighsSearch::getCutoffBound() const {
78
+ return std::min(mipsolver.mipdata_->upper_limit, upper_limit);
79
+ }
80
+
81
+ void HighsSearch::setRINSNeighbourhood(const std::vector<double>& basesol,
82
+ const std::vector<double>& relaxsol) {
83
+ for (HighsInt i = 0; i != mipsolver.numCol(); ++i) {
84
+ if (!mipsolver.isColInteger(i)) continue;
85
+ if (localdom.col_lower_[i] == localdom.col_upper_[i]) continue;
86
+
87
+ double intval = std::floor(basesol[i] + 0.5);
88
+ if (std::abs(relaxsol[i] - intval) < mipsolver.mipdata_->feastol) {
89
+ if (localdom.col_lower_[i] < intval)
90
+ localdom.changeBound(HighsBoundType::kLower, i,
91
+ std::min(intval, localdom.col_upper_[i]),
92
+ HighsDomain::Reason::unspecified());
93
+ if (localdom.col_upper_[i] > intval)
94
+ localdom.changeBound(HighsBoundType::kUpper, i,
95
+ std::max(intval, localdom.col_lower_[i]),
96
+ HighsDomain::Reason::unspecified());
97
+ }
98
+ }
99
+ }
100
+
101
+ void HighsSearch::setRENSNeighbourhood(const std::vector<double>& lpsol) {
102
+ for (HighsInt i = 0; i != mipsolver.numCol(); ++i) {
103
+ if (!mipsolver.isColInteger(i)) continue;
104
+ if (localdom.col_lower_[i] == localdom.col_upper_[i]) continue;
105
+
106
+ double downval = std::floor(lpsol[i] + mipsolver.mipdata_->feastol);
107
+ double upval = std::ceil(lpsol[i] - mipsolver.mipdata_->feastol);
108
+
109
+ if (localdom.col_lower_[i] < downval) {
110
+ localdom.changeBound(HighsBoundType::kLower, i,
111
+ std::min(downval, localdom.col_upper_[i]),
112
+ HighsDomain::Reason::unspecified());
113
+ if (localdom.infeasible()) return;
114
+ }
115
+ if (localdom.col_upper_[i] > upval) {
116
+ localdom.changeBound(HighsBoundType::kUpper, i,
117
+ std::max(upval, localdom.col_lower_[i]),
118
+ HighsDomain::Reason::unspecified());
119
+ if (localdom.infeasible()) return;
120
+ }
121
+ }
122
+ }
123
+
124
+ void HighsSearch::createNewNode() {
125
+ nodestack.emplace_back();
126
+ nodestack.back().domgchgStackPos = localdom.getDomainChangeStack().size();
127
+ }
128
+
129
+ void HighsSearch::cutoffNode() { nodestack.back().opensubtrees = 0; }
130
+
131
+ void HighsSearch::setMinReliable(HighsInt minreliable) {
132
+ pseudocost.setMinReliable(minreliable);
133
+ }
134
+
135
+ void HighsSearch::branchDownwards(HighsInt col, double newub,
136
+ double branchpoint) {
137
+ NodeData& currnode = nodestack.back();
138
+
139
+ assert(currnode.opensubtrees == 2);
140
+ assert(mipsolver.isColIntegral(col));
141
+
142
+ currnode.opensubtrees = 1;
143
+ currnode.branching_point = branchpoint;
144
+ currnode.branchingdecision.column = col;
145
+ currnode.branchingdecision.boundval = newub;
146
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
147
+
148
+ HighsInt domchgPos = localdom.getDomainChangeStack().size();
149
+ bool passStabilizerToChildNode =
150
+ orbitsValidInChildNode(currnode.branchingdecision);
151
+ localdom.changeBound(currnode.branchingdecision);
152
+ nodestack.emplace_back(
153
+ currnode.lower_bound, currnode.estimate, currnode.nodeBasis,
154
+ passStabilizerToChildNode ? currnode.stabilizerOrbits : nullptr);
155
+ nodestack.back().domgchgStackPos = domchgPos;
156
+ }
157
+
158
+ void HighsSearch::branchUpwards(HighsInt col, double newlb,
159
+ double branchpoint) {
160
+ NodeData& currnode = nodestack.back();
161
+
162
+ assert(currnode.opensubtrees == 2);
163
+ assert(mipsolver.isColIntegral(col));
164
+
165
+ currnode.opensubtrees = 1;
166
+ currnode.branching_point = branchpoint;
167
+ currnode.branchingdecision.column = col;
168
+ currnode.branchingdecision.boundval = newlb;
169
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
170
+
171
+ HighsInt domchgPos = localdom.getDomainChangeStack().size();
172
+ bool passStabilizerToChildNode =
173
+ orbitsValidInChildNode(currnode.branchingdecision);
174
+ localdom.changeBound(currnode.branchingdecision);
175
+ nodestack.emplace_back(
176
+ currnode.lower_bound, currnode.estimate, currnode.nodeBasis,
177
+ passStabilizerToChildNode ? currnode.stabilizerOrbits : nullptr);
178
+ nodestack.back().domgchgStackPos = domchgPos;
179
+ }
180
+
181
+ void HighsSearch::addBoundExceedingConflict() {
182
+ if (mipsolver.mipdata_->upper_limit != kHighsInf) {
183
+ double rhs;
184
+ if (lp->computeDualProof(mipsolver.mipdata_->domain,
185
+ mipsolver.mipdata_->upper_limit, inds, vals,
186
+ rhs)) {
187
+ if (mipsolver.mipdata_->domain.infeasible()) return;
188
+ localdom.conflictAnalysis(inds.data(), vals.data(), inds.size(), rhs,
189
+ mipsolver.mipdata_->conflictPool);
190
+
191
+ HighsCutGeneration cutGen(*lp, mipsolver.mipdata_->cutpool);
192
+ mipsolver.mipdata_->debugSolution.checkCut(inds.data(), vals.data(),
193
+ inds.size(), rhs);
194
+ cutGen.generateConflict(localdom, inds, vals, rhs);
195
+ }
196
+ }
197
+ }
198
+
199
+ void HighsSearch::addInfeasibleConflict() {
200
+ double rhs;
201
+ if (lp->getLpSolver().getModelStatus() == HighsModelStatus::kObjectiveBound)
202
+ lp->performAging();
203
+
204
+ if (lp->computeDualInfProof(mipsolver.mipdata_->domain, inds, vals, rhs)) {
205
+ if (mipsolver.mipdata_->domain.infeasible()) return;
206
+ // double minactlocal = 0.0;
207
+ // double minactglobal = 0.0;
208
+ // for (HighsInt i = 0; i < int(inds.size()); ++i) {
209
+ // if (vals[i] > 0.0) {
210
+ // minactlocal += localdom.col_lower_[inds[i]] * vals[i];
211
+ // minactglobal += globaldom.col_lower_[inds[i]] * vals[i];
212
+ // } else {
213
+ // minactlocal += localdom.col_upper_[inds[i]] * vals[i];
214
+ // minactglobal += globaldom.col_upper_[inds[i]] * vals[i];
215
+ // }
216
+ //}
217
+ // HighsInt oldnumcuts = cutpool.getNumCuts();
218
+ localdom.conflictAnalysis(inds.data(), vals.data(), inds.size(), rhs,
219
+ mipsolver.mipdata_->conflictPool);
220
+
221
+ HighsCutGeneration cutGen(*lp, mipsolver.mipdata_->cutpool);
222
+ mipsolver.mipdata_->debugSolution.checkCut(inds.data(), vals.data(),
223
+ inds.size(), rhs);
224
+ cutGen.generateConflict(localdom, inds, vals, rhs);
225
+
226
+ // if (cutpool.getNumCuts() > oldnumcuts) {
227
+ // printf(
228
+ // "added cut from infeasibility proof with local min activity %g, "
229
+ // "global min activity %g, and rhs %g\n",
230
+ // minactlocal, minactglobal, rhs);
231
+ //} else {
232
+ // printf(
233
+ // "no cut found for infeasibility proof with local min activity %g, "
234
+ // "global min "
235
+ // " activity %g, and rhs % g\n ",
236
+ // minactlocal, minactglobal, rhs);
237
+ //}
238
+ // HighsInt cutind = cutpool.addCut(inds.data(), vals.data(), inds.size(),
239
+ // rhs); localdom.cutAdded(cutind);
240
+ }
241
+ }
242
+
243
+ HighsInt HighsSearch::selectBranchingCandidate(int64_t maxSbIters,
244
+ double& downNodeLb,
245
+ double& upNodeLb) {
246
+ assert(!lp->getFractionalIntegers().empty());
247
+
248
+ std::vector<double> upscore;
249
+ std::vector<double> downscore;
250
+ std::vector<uint8_t> upscorereliable;
251
+ std::vector<uint8_t> downscorereliable;
252
+ std::vector<double> upbound;
253
+ std::vector<double> downbound;
254
+
255
+ HighsInt numfrac = lp->getFractionalIntegers().size();
256
+ const auto& fracints = lp->getFractionalIntegers();
257
+
258
+ upscore.resize(numfrac, kHighsInf);
259
+ downscore.resize(numfrac, kHighsInf);
260
+ upbound.resize(numfrac, getCurrentLowerBound());
261
+ downbound.resize(numfrac, getCurrentLowerBound());
262
+
263
+ upscorereliable.resize(numfrac, 0);
264
+ downscorereliable.resize(numfrac, 0);
265
+
266
+ // initialize up and down scores of variables that have a
267
+ // reliable pseudocost so that they do not get evaluated
268
+ for (HighsInt k = 0; k != numfrac; ++k) {
269
+ HighsInt col = fracints[k].first;
270
+ double fracval = fracints[k].second;
271
+
272
+ const double lower_residual =
273
+ (fracval - localdom.col_lower_[col]) - mipsolver.mipdata_->feastol;
274
+ const bool lower_ok = lower_residual > 0;
275
+ if (!lower_ok)
276
+ highsLogUser(mipsolver.options_mip_->log_options, HighsLogType::kError,
277
+ "HighsSearch::selectBranchingCandidate Error fracval = %g "
278
+ "<= %g = %g + %g = "
279
+ "localdom.col_lower_[col] + mipsolver.mipdata_->feastol: "
280
+ "Residual %g\n",
281
+ fracval,
282
+ localdom.col_lower_[col] + mipsolver.mipdata_->feastol,
283
+ localdom.col_lower_[col], mipsolver.mipdata_->feastol,
284
+ lower_residual);
285
+
286
+ const double upper_residual =
287
+ (localdom.col_upper_[col] - fracval) - mipsolver.mipdata_->feastol;
288
+ const bool upper_ok = upper_residual > 0;
289
+ if (!upper_ok)
290
+ highsLogUser(mipsolver.options_mip_->log_options, HighsLogType::kError,
291
+ "HighsSearch::selectBranchingCandidate Error fracval = %g "
292
+ ">= %g = %g - %g = "
293
+ "localdom.col_upper_[col] - mipsolver.mipdata_->feastol: "
294
+ "Residual %g\n",
295
+ fracval,
296
+ localdom.col_upper_[col] - mipsolver.mipdata_->feastol,
297
+ localdom.col_upper_[col], mipsolver.mipdata_->feastol,
298
+ upper_residual);
299
+
300
+ assert(lower_residual > -1e-12 && upper_residual > -1e-12);
301
+
302
+ // assert(fracval > localdom.col_lower_[col] +
303
+ // mipsolver.mipdata_->feastol); assert(fracval <
304
+ // localdom.col_upper_[col] - mipsolver.mipdata_->feastol);
305
+
306
+ if (pseudocost.isReliable(col)) {
307
+ upscore[k] = pseudocost.getPseudocostUp(col, fracval);
308
+ downscore[k] = pseudocost.getPseudocostDown(col, fracval);
309
+ upscorereliable[k] = true;
310
+ downscorereliable[k] = true;
311
+ } else {
312
+ int flags = branchingVarReliableAtNodeFlags(col);
313
+ if (flags & kUpReliable) {
314
+ upscore[k] = pseudocost.getPseudocostUp(col, fracval);
315
+ upscorereliable[k] = true;
316
+ }
317
+
318
+ if (flags & kDownReliable) {
319
+ downscore[k] = pseudocost.getPseudocostDown(col, fracval);
320
+ downscorereliable[k] = true;
321
+ }
322
+ }
323
+ }
324
+
325
+ std::vector<HighsInt> evalqueue;
326
+ evalqueue.resize(numfrac);
327
+ std::iota(evalqueue.begin(), evalqueue.end(), 0);
328
+
329
+ auto numNodesUp = [&](HighsInt k) {
330
+ return mipsolver.mipdata_->nodequeue.numNodesUp(fracints[k].first);
331
+ };
332
+
333
+ auto numNodesDown = [&](HighsInt k) {
334
+ return mipsolver.mipdata_->nodequeue.numNodesDown(fracints[k].first);
335
+ };
336
+
337
+ double minScore = mipsolver.mipdata_->feastol;
338
+
339
+ auto selectBestScore = [&](bool finalSelection) {
340
+ HighsInt best = -1;
341
+ double bestscore = -1.0;
342
+ double bestnodes = -1.0;
343
+ int64_t bestnumnodes = 0;
344
+
345
+ double oldminscore = minScore;
346
+ for (HighsInt k : evalqueue) {
347
+ double score;
348
+
349
+ if (upscore[k] <= oldminscore) upscorereliable[k] = true;
350
+ if (downscore[k] <= oldminscore) downscorereliable[k] = true;
351
+
352
+ double s = 1e-3 * std::min(upscorereliable[k] ? upscore[k] : 0,
353
+ downscorereliable[k] ? downscore[k] : 0);
354
+ minScore = std::max(s, minScore);
355
+
356
+ if (upscore[k] <= oldminscore || downscore[k] <= oldminscore)
357
+ score = pseudocost.getScore(fracints[k].first,
358
+ std::min(upscore[k], oldminscore),
359
+ std::min(downscore[k], oldminscore));
360
+ else {
361
+ score = upscore[k] == kHighsInf || downscore[k] == kHighsInf
362
+ ? finalSelection ? pseudocost.getScore(fracints[k].first,
363
+ fracints[k].second)
364
+ : kHighsInf
365
+ : pseudocost.getScore(fracints[k].first, upscore[k],
366
+ downscore[k]);
367
+ }
368
+
369
+ assert(score >= 0.0);
370
+ int64_t upnodes = numNodesUp(k);
371
+ int64_t downnodes = numNodesDown(k);
372
+ double nodes = 0;
373
+ int64_t numnodes = upnodes + downnodes;
374
+ if (upnodes != 0 || downnodes != 0)
375
+ nodes =
376
+ (downnodes / (double)(numnodes)) * (upnodes / (double)(numnodes));
377
+ if (score > bestscore ||
378
+ (score > bestscore - mipsolver.mipdata_->feastol &&
379
+ std::make_pair(nodes, numnodes) >
380
+ std::make_pair(bestnodes, bestnumnodes))) {
381
+ bestscore = score;
382
+ best = k;
383
+ bestnodes = nodes;
384
+ bestnumnodes = numnodes;
385
+ }
386
+ }
387
+
388
+ return best;
389
+ };
390
+
391
+ HighsLpRelaxation::Playground playground = lp->playground();
392
+
393
+ while (true) {
394
+ bool mustStop = getStrongBranchingLpIterations() >= maxSbIters ||
395
+ mipsolver.mipdata_->checkLimits();
396
+
397
+ HighsInt candidate = selectBestScore(mustStop);
398
+
399
+ if ((upscorereliable[candidate] && downscorereliable[candidate]) ||
400
+ mustStop) {
401
+ downNodeLb = downbound[candidate];
402
+ upNodeLb = upbound[candidate];
403
+ return candidate;
404
+ }
405
+
406
+ lp->setObjectiveLimit(mipsolver.mipdata_->upper_limit);
407
+
408
+ HighsInt col = fracints[candidate].first;
409
+ double fracval = fracints[candidate].second;
410
+ double upval = std::ceil(fracval);
411
+ double downval = std::floor(fracval);
412
+
413
+ auto analyzeSolution = [&](double objdelta,
414
+ const std::vector<double>& sol) {
415
+ size_t numChangedCols = localdom.getChangedCols().size();
416
+ HighsInt domchgStackSize = localdom.getDomainChangeStack().size();
417
+ const auto& domchgstack = localdom.getDomainChangeStack();
418
+
419
+ for (HighsInt k = 0; k != numfrac; ++k) {
420
+ if (fracints[k].first == col) continue;
421
+ double otherfracval = fracints[k].second;
422
+ double otherdownval = std::floor(fracints[k].second);
423
+ double otherupval = std::ceil(fracints[k].second);
424
+ if (sol[fracints[k].first] <=
425
+ otherdownval + mipsolver.mipdata_->feastol) {
426
+ if (localdom.col_upper_[fracints[k].first] >
427
+ otherdownval + mipsolver.mipdata_->feastol) {
428
+ localdom.changeBound(HighsBoundType::kUpper, fracints[k].first,
429
+ otherdownval);
430
+ if (localdom.infeasible()) {
431
+ localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
432
+ localdom.backtrack();
433
+ localdom.clearChangedCols(numChangedCols);
434
+ continue;
435
+ }
436
+ localdom.propagate();
437
+ if (localdom.infeasible()) {
438
+ localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
439
+ localdom.backtrack();
440
+ localdom.clearChangedCols(numChangedCols);
441
+ continue;
442
+ }
443
+
444
+ HighsInt newStackSize = localdom.getDomainChangeStack().size();
445
+
446
+ bool solutionValid = true;
447
+ for (HighsInt j = domchgStackSize + 1; j < newStackSize; ++j) {
448
+ if (domchgstack[j].boundtype == HighsBoundType::kLower) {
449
+ if (domchgstack[j].boundval >
450
+ sol[domchgstack[j].column] + mipsolver.mipdata_->feastol) {
451
+ solutionValid = false;
452
+ break;
453
+ }
454
+ } else {
455
+ if (domchgstack[j].boundval <
456
+ sol[domchgstack[j].column] - mipsolver.mipdata_->feastol) {
457
+ solutionValid = false;
458
+ break;
459
+ }
460
+ }
461
+ }
462
+
463
+ localdom.backtrack();
464
+ localdom.clearChangedCols(numChangedCols);
465
+ if (!solutionValid) continue;
466
+ }
467
+
468
+ if (objdelta <= mipsolver.mipdata_->feastol) {
469
+ pseudocost.addObservation(fracints[k].first,
470
+ otherdownval - otherfracval, objdelta);
471
+ markBranchingVarDownReliableAtNode(fracints[k].first);
472
+ }
473
+
474
+ downscore[k] = std::min(downscore[k], objdelta);
475
+ } else if (sol[fracints[k].first] >=
476
+ otherupval - mipsolver.mipdata_->feastol) {
477
+ if (localdom.col_lower_[fracints[k].first] <
478
+ otherupval - mipsolver.mipdata_->feastol) {
479
+ localdom.changeBound(HighsBoundType::kLower, fracints[k].first,
480
+ otherupval);
481
+
482
+ if (localdom.infeasible()) {
483
+ localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
484
+ localdom.backtrack();
485
+ localdom.clearChangedCols(numChangedCols);
486
+ continue;
487
+ }
488
+ localdom.propagate();
489
+ if (localdom.infeasible()) {
490
+ localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
491
+ localdom.backtrack();
492
+ localdom.clearChangedCols(numChangedCols);
493
+ continue;
494
+ }
495
+
496
+ HighsInt newStackSize = localdom.getDomainChangeStack().size();
497
+
498
+ bool solutionValid = true;
499
+ for (HighsInt j = domchgStackSize + 1; j < newStackSize; ++j) {
500
+ if (domchgstack[j].boundtype == HighsBoundType::kLower) {
501
+ if (domchgstack[j].boundval >
502
+ sol[domchgstack[j].column] + mipsolver.mipdata_->feastol) {
503
+ solutionValid = false;
504
+ break;
505
+ }
506
+ } else {
507
+ if (domchgstack[j].boundval <
508
+ sol[domchgstack[j].column] - mipsolver.mipdata_->feastol) {
509
+ solutionValid = false;
510
+ break;
511
+ }
512
+ }
513
+ }
514
+
515
+ localdom.backtrack();
516
+ localdom.clearChangedCols(numChangedCols);
517
+
518
+ if (!solutionValid) continue;
519
+ }
520
+
521
+ if (objdelta <= mipsolver.mipdata_->feastol) {
522
+ pseudocost.addObservation(fracints[k].first,
523
+ otherupval - otherfracval, objdelta);
524
+ markBranchingVarUpReliableAtNode(fracints[k].first);
525
+ }
526
+
527
+ upscore[k] = std::min(upscore[k], objdelta);
528
+ }
529
+ }
530
+ };
531
+
532
+ auto strongBranch = [&](bool upbranch) -> bool {
533
+ int64_t inferences = -(int64_t)localdom.getDomainChangeStack().size() - 1;
534
+ HighsBoundType boundtype =
535
+ upbranch ? HighsBoundType::kLower : HighsBoundType::kUpper;
536
+ double boundval = upbranch ? upval : downval;
537
+ HighsDomainChange domchg{boundval, col, boundtype};
538
+
539
+ bool orbitalFixing =
540
+ nodestack.back().stabilizerOrbits && orbitsValidInChildNode(domchg);
541
+ localdom.changeBound(domchg);
542
+ localdom.propagate();
543
+
544
+ if (!localdom.infeasible()) {
545
+ if (orbitalFixing)
546
+ nodestack.back().stabilizerOrbits->orbitalFixing(localdom);
547
+ else
548
+ mipsolver.mipdata_->symmetries.propagateOrbitopes(localdom);
549
+ }
550
+
551
+ inferences += localdom.getDomainChangeStack().size();
552
+ if (localdom.infeasible()) {
553
+ localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
554
+ pseudocost.addCutoffObservation(col, upbranch);
555
+ localdom.backtrack();
556
+ localdom.clearChangedCols();
557
+
558
+ if (upbranch) {
559
+ branchDownwards(col, downval, fracval);
560
+ } else {
561
+ branchUpwards(col, upval, fracval);
562
+ }
563
+ nodestack[nodestack.size() - 2].opensubtrees = 0;
564
+ nodestack[nodestack.size() - 2].skipDepthCount = 1;
565
+ depthoffset -= 1;
566
+
567
+ return true;
568
+ }
569
+
570
+ pseudocost.addInferenceObservation(col, inferences, upbranch);
571
+
572
+ int64_t numiters = lp->getNumLpIterations();
573
+ HighsLpRelaxation::Status status = playground.solveLp(localdom);
574
+ numiters = lp->getNumLpIterations() - numiters;
575
+ lpiterations += numiters;
576
+ sblpiterations += numiters;
577
+
578
+ if (lp->scaledOptimal(status)) {
579
+ lp->performAging();
580
+
581
+ double delta = upbranch ? upval - fracval : downval - fracval;
582
+ bool integerfeasible;
583
+ const std::vector<double>& sol = lp->getSolution().col_value;
584
+ double solobj = checkSol(sol, integerfeasible);
585
+
586
+ double objdelta = std::max(solobj - lp->getObjective(), 0.0);
587
+ if (objdelta <= mipsolver.mipdata_->epsilon) objdelta = 0.0;
588
+
589
+ if (upbranch) {
590
+ upscore[candidate] = objdelta;
591
+ upscorereliable[candidate] = true;
592
+ markBranchingVarUpReliableAtNode(col);
593
+ } else {
594
+ downscore[candidate] = objdelta;
595
+ downscorereliable[candidate] = true;
596
+ markBranchingVarDownReliableAtNode(col);
597
+ }
598
+ pseudocost.addObservation(col, delta, objdelta);
599
+ analyzeSolution(objdelta, sol);
600
+
601
+ if (lp->unscaledPrimalFeasible(status) && integerfeasible) {
602
+ double cutoffbnd = getCutoffBound();
603
+ mipsolver.mipdata_->addIncumbent(
604
+ lp->getLpSolver().getSolution().col_value, solobj,
605
+ inheuristic ? kSolutionSourceHeuristic
606
+ : kSolutionSourceBranching);
607
+
608
+ if (mipsolver.mipdata_->upper_limit < cutoffbnd)
609
+ lp->setObjectiveLimit(mipsolver.mipdata_->upper_limit);
610
+ }
611
+
612
+ if (lp->unscaledDualFeasible(status)) {
613
+ if (upbranch) {
614
+ upbound[candidate] = solobj;
615
+ } else {
616
+ downbound[candidate] = solobj;
617
+ }
618
+ if (solobj > mipsolver.mipdata_->optimality_limit) {
619
+ addBoundExceedingConflict();
620
+
621
+ bool pruned = solobj > getCutoffBound();
622
+ if (pruned) mipsolver.mipdata_->debugSolution.nodePruned(localdom);
623
+
624
+ localdom.backtrack();
625
+ lp->flushDomain(localdom);
626
+
627
+ if (upbranch) {
628
+ branchDownwards(col, downval, fracval);
629
+ } else {
630
+ branchUpwards(col, upval, fracval);
631
+ }
632
+ nodestack[nodestack.size() - 2].opensubtrees = pruned ? 0 : 1;
633
+ nodestack[nodestack.size() - 2].other_child_lb = solobj;
634
+ nodestack[nodestack.size() - 2].skipDepthCount = 1;
635
+ depthoffset -= 1;
636
+
637
+ return true;
638
+ }
639
+ } else if (solobj > getCutoffBound()) {
640
+ addBoundExceedingConflict();
641
+ localdom.propagate();
642
+ bool infeas = localdom.infeasible();
643
+ if (infeas) {
644
+ localdom.backtrack();
645
+ lp->flushDomain(localdom);
646
+
647
+ if (upbranch) {
648
+ branchDownwards(col, downval, fracval);
649
+ } else {
650
+ branchUpwards(col, upval, fracval);
651
+ }
652
+ nodestack[nodestack.size() - 2].opensubtrees = 0;
653
+ nodestack[nodestack.size() - 2].skipDepthCount = 1;
654
+ depthoffset -= 1;
655
+
656
+ return true;
657
+ }
658
+ }
659
+ } else if (status == HighsLpRelaxation::Status::kInfeasible) {
660
+ mipsolver.mipdata_->debugSolution.nodePruned(localdom);
661
+ addInfeasibleConflict();
662
+ pseudocost.addCutoffObservation(col, upbranch);
663
+ localdom.backtrack();
664
+ lp->flushDomain(localdom);
665
+
666
+ if (upbranch) {
667
+ branchDownwards(col, downval, fracval);
668
+ } else {
669
+ branchUpwards(col, upval, fracval);
670
+ }
671
+ nodestack[nodestack.size() - 2].opensubtrees = 0;
672
+ nodestack[nodestack.size() - 2].skipDepthCount = 1;
673
+ depthoffset -= 1;
674
+
675
+ return true;
676
+ } else {
677
+ // printf("todo2\n");
678
+ // in case of an LP error we set the score of this variable to zero to
679
+ // avoid choosing it as branching candidate if possible
680
+ downscore[candidate] = 0.0;
681
+ upscore[candidate] = 0.0;
682
+ downscorereliable[candidate] = 1;
683
+ upscorereliable[candidate] = 1;
684
+ markBranchingVarUpReliableAtNode(col);
685
+ markBranchingVarDownReliableAtNode(col);
686
+ }
687
+
688
+ localdom.backtrack();
689
+ lp->flushDomain(localdom);
690
+ return false;
691
+ };
692
+
693
+ if (!downscorereliable[candidate] &&
694
+ (upscorereliable[candidate] ||
695
+ std::make_pair(downscore[candidate],
696
+ pseudocost.getAvgInferencesDown(col)) >=
697
+ std::make_pair(upscore[candidate],
698
+ pseudocost.getAvgInferencesUp(col)))) {
699
+ // evaluate down branch
700
+ // if (!mipsolver.submip)
701
+ // printf("down eval col=%d fracval=%g\n", col, fracval);
702
+ if (strongBranch(false)) return -1;
703
+ } else {
704
+ // if (!mipsolver.submip)
705
+ // printf("up eval col=%d fracval=%g\n", col, fracval);
706
+ // evaluate up branch
707
+ if (strongBranch(true)) return -1;
708
+ }
709
+ }
710
+ }
711
+
712
+ const HighsSearch::NodeData* HighsSearch::getParentNodeData() const {
713
+ if (nodestack.size() <= 1) return nullptr;
714
+
715
+ return &nodestack[nodestack.size() - 2];
716
+ }
717
+
718
+ void HighsSearch::currentNodeToQueue(HighsNodeQueue& nodequeue) {
719
+ auto oldchangedcols = localdom.getChangedCols().size();
720
+ bool prune = nodestack.back().lower_bound > getCutoffBound();
721
+ if (!prune) {
722
+ localdom.propagate();
723
+ localdom.clearChangedCols(oldchangedcols);
724
+ prune = localdom.infeasible();
725
+ if (prune) localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
726
+ }
727
+ if (!prune) {
728
+ std::vector<HighsInt> branchPositions;
729
+ auto domchgStack = localdom.getReducedDomainChangeStack(branchPositions);
730
+ double tmpTreeWeight = nodequeue.emplaceNode(
731
+ std::move(domchgStack), std::move(branchPositions),
732
+ std::max(nodestack.back().lower_bound,
733
+ localdom.getObjectiveLowerBound()),
734
+ nodestack.back().estimate, getCurrentDepth());
735
+ if (countTreeWeight) treeweight += tmpTreeWeight;
736
+ } else {
737
+ mipsolver.mipdata_->debugSolution.nodePruned(localdom);
738
+ if (countTreeWeight) treeweight += std::ldexp(1.0, 1 - getCurrentDepth());
739
+ }
740
+ nodestack.back().opensubtrees = 0;
741
+ }
742
+
743
+ void HighsSearch::openNodesToQueue(HighsNodeQueue& nodequeue) {
744
+ if (nodestack.empty()) return;
745
+
746
+ // get the basis of the node highest up in the tree
747
+ std::shared_ptr<const HighsBasis> basis;
748
+ for (NodeData& nodeData : nodestack) {
749
+ if (nodeData.nodeBasis) {
750
+ basis = std::move(nodeData.nodeBasis);
751
+ break;
752
+ }
753
+ }
754
+
755
+ if (nodestack.back().opensubtrees == 0) backtrack(false);
756
+
757
+ while (!nodestack.empty()) {
758
+ auto oldchangedcols = localdom.getChangedCols().size();
759
+ bool prune = nodestack.back().lower_bound > getCutoffBound();
760
+ if (!prune) {
761
+ localdom.propagate();
762
+ localdom.clearChangedCols(oldchangedcols);
763
+ prune = localdom.infeasible();
764
+ if (prune) localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
765
+ }
766
+ if (!prune) {
767
+ std::vector<HighsInt> branchPositions;
768
+ auto domchgStack = localdom.getReducedDomainChangeStack(branchPositions);
769
+ double tmpTreeWeight = nodequeue.emplaceNode(
770
+ std::move(domchgStack), std::move(branchPositions),
771
+ std::max(nodestack.back().lower_bound,
772
+ localdom.getObjectiveLowerBound()),
773
+ nodestack.back().estimate, getCurrentDepth());
774
+ if (countTreeWeight) treeweight += tmpTreeWeight;
775
+ } else {
776
+ mipsolver.mipdata_->debugSolution.nodePruned(localdom);
777
+ if (countTreeWeight) treeweight += std::ldexp(1.0, 1 - getCurrentDepth());
778
+ }
779
+ nodestack.back().opensubtrees = 0;
780
+ backtrack(false);
781
+ }
782
+
783
+ lp->flushDomain(localdom);
784
+ if (basis) {
785
+ if ((HighsInt)basis->row_status.size() == lp->numRows())
786
+ lp->setStoredBasis(std::move(basis));
787
+ lp->recoverBasis();
788
+ }
789
+ }
790
+
791
+ void HighsSearch::flushStatistics() {
792
+ mipsolver.mipdata_->num_nodes += nnodes;
793
+ nnodes = 0;
794
+
795
+ mipsolver.mipdata_->pruned_treeweight += treeweight;
796
+ treeweight = 0;
797
+
798
+ mipsolver.mipdata_->total_lp_iterations += lpiterations;
799
+ lpiterations = 0;
800
+
801
+ mipsolver.mipdata_->heuristic_lp_iterations += heurlpiterations;
802
+ heurlpiterations = 0;
803
+
804
+ mipsolver.mipdata_->sb_lp_iterations += sblpiterations;
805
+ sblpiterations = 0;
806
+ }
807
+
808
+ int64_t HighsSearch::getHeuristicLpIterations() const {
809
+ return heurlpiterations + mipsolver.mipdata_->heuristic_lp_iterations;
810
+ }
811
+
812
+ int64_t HighsSearch::getTotalLpIterations() const {
813
+ return lpiterations + mipsolver.mipdata_->total_lp_iterations;
814
+ }
815
+
816
+ int64_t HighsSearch::getLocalLpIterations() const { return lpiterations; }
817
+
818
+ int64_t HighsSearch::getLocalNodes() const { return nnodes; }
819
+
820
+ int64_t HighsSearch::getStrongBranchingLpIterations() const {
821
+ return sblpiterations + mipsolver.mipdata_->sb_lp_iterations;
822
+ }
823
+
824
+ void HighsSearch::resetLocalDomain() {
825
+ this->lp->resetToGlobalDomain();
826
+ localdom = mipsolver.mipdata_->domain;
827
+
828
+ #ifndef NDEBUG
829
+ for (HighsInt i = 0; i != mipsolver.numCol(); ++i) {
830
+ assert(lp->getLpSolver().getLp().col_lower_[i] == localdom.col_lower_[i] ||
831
+ mipsolver.isColContinuous(i));
832
+ assert(lp->getLpSolver().getLp().col_upper_[i] == localdom.col_upper_[i] ||
833
+ mipsolver.isColContinuous(i));
834
+ }
835
+ #endif
836
+ }
837
+
838
+ void HighsSearch::installNode(HighsNodeQueue::OpenNode&& node) {
839
+ localdom.setDomainChangeStack(node.domchgstack, node.branchings);
840
+ bool globalSymmetriesValid = true;
841
+ if (mipsolver.mipdata_->globalOrbits) {
842
+ // if global orbits have been computed we check whether they are still valid
843
+ // in this node
844
+ const auto& domchgstack = localdom.getDomainChangeStack();
845
+ for (HighsInt i : localdom.getBranchingPositions()) {
846
+ HighsInt col = domchgstack[i].column;
847
+ if (mipsolver.mipdata_->symmetries.columnPosition[col] == -1) continue;
848
+
849
+ if (!mipsolver.mipdata_->domain.isBinary(col) ||
850
+ (domchgstack[i].boundtype == HighsBoundType::kLower &&
851
+ domchgstack[i].boundval == 1.0)) {
852
+ globalSymmetriesValid = false;
853
+ break;
854
+ }
855
+ }
856
+ }
857
+ nodestack.emplace_back(
858
+ node.lower_bound, node.estimate, nullptr,
859
+ globalSymmetriesValid ? mipsolver.mipdata_->globalOrbits : nullptr);
860
+ subrootsol.clear();
861
+ depthoffset = node.depth - 1;
862
+ }
863
+
864
+ HighsSearch::NodeResult HighsSearch::evaluateNode() {
865
+ assert(!nodestack.empty());
866
+ NodeData& currnode = nodestack.back();
867
+ const NodeData* parent = getParentNodeData();
868
+
869
+ const auto& domchgstack = localdom.getDomainChangeStack();
870
+
871
+ if (!inheuristic &&
872
+ currnode.lower_bound > mipsolver.mipdata_->optimality_limit)
873
+ return NodeResult::kSubOptimal;
874
+
875
+ localdom.propagate();
876
+
877
+ if (!inheuristic && !localdom.infeasible()) {
878
+ if (mipsolver.mipdata_->symmetries.numPerms > 0 &&
879
+ !currnode.stabilizerOrbits &&
880
+ (parent == nullptr || !parent->stabilizerOrbits ||
881
+ !parent->stabilizerOrbits->orbitCols.empty())) {
882
+ currnode.stabilizerOrbits =
883
+ mipsolver.mipdata_->symmetries.computeStabilizerOrbits(localdom);
884
+ }
885
+
886
+ if (currnode.stabilizerOrbits)
887
+ currnode.stabilizerOrbits->orbitalFixing(localdom);
888
+ else
889
+ mipsolver.mipdata_->symmetries.propagateOrbitopes(localdom);
890
+ }
891
+ if (parent != nullptr) {
892
+ int64_t inferences = domchgstack.size() - (currnode.domgchgStackPos + 1);
893
+
894
+ pseudocost.addInferenceObservation(
895
+ parent->branchingdecision.column, inferences,
896
+ parent->branchingdecision.boundtype == HighsBoundType::kLower);
897
+ }
898
+
899
+ NodeResult result = NodeResult::kOpen;
900
+
901
+ if (localdom.infeasible()) {
902
+ result = NodeResult::kDomainInfeasible;
903
+ localdom.clearChangedCols();
904
+ if (parent != nullptr && parent->lp_objective != -kHighsInf &&
905
+ parent->branching_point != parent->branchingdecision.boundval) {
906
+ bool upbranch =
907
+ parent->branchingdecision.boundtype == HighsBoundType::kLower;
908
+ pseudocost.addCutoffObservation(parent->branchingdecision.column,
909
+ upbranch);
910
+ }
911
+
912
+ localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
913
+ } else {
914
+ lp->flushDomain(localdom);
915
+ lp->setObjectiveLimit(mipsolver.mipdata_->upper_limit);
916
+
917
+ #ifndef NDEBUG
918
+ for (HighsInt i = 0; i != mipsolver.numCol(); ++i) {
919
+ assert(lp->getLpSolver().getLp().col_lower_[i] ==
920
+ localdom.col_lower_[i] ||
921
+ mipsolver.isColContinuous(i));
922
+ assert(lp->getLpSolver().getLp().col_upper_[i] ==
923
+ localdom.col_upper_[i] ||
924
+ mipsolver.isColContinuous(i));
925
+ }
926
+ #endif
927
+ int64_t oldnumiters = lp->getNumLpIterations();
928
+ HighsLpRelaxation::Status status = lp->resolveLp(&localdom);
929
+ lpiterations += lp->getNumLpIterations() - oldnumiters;
930
+
931
+ currnode.lower_bound =
932
+ std::max(localdom.getObjectiveLowerBound(), currnode.lower_bound);
933
+
934
+ if (localdom.infeasible()) {
935
+ result = NodeResult::kDomainInfeasible;
936
+ localdom.clearChangedCols();
937
+ if (parent != nullptr && parent->lp_objective != -kHighsInf &&
938
+ parent->branching_point != parent->branchingdecision.boundval) {
939
+ bool upbranch =
940
+ parent->branchingdecision.boundtype == HighsBoundType::kLower;
941
+ pseudocost.addCutoffObservation(parent->branchingdecision.column,
942
+ upbranch);
943
+ }
944
+
945
+ localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
946
+ } else if (lp->scaledOptimal(status)) {
947
+ lp->storeBasis();
948
+ lp->performAging();
949
+
950
+ currnode.nodeBasis = lp->getStoredBasis();
951
+ currnode.estimate = lp->computeBestEstimate(pseudocost);
952
+ currnode.lp_objective = lp->getObjective();
953
+
954
+ if (parent != nullptr && parent->lp_objective != -kHighsInf &&
955
+ parent->branching_point != parent->branchingdecision.boundval) {
956
+ double delta =
957
+ parent->branchingdecision.boundval - parent->branching_point;
958
+ double objdelta =
959
+ std::max(0.0, currnode.lp_objective - parent->lp_objective);
960
+
961
+ pseudocost.addObservation(parent->branchingdecision.column, delta,
962
+ objdelta);
963
+ }
964
+
965
+ if (lp->unscaledPrimalFeasible(status)) {
966
+ if (lp->getFractionalIntegers().empty()) {
967
+ double cutoffbnd = getCutoffBound();
968
+ mipsolver.mipdata_->addIncumbent(
969
+ lp->getLpSolver().getSolution().col_value, lp->getObjective(),
970
+ inheuristic ? kSolutionSourceHeuristic
971
+ : kSolutionSourceEvaluateNode);
972
+ if (mipsolver.mipdata_->upper_limit < cutoffbnd)
973
+ lp->setObjectiveLimit(mipsolver.mipdata_->upper_limit);
974
+
975
+ if (lp->unscaledDualFeasible(status)) {
976
+ addBoundExceedingConflict();
977
+ result = NodeResult::kBoundExceeding;
978
+ }
979
+ }
980
+ }
981
+
982
+ if (result == NodeResult::kOpen) {
983
+ if (lp->unscaledDualFeasible(status)) {
984
+ currnode.lower_bound =
985
+ std::max(currnode.lp_objective, currnode.lower_bound);
986
+
987
+ if (currnode.lower_bound > getCutoffBound()) {
988
+ result = NodeResult::kBoundExceeding;
989
+ addBoundExceedingConflict();
990
+ } else if (mipsolver.mipdata_->upper_limit != kHighsInf) {
991
+ if (!inheuristic) {
992
+ double gap = mipsolver.mipdata_->upper_limit - lp->getObjective();
993
+ lp->computeBasicDegenerateDuals(
994
+ gap + std::max(10 * mipsolver.mipdata_->feastol,
995
+ mipsolver.mipdata_->epsilon * gap),
996
+ &localdom);
997
+ }
998
+ HighsRedcostFixing::propagateRedCost(mipsolver, localdom, *lp);
999
+ localdom.propagate();
1000
+ if (localdom.infeasible()) {
1001
+ result = NodeResult::kDomainInfeasible;
1002
+ localdom.clearChangedCols();
1003
+ if (parent != nullptr && parent->lp_objective != -kHighsInf &&
1004
+ parent->branching_point !=
1005
+ parent->branchingdecision.boundval) {
1006
+ bool upbranch = parent->branchingdecision.boundtype ==
1007
+ HighsBoundType::kLower;
1008
+ pseudocost.addCutoffObservation(
1009
+ parent->branchingdecision.column, upbranch);
1010
+ }
1011
+
1012
+ localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
1013
+ } else if (!localdom.getChangedCols().empty()) {
1014
+ return evaluateNode();
1015
+ }
1016
+ } else {
1017
+ if (!inheuristic) {
1018
+ lp->computeBasicDegenerateDuals(kHighsInf, &localdom);
1019
+ localdom.propagate();
1020
+ if (localdom.infeasible()) {
1021
+ result = NodeResult::kDomainInfeasible;
1022
+ localdom.clearChangedCols();
1023
+ if (parent != nullptr && parent->lp_objective != -kHighsInf &&
1024
+ parent->branching_point !=
1025
+ parent->branchingdecision.boundval) {
1026
+ bool upbranch = parent->branchingdecision.boundtype ==
1027
+ HighsBoundType::kLower;
1028
+ pseudocost.addCutoffObservation(
1029
+ parent->branchingdecision.column, upbranch);
1030
+ }
1031
+
1032
+ localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
1033
+ } else if (!localdom.getChangedCols().empty()) {
1034
+ return evaluateNode();
1035
+ }
1036
+ }
1037
+ }
1038
+ } else if (lp->getObjective() > getCutoffBound()) {
1039
+ // the LP is not solved to dual feasibility due to scaling/numerics
1040
+ // therefore we compute a conflict constraint as if the LP was bound
1041
+ // exceeding and propagate the local domain again. The lp relaxation
1042
+ // class will take care to consider the dual multipliers with an
1043
+ // increased zero tolerance due to the dual infeasibility when
1044
+ // computing the proof conBoundExceedingstraint.
1045
+ addBoundExceedingConflict();
1046
+ localdom.propagate();
1047
+ if (localdom.infeasible()) {
1048
+ result = NodeResult::kBoundExceeding;
1049
+ }
1050
+ }
1051
+ }
1052
+ } else if (status == HighsLpRelaxation::Status::kInfeasible) {
1053
+ if (lp->getLpSolver().getModelStatus() ==
1054
+ HighsModelStatus::kObjectiveBound)
1055
+ result = NodeResult::kBoundExceeding;
1056
+ else
1057
+ result = NodeResult::kLpInfeasible;
1058
+ addInfeasibleConflict();
1059
+ if (parent != nullptr && parent->lp_objective != -kHighsInf &&
1060
+ parent->branching_point != parent->branchingdecision.boundval) {
1061
+ bool upbranch =
1062
+ parent->branchingdecision.boundtype == HighsBoundType::kLower;
1063
+ pseudocost.addCutoffObservation(parent->branchingdecision.column,
1064
+ upbranch);
1065
+ }
1066
+ }
1067
+ }
1068
+
1069
+ if (result != NodeResult::kOpen) {
1070
+ mipsolver.mipdata_->debugSolution.nodePruned(localdom);
1071
+ treeweight += std::ldexp(1.0, 1 - getCurrentDepth());
1072
+ currnode.opensubtrees = 0;
1073
+ } else if (!inheuristic) {
1074
+ if (currnode.lower_bound > mipsolver.mipdata_->optimality_limit) {
1075
+ result = NodeResult::kSubOptimal;
1076
+ addBoundExceedingConflict();
1077
+ }
1078
+ }
1079
+
1080
+ return result;
1081
+ }
1082
+
1083
+ HighsSearch::NodeResult HighsSearch::branch() {
1084
+ assert(localdom.getChangedCols().empty());
1085
+
1086
+ assert(nodestack.back().opensubtrees == 2);
1087
+ nodestack.back().branchingdecision.column = -1;
1088
+ inbranching = true;
1089
+
1090
+ HighsInt minrel = pseudocost.getMinReliable();
1091
+ double childLb = getCurrentLowerBound();
1092
+ NodeResult result = NodeResult::kOpen;
1093
+ while (nodestack.back().opensubtrees == 2 &&
1094
+ lp->scaledOptimal(lp->getStatus()) &&
1095
+ !lp->getFractionalIntegers().empty()) {
1096
+ int64_t sbmaxiters = 0;
1097
+ if (minrel > 0) {
1098
+ int64_t sbiters = getStrongBranchingLpIterations();
1099
+ sbmaxiters =
1100
+ 100000 + ((getTotalLpIterations() - getHeuristicLpIterations() -
1101
+ getStrongBranchingLpIterations()) >>
1102
+ 1);
1103
+ if (sbiters > sbmaxiters) {
1104
+ pseudocost.setMinReliable(0);
1105
+ } else if (sbiters > (sbmaxiters >> 1)) {
1106
+ double reductionratio = (sbiters - (sbmaxiters >> 1)) /
1107
+ (double)(sbmaxiters - (sbmaxiters >> 1));
1108
+
1109
+ HighsInt minrelreduced = int(minrel - reductionratio * (minrel - 1));
1110
+ pseudocost.setMinReliable(std::min(minrel, minrelreduced));
1111
+ }
1112
+ }
1113
+
1114
+ double degeneracyFac = lp->computeLPDegneracy(localdom);
1115
+ pseudocost.setDegeneracyFactor(degeneracyFac);
1116
+ if (degeneracyFac >= 10.0) pseudocost.setMinReliable(0);
1117
+ // if (!mipsolver.submip)
1118
+ // printf("selecting branching cand with minrel=%d\n",
1119
+ // pseudocost.getMinReliable());
1120
+ double downNodeLb = getCurrentLowerBound();
1121
+ double upNodeLb = getCurrentLowerBound();
1122
+ HighsInt branchcand =
1123
+ selectBranchingCandidate(sbmaxiters, downNodeLb, upNodeLb);
1124
+ // if (!mipsolver.submip)
1125
+ // printf("branching cand returned as %d\n", branchcand);
1126
+ NodeData& currnode = nodestack.back();
1127
+ childLb = currnode.lower_bound;
1128
+ if (branchcand != -1) {
1129
+ auto branching = lp->getFractionalIntegers()[branchcand];
1130
+ currnode.branchingdecision.column = branching.first;
1131
+ currnode.branching_point = branching.second;
1132
+
1133
+ HighsInt col = branching.first;
1134
+
1135
+ switch (childselrule) {
1136
+ case ChildSelectionRule::kUp:
1137
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1138
+ currnode.branchingdecision.boundval =
1139
+ std::ceil(currnode.branching_point);
1140
+ currnode.other_child_lb = downNodeLb;
1141
+ childLb = upNodeLb;
1142
+ break;
1143
+ case ChildSelectionRule::kDown:
1144
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1145
+ currnode.branchingdecision.boundval =
1146
+ std::floor(currnode.branching_point);
1147
+ currnode.other_child_lb = upNodeLb;
1148
+ childLb = downNodeLb;
1149
+ break;
1150
+ case ChildSelectionRule::kRootSol: {
1151
+ double downPrio = pseudocost.getAvgInferencesDown(col) +
1152
+ mipsolver.mipdata_->epsilon;
1153
+ double upPrio =
1154
+ pseudocost.getAvgInferencesUp(col) + mipsolver.mipdata_->epsilon;
1155
+ double downVal = std::floor(currnode.branching_point);
1156
+ double upVal = std::ceil(currnode.branching_point);
1157
+ if (!subrootsol.empty()) {
1158
+ double rootsol = subrootsol[col];
1159
+ if (rootsol < downVal)
1160
+ rootsol = downVal;
1161
+ else if (rootsol > upVal)
1162
+ rootsol = upVal;
1163
+
1164
+ upPrio *= (1.0 + (currnode.branching_point - rootsol));
1165
+ downPrio *= (1.0 + (rootsol - currnode.branching_point));
1166
+
1167
+ } else {
1168
+ if (currnode.lp_objective != -kHighsInf)
1169
+ subrootsol = lp->getSolution().col_value;
1170
+ if (!mipsolver.mipdata_->rootlpsol.empty()) {
1171
+ double rootsol = mipsolver.mipdata_->rootlpsol[col];
1172
+ if (rootsol < downVal)
1173
+ rootsol = downVal;
1174
+ else if (rootsol > upVal)
1175
+ rootsol = upVal;
1176
+
1177
+ upPrio *= (1.0 + (currnode.branching_point - rootsol));
1178
+ downPrio *= (1.0 + (rootsol - currnode.branching_point));
1179
+ }
1180
+ }
1181
+ if (upPrio + mipsolver.mipdata_->epsilon >= downPrio) {
1182
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1183
+ currnode.branchingdecision.boundval = upVal;
1184
+ currnode.other_child_lb = downNodeLb;
1185
+ childLb = upNodeLb;
1186
+ } else {
1187
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1188
+ currnode.branchingdecision.boundval = downVal;
1189
+ currnode.other_child_lb = upNodeLb;
1190
+ childLb = downNodeLb;
1191
+ }
1192
+ break;
1193
+ }
1194
+ case ChildSelectionRule::kObj:
1195
+ if (mipsolver.colCost(col) >= 0) {
1196
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1197
+ currnode.branchingdecision.boundval =
1198
+ std::ceil(currnode.branching_point);
1199
+ currnode.other_child_lb = downNodeLb;
1200
+ childLb = upNodeLb;
1201
+ } else {
1202
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1203
+ currnode.branchingdecision.boundval =
1204
+ std::floor(currnode.branching_point);
1205
+ currnode.other_child_lb = upNodeLb;
1206
+ childLb = downNodeLb;
1207
+ }
1208
+ break;
1209
+ case ChildSelectionRule::kRandom:
1210
+ if (random.bit()) {
1211
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1212
+ currnode.branchingdecision.boundval =
1213
+ std::ceil(currnode.branching_point);
1214
+ currnode.other_child_lb = downNodeLb;
1215
+ childLb = upNodeLb;
1216
+ } else {
1217
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1218
+ currnode.branchingdecision.boundval =
1219
+ std::floor(currnode.branching_point);
1220
+ currnode.other_child_lb = upNodeLb;
1221
+ childLb = downNodeLb;
1222
+ }
1223
+ break;
1224
+ case ChildSelectionRule::kBestCost: {
1225
+ if (pseudocost.getPseudocostUp(col, currnode.branching_point,
1226
+ mipsolver.mipdata_->feastol) >
1227
+ pseudocost.getPseudocostDown(col, currnode.branching_point,
1228
+ mipsolver.mipdata_->feastol)) {
1229
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1230
+ currnode.branchingdecision.boundval =
1231
+ std::floor(currnode.branching_point);
1232
+ currnode.other_child_lb = upNodeLb;
1233
+ childLb = downNodeLb;
1234
+ } else {
1235
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1236
+ currnode.branchingdecision.boundval =
1237
+ std::ceil(currnode.branching_point);
1238
+ currnode.other_child_lb = downNodeLb;
1239
+ childLb = upNodeLb;
1240
+ }
1241
+ break;
1242
+ }
1243
+ case ChildSelectionRule::kWorstCost:
1244
+ if (pseudocost.getPseudocostUp(col, currnode.branching_point) >=
1245
+ pseudocost.getPseudocostDown(col, currnode.branching_point)) {
1246
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1247
+ currnode.branchingdecision.boundval =
1248
+ std::ceil(currnode.branching_point);
1249
+ currnode.other_child_lb = downNodeLb;
1250
+ childLb = upNodeLb;
1251
+ } else {
1252
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1253
+ currnode.branchingdecision.boundval =
1254
+ std::floor(currnode.branching_point);
1255
+ currnode.other_child_lb = upNodeLb;
1256
+ childLb = downNodeLb;
1257
+ }
1258
+ break;
1259
+ case ChildSelectionRule::kDisjunction: {
1260
+ int64_t numnodesup;
1261
+ int64_t numnodesdown;
1262
+ numnodesup = mipsolver.mipdata_->nodequeue.numNodesUp(col);
1263
+ numnodesdown = mipsolver.mipdata_->nodequeue.numNodesDown(col);
1264
+ if (numnodesup > numnodesdown) {
1265
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1266
+ currnode.branchingdecision.boundval =
1267
+ std::ceil(currnode.branching_point);
1268
+ currnode.other_child_lb = downNodeLb;
1269
+ childLb = upNodeLb;
1270
+ } else if (numnodesdown > numnodesup) {
1271
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1272
+ currnode.branchingdecision.boundval =
1273
+ std::floor(currnode.branching_point);
1274
+ currnode.other_child_lb = upNodeLb;
1275
+ childLb = downNodeLb;
1276
+ } else {
1277
+ if (mipsolver.colCost(col) >= 0) {
1278
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1279
+ currnode.branchingdecision.boundval =
1280
+ std::ceil(currnode.branching_point);
1281
+ currnode.other_child_lb = downNodeLb;
1282
+ childLb = upNodeLb;
1283
+ } else {
1284
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1285
+ currnode.branchingdecision.boundval =
1286
+ std::floor(currnode.branching_point);
1287
+ currnode.other_child_lb = upNodeLb;
1288
+ childLb = downNodeLb;
1289
+ }
1290
+ }
1291
+ break;
1292
+ }
1293
+ case ChildSelectionRule::kHybridInferenceCost: {
1294
+ double upVal = std::ceil(currnode.branching_point);
1295
+ double downVal = std::floor(currnode.branching_point);
1296
+ double upScore =
1297
+ (1 + pseudocost.getAvgInferencesUp(col)) /
1298
+ pseudocost.getPseudocostUp(col, currnode.branching_point,
1299
+ mipsolver.mipdata_->feastol);
1300
+ double downScore =
1301
+ (1 + pseudocost.getAvgInferencesDown(col)) /
1302
+ pseudocost.getPseudocostDown(col, currnode.branching_point,
1303
+ mipsolver.mipdata_->feastol);
1304
+
1305
+ if (upScore >= downScore) {
1306
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1307
+ currnode.branchingdecision.boundval = upVal;
1308
+ currnode.other_child_lb = downNodeLb;
1309
+ childLb = upNodeLb;
1310
+ } else {
1311
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1312
+ currnode.branchingdecision.boundval = downVal;
1313
+ currnode.other_child_lb = upNodeLb;
1314
+ childLb = downNodeLb;
1315
+ }
1316
+ }
1317
+ }
1318
+ result = NodeResult::kBranched;
1319
+ break;
1320
+ }
1321
+
1322
+ assert(!localdom.getChangedCols().empty());
1323
+ result = evaluateNode();
1324
+ if (result == NodeResult::kSubOptimal) break;
1325
+ }
1326
+ inbranching = false;
1327
+ NodeData& currnode = nodestack.back();
1328
+ pseudocost.setMinReliable(minrel);
1329
+ pseudocost.setDegeneracyFactor(1.0);
1330
+
1331
+ assert(currnode.opensubtrees == 2 || currnode.opensubtrees == 0);
1332
+
1333
+ if (currnode.opensubtrees != 2 || result == NodeResult::kSubOptimal)
1334
+ return result;
1335
+
1336
+ if (currnode.branchingdecision.column == -1) {
1337
+ double bestscore = -1.0;
1338
+ // solution branching failed, so choose any integer variable to branch
1339
+ // on in case we have a different solution status could happen due to a
1340
+ // fail in the LP solution process
1341
+ pseudocost.setDegeneracyFactor(1e6);
1342
+
1343
+ for (HighsInt i : mipsolver.mipdata_->integral_cols) {
1344
+ if (localdom.col_upper_[i] - localdom.col_lower_[i] < 0.5) continue;
1345
+
1346
+ double fracval;
1347
+ if (localdom.col_lower_[i] != -kHighsInf &&
1348
+ localdom.col_upper_[i] != kHighsInf)
1349
+ fracval = std::floor(0.5 * (localdom.col_lower_[i] +
1350
+ localdom.col_upper_[i] + 0.5)) +
1351
+ 0.5;
1352
+ if (localdom.col_lower_[i] != -kHighsInf)
1353
+ fracval = localdom.col_lower_[i] + 0.5;
1354
+ else if (localdom.col_upper_[i] != kHighsInf)
1355
+ fracval = localdom.col_upper_[i] - 0.5;
1356
+ else
1357
+ fracval = 0.5;
1358
+
1359
+ double score = pseudocost.getScore(i, fracval);
1360
+ assert(score >= 0.0);
1361
+
1362
+ if (score > bestscore) {
1363
+ bestscore = score;
1364
+ bool branchUpwards;
1365
+ double cost = lp->unscaledDualFeasible(lp->getStatus())
1366
+ ? lp->getSolution().col_dual[i]
1367
+ : mipsolver.colCost(i);
1368
+ if (std::fabs(cost) > mipsolver.mipdata_->feastol &&
1369
+ getCutoffBound() < kHighsInf) {
1370
+ // branch in direction of worsening cost first in case the column has
1371
+ // cost and we do have an upper bound
1372
+ branchUpwards = cost > 0;
1373
+ } else if (pseudocost.getAvgInferencesUp(i) >
1374
+ pseudocost.getAvgInferencesDown(i) +
1375
+ mipsolver.mipdata_->feastol) {
1376
+ // column does not have (reduced) cost above tolerance so branch in
1377
+ // direction of more inferences
1378
+ branchUpwards = true;
1379
+ } else if (pseudocost.getAvgInferencesUp(i) <
1380
+ pseudocost.getAvgInferencesDown(i) -
1381
+ mipsolver.mipdata_->feastol) {
1382
+ branchUpwards = false;
1383
+ } else {
1384
+ // number of inferences give a tie, so we branch in the direction that
1385
+ // does have a less recent domain change to avoid branching the same
1386
+ // integer column into the same direction over and over
1387
+ HighsInt colLowerPos;
1388
+ HighsInt colUpperPos;
1389
+ localdom.getColLowerPos(i, localdom.getNumDomainChanges(),
1390
+ colLowerPos);
1391
+ localdom.getColUpperPos(i, localdom.getNumDomainChanges(),
1392
+ colUpperPos);
1393
+ branchUpwards = colLowerPos <= colUpperPos;
1394
+ }
1395
+ if (branchUpwards) {
1396
+ double upval = std::ceil(fracval);
1397
+ currnode.branching_point = upval;
1398
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1399
+ currnode.branchingdecision.column = i;
1400
+ currnode.branchingdecision.boundval = upval;
1401
+ } else {
1402
+ double downval = std::floor(fracval);
1403
+ currnode.branching_point = downval;
1404
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1405
+ currnode.branchingdecision.column = i;
1406
+ currnode.branchingdecision.boundval = downval;
1407
+ }
1408
+ }
1409
+ }
1410
+
1411
+ pseudocost.setDegeneracyFactor(1);
1412
+ }
1413
+
1414
+ if (currnode.branchingdecision.column == -1) {
1415
+ if (lp->getStatus() == HighsLpRelaxation::Status::kOptimal) {
1416
+ // if the LP was solved to optimality and all columns are fixed, then this
1417
+ // particular assignment is not feasible or has a worse objective in the
1418
+ // original space, otherwise the node would not be open. Hence we prune
1419
+ // this particular assignment
1420
+ currnode.opensubtrees = 0;
1421
+ result = NodeResult::kLpInfeasible;
1422
+ return result;
1423
+ }
1424
+ lp->setIterationLimit();
1425
+
1426
+ // create a fresh LP only with model rows since all integer columns are
1427
+ // fixed, the cutting planes are not required and the LP could not be solved
1428
+ // so we want to make it as easy as possible
1429
+ HighsLpRelaxation lpCopy(mipsolver);
1430
+ lpCopy.loadModel();
1431
+ lpCopy.getLpSolver().changeColsBounds(0, mipsolver.numCol() - 1,
1432
+ localdom.col_lower_.data(),
1433
+ localdom.col_upper_.data());
1434
+ // temporarily use the fresh LP for the HighsSearch class
1435
+ HighsLpRelaxation* tmpLp = &lpCopy;
1436
+ std::swap(tmpLp, lp);
1437
+
1438
+ // reevaluate the node with LP presolve enabled
1439
+ lp->getLpSolver().setOptionValue("presolve", kHighsOnString);
1440
+ result = evaluateNode();
1441
+
1442
+ if (result == NodeResult::kOpen) {
1443
+ // LP still not solved, reevaluate with primal simplex
1444
+ lp->getLpSolver().clearSolver();
1445
+ lp->getLpSolver().setOptionValue("simplex_strategy",
1446
+ kSimplexStrategyPrimal);
1447
+ result = evaluateNode();
1448
+ lp->getLpSolver().setOptionValue("simplex_strategy",
1449
+ kSimplexStrategyDual);
1450
+ if (result == NodeResult::kOpen) {
1451
+ // LP still not solved, reevaluate with IPM instead of simplex
1452
+ lp->getLpSolver().clearSolver();
1453
+ lp->getLpSolver().setOptionValue("solver", "ipm");
1454
+ result = evaluateNode();
1455
+
1456
+ if (result == NodeResult::kOpen) {
1457
+ highsLogUser(mipsolver.options_mip_->log_options,
1458
+ HighsLogType::kWarning,
1459
+ "Failed to solve node with all integer columns "
1460
+ "fixed. Declaring node infeasible.\n");
1461
+ // LP still not solved, give up and declare as infeasible
1462
+ currnode.opensubtrees = 0;
1463
+ result = NodeResult::kLpInfeasible;
1464
+ }
1465
+ }
1466
+ }
1467
+
1468
+ // restore old lp relaxation
1469
+ std::swap(tmpLp, lp);
1470
+
1471
+ return result;
1472
+ }
1473
+
1474
+ // finally open a new node with the branching decision added
1475
+ // and remember that we have one open subtree left
1476
+ HighsInt domchgPos = localdom.getDomainChangeStack().size();
1477
+
1478
+ bool passStabilizerToChildNode =
1479
+ orbitsValidInChildNode(currnode.branchingdecision);
1480
+ localdom.changeBound(currnode.branchingdecision);
1481
+ currnode.opensubtrees = 1;
1482
+ nodestack.emplace_back(
1483
+ std::max(childLb, currnode.lower_bound), currnode.estimate,
1484
+ currnode.nodeBasis,
1485
+ passStabilizerToChildNode ? currnode.stabilizerOrbits : nullptr);
1486
+ nodestack.back().domgchgStackPos = domchgPos;
1487
+
1488
+ return NodeResult::kBranched;
1489
+ }
1490
+
1491
+ bool HighsSearch::backtrack(bool recoverBasis) {
1492
+ if (nodestack.empty()) return false;
1493
+ assert(!nodestack.empty());
1494
+ assert(nodestack.back().opensubtrees == 0);
1495
+ while (true) {
1496
+ while (nodestack.back().opensubtrees == 0) {
1497
+ countTreeWeight = true;
1498
+ depthoffset += nodestack.back().skipDepthCount;
1499
+ if (nodestack.size() == 1) {
1500
+ if (recoverBasis && nodestack.back().nodeBasis)
1501
+ lp->setStoredBasis(std::move(nodestack.back().nodeBasis));
1502
+ nodestack.pop_back();
1503
+ localdom.backtrackToGlobal();
1504
+ lp->flushDomain(localdom);
1505
+ if (recoverBasis) lp->recoverBasis();
1506
+ return false;
1507
+ }
1508
+
1509
+ nodestack.pop_back();
1510
+ #ifndef NDEBUG
1511
+ HighsDomainChange branchchg =
1512
+ #endif
1513
+ localdom.backtrack();
1514
+
1515
+ if (nodestack.back().opensubtrees != 0) {
1516
+ countTreeWeight = nodestack.back().skipDepthCount == 0;
1517
+ // repropagate the node, as it may have become infeasible due to
1518
+ // conflicts
1519
+ HighsInt oldNumDomchgs = localdom.getNumDomainChanges();
1520
+ size_t oldNumChangedCols = localdom.getChangedCols().size();
1521
+ localdom.propagate();
1522
+ if (!localdom.infeasible() &&
1523
+ oldNumDomchgs != localdom.getNumDomainChanges()) {
1524
+ if (nodestack.back().stabilizerOrbits)
1525
+ nodestack.back().stabilizerOrbits->orbitalFixing(localdom);
1526
+ else
1527
+ mipsolver.mipdata_->symmetries.propagateOrbitopes(localdom);
1528
+ }
1529
+ if (localdom.infeasible()) {
1530
+ localdom.clearChangedCols(oldNumChangedCols);
1531
+ if (countTreeWeight)
1532
+ treeweight += std::ldexp(1.0, -getCurrentDepth());
1533
+ nodestack.back().opensubtrees = 0;
1534
+ }
1535
+ }
1536
+
1537
+ assert(
1538
+ (branchchg.boundtype == HighsBoundType::kLower &&
1539
+ branchchg.boundval >= nodestack.back().branchingdecision.boundval) ||
1540
+ (branchchg.boundtype == HighsBoundType::kUpper &&
1541
+ branchchg.boundval <= nodestack.back().branchingdecision.boundval));
1542
+ assert(branchchg.boundtype ==
1543
+ nodestack.back().branchingdecision.boundtype);
1544
+ assert(branchchg.column == nodestack.back().branchingdecision.column);
1545
+ }
1546
+
1547
+ NodeData& currnode = nodestack.back();
1548
+
1549
+ assert(currnode.opensubtrees == 1);
1550
+ currnode.opensubtrees = 0;
1551
+ bool fallbackbranch =
1552
+ currnode.branchingdecision.boundval == currnode.branching_point;
1553
+ HighsInt domchgPos = localdom.getDomainChangeStack().size();
1554
+ if (currnode.branchingdecision.boundtype == HighsBoundType::kLower) {
1555
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1556
+ currnode.branchingdecision.boundval =
1557
+ std::floor(currnode.branchingdecision.boundval - 0.5);
1558
+ } else {
1559
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1560
+ currnode.branchingdecision.boundval =
1561
+ std::ceil(currnode.branchingdecision.boundval + 0.5);
1562
+ }
1563
+
1564
+ if (fallbackbranch)
1565
+ currnode.branching_point = currnode.branchingdecision.boundval;
1566
+
1567
+ size_t numChangedCols = localdom.getChangedCols().size();
1568
+ bool passStabilizerToChildNode =
1569
+ orbitsValidInChildNode(currnode.branchingdecision);
1570
+ localdom.changeBound(currnode.branchingdecision);
1571
+ double nodelb = std::max(currnode.lower_bound, currnode.other_child_lb);
1572
+ bool prune = nodelb > getCutoffBound() || localdom.infeasible();
1573
+ if (!prune) {
1574
+ localdom.propagate();
1575
+ prune = localdom.infeasible();
1576
+ if (prune) localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
1577
+ }
1578
+ if (!prune) {
1579
+ mipsolver.mipdata_->symmetries.propagateOrbitopes(localdom);
1580
+ prune = localdom.infeasible();
1581
+ }
1582
+ if (!prune && passStabilizerToChildNode && currnode.stabilizerOrbits) {
1583
+ currnode.stabilizerOrbits->orbitalFixing(localdom);
1584
+ prune = localdom.infeasible();
1585
+ }
1586
+ if (prune) {
1587
+ localdom.backtrack();
1588
+ localdom.clearChangedCols(numChangedCols);
1589
+ if (countTreeWeight) treeweight += std::ldexp(1.0, -getCurrentDepth());
1590
+ continue;
1591
+ }
1592
+ nodestack.emplace_back(
1593
+ nodelb, currnode.estimate, currnode.nodeBasis,
1594
+ passStabilizerToChildNode ? currnode.stabilizerOrbits : nullptr);
1595
+
1596
+ lp->flushDomain(localdom);
1597
+ nodestack.back().domgchgStackPos = domchgPos;
1598
+ break;
1599
+ }
1600
+
1601
+ if (recoverBasis && nodestack.back().nodeBasis) {
1602
+ lp->setStoredBasis(nodestack.back().nodeBasis);
1603
+ lp->recoverBasis();
1604
+ }
1605
+
1606
+ return true;
1607
+ }
1608
+
1609
+ bool HighsSearch::backtrackPlunge(HighsNodeQueue& nodequeue) {
1610
+ const std::vector<HighsDomainChange>& domchgstack =
1611
+ localdom.getDomainChangeStack();
1612
+
1613
+ if (nodestack.empty()) return false;
1614
+ assert(!nodestack.empty());
1615
+ assert(nodestack.back().opensubtrees == 0);
1616
+
1617
+ while (true) {
1618
+ while (nodestack.back().opensubtrees == 0) {
1619
+ countTreeWeight = true;
1620
+ depthoffset += nodestack.back().skipDepthCount;
1621
+
1622
+ if (nodestack.size() == 1) {
1623
+ if (nodestack.back().nodeBasis)
1624
+ lp->setStoredBasis(std::move(nodestack.back().nodeBasis));
1625
+ nodestack.pop_back();
1626
+ localdom.backtrackToGlobal();
1627
+ lp->flushDomain(localdom);
1628
+ lp->recoverBasis();
1629
+ return false;
1630
+ }
1631
+
1632
+ nodestack.pop_back();
1633
+ #ifndef NDEBUG
1634
+ HighsDomainChange branchchg =
1635
+ #endif
1636
+ localdom.backtrack();
1637
+
1638
+ if (nodestack.back().opensubtrees != 0) {
1639
+ countTreeWeight = nodestack.back().skipDepthCount == 0;
1640
+ // repropagate the node, as it may have become infeasible due to
1641
+ // conflicts
1642
+ HighsInt oldNumDomchgs = localdom.getNumDomainChanges();
1643
+ HighsInt oldNumChangedCols = localdom.getChangedCols().size();
1644
+ localdom.propagate();
1645
+ if (!localdom.infeasible() &&
1646
+ oldNumDomchgs != localdom.getNumDomainChanges()) {
1647
+ if (nodestack.back().stabilizerOrbits)
1648
+ nodestack.back().stabilizerOrbits->orbitalFixing(localdom);
1649
+ else
1650
+ mipsolver.mipdata_->symmetries.propagateOrbitopes(localdom);
1651
+ }
1652
+ if (localdom.infeasible()) {
1653
+ localdom.clearChangedCols(oldNumChangedCols);
1654
+ if (countTreeWeight)
1655
+ treeweight += std::ldexp(1.0, -getCurrentDepth());
1656
+ nodestack.back().opensubtrees = 0;
1657
+ }
1658
+ }
1659
+
1660
+ assert(
1661
+ (branchchg.boundtype == HighsBoundType::kLower &&
1662
+ branchchg.boundval >= nodestack.back().branchingdecision.boundval) ||
1663
+ (branchchg.boundtype == HighsBoundType::kUpper &&
1664
+ branchchg.boundval <= nodestack.back().branchingdecision.boundval));
1665
+ assert(branchchg.boundtype ==
1666
+ nodestack.back().branchingdecision.boundtype);
1667
+ assert(branchchg.column == nodestack.back().branchingdecision.column);
1668
+ }
1669
+
1670
+ NodeData& currnode = nodestack.back();
1671
+
1672
+ assert(currnode.opensubtrees == 1);
1673
+ currnode.opensubtrees = 0;
1674
+ bool fallbackbranch =
1675
+ currnode.branchingdecision.boundval == currnode.branching_point;
1676
+ double nodeScore;
1677
+ if (currnode.branchingdecision.boundtype == HighsBoundType::kLower) {
1678
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1679
+ currnode.branchingdecision.boundval =
1680
+ std::floor(currnode.branchingdecision.boundval - 0.5);
1681
+ nodeScore = pseudocost.getScoreDown(
1682
+ currnode.branchingdecision.column,
1683
+ fallbackbranch ? 0.5 : currnode.branching_point);
1684
+ } else {
1685
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1686
+ currnode.branchingdecision.boundval =
1687
+ std::ceil(currnode.branchingdecision.boundval + 0.5);
1688
+ nodeScore = pseudocost.getScoreUp(
1689
+ currnode.branchingdecision.column,
1690
+ fallbackbranch ? 0.5 : currnode.branching_point);
1691
+ }
1692
+
1693
+ if (fallbackbranch)
1694
+ currnode.branching_point = currnode.branchingdecision.boundval;
1695
+
1696
+ HighsInt domchgPos = domchgstack.size();
1697
+ size_t numChangedCols = localdom.getChangedCols().size();
1698
+ bool passStabilizerToChildNode =
1699
+ orbitsValidInChildNode(currnode.branchingdecision);
1700
+ localdom.changeBound(currnode.branchingdecision);
1701
+ double nodelb = std::max(currnode.lower_bound, currnode.other_child_lb);
1702
+ bool prune = nodelb > getCutoffBound() || localdom.infeasible();
1703
+ if (!prune) {
1704
+ localdom.propagate();
1705
+ prune = localdom.infeasible();
1706
+ if (prune) localdom.conflictAnalysis(mipsolver.mipdata_->conflictPool);
1707
+ }
1708
+ if (!prune) {
1709
+ mipsolver.mipdata_->symmetries.propagateOrbitopes(localdom);
1710
+ prune = localdom.infeasible();
1711
+ }
1712
+ if (!prune && passStabilizerToChildNode && currnode.stabilizerOrbits) {
1713
+ currnode.stabilizerOrbits->orbitalFixing(localdom);
1714
+ prune = localdom.infeasible();
1715
+ }
1716
+ if (prune) {
1717
+ localdom.backtrack();
1718
+ localdom.clearChangedCols(numChangedCols);
1719
+ if (countTreeWeight) treeweight += std::ldexp(1.0, -getCurrentDepth());
1720
+ continue;
1721
+ }
1722
+
1723
+ nodelb = std::max(nodelb, localdom.getObjectiveLowerBound());
1724
+ bool nodeToQueue = nodelb > mipsolver.mipdata_->optimality_limit;
1725
+ // we check if switching to the other branch of an ancestor yields a higher
1726
+ // additive branch score than staying in this node and if so we postpone the
1727
+ // node and put it to the queue to backtrack further.
1728
+ if (!nodeToQueue) {
1729
+ for (HighsInt i = nodestack.size() - 2; i >= 0; --i) {
1730
+ if (nodestack[i].opensubtrees == 0) continue;
1731
+
1732
+ bool fallbackbranch = nodestack[i].branchingdecision.boundval ==
1733
+ nodestack[i].branching_point;
1734
+ double branchpoint =
1735
+ fallbackbranch ? 0.5 : nodestack[i].branching_point;
1736
+ double ancestorScoreActive;
1737
+ double ancestorScoreInactive;
1738
+ if (nodestack[i].branchingdecision.boundtype ==
1739
+ HighsBoundType::kLower) {
1740
+ ancestorScoreInactive = pseudocost.getScoreDown(
1741
+ nodestack[i].branchingdecision.column, branchpoint);
1742
+ ancestorScoreActive = pseudocost.getScoreUp(
1743
+ nodestack[i].branchingdecision.column, branchpoint);
1744
+ } else {
1745
+ ancestorScoreActive = pseudocost.getScoreDown(
1746
+ nodestack[i].branchingdecision.column, branchpoint);
1747
+ ancestorScoreInactive = pseudocost.getScoreUp(
1748
+ nodestack[i].branchingdecision.column, branchpoint);
1749
+ }
1750
+
1751
+ // if (!mipsolver.submip)
1752
+ // printf("nodeScore: %g, ancestorScore: %g\n", nodeScore,
1753
+ // ancestorScore);
1754
+ nodeToQueue = ancestorScoreInactive - ancestorScoreActive >
1755
+ nodeScore + mipsolver.mipdata_->feastol;
1756
+ break;
1757
+ }
1758
+ }
1759
+
1760
+ if (nodeToQueue) {
1761
+ // if (!mipsolver.submip) printf("node goes to queue\n");
1762
+ std::vector<HighsInt> branchPositions;
1763
+ auto domchgStack = localdom.getReducedDomainChangeStack(branchPositions);
1764
+ double tmpTreeWeight = nodequeue.emplaceNode(
1765
+ std::move(domchgStack), std::move(branchPositions), nodelb,
1766
+ nodestack.back().estimate, getCurrentDepth() + 1);
1767
+ if (countTreeWeight) treeweight += tmpTreeWeight;
1768
+ localdom.backtrack();
1769
+ localdom.clearChangedCols(numChangedCols);
1770
+ continue;
1771
+ }
1772
+ nodestack.emplace_back(
1773
+ nodelb, currnode.estimate, currnode.nodeBasis,
1774
+ passStabilizerToChildNode ? currnode.stabilizerOrbits : nullptr);
1775
+
1776
+ lp->flushDomain(localdom);
1777
+ nodestack.back().domgchgStackPos = domchgPos;
1778
+ break;
1779
+ }
1780
+
1781
+ if (nodestack.back().nodeBasis) {
1782
+ lp->setStoredBasis(nodestack.back().nodeBasis);
1783
+ lp->recoverBasis();
1784
+ }
1785
+
1786
+ return true;
1787
+ }
1788
+
1789
+ bool HighsSearch::backtrackUntilDepth(HighsInt targetDepth) {
1790
+ if (nodestack.empty()) return false;
1791
+ assert(!nodestack.empty());
1792
+ if (getCurrentDepth() >= targetDepth) nodestack.back().opensubtrees = 0;
1793
+
1794
+ while (nodestack.back().opensubtrees == 0) {
1795
+ depthoffset += nodestack.back().skipDepthCount;
1796
+ nodestack.pop_back();
1797
+
1798
+ #ifndef NDEBUG
1799
+ HighsDomainChange branchchg =
1800
+ #endif
1801
+ localdom.backtrack();
1802
+ if (nodestack.empty()) {
1803
+ lp->flushDomain(localdom);
1804
+ return false;
1805
+ }
1806
+ assert(
1807
+ (branchchg.boundtype == HighsBoundType::kLower &&
1808
+ branchchg.boundval >= nodestack.back().branchingdecision.boundval) ||
1809
+ (branchchg.boundtype == HighsBoundType::kUpper &&
1810
+ branchchg.boundval <= nodestack.back().branchingdecision.boundval));
1811
+ assert(branchchg.boundtype == nodestack.back().branchingdecision.boundtype);
1812
+ assert(branchchg.column == nodestack.back().branchingdecision.column);
1813
+
1814
+ if (getCurrentDepth() >= targetDepth) nodestack.back().opensubtrees = 0;
1815
+ }
1816
+
1817
+ NodeData& currnode = nodestack.back();
1818
+ assert(currnode.opensubtrees == 1);
1819
+ currnode.opensubtrees = 0;
1820
+ bool fallbackbranch =
1821
+ currnode.branchingdecision.boundval == currnode.branching_point;
1822
+ if (currnode.branchingdecision.boundtype == HighsBoundType::kLower) {
1823
+ currnode.branchingdecision.boundtype = HighsBoundType::kUpper;
1824
+ currnode.branchingdecision.boundval =
1825
+ std::floor(currnode.branchingdecision.boundval - 0.5);
1826
+ } else {
1827
+ currnode.branchingdecision.boundtype = HighsBoundType::kLower;
1828
+ currnode.branchingdecision.boundval =
1829
+ std::ceil(currnode.branchingdecision.boundval + 0.5);
1830
+ }
1831
+
1832
+ if (fallbackbranch)
1833
+ currnode.branching_point = currnode.branchingdecision.boundval;
1834
+
1835
+ HighsInt domchgPos = localdom.getDomainChangeStack().size();
1836
+ bool passStabilizerToChildNode =
1837
+ orbitsValidInChildNode(currnode.branchingdecision);
1838
+ localdom.changeBound(currnode.branchingdecision);
1839
+ nodestack.emplace_back(
1840
+ currnode.lower_bound, currnode.estimate, currnode.nodeBasis,
1841
+ passStabilizerToChildNode ? currnode.stabilizerOrbits : nullptr);
1842
+
1843
+ lp->flushDomain(localdom);
1844
+ nodestack.back().domgchgStackPos = domchgPos;
1845
+ if (nodestack.back().nodeBasis &&
1846
+ (HighsInt)nodestack.back().nodeBasis->row_status.size() ==
1847
+ lp->getLp().num_row_)
1848
+ lp->setStoredBasis(nodestack.back().nodeBasis);
1849
+ lp->recoverBasis();
1850
+
1851
+ return true;
1852
+ }
1853
+
1854
+ HighsSearch::NodeResult HighsSearch::dive() {
1855
+ reliableatnode.clear();
1856
+
1857
+ do {
1858
+ ++nnodes;
1859
+ NodeResult result = evaluateNode();
1860
+
1861
+ if (mipsolver.mipdata_->checkLimits(nnodes)) return result;
1862
+
1863
+ if (result != NodeResult::kOpen) return result;
1864
+
1865
+ result = branch();
1866
+ if (result != NodeResult::kBranched) return result;
1867
+ } while (true);
1868
+ }
1869
+
1870
+ void HighsSearch::solveDepthFirst(int64_t maxbacktracks) {
1871
+ do {
1872
+ if (maxbacktracks == 0) break;
1873
+
1874
+ NodeResult result = dive();
1875
+ // if a limit was reached the result might be open
1876
+ if (result == NodeResult::kOpen) break;
1877
+
1878
+ --maxbacktracks;
1879
+
1880
+ } while (backtrack());
1881
+ }