math_opt: export from google3
* CMake has not been updated yet * bazel was compiling at least last week bazel: disable math opt facility_location.py missing some dependencies...
This commit is contained in:
@@ -13,12 +13,16 @@
|
||||
|
||||
"""Model specific solver configuration (e.g. starting basis)."""
|
||||
import dataclasses
|
||||
from typing import Dict, List, Optional
|
||||
import datetime
|
||||
from typing import Dict, List, Optional, Set
|
||||
|
||||
from ortools.math_opt import model_parameters_pb2
|
||||
from ortools.math_opt.python import linear_constraints
|
||||
from ortools.math_opt.python import model
|
||||
from ortools.math_opt.python import objectives
|
||||
from ortools.math_opt.python import solution
|
||||
from ortools.math_opt.python import sparse_containers
|
||||
from ortools.math_opt.python import variables
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
@@ -51,10 +55,10 @@ class SolutionHint:
|
||||
constraints to finite (and not NaN) double values.
|
||||
"""
|
||||
|
||||
variable_values: Dict[model.Variable, float] = dataclasses.field(
|
||||
variable_values: Dict[variables.Variable, float] = dataclasses.field(
|
||||
default_factory=dict
|
||||
)
|
||||
dual_values: Dict[model.LinearConstraint, float] = dataclasses.field(
|
||||
dual_values: Dict[linear_constraints.LinearConstraint, float] = dataclasses.field(
|
||||
default_factory=dict
|
||||
)
|
||||
|
||||
@@ -98,6 +102,81 @@ def parse_solution_hint(
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ObjectiveParameters:
|
||||
"""Parameters for an individual objective in a multi-objective model.
|
||||
|
||||
This class mirrors (and can generate) the related proto
|
||||
model_parameters_pb2.ObjectiveParametersProto.
|
||||
|
||||
Attributes:
|
||||
objective_degradation_absolute_tolerance: Optional objective degradation
|
||||
absolute tolerance. For a hierarchical multi-objective solver, each
|
||||
objective fⁱ is processed in priority order: the solver determines the
|
||||
optimal objective value Γⁱ, if it exists, subject to all constraints in
|
||||
the model and the additional constraints that fᵏ(x) = Γᵏ (within
|
||||
tolerances) for each k < i. If set, a solution is considered to be "within
|
||||
tolerances" for this objective fᵏ if |fᵏ(x) - Γᵏ| ≤
|
||||
`objective_degradation_absolute_tolerance`. See also
|
||||
`objective_degradation_relative_tolerance`; if both parameters are set for
|
||||
a given objective, the solver need only satisfy one to be considered
|
||||
"within tolerances". If not None, must be nonnegative.
|
||||
objective_degradation_relative_tolerance: Optional objective degradation
|
||||
relative tolerance. For a hierarchical multi-objective solver, each
|
||||
objective fⁱ is processed in priority order: the solver determines the
|
||||
optimal objective value Γⁱ, if it exists, subject to all constraints in
|
||||
the model and the additional constraints that fᵏ(x) = Γᵏ (within
|
||||
tolerances) for each k < i. If set, a solution is considered to be "within
|
||||
tolerances" for this objective fᵏ if |fᵏ(x) - Γᵏ| ≤
|
||||
`objective_degradation_relative_tolerance` * |Γᵏ|. See also
|
||||
`objective_degradation_absolute_tolerance`; if both parameters are set for
|
||||
a given objective, the solver need only satisfy one to be considered
|
||||
"within tolerances". If not None, must be nonnegative.
|
||||
time_limit: The maximum time a solver should spend on optimizing this
|
||||
particular objective (or infinite if not set). Note that this does not
|
||||
supersede the global time limit in SolveParameters.time_limit; both will
|
||||
be enforced when set. This value is not a hard limit, solve time may
|
||||
slightly exceed this value.
|
||||
"""
|
||||
|
||||
objective_degradation_absolute_tolerance: Optional[float] = None
|
||||
objective_degradation_relative_tolerance: Optional[float] = None
|
||||
time_limit: Optional[datetime.timedelta] = None
|
||||
|
||||
def to_proto(self) -> model_parameters_pb2.ObjectiveParametersProto:
|
||||
"""Returns an equivalent protocol buffer."""
|
||||
result = model_parameters_pb2.ObjectiveParametersProto()
|
||||
if self.objective_degradation_absolute_tolerance is not None:
|
||||
result.objective_degradation_absolute_tolerance = (
|
||||
self.objective_degradation_absolute_tolerance
|
||||
)
|
||||
if self.objective_degradation_relative_tolerance is not None:
|
||||
result.objective_degradation_relative_tolerance = (
|
||||
self.objective_degradation_relative_tolerance
|
||||
)
|
||||
if self.time_limit is not None:
|
||||
result.time_limit.FromTimedelta(self.time_limit)
|
||||
return result
|
||||
|
||||
|
||||
def parse_objective_parameters(
|
||||
proto: model_parameters_pb2.ObjectiveParametersProto,
|
||||
) -> ObjectiveParameters:
|
||||
"""Returns an equivalent ObjectiveParameters to the input proto."""
|
||||
result = ObjectiveParameters()
|
||||
if proto.HasField("objective_degradation_absolute_tolerance"):
|
||||
result.objective_degradation_absolute_tolerance = (
|
||||
proto.objective_degradation_absolute_tolerance
|
||||
)
|
||||
if proto.HasField("objective_degradation_relative_tolerance"):
|
||||
result.objective_degradation_relative_tolerance = (
|
||||
proto.objective_degradation_relative_tolerance
|
||||
)
|
||||
if proto.HasField("time_limit"):
|
||||
result.time_limit = proto.time_limit.ToTimedelta()
|
||||
return result
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class ModelSolveParameters:
|
||||
"""Model specific solver configuration, for example, an initial basis.
|
||||
@@ -109,8 +188,10 @@ class ModelSolveParameters:
|
||||
variable_values_filter: Only return solution and primal ray values for
|
||||
variables accepted by this filter (default accepts all variables).
|
||||
dual_values_filter: Only return dual variable values and dual ray values for
|
||||
linear constraints accepted by thei filter (default accepts all linear
|
||||
linear constraints accepted by this filter (default accepts all linear
|
||||
constraints).
|
||||
quadratic_dual_values_filter: Only return quadratic constraint dual values
|
||||
accepted by this filter (default accepts all quadratic constraints).
|
||||
reduced_costs_filter: Only return reduced cost and dual ray values for
|
||||
variables accepted by this filter (default accepts all variables).
|
||||
initial_basis: If set, provides a warm start for simplex based solvers.
|
||||
@@ -119,6 +200,14 @@ class ModelSolveParameters:
|
||||
branching_priorities: Optional branching priorities. Variables with higher
|
||||
values will be branched on first. Variables for which priorities are not
|
||||
set get the solver's default priority (usually zero).
|
||||
objective_parameters: Optional per objective parameters used only only for
|
||||
multi-objective models.
|
||||
lazy_linear_constraints: Optional lazy constraint annotations. Included
|
||||
linear constraints will be marked as "lazy" with supporting solvers,
|
||||
meaning that they will only be added to the working model as-needed as the
|
||||
solver runs. Note that this an algorithmic hint that does not affect the
|
||||
model's feasible region; solvers not supporting these annotations will
|
||||
simply ignore it.
|
||||
"""
|
||||
|
||||
variable_values_filter: sparse_containers.VariableFilter = (
|
||||
@@ -127,14 +216,23 @@ class ModelSolveParameters:
|
||||
dual_values_filter: sparse_containers.LinearConstraintFilter = (
|
||||
sparse_containers.LinearConstraintFilter()
|
||||
)
|
||||
quadratic_dual_values_filter: sparse_containers.QuadraticConstraintFilter = (
|
||||
sparse_containers.QuadraticConstraintFilter()
|
||||
)
|
||||
reduced_costs_filter: sparse_containers.VariableFilter = (
|
||||
sparse_containers.VariableFilter()
|
||||
)
|
||||
initial_basis: Optional[solution.Basis] = None
|
||||
solution_hints: List[SolutionHint] = dataclasses.field(default_factory=list)
|
||||
branching_priorities: Dict[model.Variable, int] = dataclasses.field(
|
||||
branching_priorities: Dict[variables.Variable, int] = dataclasses.field(
|
||||
default_factory=dict
|
||||
)
|
||||
objective_parameters: Dict[objectives.Objective, ObjectiveParameters] = (
|
||||
dataclasses.field(default_factory=dict)
|
||||
)
|
||||
lazy_linear_constraints: Set[linear_constraints.LinearConstraint] = (
|
||||
dataclasses.field(default_factory=set)
|
||||
)
|
||||
|
||||
def to_proto(self) -> model_parameters_pb2.ModelSolveParametersProto:
|
||||
"""Returns an equivalent protocol buffer."""
|
||||
@@ -143,6 +241,7 @@ class ModelSolveParameters:
|
||||
result = model_parameters_pb2.ModelSolveParametersProto(
|
||||
variable_values_filter=self.variable_values_filter.to_proto(),
|
||||
dual_values_filter=self.dual_values_filter.to_proto(),
|
||||
quadratic_dual_values_filter=self.quadratic_dual_values_filter.to_proto(),
|
||||
reduced_costs_filter=self.reduced_costs_filter.to_proto(),
|
||||
branching_priorities=sparse_containers.to_sparse_int32_vector_proto(
|
||||
self.branching_priorities
|
||||
@@ -152,4 +251,14 @@ class ModelSolveParameters:
|
||||
result.initial_basis.CopyFrom(self.initial_basis.to_proto())
|
||||
for hint in self.solution_hints:
|
||||
result.solution_hints.append(hint.to_proto())
|
||||
for obj, params in self.objective_parameters.items():
|
||||
if isinstance(obj, objectives.AuxiliaryObjective):
|
||||
result.auxiliary_objective_parameters[obj.id].CopyFrom(
|
||||
params.to_proto()
|
||||
)
|
||||
else:
|
||||
result.primary_objective_parameters.CopyFrom(params.to_proto())
|
||||
result.lazy_linear_constraint_ids[:] = sorted(
|
||||
con.id for con in self.lazy_linear_constraints
|
||||
)
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user