optiwindnet.MILP

Submodules

Package Contents

Re-exported

class optiwindnet.MILP.FeederRoute[source]

Importable from this module. Documented at optiwindnet.types.FeederRoute.

exception optiwindnet.MILP.OWNWarmupFailed[source]

Importable from this module. Documented at optiwindnet.types.OWNWarmupFailed.

class optiwindnet.MILP.Topology[source]

Importable from this module. Documented at optiwindnet.types.Topology.

class optiwindnet.MILP.FeederLimit[source]

Bases: enum.StrEnum

Whether to limit the number of feeders. Both 'specified' (an upper bound) and 'exactly' (an exact count) require the additional kwarg 'max_feeders'. Option 'balanced' is only enforceable if the feeder count is pinned to a single value, i.e. 'minimum' or 'exactly'.

Nonunitary terminal inflow rule out 'minimum' and the 'min_plus*' modes, whose bounds come from a minimum feeder count that indivisible terminal inflow may not reach.

Initialize self. See help(type(self)) for accurate signature.

UNLIMITED
EXACTLY
SPECIFIED
MINIMUM
MIN_PLUS1
MIN_PLUS2
MIN_PLUS3
DEFAULT
class optiwindnet.MILP.ModelMetadata[source]
R: int
T: int
capacity: int
linkset: tuple[_Link, ...]
flow_: collections.abc.Mapping[_Link, Any]
topology: optiwindnet.types.Topology
fun_fingerprint: dict[str, str | bytes]
weight_: tuple[float, ...] = ()
solution_hint: dict[Any, float]
warmed_by: str = ''
class optiwindnet.MILP.ModelOptions(*, topology: optiwindnet.types.Topology | str = ..., feeder_route: optiwindnet.types.FeederRoute | str = ..., feeder_limit: FeederLimit | str = ..., balanced: bool = ..., max_feeders: int = ...)[source]

Bases: dict

Hold options for the modelling of the cable routing problem.

Deprecated (removed in v0.4.0), and constructing one warns: superseded by NetworkConstraints, which to_constraints() translates the options into.

Use ModelOptions.help() to get the options and their permitted and default values. Use ModelOptions() without any parameters to use the defaults.

Initialize self. See help(type(self)) for accurate signature.

hints: ClassVar[dict[str, type]]
simple: ClassVar[dict[str, tuple]]
__reduce__()[source]

Helper for pickle.

to_constraints() → optiwindnet.constraints.NetworkConstraints[source]

Translate the options into network constraints.

feeder_limit='min_plus<k>' becomes max_feeders='min+<k>', with k doubled for RINGED (a ring has two feeders). An unenforceable balanced is dropped with a warning.

classmethod help()[source]
exception optiwindnet.MILP.OWNSolutionNotFound[source]

Bases: Exception

Common base class for all non-exit exceptions.

Initialize self. See help(type(self)) for accurate signature.

class optiwindnet.MILP.SolutionInfo[source]

Search outcome, plus the id of the topology the search settled on.

topology_id is the topology_id() of the model-objective incumbent, which solve() derives from the link bits it reads off the solver – no topology is built to obtain it, and the bits themselves stay on the solver, as Solver.incumbent_linkbits. It is empty only in an instance made outside a solver. A solution pool may hand over a different entry, whose own id is the _topology_id of the topology get_solution() returns.

runtime: float
bound: float
objective: float
relgap: float
termination: str
topology_id: bytes = b''
__repr__() → str[source]

Fixed-shape summary: one field per line, keys column-aligned.

The floats are rounded for reading, so this is not a reconstructible repr: use dataclasses.asdict() when exact values are needed.

class optiwindnet.MILP.Solver[source]

Bases: abc.ABC

Common interface to multiple MILP solvers

name: str
metadata: ModelMetadata
A: networkx.Graph
model: Any
solver: Any
options: dict[str, Any]
stopping: dict[str, Any]
constraints: optiwindnet.constraints.NetworkConstraints
bounds: optiwindnet.constraints.NetworkBounds
solution_info: SolutionInfo
applied_options: dict[str, Any]
property incumbent_linkbits: bitarray.frozenbitarray

Canonical link bits of the model-objective incumbent, read by solve().

The solution itself, in the encoding S_from_linkbits() decodes: the route to a topology that skips the detour routing get_solution() performs. These are the incumbent’s bits, not those of whichever solution-pool entry get_solution() settles on once the entries are ranked by routed length.

set_problem(P: networkx.PlanarEmbedding, A: networkx.Graph, *, constraints: optiwindnet.constraints.NetworkConstraints | None = None, model_options: collections.abc.Mapping[str, Any] | None = None, capacity: int | None = None, capacity_nominal: float | fractions.Fraction | None = None, power_rtol: float = DEFAULT_POWER_RTOL, warmstart: networkx.Graph | None = None) → None[source]

Define the problem geometry, available links and tree properties.

Parameters:
  • P – planar embedding of the location

  • A – available links for the location

  • constraints – network constraints (defaults to NetworkConstraints())

  • model_options – deprecated (removed in v0.4.0), use constraints: tree properties - see ModelOptions.help()

  • capacity – maximum inflow of a subtree

  • capacity_nominal – maximum power of a subtree, instead of capacity (see quantized())

  • power_rtol – quantization tolerance of unequal turbine power

  • warmstart – initial feasible solution to pass to solver

Raises:
abstractmethod solve(time_limit: float, mip_gap: float, options: collections.abc.Mapping[str, Any] = MappingProxyType({}), verbose: bool = False) → SolutionInfo[source]

Run the MILP solver search.

Parameters:
  • time_limit – maximum time (s) the solver is allowed to run.

  • mip_gap – relative difference from incumbent solution to lower bound at which the search may be stopped before time_limit is reached.

  • options – additional options to pass to solver (see solver manual).

Returns:

General information about the solution search (use get_solution() for

the actual solution).

abstractmethod get_solution(A: networkx.Graph | None = None) → tuple[networkx.Graph, networkx.Graph][source]

Output solution topology S and routeset G.

Parameters:

A – optionally replace a normalized A given via set_problem() with its unscaled counterpart for routing. It must have the same candidate links; the MILP topology is defined by the original A.

Returns:

Topology graph S and routeset G.

optiwindnet.MILP.solver_factory(solver_name: str) → Solver[source]

Create a Solver object tied to the specified external MILP solver.

Note that the only solver that is a dependency of OptiWindNet is 'ortools'. Check OptiWindNet’s documentation on how to install optional solvers.

Legacy compatibility: if solver_name == 'ortools' then the CP-SAT backend is used.

Parameters:

solver_name – one of 'ortools.cp_sat', 'ortools.gscip', 'ortools.highs', 'ortools.cbcbox', 'cplex', 'gurobi', 'cbc', 'scip', 'fscip', 'highs', 'pyomo.cbc', 'pyomo.highs' ('cbc' is an alias of 'pyomo.cbc').

Returns:

Solver instance that can produce solutions for the cable routing problem.

Raises:

RuntimeError – if the solver’s backend package shares a native library with a backend already in use in this interpreter instance ('ortools*' clashes with 'highs', 'pyomo.highs' and 'scip'/'fscip').