localmip 2.0.1__tar.gz

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 (58) hide show
  1. localmip-2.0.1/CMakeLists.txt +64 -0
  2. localmip-2.0.1/LICENSE +21 -0
  3. localmip-2.0.1/MANIFEST.in +6 -0
  4. localmip-2.0.1/PKG-INFO +171 -0
  5. localmip-2.0.1/README.md +123 -0
  6. localmip-2.0.1/VERSION +1 -0
  7. localmip-2.0.1/local_mip_py.cpp +1213 -0
  8. localmip-2.0.1/localmip.egg-info/PKG-INFO +171 -0
  9. localmip-2.0.1/localmip.egg-info/SOURCES.txt +14 -0
  10. localmip-2.0.1/localmip.egg-info/dependency_links.txt +1 -0
  11. localmip-2.0.1/localmip.egg-info/not-zip-safe +1 -0
  12. localmip-2.0.1/localmip.egg-info/top_level.txt +1 -0
  13. localmip-2.0.1/localmip_core/src/local_mip/Local_MIP.cpp +644 -0
  14. localmip-2.0.1/localmip_core/src/local_mip/Local_MIP.h +212 -0
  15. localmip-2.0.1/localmip_core/src/local_search/Local_Search.cpp +676 -0
  16. localmip-2.0.1/localmip_core/src/local_search/Local_Search.h +462 -0
  17. localmip-2.0.1/localmip_core/src/local_search/context/context.h +136 -0
  18. localmip-2.0.1/localmip_core/src/local_search/lift_move/lift_move.cpp +161 -0
  19. localmip-2.0.1/localmip_core/src/local_search/neighbor/explore_easy.cpp +90 -0
  20. localmip-2.0.1/localmip_core/src/local_search/neighbor/explore_flip.cpp +44 -0
  21. localmip-2.0.1/localmip_core/src/local_search/neighbor/explore_sat.cpp +57 -0
  22. localmip-2.0.1/localmip_core/src/local_search/neighbor/explore_unsat.cpp +72 -0
  23. localmip-2.0.1/localmip_core/src/local_search/neighbor/explore_unsat_random.cpp +66 -0
  24. localmip-2.0.1/localmip_core/src/local_search/neighbor/neighbor.cpp +242 -0
  25. localmip-2.0.1/localmip_core/src/local_search/neighbor/neighbor.h +214 -0
  26. localmip-2.0.1/localmip_core/src/local_search/restart/restart.cpp +227 -0
  27. localmip-2.0.1/localmip_core/src/local_search/restart/restart.h +95 -0
  28. localmip-2.0.1/localmip_core/src/local_search/scoring/lift_scoring.cpp +126 -0
  29. localmip-2.0.1/localmip_core/src/local_search/scoring/neighbor_scoring.cpp +268 -0
  30. localmip-2.0.1/localmip_core/src/local_search/scoring/scoring.h +145 -0
  31. localmip-2.0.1/localmip_core/src/local_search/start/start.cpp +118 -0
  32. localmip-2.0.1/localmip_core/src/local_search/start/start.h +70 -0
  33. localmip-2.0.1/localmip_core/src/local_search/weight/weight.cpp +123 -0
  34. localmip-2.0.1/localmip_core/src/local_search/weight/weight.h +77 -0
  35. localmip-2.0.1/localmip_core/src/model_api/Model_API.cpp +345 -0
  36. localmip-2.0.1/localmip_core/src/model_api/Model_API.h +122 -0
  37. localmip-2.0.1/localmip_core/src/model_data/Model_Con.cpp +100 -0
  38. localmip-2.0.1/localmip_core/src/model_data/Model_Con.h +221 -0
  39. localmip-2.0.1/localmip_core/src/model_data/Model_Manager.cpp +791 -0
  40. localmip-2.0.1/localmip_core/src/model_data/Model_Manager.h +328 -0
  41. localmip-2.0.1/localmip_core/src/model_data/Model_Var.cpp +71 -0
  42. localmip-2.0.1/localmip_core/src/model_data/Model_Var.h +161 -0
  43. localmip-2.0.1/localmip_core/src/reader/LP_Reader.cpp +958 -0
  44. localmip-2.0.1/localmip_core/src/reader/LP_Reader.h +54 -0
  45. localmip-2.0.1/localmip_core/src/reader/MPS_Reader.cpp +376 -0
  46. localmip-2.0.1/localmip_core/src/reader/MPS_Reader.h +74 -0
  47. localmip-2.0.1/localmip_core/src/reader/Model_Reader.h +22 -0
  48. localmip-2.0.1/localmip_core/src/utils/cmdline.h +806 -0
  49. localmip-2.0.1/localmip_core/src/utils/global_defs.h +98 -0
  50. localmip-2.0.1/localmip_core/src/utils/main.cpp +148 -0
  51. localmip-2.0.1/localmip_core/src/utils/paras.cpp +380 -0
  52. localmip-2.0.1/localmip_core/src/utils/paras.h +238 -0
  53. localmip-2.0.1/localmip_core/src/utils/solver_error.h +26 -0
  54. localmip-2.0.1/localmip_core/src/utils/utils.cpp +75 -0
  55. localmip-2.0.1/pyproject.toml +42 -0
  56. localmip-2.0.1/setup.cfg +4 -0
  57. localmip-2.0.1/setup.py +109 -0
  58. localmip-2.0.1/smoke_test.py +23 -0
