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,2430 @@
1
+ from __future__ import annotations
2
+ import sys
3
+ import numpy as np
4
+ from numbers import Integral
5
+ from itertools import product
6
+ from threading import Thread, local, RLock, Lock
7
+ from typing import Optional, Any, overload, Callable, Sequence, Mapping, Iterable, SupportsIndex, cast, Union, Tuple
8
+ from weakref import proxy
9
+
10
+ from ._core import (
11
+ ObjSense,
12
+ HighsVarType,
13
+ HighsStatus,
14
+ HighsLinearObjective,
15
+ cb, # type: ignore
16
+ _Highs, # type: ignore
17
+ kHighsInf,
18
+ kHighsUndefined
19
+ )
20
+
21
+ # backwards typing support information for HighspyArray
22
+ np_version = tuple(map(int, np.__version__.split('.')))
23
+ if sys.version_info >= (3, 9) and np_version >= (1,22,0):
24
+ ndarray_object_type = np.ndarray[Any, np.dtype[np.object_]]
25
+ else:
26
+ ndarray_object_type = np.ndarray
27
+
28
+ class Highs(_Highs):
29
+ """
30
+ HiGHS solver interface
31
+ """
32
+
33
+ __handle_keyboard_interrupt: bool = False
34
+ __handle_user_interrupt: bool = False
35
+ __solver_should_stop: bool = False
36
+ __solver_stopped: RLock = RLock()
37
+ __solver_started: Lock = Lock()
38
+ __solver_status: Optional[HighsStatus] = None
39
+
40
+ def __init__(self):
41
+ super().__init__()
42
+ self.callbacks = [HighsCallback(cb.HighsCallbackType(_), self) for _ in range(int(cb.HighsCallbackType.kCallbackMax) + 1)]
43
+ self.enableCallbacks()
44
+
45
+ # Silence logging
46
+ def silent(self, turn_off_output: bool = True):
47
+ """
48
+ Disables solver output to the console.
49
+ """
50
+ super().setOptionValue("output_flag", not turn_off_output)
51
+
52
+ # solve
53
+ def solve(self):
54
+ """Runs the solver on the current problem.
55
+
56
+ Returns:
57
+ A HighsStatus object containing the solve status.
58
+ """
59
+ if not self.HandleKeyboardInterrupt:
60
+ return super().run()
61
+ else:
62
+ return self.joinSolve(self.startSolve())
63
+
64
+ def startSolve(self):
65
+ """
66
+ Starts the solver in a separate thread. Useful for handling KeyboardInterrupts.
67
+ Do not attempt to modify the model while the solver is running.
68
+
69
+ Returns:
70
+ A Thread object representing the solver thread.
71
+ """
72
+ if not self.is_solver_running():
73
+ self.__solver_started.acquire()
74
+ self.__solver_should_stop = False
75
+ self.__solver_status = None
76
+
77
+ t = Thread(target=Highs.__solve, args=(self,), daemon=True)
78
+ t.start()
79
+
80
+ # wait for solver thread to start to avoid synchronization issues
81
+ try:
82
+ self.__solver_started.acquire(True)
83
+ finally:
84
+ self.__solver_started.release()
85
+ return t
86
+ else:
87
+ raise Exception("Solver is already running.")
88
+
89
+ def is_solver_running(self):
90
+ is_running = True
91
+ try:
92
+ # try to acquire lock, if we can't, solver is already running
93
+ is_running = not self.__solver_stopped.acquire(False)
94
+ return is_running
95
+ finally:
96
+ if not is_running:
97
+ self.__solver_stopped.release()
98
+
99
+ # internal solve method for use with threads
100
+ # will set the status of the solver when finished and release the shared lock
101
+ def __solve(self):
102
+ try:
103
+ self.__solver_stopped.acquire(True)
104
+ self.__solver_started.release() # allow main thread to continue
105
+ self.__solver_status = super().run()
106
+
107
+ # avoid potential deadlock in Windows
108
+ # can remove once HiGHS is updated to handle this internally
109
+ _Highs.resetGlobalScheduler(False)
110
+ finally:
111
+ self.__solver_stopped.release()
112
+
113
+ def joinSolve(self, solver_thread: Optional[Thread] = None, interrupt_limit: int = 5):
114
+ """
115
+ Waits for the solver to finish. If solver_thread is provided, it will handle KeyboardInterrupts.
116
+
117
+ Args:
118
+ solver_thread: A Thread object representing the solver thread (optional).
119
+ interrupt_limit: The number of times to allow KeyboardInterrupt before forcing termination (optional).
120
+
121
+ Returns:
122
+ A HighsStatus object containing the solve status.
123
+ """
124
+ if solver_thread is not None and interrupt_limit <= 0:
125
+ result = (False, None)
126
+
127
+ try:
128
+ while not result[0]:
129
+ result = self.wait(0.1)
130
+ return result[1]
131
+
132
+ except KeyboardInterrupt:
133
+ print("KeyboardInterrupt: Waiting for HiGHS to finish...")
134
+ self.cancelSolve()
135
+
136
+ elif interrupt_limit > 0:
137
+ result = (False, None)
138
+
139
+ for count in range(interrupt_limit):
140
+ try:
141
+ while not result[0]:
142
+ result = self.wait(0.1)
143
+ return result[1]
144
+
145
+ except KeyboardInterrupt:
146
+ print(f"Ctrl-C pressed {count+1} times: Waiting for HiGHS to finish. ({interrupt_limit} times to force termination)")
147
+ self.cancelSolve()
148
+
149
+ # if we reach this point, we should force termination
150
+ print("Forcing termination...")
151
+ exit(1)
152
+
153
+ try:
154
+ # wait for shared lock, i.e., solver to finish
155
+ self.__solver_stopped.acquire(True)
156
+ except KeyboardInterrupt:
157
+ pass # ignore additional KeyboardInterrupt here
158
+ finally:
159
+ self.__solver_stopped.release()
160
+
161
+ return self.__solver_status
162
+
163
+ def wait(self, timeout: float = -1.0):
164
+ result = False, None
165
+
166
+ try:
167
+ result = (
168
+ self.__solver_stopped.acquire(True, timeout=timeout),
169
+ self.__solver_status,
170
+ )
171
+ return result
172
+ finally:
173
+ if result[0]:
174
+ self.__solver_status = None # reset status
175
+ self.__solver_stopped.release()
176
+
177
+ def optimize(self):
178
+ """
179
+ Alias for the solve method.
180
+ """
181
+ return self.solve()
182
+
183
+
184
+ def getObjective(self) -> Tuple[highs_linear_expression, ObjSense]:
185
+ """
186
+ Retrieves the current objective function (as a linear expression) and sense.
187
+ """
188
+ lp = super().getLp()
189
+ assert(isinstance(lp.col_cost_, np.ndarray))
190
+ nonzero_idxs = np.nonzero(lp.col_cost_)
191
+
192
+ objective = highs_linear_expression()
193
+ objective.idxs = nonzero_idxs[0].tolist()
194
+ objective.vals = lp.col_cost_[nonzero_idxs].tolist()
195
+ objective.constant = lp.offset_
196
+
197
+ return objective, super().getObjectiveSense()[1]
198
+
199
+
200
+ # reset the objective
201
+ def setObjective(self, obj: Optional[Union[highs_var, highs_linear_expression]] = None, sense: Optional[ObjSense] = None):
202
+ """
203
+ Updates the costs.
204
+
205
+ Args:
206
+ obj: An optional highs_linear_expression representing the new objective function.
207
+ sense: An optional ObjSense value representing the new objective sense.
208
+
209
+ Raises:
210
+ Exception: If obj is an inequality or not a highs_linear_expression.
211
+ """
212
+ if obj is not None:
213
+ # if we have a single variable, wrap it in a linear expression
214
+ expr = highs_linear_expression(obj) if isinstance(obj, highs_var) else obj
215
+
216
+ if expr.bounds is not None:
217
+ raise Exception("Objective cannot be an inequality")
218
+
219
+ # reset objective
220
+ super().changeColsCost(
221
+ self.numVariables,
222
+ np.arange(self.numVariables, dtype=np.int32),
223
+ np.full(self.numVariables, 0, dtype=np.float64),
224
+ )
225
+
226
+ # if we have duplicate variables, add the vals
227
+ idxs, vals = expr.unique_elements()
228
+ super().changeColsCost(len(idxs), idxs, vals)
229
+ super().changeObjectiveOffset(expr.constant or 0.0)
230
+
231
+ if sense is not None:
232
+ super().changeObjectiveSense(sense)
233
+
234
+ # reset the objective and sense, then solve
235
+ def minimize(self, obj: Optional[Union[highs_var, highs_linear_expression]] = None):
236
+ """
237
+ Solves a minimization of the objective and optionally updates the costs.
238
+
239
+ Args:
240
+ obj: An optional highs_linear_expression representing the new objective function.
241
+
242
+ Raises:
243
+ Exception: If obj is an inequality or not a highs_linear_expression.
244
+
245
+ Returns:
246
+ A HighsStatus object containing the solve status after minimization.
247
+ """
248
+ self.setObjective(obj, ObjSense.kMinimize)
249
+ return self.solve()
250
+
251
+ # reset the objective and sense, then solve
252
+ def maximize(self, obj: Optional[Union[highs_var, highs_linear_expression]] = None):
253
+ """
254
+ Solves a maximization of the objective and optionally updates the costs.
255
+
256
+ Args:
257
+ obj: An optional highs_linear_expression representing the new objective function.
258
+
259
+ Raises:
260
+ Exception: If obj is an inequality or not a highs_linear_expression.
261
+
262
+ Returns:
263
+ A HighsStatus object containing the solve status after maximization.
264
+ """
265
+ self.setObjective(obj, ObjSense.kMaximize)
266
+ return self.solve()
267
+
268
+ @staticmethod
269
+ def internal_get_value(
270
+ array_values: Union[Sequence[float], np.ndarray[Any, np.dtype[np.float64]]],
271
+ index_collection: Union[
272
+ Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], Sequence[Any], np.ndarray[Any, np.dtype[Any]]
273
+ ],
274
+ ) -> Union[float, bool, Mapping[Any, Any], np.ndarray[Any, np.dtype[np.float64]]]:
275
+ """
276
+ Internal method to get the value of an index from an array of values. Could be value or dual, variable or constraint.
277
+ """
278
+ if isinstance(index_collection, (Integral, highs_var, highs_cons)):
279
+ return array_values[int(index_collection)]
280
+
281
+ elif isinstance(index_collection, highs_linear_expression):
282
+ return index_collection.evaluate(array_values)
283
+
284
+ elif isinstance(index_collection, Mapping):
285
+ return {k: Highs.internal_get_value(array_values, v) for k, v in index_collection.items()}
286
+
287
+ else:
288
+ return np.asarray([Highs.internal_get_value(array_values, v) for v in index_collection])
289
+
290
+ @overload
291
+ def val(self, var: Union[Integral, highs_var, highs_cons]) -> float: ...
292
+
293
+ @overload
294
+ def val(self, var: highs_linear_expression) -> Union[float, bool]: ...
295
+
296
+ @overload
297
+ def val(self, var: Mapping[Any, Any]) -> Mapping[Any, Any]: ...
298
+
299
+ @overload
300
+ def val(self, var: Union[Sequence[Any], np.ndarray[Any, np.dtype[Any]]]) -> np.ndarray[Any, np.dtype[np.float64]]: ...
301
+
302
+ def val(
303
+ self,
304
+ var: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], Sequence[Any], np.ndarray[Any, np.dtype[Any]]],
305
+ ):
306
+ """
307
+ Gets the value of a variable/index or expression in the solution.
308
+
309
+ Args:
310
+ var: A highs_var/index or highs_linear_expression object representing the variable.
311
+
312
+ Returns:
313
+ The value of the variable in the solution.
314
+ """
315
+ return Highs.internal_get_value(super().getSolution().col_value, var)
316
+
317
+ @overload
318
+ def vals(self, idxs: Union[Integral, highs_var, highs_cons]) -> float: ...
319
+
320
+ @overload
321
+ def vals(self, idxs: highs_linear_expression) -> Union[float, bool]: ...
322
+
323
+ @overload
324
+ def vals(self, idxs: Mapping[Any, Any]) -> Mapping[Any, Any]: ...
325
+
326
+ @overload
327
+ def vals(self, idxs: Union[Sequence[Any], np.ndarray[Any, np.dtype[Any]]]) -> np.ndarray[Any, np.dtype[np.float64]]: ...
328
+
329
+ def vals(
330
+ self,
331
+ idxs: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], Sequence[Any], np.ndarray[Any, np.dtype[Any]]],
332
+ ):
333
+ """
334
+ Gets the values of multiple variables in the solution.
335
+
336
+ Args:
337
+ idxs: A collection of highs_var objects representing the variables. Can be a Mapping (e.g., dict) where keys are variable names and values are highs_var objects, or an iterable of highs_var objects.
338
+
339
+ Returns:
340
+ If idxs is a Mapping, returns a dict where keys are the same keys from the input idxs and values are the solution values of the corresponding variables. If idxs is an iterable, returns a list of solution values for the variables.
341
+ """
342
+ return Highs.internal_get_value(super().getSolution().col_value, idxs)
343
+
344
+ def variableName(self, var: Union[Integral, highs_var]):
345
+ """
346
+ Retrieves the name of a specific variable.
347
+
348
+ Args:
349
+ var: A highs_var object representing the variable.
350
+
351
+ Raises:
352
+ Exception: If the variable name cannot be found.
353
+
354
+ Returns:
355
+ The name of the specified variable.
356
+ """
357
+ [status, name] = super().getColName(int(var))
358
+ failed = status != HighsStatus.kOk
359
+ if failed:
360
+ raise Exception("Variable name not found")
361
+ return name
362
+
363
+ @overload
364
+ def variableNames(self, idxs: Mapping[Any, Union[highs_var, Integral]]) -> dict[Any, str]: ...
365
+
366
+ @overload
367
+ def variableNames(self, idxs: Iterable[Union[highs_var, Integral]]) -> list[str]: ...
368
+
369
+ def variableNames(self, idxs: Iterable[Union[highs_var, Integral]]):
370
+ """
371
+ Retrieves the names of multiple variables.
372
+
373
+ Args:
374
+ idxs: An iterable of highs_var objects or a mapping where keys are identifiers and values are highs_var objects.
375
+
376
+ Raises:
377
+ Exception: If any variable name cannot be found.
378
+
379
+ Returns:
380
+ If idxs is a mapping, returns a dict where keys are the same keys from the input idxs and values are the names of the corresponding variables.
381
+ If idxs is an iterable, returns a list of names for the specified variables.
382
+ """
383
+ if isinstance(idxs, Mapping):
384
+ convert: Mapping[Any, Union[highs_var, Integral]] = idxs
385
+ return {key: self.variableName(v) for key, v in convert.items()}
386
+ else:
387
+ return [self.variableName(v) for v in idxs]
388
+
389
+ def allVariableNames(self) -> list[str]:
390
+ """
391
+ Retrieves the names of all variables in the model.
392
+
393
+ Returns:
394
+ A list of strings representing the names of all variables.
395
+ """
396
+ return super().getLp().col_names_
397
+
398
+ def variableValue(
399
+ self,
400
+ var: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], np.ndarray[Any, np.dtype[Any]]],
401
+ ):
402
+ """
403
+ Retrieves the value of a specific variable in the solution.
404
+
405
+ Args:
406
+ var: A highs_var object representing the variable.
407
+
408
+ Returns:
409
+ The value of the specified variable in the solution.
410
+ """
411
+ return self.val(var)
412
+
413
+ def variableValues(
414
+ self,
415
+ idxs: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], np.ndarray[Any, np.dtype[Any]]],
416
+ ):
417
+ """
418
+ Retrieves the values of multiple variables in the solution.
419
+
420
+ Args:
421
+ idxs: A collection of highs_var objects representing the variables. Can be a Mapping (e.g., dict) where keys are variable names and values are highs_var objects, or an iterable of highs_var objects.
422
+
423
+ Returns:
424
+ If idxs is a Mapping, returns a dict where keys are the same keys from the input idxs and values are the solution values of the corresponding variables. If idxs is an iterable, returns a list of solution values for the variables.
425
+ """
426
+ return self.vals(idxs)
427
+
428
+ def allVariableValues(self):
429
+ """
430
+ Retrieves the values of all variables in the solution.
431
+
432
+ Returns:
433
+ A list of values for all variables in the solution.
434
+ """
435
+ return super().getSolution().col_value
436
+
437
+ def variableDual(
438
+ self,
439
+ var: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], np.ndarray[Any, np.dtype[Any]]],
440
+ ):
441
+ """
442
+ Retrieves the dual value of a specific variable/index or expression in the solution.
443
+
444
+ Args:
445
+ var: A highs_var object representing the variable.
446
+
447
+ Returns:
448
+ The dual value of the specified variable in the solution.
449
+ """
450
+ return Highs.internal_get_value(super().getSolution().col_dual, var)
451
+
452
+ def variableDuals(
453
+ self,
454
+ idxs: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], np.ndarray[Any, np.dtype[Any]]],
455
+ ):
456
+ """
457
+ Retrieves the dual values of multiple variables in the solution.
458
+
459
+ Args:
460
+ idxs: A collection of highs_var objects representing the variables. Can be a Mapping (e.g., dict) where keys are variable names and values are highs_var objects, or an iterable of highs_var objects.
461
+
462
+ Returns:
463
+ If idxs is a Mapping, returns a dict where keys are the same keys from the input idxs and values are the dual values of the corresponding variables. If idxs is an iterable, returns a list of dual values for the variables.
464
+ """
465
+ return Highs.internal_get_value(super().getSolution().col_dual, idxs)
466
+
467
+ def allVariableDuals(self):
468
+ """
469
+ Retrieves the dual values of all variables in the solution.
470
+
471
+ Returns:
472
+ A list of dual values for all variables in the solution.
473
+ """
474
+ return super().getSolution().col_dual
475
+
476
+ def constrValue(
477
+ self,
478
+ con: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], np.ndarray[Any, np.dtype[Any]]],
479
+ ):
480
+ """
481
+ Retrieves the value of a specific constraint in the solution.
482
+
483
+ Args:
484
+ con: A highs_con object representing the constraint.
485
+
486
+ Returns:
487
+ The value of the specified constraint in the solution.
488
+ """
489
+ return Highs.internal_get_value(super().getSolution().row_value, con)
490
+
491
+ def constrValues(
492
+ self,
493
+ cons: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], np.ndarray[Any, np.dtype[Any]]],
494
+ ):
495
+ """
496
+ Retrieves the values of multiple constraints in the solution.
497
+
498
+ Args:
499
+ cons: A collection of highs_con objects representing the constraints. Can be a Mapping (e.g., dict) where keys are constraint names and values are highs_con objects, or an iterable of highs_con objects.
500
+
501
+ Returns:
502
+ If cons is a Mapping, returns a dict where keys are the same keys from the input cons and values are the solution values of the corresponding constraints. If cons is an iterable, returns a list of solution values for the constraints.
503
+ """
504
+ return Highs.internal_get_value(super().getSolution().row_value, cons)
505
+
506
+ def allConstrValues(self):
507
+ """
508
+ Retrieves the values of all constraints in the solution.
509
+
510
+ Returns:
511
+ A list of values for all constraints in the solution.
512
+ """
513
+ return super().getSolution().row_value
514
+
515
+ def constrDual(
516
+ self,
517
+ con: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], np.ndarray[Any, np.dtype[Any]]],
518
+ ):
519
+ """
520
+ Retrieves the dual value of a specific constraint in the solution.
521
+
522
+ Args:
523
+ con: A highs_con object representing the constraint.
524
+
525
+ Returns:
526
+ The dual value of the specified constraint in the solution.
527
+ """
528
+ return Highs.internal_get_value(super().getSolution().row_dual, con)
529
+
530
+ def constrDuals(
531
+ self,
532
+ cons: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], np.ndarray[Any, np.dtype[Any]]],
533
+ ):
534
+ """
535
+ Retrieves the dual values of multiple constraints in the solution.
536
+
537
+ Args:
538
+ cons: A collection of highs_con objects representing the constraints. Can be a Mapping (e.g., dict) where keys are constraint names and values are highs_con objects, or an iterable of highs_con objects.
539
+
540
+ Returns:
541
+ If cons is a Mapping, returns a dict where keys are the same keys from the input cons and values are the dual values of the corresponding constraints. If cons is an iterable, returns a list of dual values for the constraints.
542
+ """
543
+ return Highs.internal_get_value(super().getSolution().row_dual, cons)
544
+
545
+ def allConstrDuals(self):
546
+ """
547
+ Retrieves the dual values of all constraints in the solution.
548
+
549
+ Returns:
550
+ A list of dual values for all constraints in the solution.
551
+ """
552
+ return super().getSolution().row_dual
553
+
554
+ def addVariable(
555
+ self,
556
+ lb: float = 0,
557
+ ub: float = kHighsInf,
558
+ obj: float = 0.0,
559
+ type: HighsVarType = HighsVarType.kContinuous,
560
+ name: Optional[str] = None,
561
+ ):
562
+ """
563
+ Adds a variable to the model.
564
+
565
+ Args:
566
+ lb: Lower bound of the variable (default is 0).
567
+ ub: Upper bound of the variable (default is infinity).
568
+ obj: Objective coefficient of the variable (default is 0).
569
+ type: Type of the variable (continuous, integer; default is continuous).
570
+ name: Optional name for the variable.
571
+
572
+ Returns:
573
+ A highs_var object representing the added variable.
574
+ """
575
+ status = super().addCol(obj, lb, ub, 0, np.empty(0, dtype=np.int32), np.empty(0, np.float64))
576
+
577
+ if status != HighsStatus.kOk:
578
+ raise Exception("Failed to add variable to the model.")
579
+
580
+ var = highs_var(self.numVariables - 1, self)
581
+
582
+ if type != HighsVarType.kContinuous:
583
+ super().changeColIntegrality(var.index, type)
584
+
585
+ if name is not None:
586
+ super().passColName(var.index, name)
587
+
588
+ return var
589
+
590
+ @overload
591
+ def addVariables(
592
+ self,
593
+ *nvars: int,
594
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
595
+ ) -> HighspyArray: ...
596
+
597
+ @overload
598
+ def addVariables(
599
+ self,
600
+ *nvars: Mapping[Any, Any],
601
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
602
+ ) -> dict[Any, highs_var]: ...
603
+
604
+ @overload
605
+ def addVariables(
606
+ self,
607
+ *nvars: Sequence[Any],
608
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
609
+ ) -> Union[dict[Any, highs_var], HighspyArray]: ...
610
+
611
+ @overload
612
+ def addVariables(
613
+ self,
614
+ *nvars: Union[int, Mapping[Any, Any], Sequence[Any]],
615
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
616
+ ) -> Optional[Union[dict[Any, highs_var], HighspyArray]]: ...
617
+
618
+ def addVariables(
619
+ self,
620
+ *nvars: Union[int, Mapping[Any, Any], Sequence[Any]],
621
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
622
+ ) -> Optional[Union[dict[Any, highs_var], HighspyArray]]:
623
+ """
624
+ Adds multiple variables to the model.
625
+
626
+ Args:
627
+ *args: A sequence of variables to be added. Can be a collection of scalars or indices (or mix).
628
+
629
+ **kwargs: Optional keyword arguments. Can be scalars, arrays, or mappings.
630
+ lb: Lower bound of the variables (default is 0).
631
+ ub: Upper bound of the variables (default is infinity).
632
+ obj: Objective coefficient of the variables (default is 0).
633
+ type: Type of the variables (continuous, integer; default is continuous).
634
+ name: A collection of names for the variables (list or mapping).
635
+ name_prefix: Prefix for the variable names. Constructed name will be name_prefix + index.
636
+ out_array: Return an array of highs_var objects instead of a dictionary.
637
+
638
+ Returns:
639
+ A highs_var collection (array or dictionary) representing the added variables.
640
+ """
641
+ if len(nvars) == 0:
642
+ return None
643
+
644
+ # if all nvars are scalars, we can assume they are the dimensions
645
+ shape = [n for n in nvars if isinstance(n, int)]
646
+
647
+ expanded = [range(n) if isinstance(n, int) else n for n in nvars]
648
+ indices: list[Any] = list(expanded[0] if len(expanded) == 1 else product(*expanded)) # unpack tuple if needed
649
+ N = len(indices)
650
+
651
+ if len(shape) != len(nvars):
652
+ shape = [N]
653
+
654
+ # parameter can be scalar, array, or mapping lookup (i.e., dictionary, custom class, etc.)
655
+ # scalar: repeat for all N, array: use as is, lookup: convert to array using indices
656
+ def ensure_real(x: Union[Any, Mapping[Any, Any], Sequence[Any]]):
657
+ if isinstance(x, (float, int)):
658
+ return np.full(N, x, dtype=np.float64)
659
+
660
+ elif isinstance(x, Mapping):
661
+ mt: Mapping[Any, Any] = x
662
+
663
+ if all(isinstance(v, (float, int)) for v in mt.values()):
664
+ m: Mapping[Any, Union[float, int]] = x
665
+ return np.fromiter((m[i] for i in indices), np.float64)
666
+
667
+ elif isinstance(x, Sequence) and len(x) == N and all(isinstance(v, (float, int)) for v in x):
668
+ return np.asarray(x, dtype=np.float64)
669
+
670
+ raise Exception("Invalid parameter.")
671
+
672
+ def ensure_HighsVarType(x: Union[Any, Mapping[Any, Any], Sequence[Any]]):
673
+ if x == HighsVarType.kContinuous:
674
+ return None
675
+
676
+ elif isinstance(x, HighsVarType):
677
+ return np.full(N, x, dtype=np.uint8)
678
+
679
+ elif isinstance(x, Mapping):
680
+ mt: Mapping[Any, Any] = x
681
+
682
+ if all(isinstance(v, HighsVarType) for v in mt.values()):
683
+ m: Mapping[Any, HighsVarType] = x
684
+ return np.fromiter((m[i] for i in indices), np.uint8)
685
+
686
+ elif isinstance(x, Sequence) and len(x) == N and all(isinstance(v, HighsVarType) for v in x):
687
+ return np.asarray(x, dtype=np.uint8)
688
+
689
+ raise Exception("Invalid parameter.")
690
+
691
+ def ensure_optional_str(x: Optional[Any]):
692
+ if x is None:
693
+ return None
694
+ elif isinstance(x, Sequence):
695
+ mt: Sequence[Any] = x
696
+
697
+ if len(mt) == N and all(isinstance(v, str) for v in mt):
698
+ m: Sequence[str] = mt
699
+ return m
700
+
701
+ raise Exception("Invalid parameter.")
702
+
703
+ def ensure_str_or_none(x: Any) -> Optional[str]:
704
+ if x is None or isinstance(x, str):
705
+ return x
706
+ else:
707
+ raise Exception("Invalid parameter.")
708
+
709
+ def ensure_bool(x: Any) -> bool:
710
+ if isinstance(x, bool):
711
+ return x
712
+ raise Exception("Invalid parameter.")
713
+
714
+ lb = ensure_real(kwargs.get("lb", 0.0))
715
+ ub = ensure_real(kwargs.get("ub", kHighsInf))
716
+ obj = ensure_real(kwargs.get("obj", 0))
717
+ vartype = ensure_HighsVarType(kwargs.get("type", HighsVarType.kContinuous))
718
+ name_prefix = ensure_str_or_none(kwargs.get("name_prefix", None))
719
+ name = ensure_optional_str(kwargs.get("name", None))
720
+ out_array = ensure_bool(kwargs.get("out_array", all(isinstance(n, int) for n in nvars)))
721
+
722
+ start_idx = self.numVariables
723
+ idx = np.arange(start_idx, start_idx + N, dtype=np.int32)
724
+ status = super().addCols(
725
+ N,
726
+ obj,
727
+ lb,
728
+ ub,
729
+ 0,
730
+ np.empty(0, dtype=np.int32),
731
+ np.empty(0, dtype=np.int32),
732
+ np.empty(0, dtype=np.float64),
733
+ )
734
+
735
+ if status != HighsStatus.kOk:
736
+ raise Exception("Failed to add columns to the model.")
737
+
738
+ # only set integrality if we have non-continuous variables
739
+ if vartype is not None:
740
+ super().changeColsIntegrality(N, idx, vartype)
741
+
742
+ if name or name_prefix:
743
+ # Changed to fix #2887 names = name or [f"{name_prefix}{i}" for i in indices]
744
+ names = name or [f"{name_prefix}{i}".replace(" ", "") for i in indices]
745
+ for i, n in zip(idx, names):
746
+ super().passColName(int(i), str(n))
747
+
748
+ return (
749
+ HighspyArray(np.asarray([highs_var(int(i), self) for i in idx]).reshape(shape), self)
750
+ if out_array
751
+ else {index: highs_var(int(i), self) for index, i in zip(indices, idx)}
752
+ )
753
+
754
+ @overload
755
+ def addIntegrals(
756
+ self,
757
+ *nvars: int,
758
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
759
+ ) -> HighspyArray: ...
760
+
761
+ @overload
762
+ def addIntegrals(
763
+ self,
764
+ *nvars: Mapping[Any, Any],
765
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
766
+ ) -> dict[Any, highs_var]: ...
767
+
768
+ @overload
769
+ def addIntegrals(
770
+ self,
771
+ *nvars: Sequence[Any],
772
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
773
+ ) -> Union[dict[Any, highs_var], HighspyArray]: ...
774
+
775
+ @overload
776
+ def addIntegrals(
777
+ self,
778
+ *nvars: Union[int, Mapping[Any, Any], Sequence[Any]],
779
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
780
+ ) -> Optional[Union[dict[Any, highs_var], HighspyArray]]: ...
781
+
782
+ def addIntegrals(
783
+ self,
784
+ *nvars: Union[int, Mapping[Any, Any], Sequence[Any]],
785
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
786
+ ):
787
+ """
788
+ Alias for the addVariables method, for integer variables.
789
+ """
790
+ kwargs.setdefault("type", HighsVarType.kInteger)
791
+ return self.addVariables(*nvars, **kwargs)
792
+
793
+ @overload
794
+ def addBinaries(
795
+ self,
796
+ *nvars: int,
797
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
798
+ ) -> HighspyArray: ...
799
+
800
+ @overload
801
+ def addBinaries(
802
+ self,
803
+ *nvars: Mapping[Any, Any],
804
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
805
+ ) -> dict[Any, highs_var]: ...
806
+
807
+ @overload
808
+ def addBinaries(
809
+ self,
810
+ *nvars: Sequence[Any],
811
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
812
+ ) -> Union[dict[Any, highs_var], HighspyArray]: ...
813
+
814
+ @overload
815
+ def addBinaries(
816
+ self,
817
+ *nvars: Union[int, Mapping[Any, Any], Sequence[Any]],
818
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
819
+ ) -> Optional[Union[dict[Any, highs_var], HighspyArray]]: ...
820
+
821
+ def addBinaries(
822
+ self,
823
+ *nvars: Union[int, Mapping[Any, Any], Sequence[Any]],
824
+ **kwargs: Union[Any, HighsVarType, Mapping[Any, Any], Sequence[Any]],
825
+ ):
826
+ """
827
+ Alias for the addVariables method, for binary variables.
828
+ """
829
+ kwargs.setdefault("lb", 0)
830
+ kwargs.setdefault("ub", 1)
831
+ kwargs.setdefault("type", HighsVarType.kInteger)
832
+
833
+ return self.addVariables(*nvars, **kwargs)
834
+
835
+ def addIntegral(self, lb: float = 0.0, ub: float = kHighsInf, obj: float = 0.0, name: Optional[str] = None):
836
+ """
837
+ Alias for the addVariable method, for integer variables.
838
+ """
839
+ return self.addVariable(lb, ub, obj, HighsVarType.kInteger, name)
840
+
841
+ def addBinary(self, obj: float = 0.0, name: Optional[str] = None):
842
+ """
843
+ Alias for the addVariable method, for binary variables.
844
+ """
845
+ return self.addVariable(0, 1, obj, HighsVarType.kInteger, name)
846
+
847
+ def deleteVariable(
848
+ self,
849
+ var_or_index: Union[Integral, highs_var],
850
+ *args: Union[Mapping[Any, highs_var], Iterable[highs_var], highs_var],
851
+ ):
852
+ """
853
+ Deletes a variable from the model and updates the indices of subsequent variables in provided collections.
854
+
855
+ Args:
856
+ var_or_index: A highs_var object or an index representing the variable to be deleted.
857
+ *args: Optional collections (lists, dicts, etc.) of highs_var objects whose indices need to be updated.
858
+ """
859
+ # Determine the index of the variable to delete
860
+ index = int(var_or_index)
861
+
862
+ # Delete the variable from the model if it exists
863
+ if index < self.numVariables:
864
+ super().deleteVars(1, [index])
865
+
866
+ # Update the indices of variables in the provided collections
867
+ for collection in args:
868
+ if isinstance(collection, Mapping):
869
+ mt: Mapping[Any, highs_var] = collection
870
+
871
+ # Update indices in a dictionary of variables
872
+ for _, var in mt.items():
873
+ if var.index > index:
874
+ var.index -= 1
875
+ elif var.index == index:
876
+ var.index = -1
877
+
878
+ elif isinstance(collection, Iterable):
879
+ # Update indices in an iterable of variables
880
+ for var in collection:
881
+ if var.index > index:
882
+ var.index -= 1
883
+ elif var.index == index:
884
+ var.index = -1
885
+
886
+ # If the collection is a single highs_var object, check and update if necessary
887
+ elif collection.index > index:
888
+ collection.index -= 1
889
+ elif collection.index == index:
890
+ collection.index = -1
891
+
892
+ def getVariables(self):
893
+ """
894
+ Retrieves all variables in the model.
895
+
896
+ Returns:
897
+ A list of highs_var objects, each representing a variable in the model.
898
+ """
899
+ return [highs_var(i, self) for i in range(self.numVariables)]
900
+
901
+ @property
902
+ def inf(self):
903
+ """
904
+ Represents infinity in the context of the solver.
905
+
906
+ Returns:
907
+ The value used to represent infinity.
908
+ """
909
+ return kHighsInf
910
+
911
+ @property
912
+ def numVariables(self):
913
+ """
914
+ Gets the number of variables in the model.
915
+
916
+ Returns:
917
+ The number of variables.
918
+ """
919
+ return super().getNumCol()
920
+
921
+ @property
922
+ def numConstrs(self):
923
+ """
924
+ Gets the number of constraints in the model.
925
+
926
+ Returns:
927
+ The number of constraints.
928
+ """
929
+ return super().getNumRow()
930
+
931
+ #
932
+ # add constraints
933
+ #
934
+ def addConstr(self, expr: highs_linear_expression, name: Optional[str] = None):
935
+ """
936
+ Adds a constraint to the model.
937
+
938
+ Args:
939
+ expr: A highs_linear_expression to be added.
940
+ name: Optional name of the constraint.
941
+
942
+ Returns:
943
+ A highs_con object representing the added constraint.
944
+ """
945
+ con = self.__addRow(expr, self.numConstrs)
946
+
947
+ if name is not None:
948
+ super().passRowName(con.index, name)
949
+
950
+ return con
951
+
952
+ @overload
953
+ def addConstrs(
954
+ self,
955
+ *args: highs_linear_expression,
956
+ **kwargs: Optional[Union[str, Sequence[str]]],
957
+ ) -> list[highs_cons]: ...
958
+
959
+ @overload
960
+ def addConstrs(
961
+ self,
962
+ *args: Mapping[Any, highs_linear_expression],
963
+ **kwargs: Optional[Union[str, Sequence[str]]],
964
+ ) -> dict[Any, highs_cons]: ...
965
+
966
+ @overload
967
+ def addConstrs(
968
+ self,
969
+ *args: Iterable[highs_linear_expression],
970
+ **kwargs: Optional[Union[str, Sequence[str]]],
971
+ ) -> list[highs_cons]: ...
972
+
973
+ def addConstrs(
974
+ self,
975
+ *args: Union[highs_linear_expression, Iterable[highs_linear_expression]],
976
+ **kwargs: Optional[Union[str, Sequence[str]]],
977
+ ):
978
+ """
979
+ Adds multiple constraints to the model.
980
+
981
+ Args:
982
+ *args: A sequence of highs_linear_expression to be added.
983
+
984
+ **kwargs: Optional keyword arguments.
985
+ name_prefix: Prefix for the constraint names. Constructed name will be name_prefix + index.
986
+ name: A collection of names for the constraints (list or mapping).
987
+
988
+ Returns:
989
+ A highs_con collection array representing the added constraints.
990
+ """
991
+ name_prefix = kwargs.get("name_prefix", None)
992
+ name = kwargs.get("name", None)
993
+
994
+ # unpack generator if needed
995
+ generator = args[0] if len(args) == 1 and isinstance(args[0], Iterable) else args
996
+ initial_rows = self.numConstrs
997
+
998
+ try:
999
+ if isinstance(generator, Mapping):
1000
+ mt: Mapping[Any, highs_linear_expression] = generator
1001
+ cons = {key: self.__addRow(expr, initial_rows + count) for count, (key, expr) in enumerate(mt.items())}
1002
+ else:
1003
+ it: Iterable[Any] = generator
1004
+ cons = [self.__addRow(expr, initial_rows + count) for count, expr in enumerate(it)]
1005
+
1006
+ # TODO: Mapping support with constraint names can be improved, e.g., by allowing a name collection to be passed
1007
+ if name or name_prefix:
1008
+ names = name or [f"{name_prefix}{n}" for n in range(self.numConstrs - initial_rows)]
1009
+
1010
+ for c, n in zip(range(initial_rows, self.numConstrs), names):
1011
+ super().passRowName(int(c), str(n))
1012
+
1013
+ except Exception as e:
1014
+ # rollback model if error - remove any constraints that were added
1015
+ status = super().deleteRows(
1016
+ self.numConstrs - initial_rows,
1017
+ np.arange(initial_rows, self.numConstrs, dtype=np.int32),
1018
+ )
1019
+
1020
+ if status != HighsStatus.kOk:
1021
+ raise Exception("Failed to rollback model after failure. Model might be in a undeterminate state.")
1022
+ else:
1023
+ raise e
1024
+
1025
+ return cons
1026
+
1027
+ def __addRow(self, expr: highs_linear_expression, idx: int):
1028
+ """
1029
+ Internal method to add a constraint to the model.
1030
+ """
1031
+ if expr.bounds is not None:
1032
+ idxs, vals = expr.unique_elements() # if we have duplicate variables, add the vals
1033
+ super().addRow(expr.bounds[0], expr.bounds[1], len(idxs), idxs, vals)
1034
+ return highs_cons(idx, self)
1035
+ else:
1036
+ raise Exception("Constraint bounds must be set via comparison (>=,==,<=).")
1037
+
1038
+ def expr(
1039
+ self,
1040
+ optional: Optional[Union[float, int, highs_var, highs_linear_expression]] = None,
1041
+ ):
1042
+ """
1043
+ Creates a new highs_linear_expression object.
1044
+
1045
+ Returns:
1046
+ A highs_linear_expression object.
1047
+ """
1048
+ return highs_linear_expression(optional)
1049
+
1050
+ def getExpr(self, cons: Union[Integral, highs_cons]):
1051
+ """
1052
+ Retrieves the highs_linear_expression of a constraint.
1053
+
1054
+ Args:
1055
+ cons: A highs_con object or index representing the constraint.
1056
+
1057
+ Returns:
1058
+ A highs_linear_expression object representing the expression of the constraint.
1059
+ """
1060
+ status, lb, ub, nnz = super().getRow(int(cons)) # type: ignore
1061
+
1062
+ if status != HighsStatus.kOk:
1063
+ raise Exception("Error retrieving constraint expression.")
1064
+
1065
+ status, idx, val = super().getRowEntries(int(cons))
1066
+
1067
+ if status != HighsStatus.kOk:
1068
+ raise Exception("Error retrieving constraint expression entries.")
1069
+
1070
+ expr = highs_linear_expression()
1071
+ expr.bounds = (lb, ub)
1072
+ expr.idxs = list(idx)
1073
+ expr.vals = list(val)
1074
+ return expr
1075
+
1076
+ def chgCoeff(self, cons: Union[highs_cons, Integral], var: Union[highs_var, Integral], val: float):
1077
+ """
1078
+ Changes the coefficient of a variable in a constraint.
1079
+
1080
+ Args:
1081
+ cons: A highs_con object representing the constraint.
1082
+ var: A highs_var object representing the variable.
1083
+ val: The new coefficient value for the variable in the constraint.
1084
+ """
1085
+ super().changeCoeff(int(cons), int(var), val)
1086
+
1087
+ def getConstrs(self):
1088
+ """
1089
+ Retrieves all constraints in the model.
1090
+
1091
+ Returns:
1092
+ A list of highs_cons objects, each representing a constraint in the model.
1093
+ """
1094
+ return [highs_cons(i, self) for i in range(self.numConstrs)]
1095
+
1096
+ def removeConstr(
1097
+ self,
1098
+ cons_or_index: Union[highs_cons, Integral],
1099
+ *args: Union[Mapping[Any, highs_cons], Sequence[highs_cons], highs_cons],
1100
+ ):
1101
+ """
1102
+ Removes a constraint from the model and updates the indices of subsequent constraints in provided collections.
1103
+
1104
+ Args:
1105
+ cons_or_index: A highs_cons object or an index representing the constraint to be removed.
1106
+ *args: Optional collections (lists, dicts, etc.) of highs_cons objects whose indices need to be updated after the removal.
1107
+ """
1108
+ # Determine the index of the constraint to delete
1109
+ index = int(cons_or_index)
1110
+
1111
+ # Delete the variable from the model if it exists
1112
+ if index < self.numConstrs:
1113
+ status = super().deleteRows(1, np.asarray([index], dtype=np.int32))
1114
+
1115
+ if status != HighsStatus.kOk:
1116
+ raise Exception("Failed to delete constraint from the model.")
1117
+
1118
+ # Update the indices of constraints in the provided collections
1119
+ for collection in args:
1120
+ if isinstance(collection, Mapping):
1121
+ mt: Mapping[Any, highs_cons] = collection
1122
+
1123
+ # Update indices in a dictionary of constraints
1124
+ for _, con in mt.items():
1125
+ if con.index > index:
1126
+ con.index -= 1
1127
+ elif con.index == index:
1128
+ con.index = -1
1129
+
1130
+ elif isinstance(collection, Sequence):
1131
+ # Update indices in an iterable of constraints
1132
+ for con in collection:
1133
+ if con.index > index:
1134
+ con.index -= 1
1135
+ elif con.index == index:
1136
+ con.index = -1
1137
+
1138
+ # If the collection is a single highs_cons object, check and update if necessary
1139
+ elif collection.index > index:
1140
+ collection.index -= 1
1141
+
1142
+ elif collection.index == index:
1143
+ collection.index = -1
1144
+
1145
+ def setMinimize(self):
1146
+ """
1147
+ Sets the objective sense of the model to minimization.
1148
+ """
1149
+ super().changeObjectiveSense(ObjSense.kMinimize)
1150
+
1151
+ def setMaximize(self):
1152
+ """
1153
+ Sets the objective sense of the model to maximization.
1154
+ """
1155
+ super().changeObjectiveSense(ObjSense.kMaximize)
1156
+
1157
+ def setInteger(self, var_or_collection: Union[highs_var, int, Iterable[Union[highs_var, int]]]):
1158
+ """
1159
+ Sets a variable/collection to integer.
1160
+
1161
+ Args:
1162
+ var_or_collection: A highs_var object/collection representing the variable to be set as integer.
1163
+ """
1164
+ if isinstance(var_or_collection, Iterable):
1165
+ idx = np.fromiter(map(int, var_or_collection), dtype=np.int32)
1166
+ super().changeColsIntegrality(len(idx), idx, np.full(len(idx), HighsVarType.kInteger, dtype=np.uint8))
1167
+ else:
1168
+ super().changeColIntegrality(int(var_or_collection), HighsVarType.kInteger)
1169
+
1170
+ def setContinuous(self, var_or_collection: Union[highs_var, int, Iterable[Union[highs_var, int]]]):
1171
+ """
1172
+ Sets a variable/collection to continuous.
1173
+
1174
+ Args:
1175
+ var_or_collection: A highs_var object/collection representing the variable to be set as continuous.
1176
+ """
1177
+ if isinstance(var_or_collection, Iterable):
1178
+ idx = np.fromiter(map(int, var_or_collection), dtype=np.int32)
1179
+ super().changeColsIntegrality(
1180
+ len(idx),
1181
+ idx,
1182
+ np.full(len(idx), HighsVarType.kContinuous, dtype=np.uint8),
1183
+ )
1184
+ else:
1185
+ super().changeColIntegrality(int(var_or_collection), HighsVarType.kContinuous)
1186
+
1187
+ @staticmethod
1188
+ def qsum(
1189
+ items: Union[Iterable[Union[highs_var, highs_linear_expression]], np.ndarray[Any, np.dtype[np.object_]]],
1190
+ initial: Optional[Union[float, int, highs_var, highs_linear_expression]] = None,
1191
+ ):
1192
+ """
1193
+ Performs a faster sum for highs_linear_expressions.
1194
+
1195
+ Args:
1196
+ items: A collection of highs_linear_expressions or highs_vars to be summed.
1197
+ """
1198
+ expr = highs_linear_expression(initial)
1199
+
1200
+ if isinstance(items, np.ndarray):
1201
+ X: np.ndarray[Any, np.dtype[np.object_]] = items
1202
+ for v in X.flat:
1203
+ expr += cast(Union[highs_var, highs_linear_expression], v)
1204
+ else:
1205
+ for v in items:
1206
+ expr += v
1207
+
1208
+ return expr
1209
+
1210
+ ##
1211
+ ## Callback support, with optional user interrupt handling
1212
+ ##
1213
+ @staticmethod
1214
+ def __internal_callback(
1215
+ callback_type: cb.HighsCallbackType,
1216
+ message: str,
1217
+ data_out: cb.HighsCallbackOutput,
1218
+ data_in: Optional[cb.HighsCallbackInput],
1219
+ user_callback_data: Any,
1220
+ ):
1221
+ user_callback_data.callbacks[int(callback_type)].fire(callback_type, message, data_out, data_in)
1222
+
1223
+ def enableCallbacks(self):
1224
+ """
1225
+ Enables callbacks, restarting them if they were previously enabled.
1226
+ """
1227
+ super().setCallback(Highs.__internal_callback, self)
1228
+
1229
+ # restart callbacks if any exist
1230
+ for c in self.callbacks:
1231
+ if len(c.callbacks) > 0:
1232
+ self.startCallback(c.callback_type)
1233
+
1234
+ def clearCallbacks(self):
1235
+ """
1236
+ Clears all callbacks.
1237
+ """
1238
+ for c in self.callbacks:
1239
+ c.clear()
1240
+
1241
+ def disableCallbacks(self):
1242
+ """
1243
+ Disables all callbacks, but does not clear them.
1244
+ """
1245
+ status = super().setCallback(None, None) # this will also stop all callbacks
1246
+
1247
+ if status != HighsStatus.kOk:
1248
+ raise Exception("Failed to disable callbacks.")
1249
+
1250
+ def cancelSolve(self):
1251
+ """
1252
+ If HandleUserInterrupt is enabled, this method will signal the solver to stop.
1253
+ """
1254
+ self.__solver_should_stop = True
1255
+
1256
+ @property
1257
+ def HandleKeyboardInterrupt(self):
1258
+ """
1259
+ Get/Set whether the solver should handle KeyboardInterrupt (i.e., cancel solve on Ctrl+C). Also enables/disables HandleUserInterrupt.
1260
+ """
1261
+ return self.__handle_keyboard_interrupt
1262
+
1263
+ @HandleKeyboardInterrupt.setter
1264
+ def HandleKeyboardInterrupt(self, value: bool):
1265
+ self.__handle_keyboard_interrupt = value
1266
+ self.HandleUserInterrupt = value
1267
+
1268
+ @property
1269
+ def HandleUserInterrupt(self):
1270
+ """
1271
+ Get/Set whether the solver should handle user interrupts (i.e., cancel solve on user request)
1272
+ """
1273
+ return self.__handle_user_interrupt
1274
+
1275
+ @HandleUserInterrupt.setter
1276
+ def HandleUserInterrupt(self, value: bool):
1277
+ self.__handle_user_interrupt = value
1278
+
1279
+ if value:
1280
+ self.cbSimplexInterrupt += self.__user_interrupt_event
1281
+ self.cbIpmInterrupt += self.__user_interrupt_event
1282
+ self.cbMipInterrupt += self.__user_interrupt_event
1283
+ else:
1284
+ self.cbSimplexInterrupt -= self.__user_interrupt_event
1285
+ self.cbIpmInterrupt -= self.__user_interrupt_event
1286
+ self.cbMipInterrupt -= self.__user_interrupt_event
1287
+
1288
+ def __user_interrupt_event(self, e: HighsCallbackEvent):
1289
+ if self.__solver_should_stop:
1290
+ e.interrupt()
1291
+
1292
+ @property
1293
+ def cbLogging(self):
1294
+ return self.callbacks[int(cb.HighsCallbackType.kCallbackLogging)]
1295
+
1296
+ @property
1297
+ def cbSimplexInterrupt(self):
1298
+ return self.callbacks[int(cb.HighsCallbackType.kCallbackSimplexInterrupt)]
1299
+
1300
+ @property
1301
+ def cbIpmInterrupt(self):
1302
+ return self.callbacks[int(cb.HighsCallbackType.kCallbackIpmInterrupt)]
1303
+
1304
+ @property
1305
+ def cbMipSolution(self):
1306
+ return self.callbacks[int(cb.HighsCallbackType.kCallbackMipSolution)]
1307
+
1308
+ @property
1309
+ def cbMipImprovingSolution(self):
1310
+ return self.callbacks[int(cb.HighsCallbackType.kCallbackMipImprovingSolution)]
1311
+
1312
+ @property
1313
+ def cbMipLogging(self):
1314
+ return self.callbacks[int(cb.HighsCallbackType.kCallbackMipLogging)]
1315
+
1316
+ @property
1317
+ def cbMipInterrupt(self):
1318
+ return self.callbacks[int(cb.HighsCallbackType.kCallbackMipInterrupt)]
1319
+
1320
+ @property
1321
+ def cbMipGetCutPool(self):
1322
+ return self.callbacks[int(cb.HighsCallbackType.kCallbackMipGetCutPool)]
1323
+
1324
+ @property
1325
+ def cbMipDefineLazyConstraints(self):
1326
+ return self.callbacks[int(cb.HighsCallbackType.kCallbackMipDefineLazyConstraints)]
1327
+
1328
+ @property
1329
+ def cbMipUserSolution(self):
1330
+ return self.callbacks[int(cb.HighsCallbackType.kCallbackMipUserSolution)]
1331
+
1332
+ # callback setters are required for +=/-= syntax
1333
+ # e.g., h.cbLogging += my_callback
1334
+ @cbLogging.setter
1335
+ def cbLogging(self, value: HighsCallback):
1336
+ if self.cbLogging is not value:
1337
+ raise Exception("Cannot set callback directly. Use .subscribe(callback) instead.")
1338
+
1339
+ @cbSimplexInterrupt.setter
1340
+ def cbSimplexInterrupt(self, value: HighsCallback):
1341
+ if self.cbSimplexInterrupt is not value:
1342
+ raise Exception("Cannot set callback directly. Use .subscribe(callback) instead.")
1343
+
1344
+ @cbIpmInterrupt.setter
1345
+ def cbIpmInterrupt(self, value: HighsCallback):
1346
+ if self.cbIpmInterrupt is not value:
1347
+ raise Exception("Cannot set callback directly. Use .subscribe(callback) instead.")
1348
+
1349
+ @cbMipSolution.setter
1350
+ def cbMipSolution(self, value: HighsCallback):
1351
+ if self.cbMipSolution is not value:
1352
+ raise Exception("Cannot set callback directly. Use .subscribe(callback) instead.")
1353
+
1354
+ @cbMipImprovingSolution.setter
1355
+ def cbMipImprovingSolution(self, value: HighsCallback):
1356
+ if self.cbMipImprovingSolution is not value:
1357
+ raise Exception("Cannot set callback directly. Use .subscribe(callback) instead.")
1358
+
1359
+ @cbMipLogging.setter
1360
+ def cbMipLogging(self, value: HighsCallback):
1361
+ if self.cbMipLogging is not value:
1362
+ raise Exception("Cannot set callback directly. Use .subscribe(callback) instead.")
1363
+
1364
+ @cbMipInterrupt.setter
1365
+ def cbMipInterrupt(self, value: HighsCallback):
1366
+ if self.cbMipInterrupt is not value:
1367
+ raise Exception("Cannot set callback directly. Use .subscribe(callback) instead.")
1368
+
1369
+ @cbMipGetCutPool.setter
1370
+ def cbMipGetCutPool(self, value: HighsCallback):
1371
+ if self.cbMipGetCutPool is not value:
1372
+ raise Exception("Cannot set callback directly. Use .subscribe(callback) instead.")
1373
+
1374
+ @cbMipDefineLazyConstraints.setter
1375
+ def cbMipDefineLazyConstraints(self, value: HighsCallback):
1376
+ if self.cbMipDefineLazyConstraints is not value:
1377
+ raise Exception("Cannot set callback directly. Use .subscribe(callback) instead.")
1378
+
1379
+ @cbMipUserSolution.setter
1380
+ def cbMipUserSolution(self, value: HighsCallback):
1381
+ if self.cbMipUserSolution is not value:
1382
+ raise Exception("Cannot set callback directly. Use .subscribe(callback) instead.")
1383
+
1384
+
1385
+
1386
+ ##
1387
+ ## Callback support
1388
+ ##
1389
+ class HighsCallbackEvent(object):
1390
+ __slots__ = ["callback_type", "message", "data_out", "data_in", "user_data"]
1391
+
1392
+ def __init__(
1393
+ self,
1394
+ callback_type: cb.HighsCallbackType,
1395
+ message: str,
1396
+ data_out: cb.HighsCallbackOutput,
1397
+ data_in: Optional[cb.HighsCallbackInput],
1398
+ user_data: Optional[Any]
1399
+ ):
1400
+ self.callback_type = callback_type
1401
+ self.message = message
1402
+ self.data_out = data_out
1403
+ self.data_in = data_in
1404
+ self.user_data = user_data
1405
+
1406
+ def interrupt(self, interrupt_value: bool = True):
1407
+ """
1408
+ Sets the user interrupt flag in the callback data.
1409
+ """
1410
+ if self.data_in is not None:
1411
+ self.data_in.user_interrupt = interrupt_value
1412
+
1413
+ def val(
1414
+ self,
1415
+ var_expr: Union[Integral, highs_var, highs_cons, highs_linear_expression, Mapping[Any, Any], np.ndarray[Any, np.dtype[Any]]],
1416
+ ):
1417
+ """
1418
+ Gets the value(s) of a variable/index or expression in the callback solution.
1419
+ """
1420
+ return Highs.internal_get_value(self.data_out.mip_solution, var_expr)
1421
+
1422
+ def cut(self, index: int):
1423
+ """
1424
+ Gets the cut pool for the given index.
1425
+ """
1426
+ cut = highs_linear_expression()
1427
+
1428
+ if self.data_out and index >= 0 and index < self.data_out.cutpool_num_cut:
1429
+ start, end = self.data_out.cutpool_start[index:index+2]
1430
+ cut.bounds = (self.data_out.cutpool_lower[index], self.data_out.cutpool_upper[index])
1431
+ cut.idxs = list(map(int, self.data_out.cutpool_index[start:end]))
1432
+ cut.vals = list(map(float, self.data_out.cutpool_value[start:end]))
1433
+
1434
+ return cut
1435
+
1436
+ @property
1437
+ def cuts(self):
1438
+ """
1439
+ Gets all cuts in the cut pool.
1440
+ """
1441
+ return [self.cut(i) for i in range(self.data_out.cutpool_num_cut)]
1442
+
1443
+ class HighsCallback(object):
1444
+ __slots__ = ["callbacks", "user_callback_data", "highs", "callback_type"]
1445
+
1446
+ def __init__(self, callback_type: cb.HighsCallbackType, highs: Highs):
1447
+ self.callbacks: list[Callable[[HighsCallbackEvent], None]] = []
1448
+ self.user_callback_data: list[Any] = []
1449
+ self.callback_type = callback_type
1450
+ self.highs = proxy(highs) # to avoid circular reference
1451
+
1452
+ def subscribe(
1453
+ self,
1454
+ callback: Callable[[HighsCallbackEvent], None],
1455
+ user_data: Optional[Any] = None,
1456
+ ):
1457
+ """
1458
+ Subscribes a callback to the event.
1459
+
1460
+ Args:
1461
+ callback: The callback function to be executed.
1462
+ user_data: Optional user data to be passed to the callback.
1463
+ """
1464
+ if len(self.callbacks) == 0:
1465
+ status = self.highs.startCallback(self.callback_type)
1466
+
1467
+ if status != HighsStatus.kOk:
1468
+ raise Exception("Failed to start callback.")
1469
+
1470
+ self.callbacks.append(callback)
1471
+ self.user_callback_data.append(user_data)
1472
+ return self
1473
+
1474
+ def unsubscribe(self, callback: Callable[[HighsCallbackEvent], None]):
1475
+ """
1476
+ Unsubscribes a callback from the event.
1477
+
1478
+ Args:
1479
+ callback: The callback function to be removed.
1480
+ """
1481
+ try:
1482
+ idx = self.callbacks.index(callback)
1483
+ del self.callbacks[idx]
1484
+ del self.user_callback_data[idx]
1485
+
1486
+ if len(self.callbacks) == 0:
1487
+ self.highs.stopCallback(self.callback_type)
1488
+
1489
+ except ValueError:
1490
+ pass
1491
+
1492
+ return self
1493
+
1494
+ def unsubscribe_by_data(self, user_data: Optional[Any]):
1495
+ """
1496
+ Unsubscribes a callback by user data.
1497
+
1498
+ Args:
1499
+ user_data: The user data corresponding to the callback(s) to be removed.
1500
+ """
1501
+ idx = reversed([i for i, ud in enumerate(self.user_callback_data) if ud == user_data])
1502
+
1503
+ for i in idx:
1504
+ del self.callbacks[i]
1505
+ del self.user_callback_data[i]
1506
+
1507
+ if len(self.callbacks) == 0:
1508
+ self.highs.stopCallback(self.callback_type)
1509
+
1510
+ return self
1511
+
1512
+ def __iadd__(self, callback: Callable[[HighsCallbackEvent], None]):
1513
+ return self.subscribe(callback)
1514
+
1515
+ def __isub__(self, callback: Callable[[HighsCallbackEvent], None]):
1516
+ return self.unsubscribe(callback)
1517
+
1518
+ def clear(self):
1519
+ """
1520
+ Unsubscribes all callbacks from the event.
1521
+ """
1522
+ self.callbacks = []
1523
+ self.user_callback_data = []
1524
+ self.highs.stopCallback(self.callback_type)
1525
+
1526
+ def fire(
1527
+ self,
1528
+ callback_type: cb.HighsCallbackType,
1529
+ message: str,
1530
+ data_out: cb.HighsCallbackOutput,
1531
+ data_in: cb.HighsCallbackInput,
1532
+ ):
1533
+ """
1534
+ Fires the event, executing all subscribed callbacks.
1535
+ """
1536
+ e = HighsCallbackEvent(callback_type, message, data_out, data_in, None)
1537
+
1538
+ for fn, user_data in zip(self.callbacks, self.user_callback_data):
1539
+ e.user_data = user_data
1540
+ fn(e)
1541
+
1542
+
1543
+ class HighspyArray(ndarray_object_type):
1544
+ """
1545
+ A numpy array wrapper for highs_var/highs_linear_expression objects.
1546
+
1547
+ This provides additional type information for static analysis, and also allows faster sum operations.
1548
+ """
1549
+
1550
+ def __new__(cls, input_array: np.ndarray[Any, np.dtype[np.object_]], highs: Optional[Highs]):
1551
+ obj = np.asarray(input_array).view(cls)
1552
+ obj.highs = highs
1553
+ return obj
1554
+
1555
+ def __array_finalize__(self, obj: Optional[Any]):
1556
+ self.highs = getattr(obj, "highs", None)
1557
+
1558
+ @overload
1559
+ def __getitem__(self, key: Union[SupportsIndex, tuple[SupportsIndex, ...]]) -> highs_linear_expression: ... # type: ignore
1560
+
1561
+ @overload
1562
+ def __getitem__(
1563
+ self,
1564
+ key: Union[
1565
+ np.ndarray[Any, np.dtype[np.integer[Any]]],
1566
+ np.ndarray[Any, np.dtype[np.bool_]],
1567
+ tuple[Union[np.ndarray[Any, np.dtype[np.integer[Any]]], np.ndarray[Any, np.dtype[np.bool_]]], ...],
1568
+ ],
1569
+ ) -> HighspyArray: ...
1570
+
1571
+ @overload
1572
+ def __getitem__(self, key: Union[None, slice, SupportsIndex, tuple[Union[None, slice, SupportsIndex], ...]]) -> HighspyArray: ...
1573
+
1574
+ @overload
1575
+ def __getitem__(self, key: Any) -> HighspyArray: ... # type: ignore
1576
+
1577
+ def __getitem__(self, key: Any) -> Union[HighspyArray, highs_linear_expression]: # type: ignore
1578
+ return super(HighspyArray, self).__getitem__(key) # type: ignore
1579
+
1580
+ def __ge__(self, other: Any) -> HighspyArray: # type: ignore
1581
+ return cast(HighspyArray, np.greater_equal(self, other, dtype=np.object_))
1582
+
1583
+ def __le__(self, other: Any) -> HighspyArray: # type: ignore
1584
+ return cast(HighspyArray, np.less_equal(self, other, dtype=np.object_))
1585
+
1586
+ def __eq__(self, other: Any) -> HighspyArray:
1587
+ return cast(HighspyArray, np.equal(self, other, dtype=np.object_))
1588
+
1589
+ @overload
1590
+ def sum(self, axis: None = None, dtype: Optional[Any] = None, out: None = ...) -> highs_linear_expression: ...
1591
+
1592
+ @overload
1593
+ def sum(self, axis: Any, dtype: Optional[Any] = None, out: HighspyArray = ...) -> HighspyArray: ...
1594
+
1595
+ def sum( # type: ignore
1596
+ self,
1597
+ axis: Optional[int] = None,
1598
+ dtype: Optional[Any] = None,
1599
+ out: Optional[np.ndarray[Any, np.dtype[np.object_]]] = None,
1600
+ **unused_kwargs: Any,
1601
+ ) -> Union[HighspyArray, highs_linear_expression]:
1602
+ if self.highs is not None:
1603
+ if axis is not None:
1604
+ return HighspyArray(np.apply_along_axis(self.highs.qsum, axis, self, initial=unused_kwargs.get("initial", None)), self.highs)
1605
+ else:
1606
+ return self.highs.qsum(self, unused_kwargs.get("initial", None))
1607
+ else:
1608
+ raise Exception("Cannot sum without a Highs object.")
1609
+
1610
+
1611
+ # highs variable
1612
+ class highs_var(object):
1613
+ """
1614
+ Variable index wrapper for HiGHS
1615
+ """
1616
+
1617
+ __slots__ = ["index", "highs"]
1618
+
1619
+ def __init__(self, i: int, highs: Highs):
1620
+ self.index = i
1621
+ self.highs = proxy(highs) # to avoid circular reference
1622
+
1623
+ def __repr__(self):
1624
+ return f"highs_var({self.index})"
1625
+
1626
+ @property
1627
+ def name(self):
1628
+ return self.highs.variableName(self)
1629
+
1630
+ @name.setter
1631
+ def name(self, value: str):
1632
+ self.highs.passColName(self.index, value)
1633
+
1634
+ def __int__(self):
1635
+ return int(self.index)
1636
+
1637
+ def __hash__(self):
1638
+ return int(self.index)
1639
+
1640
+ def __neg__(self):
1641
+ expr = highs_linear_expression()
1642
+ expr.idxs = [self.index]
1643
+ expr.vals = [-1.0]
1644
+ return expr
1645
+
1646
+ def __add__(self, other: Union[float, int, highs_var, highs_linear_expression]):
1647
+ expr = highs_linear_expression(self)
1648
+ expr += other
1649
+ return expr
1650
+
1651
+ def __radd__(self, other: Union[float, int, highs_var, highs_linear_expression]):
1652
+ expr = highs_linear_expression(self)
1653
+ expr += other
1654
+ return expr
1655
+
1656
+ def __mul__(self, other: Union[float, int, highs_var, highs_linear_expression]):
1657
+ expr = highs_linear_expression(self)
1658
+ expr *= other
1659
+ return expr
1660
+
1661
+ def __rmul__(self, other: Union[float, int, highs_var, highs_linear_expression]):
1662
+ expr = highs_linear_expression(self)
1663
+ expr *= other
1664
+ return expr
1665
+
1666
+ def __rsub__(self, other: Union[float, int, highs_var, highs_linear_expression]):
1667
+ expr = highs_linear_expression(other)
1668
+ expr -= self
1669
+ return expr
1670
+
1671
+ def __sub__(self, other: Union[float, int, highs_var, highs_linear_expression]):
1672
+ expr = highs_linear_expression(self)
1673
+ expr -= other
1674
+ return expr
1675
+
1676
+ # self <= other
1677
+ def __le__(self, other: Union[float, int, highs_var, highs_linear_expression]):
1678
+ if isinstance(other, highs_linear_expression):
1679
+ return other.__ge__(self)
1680
+ else:
1681
+ return highs_linear_expression(self).__le__(other)
1682
+
1683
+ # self == other
1684
+ def __eq__(self, other: Any) -> highs_linear_expression: # type: ignore
1685
+ if isinstance(other, highs_linear_expression):
1686
+ return other.__eq__(self)
1687
+ else:
1688
+ return highs_linear_expression(self).__eq__(other)
1689
+
1690
+ # self != other
1691
+ def __ne__(self, other: Optional[Any]):
1692
+ if other is None:
1693
+ return True
1694
+ else:
1695
+ raise Exception("Invalid comparison.")
1696
+
1697
+ # self >= other
1698
+ def __ge__(self, other: Union[float, int, highs_var, highs_linear_expression]):
1699
+ if isinstance(other, highs_linear_expression):
1700
+ return other.__le__(self)
1701
+ else:
1702
+ return highs_linear_expression(self).__ge__(other)
1703
+
1704
+
1705
+ # highs constraint
1706
+ class highs_cons(object):
1707
+ """
1708
+ Constraint index wrapper for HiGHS
1709
+ """
1710
+
1711
+ __slots__ = ["index", "highs"]
1712
+
1713
+ def __init__(self, i: int, highs: Highs):
1714
+ self.index = i
1715
+ self.highs = proxy(highs) # to avoid circular reference
1716
+
1717
+ def __repr__(self):
1718
+ return f"highs_cons({self.index})"
1719
+
1720
+ def __int__(self):
1721
+ return int(self.index)
1722
+
1723
+ def __hash__(self):
1724
+ return int(self.index)
1725
+
1726
+ def expr(self):
1727
+ """
1728
+ Retrieves the expression of the constraint.
1729
+ """
1730
+ return self.highs.getExpr(self)
1731
+
1732
+ @property
1733
+ def name(self):
1734
+ status, name = self.highs.getRowName(self.index)
1735
+
1736
+ if status != HighsStatus.kOk:
1737
+ raise Exception("Error retrieving constraint name.")
1738
+ return name
1739
+
1740
+ @name.setter
1741
+ def name(self, value: str):
1742
+ self.highs.passRowName(self.index, value)
1743
+
1744
+
1745
+ # highs constraint builder
1746
+ #
1747
+ # Note: we only allow LHS/RHS to be set once via comparisons (>=,==,<=), otherwise it gets confusing!
1748
+ # e.g, for (0 <= x <= 1) <= 2, should this be:
1749
+ # 0 <= x <= 1 (i.e., tighter bound, x <= 1 and x <= 2 implies x <= 1),
1750
+ # or, 0 <= x <= 2 (i.e., last comparision overrides previous)?
1751
+ #
1752
+ # Throwing an error makes it obvious to the user. Note we can still set via addition,
1753
+ # e.g., (x <= 1) + (y <= 5) to get x + y <= 6
1754
+ #
1755
+ #
1756
+ # For chained comparisons, we throw an error if we have mismatched variables in the "bounds",
1757
+ # e.g., x <= y <= 1. This requires 2 constraints, x <= 1 and x <= y, and is not supported, whereas
1758
+ # x + 2 <= y <= x + 5 is supported, since we can easily rewrite this as 2 <= y - x <= 5.
1759
+ #
1760
+ # As such, trivial chaining is supported, e.g., lb <= expr <= ub, where lb and ub are numeric.
1761
+ #
1762
+ # Note: when dealing with inequalities (>=,==,<=) we need to decide which variables to move the LHS/RHS.
1763
+ # For consistency, we:
1764
+ # 1. Move variables to side with the most variables, e.g., x <= y + z -> 0 <= y + z - x <= inf
1765
+ # y + z >= x -> 0 <= y + z - x <= inf
1766
+ # x >= y + z -> -inf <= y + z - x <= 0
1767
+ # y + z <= x -> -inf <= y + z - x <= 0
1768
+ # y + z == x -> y + z - x == 0
1769
+ # x == y + z -> y + z - x == 0
1770
+ #
1771
+ # 2. If equal, move to side without a constant, e.g., y <= x + 2 -> -inf <= y - x <= 2
1772
+ # x + 2 >= y -> -inf <= y - x <= 2
1773
+ # x + 2 <= y -> 2 <= y - x <= inf
1774
+ # y >= x + 2 -> 2 <= y - x <= inf
1775
+ # y + 2 == x -> x - y == 2
1776
+ # x == y + 2 -> x - y == 2
1777
+ #
1778
+ # 3. If both have constants, move to the 'left', e.g., x + 2 <= y + 3 -> -inf <= x - y <= 1
1779
+ # y + 3 >= x + 2 -> -inf <= x - y <= 1
1780
+ # x + 2 >= y + 3 -> -inf <= y - x <= -1
1781
+ # y + 3 <= x + 2 -> -inf <= y - x <= -1
1782
+ # x + 2 == y + 3 -> x - y == 1
1783
+ # y + 3 == x + 2 -> y - x == -1
1784
+ # Hence:
1785
+ # 6 <= x + y <= 8 -> 6 <= x + y <= 8 #(1)
1786
+ # 6 + x <= y <= 8 + x -> 6 <= y - x <= 8 #(2)
1787
+ # 6 + x <= y + 2 <= 8 + x -> 4 <= y - x <= 6 #(3)
1788
+ # x <= 6 <= x -> 6 <= x <= 6 #(1)
1789
+ # x <= y + z <= x + 5 -> 0 <= y + z - x <= 5 #(1)
1790
+ class highs_linear_expression(object):
1791
+ """
1792
+ Linear constraint builder for HiGHS
1793
+ """
1794
+
1795
+ __slots__ = ["idxs", "vals", "constant", "bounds"]
1796
+
1797
+ @overload
1798
+ def __init__(self, other: None = None) -> None: ...
1799
+
1800
+ @overload
1801
+ def __init__(self, other: Union[float, int]) -> None: ...
1802
+
1803
+ @overload
1804
+ def __init__(self, other: highs_var) -> None: ...
1805
+
1806
+ @overload
1807
+ def __init__(self, other: highs_linear_expression) -> None: ...
1808
+
1809
+ def __init__(
1810
+ self,
1811
+ other: Optional[Union[float, int, highs_var, highs_linear_expression]] = None,
1812
+ ):
1813
+ self.constant: Optional[float] = None # constant is only valid when bounds are None
1814
+ self.bounds: Optional[tuple[float, float]] = None # bounds are only valid when constant is None
1815
+
1816
+ if other is None:
1817
+ self.idxs: list[int] = []
1818
+ self.vals: list[float] = []
1819
+
1820
+ elif isinstance(other, highs_linear_expression):
1821
+ self.idxs = list(other.idxs)
1822
+ self.vals = list(other.vals)
1823
+ self.constant = other.constant
1824
+ self.bounds = other.bounds if other.bounds is not None else None
1825
+
1826
+ elif isinstance(other, highs_var):
1827
+ self.idxs = [other.index]
1828
+ self.vals = [1.0]
1829
+
1830
+ else:
1831
+ self.idxs = []
1832
+ self.vals = []
1833
+ self.constant = float(other)
1834
+
1835
+ def simplify(self):
1836
+ """
1837
+ Simplifies the linear expression by combining duplicate variables.
1838
+ """
1839
+ copy = highs_linear_expression()
1840
+ copy.idxs, copy.vals = (v.tolist() for v in self.unique_elements())
1841
+ copy.bounds = self.bounds if self.bounds is not None else None
1842
+ copy.constant = self.constant
1843
+ return copy
1844
+
1845
+ def copy(self):
1846
+ """
1847
+ Creates a copy of the linear expression.
1848
+ """
1849
+ return highs_linear_expression(self)
1850
+
1851
+ def evaluate(
1852
+ self,
1853
+ values: Union[Sequence[float], np.ndarray[Any, np.dtype[np.float64]]],
1854
+ ) -> Union[float, bool]:
1855
+ """
1856
+ Evaluates the linear expression given a solution array (values).
1857
+ """
1858
+ result = sum(v * values[c] for c, v in zip(self.idxs, self.vals)) + (self.constant or 0.0)
1859
+ return result if self.bounds is None else (self.bounds[0] <= result <= self.bounds[1])
1860
+
1861
+ def __repr__(self):
1862
+ # display duplicate variables
1863
+ v = str.join(" ", [f"{c}_v{x}" for x, c in zip(self.idxs, self.vals)])
1864
+
1865
+ if self.bounds is None:
1866
+ return f"{v}" + (f" {self.constant}" if self.constant is not None else "")
1867
+ elif self.bounds[0] == self.bounds[1]:
1868
+ return f"{v} == {self.bounds[0] - (self.constant or 0.0)}"
1869
+ else:
1870
+ return f"{self.bounds[0]} <= {v} <= {self.bounds[1]}"
1871
+
1872
+ def __str__(self):
1873
+ # display unique variables (values are totaled)
1874
+ idxs, vals = self.unique_elements()
1875
+ v = str.join(" ", [f"{c}_v{x}" for x, c in zip(idxs, vals)])
1876
+
1877
+ if self.bounds is None:
1878
+ return f"{v}" + (f" {self.constant}" if self.constant is not None else "")
1879
+ elif self.bounds[0] == self.bounds[1]:
1880
+ return f"{v} == {self.bounds[0] - (self.constant or 0.0)}"
1881
+ else:
1882
+ return f"{self.bounds[0]} <= {v} <= {self.bounds[1]}"
1883
+
1884
+ # self != other
1885
+ def __ne__(self, other: Optional[Any]):
1886
+ if other is None:
1887
+ return True
1888
+ else:
1889
+ raise Exception("Invalid comparison.")
1890
+
1891
+ # self == other
1892
+ def __eq__(self, other: Any) -> highs_linear_expression: # type: ignore
1893
+ if self.bounds is not None:
1894
+ raise Exception("Bounds have already been set.")
1895
+
1896
+ # self == c
1897
+ elif isinstance(other, (float, int)):
1898
+ copy = highs_linear_expression(self)
1899
+ copy.bounds = (
1900
+ float(other) - (self.constant or 0.0),
1901
+ float(other) - (self.constant or 0.0),
1902
+ )
1903
+ copy.constant = None
1904
+ return copy
1905
+
1906
+ # self == other
1907
+ elif isinstance(other, highs_linear_expression):
1908
+ if other.bounds is not None:
1909
+ raise Exception("Bounds have already been set.")
1910
+
1911
+ copy = highs_linear_expression()
1912
+
1913
+ # prefer most idxs, constant, 'left'
1914
+ if len(other.idxs) > len(self.idxs) or (len(other.idxs) == len(self.idxs) and other.constant is None and self.constant is not None):
1915
+ copy.idxs = other.idxs + self.idxs
1916
+ copy.vals = other.vals + [-v for v in self.vals]
1917
+ copy.bounds = (
1918
+ (self.constant or 0.0) - (other.constant or 0.0),
1919
+ (self.constant or 0.0) - (other.constant or 0.0),
1920
+ )
1921
+ else:
1922
+ copy.idxs = self.idxs + other.idxs
1923
+ copy.vals = self.vals + [-v for v in other.vals]
1924
+ copy.bounds = (
1925
+ (other.constant or 0.0) - (self.constant or 0.0),
1926
+ (other.constant or 0.0) - (self.constant or 0.0),
1927
+ )
1928
+
1929
+ return copy
1930
+
1931
+ # self == x
1932
+ elif isinstance(other, highs_var):
1933
+ copy = highs_linear_expression()
1934
+
1935
+ if len(self.idxs) == 0 or len(self.idxs) == 1 and self.constant is not None:
1936
+ copy.idxs = [other.index] + self.idxs
1937
+ copy.vals = [1.0] + [-v for v in self.vals]
1938
+ copy.bounds = ((self.constant or 0.0), (self.constant or 0.0))
1939
+ else:
1940
+ copy.idxs = self.idxs + [other.index]
1941
+ copy.vals = self.vals + [-1.0]
1942
+ copy.bounds = (-(self.constant or 0.0), -(self.constant or 0.0))
1943
+
1944
+ return copy
1945
+
1946
+ # support expr == [lb, ub] --> lb <= expr <= ub
1947
+ elif hasattr(other, "__getitem__") and hasattr(other, "__len__") and len(other) == 2:
1948
+ if not (isinstance(other[0], (float, int)) and isinstance(other[1], (float, int))):
1949
+ raise Exception("Provided bounds were not valid numbers.")
1950
+
1951
+ copy = highs_linear_expression(self)
1952
+ copy.bounds = (
1953
+ float(other[0]) - (copy.constant or 0.0),
1954
+ float(other[1]) - (copy.constant or 0.0),
1955
+ )
1956
+ copy.constant = None
1957
+ return copy
1958
+
1959
+ else:
1960
+ raise Exception("Unknown comparison.")
1961
+
1962
+ # self <= other
1963
+ def __le__(self, other: Union[float, int, highs_var, highs_linear_expression]):
1964
+ if self.bounds is not None:
1965
+ raise Exception("Bounds have already been set.")
1966
+
1967
+ elif self.__is_active_chain():
1968
+ other = other if isinstance(other, highs_linear_expression) else highs_linear_expression(other)
1969
+ order = self.__get_chain(other, False) # [self, LHS, inner, RHS, other], ignores None values
1970
+
1971
+ # inner <= (self == RHS) <= other
1972
+ # LHS <= (self == inner) <= other
1973
+ if self.__is_equal_except_bounds(order[2]):
1974
+ return self.__compose_chain(*order[1:])
1975
+
1976
+ # self <= (other == inner) <= RHS
1977
+ # self <= (other == LHS) <= inner
1978
+ elif other.__is_equal_except_bounds(order[1]):
1979
+ return self.__compose_chain(*order[:-1])
1980
+
1981
+ self.__reset_chain(self, other, None)
1982
+
1983
+ # self <= c
1984
+ if isinstance(other, (float, int)):
1985
+ copy = highs_linear_expression(self)
1986
+ copy.bounds = (-kHighsInf, float(other) - (copy.constant or 0.0))
1987
+ copy.constant = None
1988
+ return copy
1989
+
1990
+ # self <= other
1991
+ elif isinstance(other, highs_linear_expression):
1992
+ if other.bounds is None:
1993
+ copy = highs_linear_expression()
1994
+
1995
+ # prefer most idxs, constant, 'left'
1996
+ if len(other.idxs) > len(self.idxs) or (len(other.idxs) == len(self.idxs) and other.constant is None and self.constant is not None):
1997
+ copy.idxs = other.idxs + self.idxs
1998
+ copy.vals = other.vals + [-v for v in self.vals]
1999
+ copy.bounds = (
2000
+ (self.constant or 0.0) - (other.constant or 0.0),
2001
+ kHighsInf,
2002
+ )
2003
+ else:
2004
+ copy.idxs = self.idxs + other.idxs
2005
+ copy.vals = self.vals + [-v for v in other.vals]
2006
+ copy.bounds = (
2007
+ -kHighsInf,
2008
+ (other.constant or 0.0) - (self.constant or 0.0),
2009
+ )
2010
+
2011
+ return copy
2012
+ else:
2013
+ raise Exception("Bounds have already been set.")
2014
+
2015
+ # self <= x
2016
+ else: # other is highs_var
2017
+ copy = highs_linear_expression()
2018
+
2019
+ if len(self.idxs) == 0 or len(self.idxs) == 1 and self.constant is not None:
2020
+ copy.idxs = [other.index] + self.idxs
2021
+ copy.vals = [1.0] + [-v for v in self.vals]
2022
+ copy.bounds = ((self.constant or 0.0), kHighsInf)
2023
+ else:
2024
+ copy.idxs = self.idxs + [other.index]
2025
+ copy.vals = self.vals + [-1.0]
2026
+ copy.bounds = (-kHighsInf, -(self.constant or 0.0))
2027
+
2028
+ return copy
2029
+
2030
+ # other <= self
2031
+ def __ge__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2032
+ if self.bounds is not None:
2033
+ raise Exception("Bounds have already been set.")
2034
+
2035
+ elif self.__is_active_chain():
2036
+ other = other if isinstance(other, highs_linear_expression) else highs_linear_expression(other)
2037
+ order = self.__get_chain(other, True) # [other, LHS, inner, RHS, self], ignores None values
2038
+
2039
+ # other <= (self == LHS) <= inner
2040
+ # other <= (self == inner) <= RHS
2041
+ if self.__is_equal_except_bounds(order[1]):
2042
+ return self.__compose_chain(*order[:-1])
2043
+
2044
+ # LHS <= (other == inner) <= self
2045
+ # inner <= (other == RHS) <= self
2046
+ elif other.__is_equal_except_bounds(order[2]):
2047
+ return self.__compose_chain(*order[1:])
2048
+
2049
+ self.__reset_chain(None, other, self)
2050
+
2051
+ # c <= self
2052
+ if isinstance(other, (float, int)):
2053
+ copy = highs_linear_expression(self)
2054
+ copy.bounds = (float(other) - (self.constant or 0.0), kHighsInf)
2055
+ copy.constant = None
2056
+ return copy
2057
+
2058
+ # other <= self
2059
+ elif isinstance(other, highs_linear_expression):
2060
+ if other.bounds is None:
2061
+ copy = highs_linear_expression()
2062
+
2063
+ # prefer most idxs, constant, 'left'
2064
+ if len(self.idxs) > len(other.idxs) or (len(self.idxs) == len(other.idxs) and self.constant is None and other.constant is not None):
2065
+ copy.idxs = self.idxs + other.idxs
2066
+ copy.vals = self.vals + [-v for v in other.vals]
2067
+ copy.bounds = (
2068
+ (other.constant or 0.0) - (self.constant or 0.0),
2069
+ kHighsInf,
2070
+ )
2071
+ else:
2072
+ copy.idxs = other.idxs + self.idxs
2073
+ copy.vals = other.vals + [-v for v in self.vals]
2074
+ copy.bounds = (
2075
+ -kHighsInf,
2076
+ (self.constant or 0.0) - (other.constant or 0.0),
2077
+ )
2078
+
2079
+ return copy
2080
+ else:
2081
+ raise Exception("Bounds have already been set.")
2082
+
2083
+ # x <= self
2084
+ else: # other is highs_var
2085
+ copy = highs_linear_expression()
2086
+
2087
+ if len(self.idxs) > 1:
2088
+ copy.idxs = self.idxs + [other.index]
2089
+ copy.vals = self.vals + [-1.0]
2090
+ copy.bounds = (-(self.constant or 0.0), kHighsInf)
2091
+ else:
2092
+ copy.idxs = [other.index] + self.idxs
2093
+ copy.vals = [1.0] + [-v for v in self.vals]
2094
+ copy.bounds = (-kHighsInf, (self.constant or 0.0))
2095
+
2096
+ return copy
2097
+
2098
+ def __radd__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2099
+ return self + other
2100
+
2101
+ # (LHS <= self <= RHS) + (LHS <= other <= RHS)
2102
+ def __add__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2103
+ copy = highs_linear_expression(self)
2104
+ copy += other
2105
+ return copy
2106
+
2107
+ def __neg__(self):
2108
+ copy = highs_linear_expression()
2109
+ copy.idxs = list(self.idxs)
2110
+ copy.vals = [-v for v in self.vals]
2111
+ copy.constant = -self.constant if self.constant is not None else None
2112
+
2113
+ if self.bounds is not None:
2114
+ copy.bounds = (-self.bounds[1], -self.bounds[0])
2115
+
2116
+ return copy
2117
+
2118
+ def __rmul__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2119
+ return self * other
2120
+
2121
+ def __mul__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2122
+ copy = highs_linear_expression(self)
2123
+ copy *= other
2124
+ return copy
2125
+
2126
+ # other - self
2127
+ def __rsub__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2128
+ copy = highs_linear_expression(other)
2129
+ copy -= self
2130
+ return copy
2131
+
2132
+ def __sub__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2133
+ copy = highs_linear_expression(self)
2134
+ copy -= other
2135
+ return copy
2136
+
2137
+ def unique_elements(self):
2138
+ """
2139
+ Collects unique variables and sums their corresponding values. Keeps all values (including zeros).
2140
+ """
2141
+ # sort by groups for fast unique
2142
+ groups = np.asarray(self.idxs, dtype=np.int32)
2143
+ order = np.argsort(groups, kind="stable")
2144
+ groups = groups[order]
2145
+
2146
+ # get unique groups
2147
+ index = np.ones(len(groups), dtype=bool)
2148
+ index[:-1] = groups[1:] != groups[:-1]
2149
+
2150
+ if index.all():
2151
+ values = np.asarray(self.vals, dtype=np.float64)
2152
+ values = values[order]
2153
+ return groups, values
2154
+ else:
2155
+ values = np.asarray(self.vals, dtype=np.float64)
2156
+ values = np.cumsum(values[order])
2157
+ values = values[index]
2158
+ groups = groups[index]
2159
+
2160
+ # calculate the correct sum (diff of cumsum)
2161
+ values[1:] = values[1:] - values[:-1]
2162
+ return groups, values
2163
+
2164
+ def reduced_elements(self):
2165
+ """
2166
+ Similar to unique_elements, except keeps only non-zero values
2167
+ """
2168
+ vx, vl = self.unique_elements()
2169
+ zx = np.nonzero(vl)
2170
+ return vx[zx], vl[zx]
2171
+
2172
+ ##
2173
+ ## mutable functions
2174
+ ##
2175
+
2176
+ # (LHS <= self <= RHS) += (LHS <= other <= RHS)
2177
+ def __iadd__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2178
+ if isinstance(other, highs_var):
2179
+ self.idxs.append(other.index)
2180
+ self.vals.append(1.0)
2181
+ return self
2182
+
2183
+ elif isinstance(other, highs_linear_expression):
2184
+ if self.constant is not None and other.bounds is not None or self.bounds is not None and other.constant is not None:
2185
+ raise Exception("""Cannot add a bounded constraint to a constraint with a constant, i.e., (lb <= expr1 <= ub) + (expr2 + c).
2186
+ Unsure of your intent. Did you want: lb + c <= expr1 + expr2 <= ub + c? Try: (lb <= expr1 <= ub) + (expr2 == c) instead.""")
2187
+
2188
+ self.idxs.extend(other.idxs)
2189
+ self.vals.extend(other.vals)
2190
+
2191
+ if self.constant is not None or other.constant is not None:
2192
+ self.constant = (self.constant or 0.0) + (other.constant or 0.0)
2193
+
2194
+ # (l1 <= expr1 <= u1) + (l2 <= expr2 <= u2) --> l1 + l2 <= expr1 + expr2 <= u1 + u2
2195
+ if self.bounds is not None and other.bounds is not None:
2196
+ self.bounds = (self.bounds[0] + other.bounds[0], self.bounds[1] + other.bounds[1])
2197
+
2198
+ # (expr1) + (lb <= expr2 <= ub) --> lb <= expr1 + expr2 <= ub
2199
+ elif self.bounds is None and other.bounds is not None:
2200
+ self.bounds = other.bounds
2201
+
2202
+ return self
2203
+
2204
+ else:
2205
+ if self.bounds is not None:
2206
+ raise Exception("""Cannot add a constant to a bounded constraint, i.e., (lb <= expr <= ub) + c.
2207
+ Unsure of your intent. Did you want: lb + c <= expr <= ub + c? Try: (lb <= expr <= ub) + (highs_linear_expression() == c) instead.""")
2208
+
2209
+ self.constant = float(other) + (self.constant or 0.0)
2210
+ return self
2211
+
2212
+ def __isub__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2213
+ if isinstance(other, highs_var):
2214
+ self.idxs.append(other.index)
2215
+ self.vals.append(-1.0)
2216
+ return self
2217
+
2218
+ elif isinstance(other, highs_linear_expression):
2219
+ if self.constant is not None and other.bounds is not None or self.bounds is not None and other.constant is not None:
2220
+ raise Exception("""Cannot subtract a bounded constraint to a constraint with a constant, i.e., (lb <= expr1 <= ub) - (expr2 + c).
2221
+ Unsure of your intent. Did you want: lb - c <= expr1 - expr2 <= ub - c? Try: (lb <= expr1 <= ub) - (expr2 == c) instead.""")
2222
+
2223
+ self.idxs.extend(other.idxs)
2224
+ self.vals.extend([-v for v in other.vals])
2225
+
2226
+ if self.constant is not None or other.constant is not None:
2227
+ self.constant = (self.constant or 0.0) - (other.constant or 0.0)
2228
+
2229
+ # (l1 <= expr1 <= u1) - (l2 <= expr2 <= u2) --> l1 - u2 <= expr1 - expr2 <= u1 - l2
2230
+ if self.bounds is not None and other.bounds is not None:
2231
+ self.bounds = (self.bounds[0] - other.bounds[1], self.bounds[1] - other.bounds[0])
2232
+
2233
+ # expr1 - (lb <= expr2 <= ub) --> -ub <= expr1 - expr2 <= -lb
2234
+ elif self.bounds is None and other.bounds is not None:
2235
+ self.bounds = (-other.bounds[1], -other.bounds[0])
2236
+
2237
+ return self
2238
+
2239
+ else:
2240
+ if self.bounds is not None:
2241
+ raise Exception("""Cannot subtract a constant to a bounded constraint, i.e., (lb <= expr <= ub) - c.
2242
+ Unsure of your intent. Did you want: lb - c <= expr <= ub - c? Try: (lb <= expr <= ub) - (highs_linear_expression() == c) instead.""")
2243
+
2244
+ self.constant = (self.constant or 0.0) - float(other)
2245
+ return self
2246
+
2247
+ def __imul__(self, other: Union[float, int, highs_var, highs_linear_expression]):
2248
+ if isinstance(other, (float, int)):
2249
+ scale = float(other)
2250
+
2251
+ # other is a constant expression, so treat as a scalar
2252
+ elif isinstance(other, highs_linear_expression) and other.idxs == [] and other.constant is not None:
2253
+ scale = float(other.constant)
2254
+ else:
2255
+ scale = None
2256
+
2257
+ if scale is not None:
2258
+ self.vals = [scale * v for v in self.vals]
2259
+
2260
+ if self.constant is not None:
2261
+ self.constant *= scale
2262
+
2263
+ if self.bounds is not None:
2264
+ # negative scale reverses bounds
2265
+ if scale >= 0:
2266
+ self.bounds = (scale * self.bounds[0], scale * self.bounds[1])
2267
+ else:
2268
+ self.bounds = (scale * self.bounds[1], scale * self.bounds[0])
2269
+
2270
+ return self
2271
+
2272
+ # self only has a constant, so treat as a scalar
2273
+ elif self.idxs == [] and self.constant is not None:
2274
+ scale = self.constant
2275
+
2276
+ if isinstance(other, highs_linear_expression):
2277
+ self.idxs = other.idxs
2278
+ self.vals = [scale * v for v in other.vals]
2279
+
2280
+ if other.constant is not None:
2281
+ self.constant = other.constant * scale
2282
+ else:
2283
+ self.constant = None
2284
+
2285
+ if other.bounds is not None:
2286
+ # negative scale reverses bounds
2287
+ if scale >= 0:
2288
+ self.bounds = (scale * other.bounds[0], scale * other.bounds[1])
2289
+ else:
2290
+ self.bounds = (scale * other.bounds[1], scale * other.bounds[0])
2291
+
2292
+ elif isinstance(other, highs_var):
2293
+ self.idxs = [other.index]
2294
+ self.vals = [scale]
2295
+ self.constant = None
2296
+
2297
+ else:
2298
+ raise Exception("Unexpected parameters.")
2299
+
2300
+ return self
2301
+
2302
+ elif isinstance(other, highs_var):
2303
+ raise Exception("Only linear expressions are allowed.")
2304
+
2305
+ else:
2306
+ raise Exception("Unexpected parameters.")
2307
+
2308
+ # The following is needed to support chained comparison, i.e., lb <= expr <= ub. This is interpreted
2309
+ # as '__bool__(lb <= expr) and (expr <= ub)'; returning (expr <= ub), since __bool__(lb <= expr) == True.
2310
+ #
2311
+ # We essentially want to "rewrite" this as '(lb <= expr) <= ub', while keeping the expr instance immutable.
2312
+ # As a slight hack, we can use a shared (thread local) object to keep track of the chain.
2313
+ #
2314
+ # Whenever we perform an inequality, we first check if the current expression is part of a chain.
2315
+ # This inner '__chain' is set by __bool__(lb <= expr) and is reset after the inequality is evaluated.
2316
+ #
2317
+ # Two potential issues:
2318
+ # 1. It is possible to manually construct this sequence, e.g.,
2319
+ # tmp = x0 + x1
2320
+ # bool(tmp <= 10)
2321
+ # print(5 <= tmp) # outputs: 5 <= 1.0_v0 + 1.0_v1 <= 10
2322
+ # print(5 <= tmp) # outputs: 5 <= 1.0_v0 + 1.0_v1 <= inf : chain is broken
2323
+ #
2324
+ # Note that:
2325
+ # bool(tmp <= 10)
2326
+ # tmp += x0 + x1 # changes tmp, so the chain is broken
2327
+ # print(5 <= tmp) # outputs: 5 <= 2.0_v0 + 2.0_v1 <= inf
2328
+ #
2329
+ # 2. The chain might "break" if run within a debugger (on same thread), i.e., "watched debugger expressions"
2330
+ # that evaluate any variant of highs_linear_expression inequalities.
2331
+ #
2332
+ # I believe these issues are low risk, the approach thread safe, and the performance/overhead is minimal.
2333
+ #
2334
+ __chain = local()
2335
+
2336
+ # capture the chain
2337
+ def __bool__(self):
2338
+ highs_linear_expression.__chain.check = self
2339
+
2340
+ # take copies of the chain to avoid issues with mutable expressions
2341
+ LHS = getattr(highs_linear_expression.__chain, "left", None)
2342
+ EXR = getattr(highs_linear_expression.__chain, "inner", None)
2343
+ RHS = getattr(highs_linear_expression.__chain, "right", None)
2344
+
2345
+ highs_linear_expression.__chain.left = highs_linear_expression(LHS) if LHS is not None else None
2346
+ highs_linear_expression.__chain.inner = highs_linear_expression(EXR) if EXR is not None else None
2347
+ highs_linear_expression.__chain.right = highs_linear_expression(RHS) if RHS is not None else None
2348
+ return True
2349
+
2350
+ def __is_equal_except_bounds(self, other: highs_linear_expression) -> bool:
2351
+ return self.idxs == other.idxs and self.vals == other.vals and self.constant == other.constant
2352
+
2353
+ def __is_active_chain(self):
2354
+ return getattr(highs_linear_expression.__chain, "check", None) is not None
2355
+
2356
+ def __reset_chain(
2357
+ self,
2358
+ LHS: Optional[Any] = None,
2359
+ inner: Optional[Any] = None,
2360
+ RHS: Optional[Any] = None,
2361
+ ) -> None:
2362
+ highs_linear_expression.__chain.check = None
2363
+ highs_linear_expression.__chain.left = LHS
2364
+ highs_linear_expression.__chain.inner = inner
2365
+ highs_linear_expression.__chain.right = RHS
2366
+
2367
+ def __get_chain(self, other: highs_linear_expression, is_ge_than: bool):
2368
+ LHS = getattr(highs_linear_expression.__chain, "left", None)
2369
+ RHS = getattr(highs_linear_expression.__chain, "right", None)
2370
+ inner = getattr(highs_linear_expression.__chain, "inner", None)
2371
+
2372
+ # assume (LHS is None) ^ (RHS is None) == 1, i.e., only LHS or RHS is set
2373
+ assert (LHS is None) ^ (RHS is None) == 1
2374
+ order = np.asarray([expr for expr in [other, LHS, inner, RHS, self] if expr is not None])
2375
+
2376
+ if not is_ge_than: # swap order for: self <= other
2377
+ order[0], order[-1] = order[-1], order[0]
2378
+
2379
+ return order
2380
+
2381
+ # left <= self <= right
2382
+ def __compose_chain(
2383
+ self,
2384
+ left: highs_linear_expression,
2385
+ inner: highs_linear_expression,
2386
+ right: highs_linear_expression,
2387
+ ):
2388
+ self.__reset_chain()
2389
+ assert not isinstance(inner, highs_linear_expression) or inner.bounds is None, "Bounds already set in chain comparison."
2390
+
2391
+ # check to see if we have a valid chain, i.e., left.idxs "==" right.idxs
2392
+ # we can assume that left and right are both highs_linear_expression
2393
+ LHS_vars, LHS_vals = left.reduced_elements()
2394
+ RHS_vars, RHS_vals = right.reduced_elements()
2395
+
2396
+ if not np.array_equal(LHS_vars, RHS_vars) or not np.array_equal(LHS_vals, RHS_vals):
2397
+ raise Exception("Mismatched variables in chain comparison.")
2398
+
2399
+ if len(LHS_vars) > len(inner.idxs):
2400
+ copy = highs_linear_expression()
2401
+ copy.idxs = LHS_vars.tolist() + inner.idxs
2402
+ copy.vals = LHS_vals.tolist() + [-v for v in inner.vals]
2403
+ copy.bounds = (
2404
+ (inner.constant or 0.0) - (right.constant or 0.0),
2405
+ (inner.constant or 0.0) - (left.constant or 0.0),
2406
+ )
2407
+ else:
2408
+ copy = highs_linear_expression(inner)
2409
+ copy.idxs.extend(LHS_vars)
2410
+ copy.vals.extend([-v for v in LHS_vals])
2411
+ copy.bounds = (
2412
+ (left.constant or 0.0) - (copy.constant or 0.0),
2413
+ (right.constant or 0.0) - (copy.constant or 0.0),
2414
+ )
2415
+ copy.constant = None
2416
+
2417
+ return copy
2418
+
2419
+
2420
+ def qsum(
2421
+ items: Iterable[Union[highs_var, highs_linear_expression]],
2422
+ initial: Optional[Union[float, int, highs_var, highs_linear_expression]] = None,
2423
+ ):
2424
+ """
2425
+ Performs a faster sum for highs_linear_expressions.
2426
+
2427
+ Args:
2428
+ items: A collection of highs_linear_expressions or highs_vars to be summed.
2429
+ """
2430
+ return Highs.qsum(items, initial)