remove the pywrap prefix from pybind11 modules; add _pybind to the cmake target of the same modules
This commit is contained in:
@@ -270,8 +270,8 @@ file(COPY
|
||||
DESTINATION ${PYTHON_PROJECT_DIR}/linear_solver)
|
||||
file(COPY
|
||||
ortools/linear_solver/python/model_builder.py
|
||||
ortools/linear_solver/python/model_builder_helper.py
|
||||
ortools/linear_solver/python/pandas_model.py
|
||||
ortools/linear_solver/python/model_builder_numbers.py
|
||||
ortools/linear_solver/python/pandas_model.py
|
||||
DESTINATION ${PYTHON_PROJECT_DIR}/linear_solver/python)
|
||||
file(COPY
|
||||
ortools/sat/python/cp_model.py
|
||||
@@ -318,18 +318,18 @@ add_custom_command(
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<STREQUAL:$<TARGET_PROPERTY:ortools,TYPE>,SHARED_LIBRARY>,copy,true>
|
||||
$<$<STREQUAL:$<TARGET_PROPERTY:ortools,TYPE>,SHARED_LIBRARY>:$<TARGET_SONAME_FILE:ortools>>
|
||||
${PYTHON_PROJECT}/.libs
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:init> ${PYTHON_PROJECT}/init/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:knapsack_solver> ${PYTHON_PROJECT}/algorithms/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:init_pybind11> ${PYTHON_PROJECT}/init/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:knapsack_solver_pybind11> ${PYTHON_PROJECT}/algorithms/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:linear_sum_assignment_pybind11> ${PYTHON_PROJECT}/graph/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:max_flow_pybind11> ${PYTHON_PROJECT}/graph/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:min_cost_flow_pybind11> ${PYTHON_PROJECT}/graph/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:pywrapcp> ${PYTHON_PROJECT}/constraint_solver
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:pywraplp> ${PYTHON_PROJECT}/linear_solver
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:pywrap_model_builder_helper> ${PYTHON_PROJECT}/linear_solver/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:model_builder_helper_pybind11> ${PYTHON_PROJECT}/linear_solver/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:pywrap_pdlp_pybind11> ${PYTHON_PROJECT}/pdlp/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:swig_helper> ${PYTHON_PROJECT}/sat/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:rcpsp> ${PYTHON_PROJECT}/scheduling/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:sorted_interval_list> ${PYTHON_PROJECT}/util/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:swig_helper_pybind11> ${PYTHON_PROJECT}/sat/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:rcpsp_pybind11> ${PYTHON_PROJECT}/scheduling/python
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:sorted_interval_list_pybind11> ${PYTHON_PROJECT}/util/python
|
||||
#COMMAND ${Python3_EXECUTABLE} setup.py bdist_egg bdist_wheel
|
||||
COMMAND ${Python3_EXECUTABLE} setup.py bdist_wheel
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${PROJECT_BINARY_DIR}/python/dist/timestamp
|
||||
@@ -339,18 +339,18 @@ add_custom_command(
|
||||
python/setup.py
|
||||
Py${PROJECT_NAME}_proto
|
||||
${PROJECT_NAMESPACE}::ortools
|
||||
init
|
||||
knapsack_solver
|
||||
init_pybind11
|
||||
knapsack_solver_pybind11
|
||||
linear_sum_assignment_pybind11
|
||||
max_flow_pybind11
|
||||
min_cost_flow_pybind11
|
||||
pywrapcp
|
||||
pywraplp
|
||||
pywrap_model_builder_helper
|
||||
model_builder_helper_pybind11
|
||||
pywrap_pdlp_pybind11
|
||||
swig_helper
|
||||
rcpsp
|
||||
sorted_interval_list
|
||||
swig_helper_pybind11
|
||||
rcpsp_pybind11
|
||||
sorted_interval_list_pybind11
|
||||
BYPRODUCTS
|
||||
python/${PYTHON_PROJECT}
|
||||
python/${PYTHON_PROJECT}.egg-info
|
||||
|
||||
@@ -11,23 +11,27 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
pybind11_add_module(knapsack_solver MODULE knapsack_solver.cc)
|
||||
pybind11_add_module(knapsack_solver_pybind11 MODULE knapsack_solver.cc)
|
||||
set_target_properties(knapsack_solver_pybind11 PROPERTIES
|
||||
LIBRARY_OUTPUT_NAME "knapsack_solver")
|
||||
|
||||
# note: macOS is APPLE and also UNIX !
|
||||
if(APPLE)
|
||||
set_target_properties(knapsack_solver PROPERTIES
|
||||
set_target_properties(knapsack_solver_pybind11 PROPERTIES
|
||||
SUFFIX ".so"
|
||||
INSTALL_RPATH "@loader_path;@loader_path/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
set_property(TARGET knapsack_solver APPEND PROPERTY
|
||||
set_property(TARGET knapsack_solver_pybind11 APPEND PROPERTY
|
||||
LINK_FLAGS "-flat_namespace -undefined suppress"
|
||||
)
|
||||
elseif(UNIX)
|
||||
set_target_properties(knapsack_solver PROPERTIES
|
||||
set_target_properties(knapsack_solver_pybind11 PROPERTIES
|
||||
INSTALL_RPATH "$ORIGIN:$ORIGIN/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
endif()
|
||||
target_link_libraries(knapsack_solver PRIVATE ${PROJECT_NAMESPACE}::ortools)
|
||||
add_library(${PROJECT_NAMESPACE}::knapsack_solver ALIAS knapsack_solver)
|
||||
|
||||
target_link_libraries(knapsack_solver_pybind11 PRIVATE ${PROJECT_NAMESPACE}::ortools)
|
||||
add_library(${PROJECT_NAMESPACE}::knapsack_solver_pybind11 ALIAS knapsack_solver_pybind11)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB PYTHON_SRCS "*_test.py")
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef OR_TOOLS_ALGORITHMS_PYTHON_knapsack_SOLVER_DOC_H_
|
||||
#define OR_TOOLS_ALGORITHMS_PYTHON_knapsack_SOLVER_DOC_H_
|
||||
#ifndef OR_TOOLS_ALGORITHMS_PYTHON_KNAPSACK_SOLVER_DOC_H_
|
||||
#define OR_TOOLS_ALGORITHMS_PYTHON_KNAPSACK_SOLVER_DOC_H_
|
||||
|
||||
/*
|
||||
This file contains docstrings for use in the Python bindings.
|
||||
@@ -292,4 +292,4 @@ static const char* __doc_operations_research_KnapsackState_is_in_2 =
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // OR_TOOLS_ALGORITHMS_PYTHON_knapsack_SOLVER_DOC_H_
|
||||
#endif // OR_TOOLS_ALGORITHMS_PYTHON_KNAPSACK_SOLVER_DOC_H_
|
||||
|
||||
@@ -17,13 +17,11 @@
|
||||
"""knapsack_solver unittest file."""
|
||||
|
||||
from absl import app
|
||||
|
||||
import unittest
|
||||
|
||||
from absl.testing import absltest
|
||||
from ortools.algorithms.python import knapsack_solver
|
||||
|
||||
|
||||
class PyWrapAlgorithmsKnapsackSolverTest(unittest.TestCase):
|
||||
class PyWrapAlgorithmsKnapsackSolverTest(absltest.TestCase):
|
||||
def RealSolve(self, profits, weights, capacities, solver_type, use_reduction):
|
||||
solver = knapsack_solver.KnapsackSolver(solver_type, "solver")
|
||||
solver.set_use_reduction(use_reduction)
|
||||
@@ -262,7 +260,7 @@ class PyWrapAlgorithmsKnapsackSolverTest(unittest.TestCase):
|
||||
|
||||
|
||||
def main(_):
|
||||
unittest.main()
|
||||
absltest.main()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -11,23 +11,27 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
pybind11_add_module(init MODULE init.cc)
|
||||
pybind11_add_module(init_pybind11 MODULE init.cc)
|
||||
set_target_properties(init_pybind11 PROPERTIES
|
||||
LIBRARY_OUTPUT_NAME "init")
|
||||
|
||||
# note: macOS is APPLE and also UNIX !
|
||||
if(APPLE)
|
||||
set_target_properties(init PROPERTIES
|
||||
set_target_properties(init_pybind11 PROPERTIES
|
||||
SUFFIX ".so"
|
||||
INSTALL_RPATH "@loader_path;@loader_path/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
set_property(TARGET init APPEND PROPERTY
|
||||
set_property(TARGET init_pybind11 APPEND PROPERTY
|
||||
LINK_FLAGS "-flat_namespace -undefined suppress"
|
||||
)
|
||||
elseif(UNIX)
|
||||
set_target_properties(init PROPERTIES
|
||||
set_target_properties(init_pybind11 PROPERTIES
|
||||
INSTALL_RPATH "$ORIGIN:$ORIGIN/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
endif()
|
||||
target_link_libraries(init PRIVATE ${PROJECT_NAMESPACE}::ortools)
|
||||
add_library(${PROJECT_NAMESPACE}::init ALIAS init)
|
||||
|
||||
target_link_libraries(init_pybind11 PRIVATE ${PROJECT_NAMESPACE}::ortools)
|
||||
add_library(${PROJECT_NAMESPACE}::init_pybind11 ALIAS init_pybind11)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB PYTHON_SRCS "*_test.py")
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef OR_TOOLS_OPEN_SOURCE_INIT_PYTHON_PYWRAPINIT_DOC_H_
|
||||
#define OR_TOOLS_OPEN_SOURCE_INIT_PYTHON_PYWRAPINIT_DOC_H_
|
||||
#ifndef OR_TOOLS_OPEN_SOURCE_INIT_PYTHON_INIT_DOC_H_
|
||||
#define OR_TOOLS_OPEN_SOURCE_INIT_PYTHON_INIT_DOC_H_
|
||||
|
||||
/*
|
||||
This file contains docstrings for use in the Python bindings.
|
||||
@@ -141,4 +141,4 @@ static const char* __doc_operations_research_OrToolsVersion_VersionString =
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // OR_TOOLS_OPEN_SOURCE_INIT_PYTHON_PYWRAPINIT_DOC_H_
|
||||
#endif // OR_TOOLS_OPEN_SOURCE_INIT_PYTHON_INIT_DOC_H_
|
||||
|
||||
@@ -17,8 +17,8 @@ load("@pybind11_bazel//:build_defs.bzl", "pybind_extension")
|
||||
load("@rules_python//python:defs.bzl", "py_library", "py_test")
|
||||
|
||||
pybind_extension(
|
||||
name = "pywrap_model_builder_helper",
|
||||
srcs = ["pywrap_model_builder_helper.cc"],
|
||||
name = "model_builder_helper",
|
||||
srcs = ["model_builder_helper.cc"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//ortools/linear_solver:linear_solver_cc_proto",
|
||||
@@ -30,17 +30,6 @@ pybind_extension(
|
||||
],
|
||||
)
|
||||
|
||||
py_library(
|
||||
name = "model_builder_helper",
|
||||
srcs = ["model_builder_helper.py"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":pywrap_model_builder_helper",
|
||||
"//ortools/linear_solver:linear_solver_py_pb2",
|
||||
requirement("numpy"),
|
||||
],
|
||||
)
|
||||
|
||||
py_test(
|
||||
name = "model_builder_helper_test",
|
||||
srcs = ["model_builder_helper_test.py"],
|
||||
@@ -51,22 +40,32 @@ py_test(
|
||||
python_version = "PY3",
|
||||
deps = [
|
||||
":model_builder_helper",
|
||||
":pywrap_model_builder_helper",
|
||||
":model_builder_numbers",
|
||||
"//ortools/linear_solver:linear_solver_py_pb2",
|
||||
requirement("absl-py"),
|
||||
requirement("numpy"),
|
||||
requirement("scipy"),
|
||||
],
|
||||
)
|
||||
|
||||
py_library(
|
||||
name = "model_builder_numbers",
|
||||
srcs = ["model_builder_numbers.py"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
requirement("numpy"),
|
||||
],
|
||||
)
|
||||
|
||||
py_library(
|
||||
name = "model_builder",
|
||||
srcs = ["model_builder.py"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":model_builder_helper",
|
||||
":pywrap_model_builder_helper",
|
||||
":model_builder_numbers",
|
||||
requirement("numpy"),
|
||||
"//ortools/linear_solver:linear_solver_py_pb2",
|
||||
"@com_google_protobuf//:protobuf_python",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -81,7 +80,8 @@ py_test(
|
||||
deps = [
|
||||
":model_builder",
|
||||
":model_builder_helper",
|
||||
":pywrap_model_builder_helper",
|
||||
":model_builder_numbers",
|
||||
requirement("absl-py"),
|
||||
requirement("numpy"),
|
||||
],
|
||||
)
|
||||
@@ -90,7 +90,7 @@ py_library(
|
||||
name = "pandas_model",
|
||||
srcs = ["pandas_model.py"],
|
||||
deps = [
|
||||
":pywrap_model_builder_helper",
|
||||
":model_builder_helper",
|
||||
requirement("numpy"),
|
||||
requirement("pandas"),
|
||||
"//ortools/linear_solver:linear_solver_py_pb2",
|
||||
|
||||
@@ -46,32 +46,33 @@ if(MSVC)
|
||||
target_link_libraries(pywraplp PRIVATE ${Python3_LIBRARIES})
|
||||
endif()
|
||||
|
||||
pybind11_add_module(pywrap_model_builder_helper MODULE pywrap_model_builder_helper.cc)
|
||||
pybind11_add_module(model_builder_helper_pybind11 MODULE model_builder_helper.cc)
|
||||
set_target_properties(model_builder_helper_pybind11 PROPERTIES
|
||||
LIBRARY_OUTPUT_NAME "model_builder_helper")
|
||||
|
||||
target_include_directories(pywrap_model_builder_helper PRIVATE
|
||||
target_include_directories(model_builder_helper_pybind11 PRIVATE
|
||||
${protobuf_SOURCE_DIR})
|
||||
|
||||
# note: macOS is APPLE and also UNIX !
|
||||
if(APPLE)
|
||||
set_target_properties(pywrap_model_builder_helper PROPERTIES
|
||||
set_target_properties(model_builder_helper_pybind11 PROPERTIES
|
||||
SUFFIX ".so"
|
||||
INSTALL_RPATH "@loader_path;@loader_path/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
set_property(TARGET pywrap_model_builder_helper APPEND PROPERTY
|
||||
set_property(TARGET model_builder_helper_pybind11 APPEND PROPERTY
|
||||
LINK_FLAGS "-flat_namespace -undefined suppress"
|
||||
)
|
||||
elseif(UNIX)
|
||||
set_target_properties(pywrap_model_builder_helper PROPERTIES
|
||||
set_target_properties(model_builder_helper_pybind11 PROPERTIES
|
||||
INSTALL_RPATH "$ORIGIN:$ORIGIN/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(pywrap_model_builder_helper PRIVATE
|
||||
target_link_libraries(model_builder_helper_pybind11 PRIVATE
|
||||
${PROJECT_NAMESPACE}::ortools
|
||||
pybind11_native_proto_caster
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAMESPACE}::pywrap_model_builder_helper ALIAS pywrap_model_builder_helper)
|
||||
add_library(${PROJECT_NAMESPACE}::model_builder_helper_pybind11 ALIAS model_builder_helper_pybind11)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB PYTHON_SRCS "*_test.py")
|
||||
|
||||
@@ -34,13 +34,14 @@ rather than for solving specific optimization problems.
|
||||
|
||||
import math
|
||||
import numbers
|
||||
from typing import Any, Callable, Dict, List, Literal, Optional, Union, Sequence, Tuple
|
||||
from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple, Union
|
||||
|
||||
import numpy as np
|
||||
from numpy import typing as npt
|
||||
from numpy.lib import mixins
|
||||
|
||||
from ortools.linear_solver.python import model_builder_helper as mbh
|
||||
from ortools.linear_solver.python import pywrap_model_builder_helper as pwmb
|
||||
from ortools.linear_solver.python import model_builder_numbers as mbn
|
||||
|
||||
|
||||
# Custom types.
|
||||
@@ -67,7 +68,7 @@ SliceT = Union[
|
||||
|
||||
|
||||
# Forward solve statuses.
|
||||
SolveStatus = pwmb.SolveStatus
|
||||
SolveStatus = mbh.SolveStatus
|
||||
|
||||
|
||||
class LinearExpr:
|
||||
@@ -118,10 +119,10 @@ class LinearExpr:
|
||||
Returns:
|
||||
a LinearExpr instance or a numerical constant.
|
||||
"""
|
||||
checked_constant: np.double = mbh.assert_is_a_number(constant)
|
||||
checked_constant: np.double = mbn.assert_is_a_number(constant)
|
||||
if not expressions:
|
||||
return checked_constant
|
||||
if len(expressions) == 1 and mbh.is_zero(checked_constant):
|
||||
if len(expressions) == 1 and mbn.is_zero(checked_constant):
|
||||
return expressions[0]
|
||||
|
||||
return LinearExpr.weighted_sum(
|
||||
@@ -154,7 +155,7 @@ class LinearExpr:
|
||||
"LinearExpr.weighted_sum: expressions and coefficients have"
|
||||
" different lengths"
|
||||
)
|
||||
checked_constant: np.double = mbh.assert_is_a_number(constant)
|
||||
checked_constant: np.double = mbn.assert_is_a_number(constant)
|
||||
if not expressions:
|
||||
return checked_constant
|
||||
|
||||
@@ -162,10 +163,10 @@ class LinearExpr:
|
||||
indices = []
|
||||
coeffs = []
|
||||
for e, c in zip(expressions, coefficients):
|
||||
if mbh.is_zero(c):
|
||||
if mbn.is_zero(c):
|
||||
continue
|
||||
|
||||
if mbh.is_a_number(e):
|
||||
if mbn.is_a_number(e):
|
||||
checked_constant += np.double(c * e)
|
||||
elif isinstance(e, Variable):
|
||||
indices.append(np.array([e.index], dtype=np.int32))
|
||||
@@ -203,14 +204,14 @@ class LinearExpr:
|
||||
Returns:
|
||||
a LinearExpr instance or a numerical constant.
|
||||
"""
|
||||
checked_coefficient: np.double = mbh.assert_is_a_number(coefficient)
|
||||
checked_constant: np.double = mbh.assert_is_a_number(constant)
|
||||
checked_coefficient: np.double = mbn.assert_is_a_number(coefficient)
|
||||
checked_constant: np.double = mbn.assert_is_a_number(constant)
|
||||
|
||||
if mbh.is_zero(checked_coefficient):
|
||||
if mbn.is_zero(checked_coefficient):
|
||||
return checked_constant
|
||||
if mbh.is_one(checked_coefficient) and mbh.is_zero(checked_constant):
|
||||
if mbn.is_one(checked_coefficient) and mbn.is_zero(checked_constant):
|
||||
return expression
|
||||
if mbh.is_a_number(expression):
|
||||
if mbn.is_a_number(expression):
|
||||
return np.double(expression) * checked_coefficient + checked_constant
|
||||
if isinstance(expression, Variable):
|
||||
return _WeightedSum(
|
||||
@@ -233,7 +234,7 @@ class LinearExpr:
|
||||
return NotImplemented
|
||||
|
||||
def __add__(self, arg: LinearExprT) -> LinearExprT:
|
||||
if mbh.is_a_number(arg):
|
||||
if mbn.is_a_number(arg):
|
||||
return LinearExpr.sum([self], constant=arg)
|
||||
return LinearExpr.weighted_sum(
|
||||
[self, arg], [1.0, 1.0], constant=0.0
|
||||
@@ -243,7 +244,7 @@ class LinearExpr:
|
||||
return self.__add__(arg)
|
||||
|
||||
def __sub__(self, arg: LinearExprT):
|
||||
if mbh.is_a_number(arg):
|
||||
if mbn.is_a_number(arg):
|
||||
return LinearExpr.sum([self], constant=arg * -1.0)
|
||||
return LinearExpr.weighted_sum(
|
||||
[self, arg], [1.0, -1.0], constant=0.0
|
||||
@@ -255,10 +256,10 @@ class LinearExpr:
|
||||
) # pytype: disable=wrong-arg-types # numpy-scalars
|
||||
|
||||
def __mul__(self, arg: NumberT):
|
||||
arg = mbh.assert_is_a_number(arg)
|
||||
if mbh.is_one(arg):
|
||||
arg = mbn.assert_is_a_number(arg)
|
||||
if mbn.is_one(arg):
|
||||
return self
|
||||
elif mbh.is_zero(arg):
|
||||
elif mbn.is_zero(arg):
|
||||
return 0.0
|
||||
return self.multiply_by(arg)
|
||||
|
||||
@@ -269,8 +270,8 @@ class LinearExpr:
|
||||
return self.__mul__(arg)
|
||||
|
||||
def __div__(self, arg: NumberT):
|
||||
coeff = mbh.assert_is_a_number(arg)
|
||||
if mbh.is_zero(coeff):
|
||||
coeff = mbn.assert_is_a_number(arg)
|
||||
if mbn.is_zero(coeff):
|
||||
raise ValueError("Cannot call the division operator with a zero divisor")
|
||||
return self.__mul__(1.0 / coeff)
|
||||
|
||||
@@ -311,8 +312,8 @@ class LinearExpr:
|
||||
) -> Union[bool, "BoundedLinearExpression"]:
|
||||
if arg is None:
|
||||
return False
|
||||
if mbh.is_a_number(arg):
|
||||
arg = mbh.assert_is_a_number(arg)
|
||||
if mbn.is_a_number(arg):
|
||||
arg = mbn.assert_is_a_number(arg)
|
||||
return BoundedLinearExpression(self, arg, arg)
|
||||
else:
|
||||
return BoundedLinearExpression(
|
||||
@@ -320,8 +321,8 @@ class LinearExpr:
|
||||
) # pytype: disable=wrong-arg-types # numpy-scalars
|
||||
|
||||
def __ge__(self, arg: LinearExprT) -> "BoundedLinearExpression":
|
||||
if mbh.is_a_number(arg):
|
||||
arg = mbh.assert_is_a_number(arg)
|
||||
if mbn.is_a_number(arg):
|
||||
arg = mbn.assert_is_a_number(arg)
|
||||
return BoundedLinearExpression(
|
||||
self, arg, math.inf
|
||||
) # pytype: disable=wrong-arg-types # numpy-scalars
|
||||
@@ -331,8 +332,8 @@ class LinearExpr:
|
||||
) # pytype: disable=wrong-arg-types # numpy-scalars
|
||||
|
||||
def __le__(self, arg: LinearExprT) -> "BoundedLinearExpression":
|
||||
if mbh.is_a_number(arg):
|
||||
arg = mbh.assert_is_a_number(arg)
|
||||
if mbn.is_a_number(arg):
|
||||
arg = mbn.assert_is_a_number(arg)
|
||||
return BoundedLinearExpression(
|
||||
self, -math.inf, arg
|
||||
) # pytype: disable=wrong-arg-types # numpy-scalars
|
||||
@@ -363,13 +364,13 @@ class _WeightedSum(LinearExpr):
|
||||
):
|
||||
super().__init__()
|
||||
self.__variable_indices: npt.NDArray[np.int32] = variable_indices
|
||||
self.__coefficients: npt.NDArray[np.double] = mbh.assert_is_a_number_array(
|
||||
self.__coefficients: npt.NDArray[np.double] = mbn.assert_is_a_number_array(
|
||||
coefficients
|
||||
)
|
||||
self.__constant: np.double = constant
|
||||
|
||||
def multiply_by(self, arg: NumberT) -> LinearExprT:
|
||||
if mbh.is_zero(arg):
|
||||
if mbn.is_zero(arg):
|
||||
return 0.0 # pytype: disable=bad-return-type # numpy-scalars
|
||||
if self.__variable_indices.size > 0:
|
||||
return _WeightedSum(
|
||||
@@ -392,7 +393,7 @@ class _WeightedSum(LinearExpr):
|
||||
def constant(self) -> np.double:
|
||||
return self.__constant
|
||||
|
||||
def pretty_string(self, helper: pwmb.ModelBuilderHelper) -> str:
|
||||
def pretty_string(self, helper: mbh.ModelBuilderHelper) -> str:
|
||||
"""Pretty print a linear expression into a string."""
|
||||
output: str = ""
|
||||
for index, coeff in zip(self.variable_indices, self.coefficients):
|
||||
@@ -400,15 +401,15 @@ class _WeightedSum(LinearExpr):
|
||||
if not var_name:
|
||||
var_name = f"unnamed_var_{index}"
|
||||
|
||||
if not output and mbh.is_one(coeff):
|
||||
if not output and mbn.is_one(coeff):
|
||||
output = var_name
|
||||
elif not output and mbh.is_minus_one(coeff):
|
||||
elif not output and mbn.is_minus_one(coeff):
|
||||
output = f"-{var_name}"
|
||||
elif not output:
|
||||
output = f"{coeff} * {var_name}"
|
||||
elif mbh.is_one(coeff):
|
||||
elif mbn.is_one(coeff):
|
||||
output += f" + {var_name}"
|
||||
elif mbh.is_minus_one(coeff):
|
||||
elif mbn.is_minus_one(coeff):
|
||||
output += f" - {var_name}"
|
||||
elif coeff > 0.0:
|
||||
output += f" + {coeff} * {var_name}"
|
||||
@@ -444,7 +445,7 @@ class Variable(LinearExpr):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
helper: pwmb.ModelBuilderHelper,
|
||||
helper: mbh.ModelBuilderHelper,
|
||||
lb: NumberT,
|
||||
ub: Optional[NumberT],
|
||||
is_integral: Optional[bool],
|
||||
@@ -452,7 +453,7 @@ class Variable(LinearExpr):
|
||||
):
|
||||
"""See ModelBuilder.new_var below."""
|
||||
LinearExpr.__init__(self)
|
||||
self.__helper: pwmb.ModelBuilderHelper = helper
|
||||
self.__helper: mbh.ModelBuilderHelper = helper
|
||||
# Python do not support multiple __init__ methods.
|
||||
# This method is only called from the ModelBuilder class.
|
||||
# We hack the parameter to support the two cases:
|
||||
@@ -462,13 +463,13 @@ class Variable(LinearExpr):
|
||||
# case 2:
|
||||
# helper is a ModelBuilderHelper, lb is an index (int), ub is None,
|
||||
# is_integral is None, and name is None.
|
||||
if mbh.is_integral(lb) and ub is None and is_integral is None:
|
||||
if mbn.is_integral(lb) and ub is None and is_integral is None:
|
||||
self.__index: np.int32 = np.int32(lb)
|
||||
self.__helper: pwmb.ModelBuilderHelper = helper
|
||||
self.__helper: mbh.ModelBuilderHelper = helper
|
||||
else:
|
||||
index: np.int32 = helper.add_var()
|
||||
self.__index: np.int32 = np.int32(index)
|
||||
self.__helper: pwmb.ModelBuilderHelper = helper
|
||||
self.__helper: mbh.ModelBuilderHelper = helper
|
||||
helper.set_var_lower_bound(index, lb)
|
||||
helper.set_var_upper_bound(index, ub)
|
||||
helper.set_var_integrality(index, is_integral)
|
||||
@@ -481,7 +482,7 @@ class Variable(LinearExpr):
|
||||
return self.__index
|
||||
|
||||
@property
|
||||
def helper(self) -> pwmb.ModelBuilderHelper:
|
||||
def helper(self) -> mbh.ModelBuilderHelper:
|
||||
"""Returns the underlying ModelBuilderHelper."""
|
||||
return self.__helper
|
||||
|
||||
@@ -571,8 +572,8 @@ class Variable(LinearExpr):
|
||||
if isinstance(arg, Variable):
|
||||
return VarCompVar(self, arg, True)
|
||||
else:
|
||||
if mbh.is_a_number(arg):
|
||||
arg = mbh.assert_is_a_number(arg)
|
||||
if mbn.is_a_number(arg):
|
||||
arg = mbn.assert_is_a_number(arg)
|
||||
return BoundedLinearExpression(self, arg, arg)
|
||||
else:
|
||||
return BoundedLinearExpression(
|
||||
@@ -601,8 +602,8 @@ _REGISTERED_NUMPY_VARIABLE_FUNCS: Dict[Any, NumpyFuncT] = {}
|
||||
class VariableContainer(mixins.NDArrayOperatorsMixin):
|
||||
"""Variable container."""
|
||||
|
||||
def __init__(self, helper: pwmb.ModelBuilderHelper, indices: npt.NDArray[np.int32]):
|
||||
self.__helper: pwmb.ModelBuilderHelper = helper
|
||||
def __init__(self, helper: mbh.ModelBuilderHelper, indices: npt.NDArray[np.int32]):
|
||||
self.__helper: mbh.ModelBuilderHelper = helper
|
||||
self.__variable_indices: npt.NDArray[np.int32] = indices
|
||||
|
||||
@property
|
||||
@@ -787,8 +788,8 @@ class BoundedLinearExpression:
|
||||
|
||||
def __init__(self, expr: LinearExprT, lb: NumberT, ub: NumberT):
|
||||
self.__expr: LinearExprT = expr
|
||||
self.__lb: np.double = mbh.assert_is_a_number(lb)
|
||||
self.__ub: np.double = mbh.assert_is_a_number(ub)
|
||||
self.__lb: np.double = mbn.assert_is_a_number(lb)
|
||||
self.__ub: np.double = mbn.assert_is_a_number(ub)
|
||||
|
||||
def __str__(self) -> str:
|
||||
if self.__lb > -math.inf and self.__ub < math.inf:
|
||||
@@ -833,9 +834,9 @@ class LinearConstraint:
|
||||
linear_constraint = model.add(x + 2 * y == 5)
|
||||
"""
|
||||
|
||||
def __init__(self, helper: pwmb.ModelBuilderHelper):
|
||||
def __init__(self, helper: mbh.ModelBuilderHelper):
|
||||
self.__index: np.int32 = helper.add_linear_constraint()
|
||||
self.__helper: pwmb.ModelBuilderHelper = helper
|
||||
self.__helper: mbh.ModelBuilderHelper = helper
|
||||
|
||||
@property
|
||||
def index(self) -> np.int32:
|
||||
@@ -843,7 +844,7 @@ class LinearConstraint:
|
||||
return self.__index
|
||||
|
||||
@property
|
||||
def helper(self) -> pwmb.ModelBuilderHelper:
|
||||
def helper(self) -> mbh.ModelBuilderHelper:
|
||||
"""Returns the ModelBuilderHelper instance."""
|
||||
return self.__helper
|
||||
|
||||
@@ -885,7 +886,7 @@ class ModelBuilder:
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.__helper: pwmb.ModelBuilderHelper = pwmb.ModelBuilderHelper()
|
||||
self.__helper: mbh.ModelBuilderHelper = mbh.ModelBuilderHelper()
|
||||
|
||||
# Integer variable.
|
||||
|
||||
@@ -1129,7 +1130,7 @@ class ModelBuilder:
|
||||
name: Optional[str] = None,
|
||||
) -> VariableContainer:
|
||||
"""Creates a vector of Boolean variables."""
|
||||
if mbh.is_integral(shape):
|
||||
if mbn.is_integral(shape):
|
||||
shape = [shape]
|
||||
|
||||
name = name or ""
|
||||
@@ -1159,7 +1160,7 @@ class ModelBuilder:
|
||||
ct = LinearConstraint(self.__helper)
|
||||
if name:
|
||||
self.__helper.set_constraint_name(ct.index, name)
|
||||
if mbh.is_a_number(linear_expr):
|
||||
if mbn.is_a_number(linear_expr):
|
||||
self.__helper.set_constraint_lower_bound(ct.index, lb - linear_expr)
|
||||
self.__helper.set_constraint_upper_bound(ct.index, ub - linear_expr)
|
||||
elif isinstance(linear_expr, Variable):
|
||||
@@ -1236,7 +1237,7 @@ class ModelBuilder:
|
||||
"""Defines the objective."""
|
||||
self.helper.clear_objective()
|
||||
self.__helper.set_maximize(maximize)
|
||||
if mbh.is_a_number(linear_expr):
|
||||
if mbn.is_a_number(linear_expr):
|
||||
self.helper.set_objective_offset(linear_expr)
|
||||
elif isinstance(linear_expr, Variable):
|
||||
self.helper.set_var_objective_coefficient(linear_expr.index, 1.0)
|
||||
@@ -1260,12 +1261,12 @@ class ModelBuilder:
|
||||
|
||||
# Input/Output
|
||||
def export_to_lp_string(self, obfuscate: bool = False) -> str:
|
||||
options: pwmb.MPModelExportOptions = pwmb.MPModelExportOptions()
|
||||
options: mbh.MPModelExportOptions = mbh.MPModelExportOptions()
|
||||
options.obfuscate = obfuscate
|
||||
return self.__helper.export_to_lp_string(options)
|
||||
|
||||
def export_to_mps_string(self, obfuscate: bool = False) -> str:
|
||||
options: pwmb.MPModelExportOptions = pwmb.MPModelExportOptions()
|
||||
options: mbh.MPModelExportOptions = mbh.MPModelExportOptions()
|
||||
options.obfuscate = obfuscate
|
||||
return self.__helper.export_to_mps_string(options)
|
||||
|
||||
@@ -1291,7 +1292,7 @@ class ModelBuilder:
|
||||
self.__helper.set_name(name)
|
||||
|
||||
@property
|
||||
def helper(self) -> pwmb.ModelBuilderHelper:
|
||||
def helper(self) -> mbh.ModelBuilderHelper:
|
||||
"""Returns the model builder helper."""
|
||||
return self.__helper
|
||||
|
||||
@@ -1308,9 +1309,7 @@ class ModelSolver:
|
||||
"""
|
||||
|
||||
def __init__(self, solver_name: str):
|
||||
self.__solve_helper: pwmb.ModelSolverHelper = pwmb.ModelSolverHelper(
|
||||
solver_name
|
||||
)
|
||||
self.__solve_helper: mbh.ModelSolverHelper = mbh.ModelSolverHelper(solver_name)
|
||||
self.log_callback: Optional[Callable[[str], None]] = None
|
||||
|
||||
def solver_is_supported(self) -> bool:
|
||||
@@ -1353,7 +1352,7 @@ class ModelSolver:
|
||||
def value(self, expr: LinearExprT) -> np.double:
|
||||
"""Returns the value of a linear expression after solve."""
|
||||
self.__check_has_feasible_solution()
|
||||
if mbh.is_a_number(expr):
|
||||
if mbn.is_a_number(expr):
|
||||
return expr
|
||||
elif isinstance(expr, Variable):
|
||||
return self.__solve_helper.var_value(expr.index)
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
// A pybind11 wrapper for model_builder_helper.
|
||||
|
||||
#include "ortools/linear_solver/wrappers/model_builder_helper.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <complex>
|
||||
#include <cstdlib>
|
||||
@@ -31,7 +33,6 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "ortools/linear_solver/linear_solver.pb.h"
|
||||
#include "ortools/linear_solver/model_exporter.h"
|
||||
#include "ortools/linear_solver/wrappers/model_builder_helper.h"
|
||||
#include "pybind11/eigen.h"
|
||||
#include "pybind11/pybind11.h"
|
||||
#include "pybind11/pytypes.h"
|
||||
@@ -150,7 +151,7 @@ std::vector<std::pair<int, double>> SortedGroupedTerms(
|
||||
return terms;
|
||||
}
|
||||
|
||||
PYBIND11_MODULE(pywrap_model_builder_helper, m) {
|
||||
PYBIND11_MODULE(model_builder_helper, m) {
|
||||
pybind11_protobuf::ImportNativeProtoCasters();
|
||||
|
||||
m.def("to_mpmodel_proto", &ToMPModelProto, arg("helper"));
|
||||
@@ -17,30 +17,31 @@
|
||||
import gzip
|
||||
import os
|
||||
import threading
|
||||
|
||||
from absl.testing import absltest
|
||||
import numpy as np
|
||||
from scipy import sparse
|
||||
|
||||
import unittest
|
||||
from ortools.linear_solver import linear_solver_pb2
|
||||
from ortools.linear_solver.python import pywrap_model_builder_helper
|
||||
from ortools.linear_solver.python import model_builder_helper
|
||||
|
||||
|
||||
class PywrapModelBuilderHelperTest(unittest.TestCase):
|
||||
class PywrapModelBuilderHelperTest(absltest.TestCase):
|
||||
def test_export_model_proto_to_mps_string(self):
|
||||
model = pywrap_model_builder_helper.ModelBuilderHelper()
|
||||
model = model_builder_helper.ModelBuilderHelper()
|
||||
model.set_name("testmodel")
|
||||
result = model.export_to_mps_string()
|
||||
self.assertIn("testmodel", result)
|
||||
self.assertIn("ENDATA", result)
|
||||
|
||||
def test_export_model_proto_to_lp_string(self):
|
||||
model = pywrap_model_builder_helper.ModelBuilderHelper()
|
||||
model = model_builder_helper.ModelBuilderHelper()
|
||||
model.set_maximize(True)
|
||||
lp_string = model.export_to_lp_string()
|
||||
self.assertIn("Maximize", lp_string)
|
||||
|
||||
def test_import_from_mps_string(self):
|
||||
model = pywrap_model_builder_helper.ModelBuilderHelper()
|
||||
model = model_builder_helper.ModelBuilderHelper()
|
||||
self.assertTrue(model.import_from_mps_string("NAME testmodel"))
|
||||
self.assertEqual(model.name(), "testmodel")
|
||||
|
||||
@@ -48,12 +49,12 @@ class PywrapModelBuilderHelperTest(unittest.TestCase):
|
||||
def test_import_from_mps_file(self):
|
||||
path = os.path.dirname(__file__)
|
||||
mps_path = f"{path}/../testdata/maximization.mps"
|
||||
model = pywrap_model_builder_helper.ModelBuilderHelper()
|
||||
model = model_builder_helper.ModelBuilderHelper()
|
||||
self.assertTrue(model.import_from_mps_file(mps_path))
|
||||
self.assertEqual(model.name(), "SupportedMaximizationProblem")
|
||||
|
||||
def test_import_from_lp_string(self):
|
||||
model = pywrap_model_builder_helper.ModelBuilderHelper()
|
||||
model = model_builder_helper.ModelBuilderHelper()
|
||||
model.import_from_lp_string("max:")
|
||||
self.assertTrue(model.maximize())
|
||||
|
||||
@@ -71,26 +72,28 @@ class PywrapModelBuilderHelperTest(unittest.TestCase):
|
||||
model=model,
|
||||
solver_type=linear_solver_pb2.MPModelRequest.GLOP_LINEAR_PROGRAMMING,
|
||||
)
|
||||
solver_helper = pywrap_model_builder_helper.ModelSolverHelper("")
|
||||
solver_helper = model_builder_helper.ModelSolverHelper("")
|
||||
result = solver_helper.solve_serialized_request(request.SerializeToString())
|
||||
response = linear_solver_pb2.MPSolutionResponse().FromString(result)
|
||||
self.assertEqual(
|
||||
response.status, linear_solver_pb2.MPSolverResponseStatus.MPSOLVER_OPTIMAL
|
||||
response.status,
|
||||
linear_solver_pb2.MPSolverResponseStatus.MPSOLVER_OPTIMAL,
|
||||
)
|
||||
self.assertAlmostEqual(response.objective_value, 1.0)
|
||||
|
||||
def test_solve_with_glop_direct(self):
|
||||
model = pywrap_model_builder_helper.ModelBuilderHelper()
|
||||
model = model_builder_helper.ModelBuilderHelper()
|
||||
self.assertEqual(0, model.add_var())
|
||||
model.set_var_lower_bound(0, 0.0)
|
||||
model.set_var_upper_bound(0, 1.0)
|
||||
model.set_var_objective_coefficient(0, 1.0)
|
||||
model.set_maximize(True)
|
||||
|
||||
solver = pywrap_model_builder_helper.ModelSolverHelper("glop")
|
||||
solver = model_builder_helper.ModelSolverHelper("glop")
|
||||
solver.solve(model)
|
||||
self.assertEqual(
|
||||
solver.status(), linear_solver_pb2.MPSolverResponseStatus.MPSOLVER_OPTIMAL
|
||||
solver.status(),
|
||||
linear_solver_pb2.MPSolverResponseStatus.MPSOLVER_OPTIMAL,
|
||||
)
|
||||
self.assertAlmostEqual(solver.objective_value(), 1.0)
|
||||
self.assertAlmostEqual(solver.var_value(0), 1.0)
|
||||
@@ -110,7 +113,7 @@ class PywrapModelBuilderHelperTest(unittest.TestCase):
|
||||
model=model,
|
||||
solver_type=linear_solver_pb2.MPModelRequest.PDLP_LINEAR_PROGRAMMING,
|
||||
)
|
||||
solver_helper = pywrap_model_builder_helper.ModelSolverHelper("")
|
||||
solver_helper = model_builder_helper.ModelSolverHelper("")
|
||||
result = solver_helper.solve_serialized_request(request.SerializeToString())
|
||||
if result:
|
||||
response = linear_solver_pb2.MPSolutionResponse().FromString(result)
|
||||
@@ -130,9 +133,9 @@ class PywrapModelBuilderHelperTest(unittest.TestCase):
|
||||
mps_path = f"{path}/../testdata/large_model.mps.gz"
|
||||
with gzip.open(mps_path, "r") as f:
|
||||
mps_data = f.read()
|
||||
model_helper = pywrap_model_builder_helper.ModelBuilderHelper()
|
||||
model_helper = model_builder_helper.ModelBuilderHelper()
|
||||
self.assertTrue(model_helper.import_from_mps_string(mps_data))
|
||||
solver_helper = pywrap_model_builder_helper.ModelSolverHelper("glop")
|
||||
solver_helper = model_builder_helper.ModelSolverHelper("glop")
|
||||
|
||||
result = []
|
||||
solve_thread = threading.Thread(
|
||||
@@ -144,7 +147,7 @@ class PywrapModelBuilderHelperTest(unittest.TestCase):
|
||||
self.assertTrue(solver_helper.has_response())
|
||||
self.assertEqual(
|
||||
solver_helper.status(),
|
||||
pywrap_model_builder_helper.SolveStatus.CANCELLED_BY_USER,
|
||||
model_builder_helper.SolveStatus.CANCELLED_BY_USER,
|
||||
)
|
||||
|
||||
def test_build_model(self):
|
||||
@@ -155,7 +158,7 @@ class PywrapModelBuilderHelperTest(unittest.TestCase):
|
||||
con_ub = np.array([5.0, 6.0])
|
||||
constraint_matrix = sparse.csr_matrix(np.array([[1.0], [2.0]]))
|
||||
|
||||
model = pywrap_model_builder_helper.ModelBuilderHelper()
|
||||
model = model_builder_helper.ModelBuilderHelper()
|
||||
model.fill_model_from_sparse_data(
|
||||
var_lb, var_ub, obj, con_lb, con_ub, constraint_matrix
|
||||
)
|
||||
@@ -183,4 +186,4 @@ class PywrapModelBuilderHelperTest(unittest.TestCase):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
absltest.main()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""helpers methods for the cp_model_builder module."""
|
||||
"""helpers methods for the cp_model_builder module on numbers."""
|
||||
|
||||
import numbers
|
||||
from typing import Any, Sequence, Union
|
||||
@@ -15,15 +15,17 @@
|
||||
"""Tests for ModelBuilder."""
|
||||
|
||||
import math
|
||||
|
||||
from absl.testing import absltest
|
||||
import numpy as np
|
||||
import numpy.testing as np_testing
|
||||
|
||||
import os
|
||||
|
||||
from ortools.linear_solver.python import model_builder as mb
|
||||
import unittest
|
||||
|
||||
|
||||
class ModelBuilderTest(unittest.TestCase):
|
||||
class ModelBuilderTest(absltest.TestCase):
|
||||
# Number of decimal places to use for numerical tolerance for
|
||||
# checking primal, dual, objective values and other values.
|
||||
NUM_PLACES = 5
|
||||
@@ -92,7 +94,9 @@ class ModelBuilderTest(unittest.TestCase):
|
||||
4.0 - 1.0 * solver.dual_value(c0) - 5.0 * solver.dual_value(c1)
|
||||
)
|
||||
self.assertAlmostEqual(
|
||||
x3_expected_reduced_cost, solver.reduced_cost(x3), places=self.NUM_PLACES
|
||||
x3_expected_reduced_cost,
|
||||
solver.reduced_cost(x3),
|
||||
places=self.NUM_PLACES,
|
||||
)
|
||||
|
||||
self.assertAlmostEqual(100.0, solver.activity(c0), places=self.NUM_PLACES)
|
||||
@@ -559,4 +563,4 @@ ENDATA
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
absltest.main()
|
||||
|
||||
@@ -26,7 +26,7 @@ import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from ortools.linear_solver import linear_solver_pb2
|
||||
from ortools.linear_solver.python import pywrap_model_builder_helper as pwmb
|
||||
from ortools.linear_solver.python import model_builder_helper as mbh
|
||||
|
||||
_Number = Union[int, float, np.number]
|
||||
_LinearType = Union[_Number, "_LinearBase"]
|
||||
@@ -208,7 +208,7 @@ class _Variable(_LinearBase):
|
||||
|
||||
__slots__ = ("_helper", "_index")
|
||||
|
||||
_helper: pwmb.ModelBuilderHelper
|
||||
_helper: mbh.ModelBuilderHelper
|
||||
_index: int
|
||||
|
||||
def __str__(self):
|
||||
@@ -250,7 +250,7 @@ class _Variable(_LinearBase):
|
||||
|
||||
|
||||
def _create_variable(
|
||||
helper: pwmb.ModelBuilderHelper,
|
||||
helper: mbh.ModelBuilderHelper,
|
||||
*,
|
||||
name: str,
|
||||
lower_bound: _Number,
|
||||
@@ -260,7 +260,7 @@ def _create_variable(
|
||||
"""Creates a new variable in the helper.
|
||||
|
||||
Args:
|
||||
helper (pwmb.ModelBuilderHelper): The helper to create the variable.
|
||||
helper (mbh.ModelBuilderHelper): The helper to create the variable.
|
||||
name (str): The name of the variable.
|
||||
lower_bound (Union[int, float]): The lower bound of the variable.
|
||||
upper_bound (Union[int, float]): The upper bound of the variable.
|
||||
@@ -289,12 +289,12 @@ class _BoundedLinearBase(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def _create_linear_constraint(
|
||||
self, helper: pwmb.ModelBuilderHelper, name: str
|
||||
self, helper: mbh.ModelBuilderHelper, name: str
|
||||
) -> "_LinearConstraint":
|
||||
"""Creates a new linear constraint in the helper.
|
||||
|
||||
Args:
|
||||
helper (pwmb.ModelBuilderHelper): The helper to create the constraint.
|
||||
helper (mbh.ModelBuilderHelper): The helper to create the constraint.
|
||||
name (str): The name of the linear constraint.
|
||||
|
||||
Returns:
|
||||
@@ -304,7 +304,7 @@ class _BoundedLinearBase(metaclass=abc.ABCMeta):
|
||||
|
||||
def _create_linear_constraint(
|
||||
constraint: Union[bool, _BoundedLinearBase],
|
||||
helper: pwmb.ModelBuilderHelper,
|
||||
helper: mbh.ModelBuilderHelper,
|
||||
name: str,
|
||||
):
|
||||
"""Creates a new linear constraint in the helper.
|
||||
@@ -370,7 +370,7 @@ class _BoundedLinearExpression(_BoundedLinearBase):
|
||||
)
|
||||
|
||||
def _create_linear_constraint(
|
||||
self, helper: pwmb.ModelBuilderHelper, name: str
|
||||
self, helper: mbh.ModelBuilderHelper, name: str
|
||||
) -> "_LinearConstraint":
|
||||
index = helper.add_linear_constraint()
|
||||
expr = _as_flat_linear_expression(self._expression)
|
||||
@@ -414,7 +414,7 @@ class _VarEqVar(_BoundedLinearBase):
|
||||
return hash(self._left) == hash(self._right)
|
||||
|
||||
def _create_linear_constraint(
|
||||
self, helper: pwmb.ModelBuilderHelper, name: str
|
||||
self, helper: mbh.ModelBuilderHelper, name: str
|
||||
) -> "_LinearConstraint":
|
||||
index = helper.add_linear_constraint()
|
||||
helper.set_constraint_lower_bound(index, 0.0)
|
||||
@@ -442,7 +442,7 @@ class _LinearConstraint:
|
||||
|
||||
__slots__ = ("_helper", "_index")
|
||||
|
||||
_helper: pwmb.ModelBuilderHelper
|
||||
_helper: mbh.ModelBuilderHelper
|
||||
_index: int
|
||||
|
||||
@property
|
||||
@@ -551,7 +551,7 @@ class OptimizationModel:
|
||||
"""Initializes an optimization model with the given name."""
|
||||
if not name.isidentifier():
|
||||
raise ValueError("name={} is not a valid identifier".format(name))
|
||||
self._helper: pwmb.ModelBuilderHelper = pwmb.ModelBuilderHelper()
|
||||
self._helper: mbh.ModelBuilderHelper = mbh.ModelBuilderHelper()
|
||||
self._helper.set_name(name)
|
||||
self._variables: dict[str, pd.Series] = {}
|
||||
self._linear_constraints: dict[str, pd.Series] = {}
|
||||
@@ -567,7 +567,7 @@ class OptimizationModel:
|
||||
|
||||
def to_proto(self) -> linear_solver_pb2.MPModelProto:
|
||||
"""Exports the optimization model to a ProtoBuf format."""
|
||||
return pwmb.to_mpmodel_proto(self._helper)
|
||||
return mbh.to_mpmodel_proto(self._helper)
|
||||
|
||||
@typing.overload
|
||||
def _get_linear_constraints(self, constraints: Optional[pd.Index]) -> pd.Index:
|
||||
@@ -1349,11 +1349,11 @@ class SolveStatus(enum.Enum):
|
||||
UNBOUNDED = enum.auto()
|
||||
|
||||
|
||||
_solve_status: dict[pwmb.SolveStatus, SolveStatus] = {
|
||||
pwmb.SolveStatus.OPTIMAL: SolveStatus.OPTIMAL,
|
||||
pwmb.SolveStatus.FEASIBLE: SolveStatus.FEASIBLE,
|
||||
pwmb.SolveStatus.INFEASIBLE: SolveStatus.INFEASIBLE,
|
||||
pwmb.SolveStatus.UNBOUNDED: SolveStatus.UNBOUNDED,
|
||||
_solve_status: dict[mbh.SolveStatus, SolveStatus] = {
|
||||
mbh.SolveStatus.OPTIMAL: SolveStatus.OPTIMAL,
|
||||
mbh.SolveStatus.FEASIBLE: SolveStatus.FEASIBLE,
|
||||
mbh.SolveStatus.INFEASIBLE: SolveStatus.INFEASIBLE,
|
||||
mbh.SolveStatus.UNBOUNDED: SolveStatus.UNBOUNDED,
|
||||
}
|
||||
|
||||
|
||||
@@ -1391,8 +1391,8 @@ class _SolveResult:
|
||||
def __init__(
|
||||
self,
|
||||
model: OptimizationModel,
|
||||
solver: pwmb.ModelSolverHelper,
|
||||
status: pwmb.SolveStatus,
|
||||
solver: mbh.ModelSolverHelper,
|
||||
status: mbh.SolveStatus,
|
||||
):
|
||||
self._model = model
|
||||
self._solver = solver
|
||||
@@ -1588,7 +1588,7 @@ class Solver:
|
||||
Solver (based on its `solver_type`).
|
||||
RuntimeError: On a solve error.
|
||||
"""
|
||||
solver = pwmb.ModelSolverHelper(_solver_type_to_name[self.solver_type])
|
||||
solver = mbh.ModelSolverHelper(_solver_type_to_name[self.solver_type])
|
||||
solver.enable_output(options.enable_output)
|
||||
solver.set_time_limit_in_seconds(options.time_limit_seconds)
|
||||
if options.solver_specific_parameters:
|
||||
|
||||
@@ -63,7 +63,6 @@ def code_sample_py(name):
|
||||
deps = [
|
||||
requirement("absl-py"),
|
||||
requirement("numpy"),
|
||||
"@com_google_protobuf//:protobuf_python",
|
||||
],
|
||||
python_version = "PY3",
|
||||
srcs_version = "PY3",
|
||||
|
||||
@@ -49,8 +49,8 @@ setup(
|
||||
],
|
||||
package_data={
|
||||
'@PYTHON_PROJECT@':[$<$<STREQUAL:$<TARGET_PROPERTY:@PROJECT_NAME@,TYPE>,SHARED_LIBRARY>:'.libs/*','../$<TARGET_SONAME_FILE_NAME:@PROJECT_NAME@>'>],
|
||||
'@PYTHON_PROJECT@.init.python':['$<TARGET_FILE_NAME:init>'],
|
||||
'@PYTHON_PROJECT@.algorithms.python':['$<TARGET_FILE_NAME:knapsack_solver>'],
|
||||
'@PYTHON_PROJECT@.init.python':['$<TARGET_FILE_NAME:init_pybind11>'],
|
||||
'@PYTHON_PROJECT@.algorithms.python':['$<TARGET_FILE_NAME:knapsack_solver_pybind11>'],
|
||||
'@PYTHON_PROJECT@.bop':['*.pyi'],
|
||||
'@PYTHON_PROJECT@.glop':['*.pyi'],
|
||||
'@PYTHON_PROJECT@.graph.python':[
|
||||
@@ -60,14 +60,14 @@ setup(
|
||||
],
|
||||
'@PYTHON_PROJECT@.constraint_solver':['$<TARGET_FILE_NAME:pywrapcp>', '*.pyi'],
|
||||
'@PYTHON_PROJECT@.linear_solver':['$<TARGET_FILE_NAME:pywraplp>', '*.pyi'],
|
||||
'@PYTHON_PROJECT@.linear_solver.python':['$<TARGET_FILE_NAME:pywrap_model_builder_helper>', '*.pyi'],
|
||||
'@PYTHON_PROJECT@.linear_solver.python':['$<TARGET_FILE_NAME:model_builder_helper_pybind11>', '*.pyi'],
|
||||
'@PYTHON_PROJECT@.packing':['*.pyi'],
|
||||
'@PYTHON_PROJECT@.pdlp':['*.pyi'],
|
||||
'@PYTHON_PROJECT@.pdlp.python':['$<TARGET_FILE_NAME:pywrap_pdlp_pybind11>'],
|
||||
'@PYTHON_PROJECT@.sat':['*.pyi'],
|
||||
'@PYTHON_PROJECT@.sat.python':['$<TARGET_FILE_NAME:swig_helper>', '*.pyi'],
|
||||
'@PYTHON_PROJECT@.scheduling.python':['$<TARGET_FILE_NAME:rcpsp>', '*.pyi'],
|
||||
'@PYTHON_PROJECT@.util.python':['$<TARGET_FILE_NAME:sorted_interval_list>', '*.pyi'],
|
||||
'@PYTHON_PROJECT@.sat.python':['$<TARGET_FILE_NAME:swig_helper_pybind11>', '*.pyi'],
|
||||
'@PYTHON_PROJECT@.scheduling.python':['$<TARGET_FILE_NAME:rcpsp_pybind11>', '*.pyi'],
|
||||
'@PYTHON_PROJECT@.util.python':['$<TARGET_FILE_NAME:sorted_interval_list_pybind11>', '*.pyi'],
|
||||
},
|
||||
include_package_data=True,
|
||||
license='Apache 2.0',
|
||||
|
||||
@@ -11,29 +11,32 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
pybind11_add_module(swig_helper MODULE swig_helper.cc)
|
||||
pybind11_add_module(swig_helper_pybind11 MODULE swig_helper.cc)
|
||||
set_target_properties(swig_helper_pybind11 PROPERTIES
|
||||
LIBRARY_OUTPUT_NAME "swig_helper")
|
||||
|
||||
# note: macOS is APPLE and also UNIX !
|
||||
if(APPLE)
|
||||
set_target_properties(swig_helper PROPERTIES
|
||||
set_target_properties(swig_helper_pybind11 PROPERTIES
|
||||
SUFFIX ".so"
|
||||
INSTALL_RPATH "@loader_path;@loader_path/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
set_property(TARGET swig_helper APPEND PROPERTY
|
||||
set_property(TARGET swig_helper_pybind11 APPEND PROPERTY
|
||||
LINK_FLAGS "-flat_namespace -undefined suppress"
|
||||
)
|
||||
elseif(UNIX)
|
||||
set_target_properties(swig_helper PROPERTIES
|
||||
set_target_properties(swig_helper_pybind11 PROPERTIES
|
||||
INSTALL_RPATH "$ORIGIN:$ORIGIN/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
endif()
|
||||
target_link_libraries(swig_helper PRIVATE
|
||||
target_link_libraries(swig_helper_pybind11 PRIVATE
|
||||
${PROJECT_NAMESPACE}::ortools
|
||||
pybind11_native_proto_caster
|
||||
protobuf::libprotobuf
|
||||
)
|
||||
target_include_directories(swig_helper PRIVATE ${protobuf_SOURCE_DIR})
|
||||
|
||||
add_library(${PROJECT_NAMESPACE}::swig_helper ALIAS swig_helper)
|
||||
target_include_directories(swig_helper_pybind11 PRIVATE ${protobuf_SOURCE_DIR})
|
||||
add_library(${PROJECT_NAMESPACE}::swig_helper_pybind11 ALIAS swig_helper_pybind11)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB PYTHON_SRCS "*_test.py")
|
||||
|
||||
@@ -11,27 +11,32 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
pybind11_add_module(rcpsp MODULE rcpsp.cc)
|
||||
pybind11_add_module(rcpsp_pybind11 MODULE rcpsp.cc)
|
||||
set_target_properties(rcpsp_pybind11 PROPERTIES
|
||||
LIBRARY_OUTPUT_NAME "rcpsp")
|
||||
|
||||
# note: macOS is APPLE and also UNIX !
|
||||
if(APPLE)
|
||||
set_target_properties(rcpsp PROPERTIES
|
||||
set_target_properties(rcpsp_pybind11 PROPERTIES
|
||||
SUFFIX ".so"
|
||||
INSTALL_RPATH "@loader_path;@loader_path/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
set_property(TARGET rcpsp APPEND PROPERTY
|
||||
set_property(TARGET rcpsp_pybind11 APPEND PROPERTY
|
||||
LINK_FLAGS "-flat_namespace -undefined suppress"
|
||||
)
|
||||
elseif(UNIX)
|
||||
set_target_properties(rcpsp PROPERTIES
|
||||
set_target_properties(rcpsp_pybind11 PROPERTIES
|
||||
INSTALL_RPATH "$ORIGIN:$ORIGIN/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
endif()
|
||||
target_link_libraries(rcpsp PRIVATE
|
||||
target_link_libraries(rcpsp_pybind11 PRIVATE
|
||||
${PROJECT_NAMESPACE}::ortools
|
||||
pybind11_native_proto_caster
|
||||
protobuf::libprotobuf
|
||||
)
|
||||
target_include_directories(rcpsp PRIVATE ${protobuf_SOURCE_DIR})
|
||||
|
||||
target_include_directories(rcpsp_pybind11 PRIVATE ${protobuf_SOURCE_DIR})
|
||||
add_library(${PROJECT_NAMESPACE}::rcpsp_pybind11 ALIAS rcpsp_pybind11)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB PYTHON_SRCS "*_test.py")
|
||||
|
||||
@@ -11,23 +11,27 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
pybind11_add_module(sorted_interval_list MODULE sorted_interval_list.cc)
|
||||
pybind11_add_module(sorted_interval_list_pybind11 MODULE sorted_interval_list.cc)
|
||||
set_target_properties(sorted_interval_list_pybind11 PROPERTIES
|
||||
LIBRARY_OUTPUT_NAME "sorted_interval_list")
|
||||
|
||||
# note: macOS is APPLE and also UNIX !
|
||||
if(APPLE)
|
||||
set_target_properties(sorted_interval_list PROPERTIES
|
||||
set_target_properties(sorted_interval_list_pybind11 PROPERTIES
|
||||
SUFFIX ".so"
|
||||
INSTALL_RPATH "@loader_path;@loader_path/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
set_property(TARGET sorted_interval_list APPEND PROPERTY
|
||||
set_property(TARGET sorted_interval_list_pybind11 APPEND PROPERTY
|
||||
LINK_FLAGS "-flat_namespace -undefined suppress"
|
||||
)
|
||||
elseif(UNIX)
|
||||
set_target_properties(sorted_interval_list PROPERTIES
|
||||
set_target_properties(sorted_interval_list_pybind11 PROPERTIES
|
||||
INSTALL_RPATH "$ORIGIN:$ORIGIN/../../../${PYTHON_PROJECT}/.libs"
|
||||
)
|
||||
endif()
|
||||
target_link_libraries(sorted_interval_list PRIVATE ${PROJECT_NAMESPACE}::ortools)
|
||||
add_library(${PROJECT_NAMESPACE}::sorted_interval_list ALIAS sorted_interval_list)
|
||||
|
||||
target_link_libraries(sorted_interval_list_pybind11 PRIVATE ${PROJECT_NAMESPACE}::ortools)
|
||||
add_library(${PROJECT_NAMESPACE}::sorted_interval_list_pybind11 ALIAS sorted_interval_list_pybind11)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB PYTHON_SRCS "*_test.py")
|
||||
|
||||
Reference in New Issue
Block a user