@@ -0,0 +1,64 @@
1
+ cmake_minimum_required(VERSION 3.15...3.27)
2
+
3
+ # Set minimum policy version to allow older pybind11 CMake files
4
+ cmake_policy(VERSION 3.5)
5
+
6
+ project(localmip_py LANGUAGES CXX)
7
+
8
+ # Suppress deprecation warnings from pybind11's legacy Python finding modules
9
+ if(POLICY CMP0148)
10
+ cmake_policy(SET CMP0148 OLD)
11
+ endif()
12
+
13
+ # Find pybind11 (expects it installed or discoverable via CMAKE_PREFIX_PATH)
14
+ find_package(Threads REQUIRED)
15
+ find_package(pybind11 REQUIRED)
16
+
17
+ # Disable IPO/LTO to avoid toolchain-induced zero-sized outputs
18
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)
19
+ set(PYBIND11_LTO_CXX_FLAGS "" CACHE STRING "" FORCE)
20
+ set(PYBIND11_LTO_C_FLAGS "" CACHE STRING "" FORCE)
21
+
22
+ # Prefer bundled core sources in source distributions; fall back to the repo root in development checkouts.
23
+ set(LOCALMIP_ROOT "${CMAKE_CURRENT_LIST_DIR}/..")
24
+ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/localmip_core/src")
25
+ set(LOCALMIP_ROOT "${CMAKE_CURRENT_LIST_DIR}/localmip_core")
26
+ endif()
27
+ set(LOCALMIP_INCLUDE_DIR "${LOCALMIP_ROOT}/src")
28
+ file(GLOB_RECURSE LOCALMIP_SOURCES CONFIGURE_DEPENDS
29
+ "${LOCALMIP_ROOT}/src/*.cpp"
30
+ "${LOCALMIP_ROOT}/src/*.cc"
31
+ )
32
+ list(REMOVE_ITEM LOCALMIP_SOURCES "${LOCALMIP_ROOT}/src/utils/main.cpp")
33
+
34
+ add_library(LocalMIP STATIC ${LOCALMIP_SOURCES})
35
+ target_include_directories(LocalMIP PUBLIC
36
+ ${LOCALMIP_INCLUDE_DIR}
37
+ ${LOCALMIP_ROOT}/src/local_mip
38
+ )
39
+ target_compile_features(LocalMIP PUBLIC cxx_std_20)
40
+ target_compile_definitions(LocalMIP PUBLIC $<$<CONFIG:Debug>:DEBUG>)
41
+ target_compile_options(LocalMIP PUBLIC
42
+ -fPIC
43
+ $<$<CONFIG:Debug>:-g>
44
+ $<$<CONFIG:Release>:-O3>
45
+ )
46
+ target_link_libraries(LocalMIP PUBLIC Threads::Threads)
47
+
48
+ pybind11_add_module(localmip_py MODULE local_mip_py.cpp)
49
+ target_include_directories(localmip_py PRIVATE ${LOCALMIP_INCLUDE_DIR})
50
+ target_link_libraries(localmip_py PRIVATE LocalMIP)
51
+ target_compile_features(localmip_py PRIVATE cxx_std_20)
52
+ set_target_properties(localmip_py PROPERTIES INTERPROCEDURAL_OPTIMIZATION OFF)
53
+
54
+ # Use parallel LTO to suppress warnings when linking against LTO-compiled static library
55
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
56
+ target_link_options(localmip_py PRIVATE -flto=auto)
57
+ endif()
58
+
59
+ # Produce a plain .so (no python prefix/suffix mangling already handled by pybind11_add_module)
60
+ set_target_properties(localmip_py PROPERTIES
61
+ OUTPUT_NAME "localmip_py"
62
+ )
63
+
64
+ install(TARGETS localmip_py LIBRARY DESTINATION .)
localmip-2.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Local-MIP
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ include README.md
2
+ include VERSION
3
+ include CMakeLists.txt
4
+ include local_mip_py.cpp
5
+ include smoke_test.py
6
+ include LICENSE
@@ -0,0 +1,171 @@
1
+ Metadata-Version: 2.4
2
+ Name: localmip
3
+ Version: 2.0.1
4
+ Summary: Python bindings for the Local-MIP solver
5
+ Author: Local-MIP authors
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Local-MIP
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/shaowei-cai-group/Local-MIP
29
+ Project-URL: Repository, https://github.com/shaowei-cai-group/Local-MIP
30
+ Project-URL: Issues, https://github.com/shaowei-cai-group/Local-MIP/issues
31
+ Classifier: Development Status :: 4 - Beta
32
+ Classifier: Intended Audience :: Science/Research
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Operating System :: POSIX :: Linux
35
+ Classifier: Programming Language :: C++
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3 :: Only
38
+ Classifier: Programming Language :: Python :: 3.8
39
+ Classifier: Programming Language :: Python :: 3.9
40
+ Classifier: Programming Language :: Python :: 3.10
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Programming Language :: Python :: 3.12
43
+ Classifier: Topic :: Scientific/Engineering
44
+ Requires-Python: >=3.8
45
+ Description-Content-Type: text/markdown
46
+ License-File: LICENSE
47
+ Dynamic: license-file
48
+
49
+ # Python Bindings (pybind11)
50
+
51
+ This folder provides a pybind11 module that exposes `Local_MIP` to Python without touching the main solver code.
52
+
53
+ The bindings expose the core solver configuration and result-query API used in normal runs, including `.set` parameter-file loading, plus the in-memory modeling interface.
54
+
55
+ ## Install from PyPI
56
+ For Linux x86_64:
57
+ ```bash
58
+ python3 -m pip install localmip
59
+ ```
60
+
61
+ Import it directly:
62
+ ```python
63
+ import localmip_py as lm
64
+ ```
65
+
66
+ ## Install from the repository
67
+ From repo root:
68
+ ```bash
69
+ python3 -m pip install ./python-bindings
70
+ ```
71
+
72
+ This builds both the Local-MIP core and the pybind11 extension during installation.
73
+ After installation, the module can be imported directly:
74
+ ```bash
75
+ python3 -c "import localmip_py as lm; print(lm.LocalMIP)"
76
+ ```
77
+
78
+ ## Run the demos
79
+ From repo root:
80
+ ```bash
81
+ python3 python-bindings/sample.py
82
+ python3 python-bindings/model_api_demo.py
83
+ python3 python-bindings/test_python_api.py
84
+ python3 python-bindings/smoke_test.py
85
+ ```
86
+
87
+ ## Development build without pip
88
+ The legacy local build flow is still supported. From repo root:
89
+ ```bash
90
+ PY_EXE="$(python3 -c 'import sys; print(sys.executable)')"
91
+ PYTHON_EXECUTABLE="${PY_EXE}" python-bindings/build.sh
92
+ ```
93
+
94
+ Output: `python-bindings/build/localmip_py.cpython-*.so` (exact suffix depends on Python version).
95
+
96
+ Use the same interpreter for build and run so the compiled module suffix matches the interpreter that imports it:
97
+ ```bash
98
+ PY_EXE="$(python3 -c 'import sys; print(sys.executable)')"
99
+ PYTHON_EXECUTABLE="${PY_EXE}" python-bindings/build.sh
100
+ "${PY_EXE}" python-bindings/sample.py
101
+ "${PY_EXE}" python-bindings/model_api_demo.py
102
+ "${PY_EXE}" python-bindings/test_python_api.py
103
+ "${PY_EXE}" python-bindings/smoke_test.py
104
+ ```
105
+
106
+ ## Use in Python
107
+ If installed with pip:
108
+ ```python
109
+ import localmip_py as lm
110
+ ```
111
+
112
+ If using the local development build, either append the build directory to `PYTHONPATH` or copy the `.so` next to your script:
113
+ ```python
114
+ import sys
115
+ sys.path.append("python-bindings/build") # if not installed
116
+ import localmip_py as lm
117
+
118
+ solver = lm.LocalMIP()
119
+ solver.set_model_file("test-set/sct1.mps")
120
+ solver.set_sol_path("py_example.sol")
121
+ solver.set_time_limit(10.0)
122
+ solver.set_log_obj(True)
123
+
124
+ # Optional: register a start callback
125
+ stats = {"calls": 0}
126
+
127
+ def start_cbk(ctx, user_data):
128
+ user_data["calls"] += 1
129
+ if ctx.shared.binary_idx_list:
130
+ idx = ctx.shared.binary_idx_list[0]
131
+ ctx.current_values[idx] = 1.0
132
+
133
+ solver.set_start_cbk(start_cbk, stats)
134
+ solver.run()
135
+
136
+ print("Feasible:", solver.is_feasible(), "Obj:", solver.get_obj_value())
137
+ print("Start callback calls:", stats["calls"])
138
+ ```
139
+
140
+ ## Model API (Programmatic Modeling)
141
+ The bindings also expose Local-MIP's **Model API**, which lets you build a model
142
+ directly in Python (mirrors `example/model-api/model_api_demo.cpp`).
143
+
144
+ Run the demo:
145
+ ```bash
146
+ PY_EXE="$(python3 -c 'import sys; print(sys.executable)')"
147
+ "${PY_EXE}" python-bindings/model_api_demo.py
148
+ ```
149
+
150
+ Smoke test:
151
+ ```bash
152
+ PY_EXE="$(python3 -c 'import sys; print(sys.executable)')"
153
+ "${PY_EXE}" python-bindings/test_python_api.py
154
+ ```
155
+
156
+ Key symbols:
157
+ - `lm.Sense.{minimize,maximize}`
158
+ - `lm.VarType.{binary,general_integer,real,fixed}`
159
+ - `LocalMIP.set_param_set_file(...)`
160
+ - `LocalMIP.set_bms_unsat_con(...)`, `set_bms_mtm_unsat_op(...)`, `set_bms_sat_con(...)`, `set_bms_mtm_sat_op(...)`, `set_bms_flip_op(...)`, `set_bms_easy_op(...)`, `set_bms_random_op(...)`
161
+ - `LocalMIP.enable_model_api()`
162
+ - `LocalMIP.add_var(...)`, `LocalMIP.add_con(...)`
163
+ - `LocalMIP.get_solution()`
164
+
165
+ ## Notes
166
+ - `pip install ./python-bindings` compiles the Local-MIP core and the extension together inside the wheel build.
167
+ - The local helper script `python-bindings/build.sh` still works for iterative development builds.
168
+ - Long-running `run()` releases the GIL; Python callbacks reacquire the GIL before execution.
169
+ - Callback contexts (`Start::Start_Ctx`, etc.) are exposed as structured Python objects with read-only shared sequence views and writable fields where the solver expects mutation.
170
+ - `NeighborCtx.op_size` is derived from `clear_ops()`, `set_single_op(...)`, and `append_op(...)`; update move outputs through those helpers instead of writing the size directly.
171
+ - Python callbacks can optionally receive a Python `user_data` object; if omitted, the old shorter callback signatures still work.
@@ -0,0 +1,123 @@
1
+ # Python Bindings (pybind11)
2
+
3
+ This folder provides a pybind11 module that exposes `Local_MIP` to Python without touching the main solver code.
4
+
5
+ The bindings expose the core solver configuration and result-query API used in normal runs, including `.set` parameter-file loading, plus the in-memory modeling interface.
6
+
7
+ ## Install from PyPI
8
+ For Linux x86_64:
9
+ ```bash
10
+ python3 -m pip install localmip
11
+ ```
12
+
13
+ Import it directly:
14
+ ```python
15
+ import localmip_py as lm
16
+ ```
17
+
18
+ ## Install from the repository
19
+ From repo root:
20
+ ```bash
21
+ python3 -m pip install ./python-bindings
22
+ ```
23
+
24
+ This builds both the Local-MIP core and the pybind11 extension during installation.
25
+ After installation, the module can be imported directly:
26
+ ```bash
27
+ python3 -c "import localmip_py as lm; print(lm.LocalMIP)"
28
+ ```
29
+
30
+ ## Run the demos
31
+ From repo root:
32
+ ```bash
33
+ python3 python-bindings/sample.py
34
+ python3 python-bindings/model_api_demo.py
35
+ python3 python-bindings/test_python_api.py
36
+ python3 python-bindings/smoke_test.py
37
+ ```
38
+
39
+ ## Development build without pip
40
+ The legacy local build flow is still supported. From repo root:
41
+ ```bash
42
+ PY_EXE="$(python3 -c 'import sys; print(sys.executable)')"
43
+ PYTHON_EXECUTABLE="${PY_EXE}" python-bindings/build.sh
44
+ ```
45
+
46
+ Output: `python-bindings/build/localmip_py.cpython-*.so` (exact suffix depends on Python version).
47
+
48
+ Use the same interpreter for build and run so the compiled module suffix matches the interpreter that imports it:
49
+ ```bash
50
+ PY_EXE="$(python3 -c 'import sys; print(sys.executable)')"
51
+ PYTHON_EXECUTABLE="${PY_EXE}" python-bindings/build.sh
52
+ "${PY_EXE}" python-bindings/sample.py
53
+ "${PY_EXE}" python-bindings/model_api_demo.py
54
+ "${PY_EXE}" python-bindings/test_python_api.py
55
+ "${PY_EXE}" python-bindings/smoke_test.py
56
+ ```
57
+
58
+ ## Use in Python
59
+ If installed with pip:
60
+ ```python
61
+ import localmip_py as lm
62
+ ```
63
+
64
+ If using the local development build, either append the build directory to `PYTHONPATH` or copy the `.so` next to your script:
65
+ ```python
66
+ import sys
67
+ sys.path.append("python-bindings/build") # if not installed
68
+ import localmip_py as lm
69
+
70
+ solver = lm.LocalMIP()
71
+ solver.set_model_file("test-set/sct1.mps")
72
+ solver.set_sol_path("py_example.sol")
73
+ solver.set_time_limit(10.0)
74
+ solver.set_log_obj(True)
75
+
76
+ # Optional: register a start callback
77
+ stats = {"calls": 0}
78
+
79
+ def start_cbk(ctx, user_data):
80
+ user_data["calls"] += 1
81
+ if ctx.shared.binary_idx_list:
82
+ idx = ctx.shared.binary_idx_list[0]
83
+ ctx.current_values[idx] = 1.0
84
+
85
+ solver.set_start_cbk(start_cbk, stats)
86
+ solver.run()
87
+
88
+ print("Feasible:", solver.is_feasible(), "Obj:", solver.get_obj_value())
89
+ print("Start callback calls:", stats["calls"])
90
+ ```
91
+
92
+ ## Model API (Programmatic Modeling)
93
+ The bindings also expose Local-MIP's **Model API**, which lets you build a model
94
+ directly in Python (mirrors `example/model-api/model_api_demo.cpp`).
95
+
96
+ Run the demo:
97
+ ```bash
98
+ PY_EXE="$(python3 -c 'import sys; print(sys.executable)')"
99
+ "${PY_EXE}" python-bindings/model_api_demo.py
100
+ ```
101
+
102
+ Smoke test:
103
+ ```bash
104
+ PY_EXE="$(python3 -c 'import sys; print(sys.executable)')"
105
+ "${PY_EXE}" python-bindings/test_python_api.py
106
+ ```
107
+
108
+ Key symbols:
109
+ - `lm.Sense.{minimize,maximize}`
110
+ - `lm.VarType.{binary,general_integer,real,fixed}`
111
+ - `LocalMIP.set_param_set_file(...)`
112
+ - `LocalMIP.set_bms_unsat_con(...)`, `set_bms_mtm_unsat_op(...)`, `set_bms_sat_con(...)`, `set_bms_mtm_sat_op(...)`, `set_bms_flip_op(...)`, `set_bms_easy_op(...)`, `set_bms_random_op(...)`
113
+ - `LocalMIP.enable_model_api()`
114
+ - `LocalMIP.add_var(...)`, `LocalMIP.add_con(...)`
115
+ - `LocalMIP.get_solution()`
116
+
117
+ ## Notes
118
+ - `pip install ./python-bindings` compiles the Local-MIP core and the extension together inside the wheel build.
119
+ - The local helper script `python-bindings/build.sh` still works for iterative development builds.
120
+ - Long-running `run()` releases the GIL; Python callbacks reacquire the GIL before execution.
121
+ - Callback contexts (`Start::Start_Ctx`, etc.) are exposed as structured Python objects with read-only shared sequence views and writable fields where the solver expects mutation.
122
+ - `NeighborCtx.op_size` is derived from `clear_ops()`, `set_single_op(...)`, and `append_op(...)`; update move outputs through those helpers instead of writing the size directly.
123
+ - Python callbacks can optionally receive a Python `user_data` object; if omitted, the old shorter callback signatures still work.
localmip-2.0.1/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.0.1