Source code for optiwindnet.MILP
# SPDX-License-Identifier: MIT
# https://gitlab.windenergy.dtu.dk/TOPFARM/OptiWindNet/
import shutil
from importlib.util import find_spec
from ._core import (
FeederLimit,
FeederRoute,
ModelMetadata,
ModelOptions,
OWNSolutionNotFound,
OWNWarmupFailed,
SolutionInfo,
Solver,
Topology,
)
__all__ = (
'Solver',
'Topology',
'FeederRoute',
'FeederLimit',
'ModelOptions',
'ModelMetadata',
'OWNWarmupFailed',
'OWNSolutionNotFound',
'SolutionInfo',
'solver_factory',
)
[docs]
def solver_factory(solver_name: str) -> Solver:
"""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.
Args:
solver_name: one of 'ortools.cp_sat', 'ortools.gscip',
'ortools.highs', 'cplex', 'gurobi', 'cbc', 'scip', 'highs'.
Returns:
Solver instance that can produce solutions for the cable routing problem.
"""
solver_name, *backend = solver_name.split('.', maxsplit=1)
match solver_name:
case 'ortools':
if find_spec('ortools'):
from .ortools import SolverORTools
return SolverORTools(backend[0] if backend else 'cp_sat')
raise ModuleNotFoundError(
"Package 'ortools' not found. Try 'pip install ortools'."
)
case 'cplex':
if find_spec('cplex'):
from .cplex import SolverCplex
return SolverCplex()
raise ModuleNotFoundError(
"Package 'cplex' not found. Try 'pip install cplex' or "
"'conda install -c IBMDecisionOptimization cplex'."
)
case 'gurobi':
if find_spec('gurobipy'):
from .gurobi import SolverGurobi
return SolverGurobi()
raise ModuleNotFoundError(
"Package 'gurobipy' not found. Try 'pip install gurobipy' or "
"'conda install -c Gurobi gurobi'."
)
case 'cbc':
if shutil.which('cbc'):
from .pyomo import SolverPyomo
return SolverPyomo(solver_name)
raise FileNotFoundError(
"Executable 'cbc' not found. Ensure the system PATH includes the "
"path to 'cbc' or try 'conda install -c conda-forge coin-or-cbc'."
)
case 'scip':
if find_spec('pyscipopt'):
from .scip import SolverSCIP
return SolverSCIP()
raise ModuleNotFoundError(
"Package 'pyscipopt' not found. Try 'pip install pyscipopt' or "
"'conda install -c conda-forge pyscipopt'."
)
case 'fscip':
if find_spec('pyscipopt'):
if shutil.which('fscip'):
from .fscip import SolverFSCIP
return SolverFSCIP()
else:
raise FileNotFoundError(
"Executable 'fscip' not found. Ensure the system PATH includes"
" the path to 'fscip' (part of scipoptsuite from"
' https://www.scipopt.org).'
)
else:
raise ModuleNotFoundError(
"Package 'pyscipopt' not found. Try 'pip install pyscipopt' or "
"'conda install -c conda-forge pyscipopt'."
)
case 'highs':
if find_spec('highspy'):
from pyomo.contrib.appsi.solvers.highs import Highs
from .pyomo import SolverPyomoAppsi
return SolverPyomoAppsi(solver_name, Highs)
raise ModuleNotFoundError(
"Package 'highspy' not found. Try 'pip install highspy' or "
"'conda install -c conda-forge highspy'."
)
case _:
raise ValueError(f'Unsupported solver: {solver_name}')