Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 4 additions & 22 deletions qiskit_optimization/algorithms/cplex_optimizer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020, 2021.
# (C) Copyright IBM 2020, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand All @@ -15,25 +15,17 @@
from typing import Any, Dict, Optional
from warnings import warn

from qiskit.exceptions import MissingOptionalLibraryError

from qiskit_optimization.problems.quadratic_program import QuadraticProgram
from qiskit_optimization.translators import to_docplex_mp
import qiskit_optimization.optionals as _optionals
from .optimization_algorithm import (
OptimizationAlgorithm,
OptimizationResult,
OptimizationResultStatus,
)


try:
from cplex import Cplex # pylint: disable=unused-import

_HAS_CPLEX = True
except ImportError:
_HAS_CPLEX = False


@_optionals.HAS_CPLEX.require_in_instance
class CplexOptimizer(OptimizationAlgorithm):
"""The CPLEX optimizer wrapped as an Qiskit :class:`OptimizationAlgorithm`.

Expand All @@ -58,24 +50,14 @@ def __init__(
disp: Whether to print CPLEX output or not.
cplex_parameters: The parameters for CPLEX.
See https://www.ibm.com/docs/en/icos/20.1.0?topic=cplex-parameters for details.

Raises:
MissingOptionalLibraryError: CPLEX is not installed.
"""
if not _HAS_CPLEX:
raise MissingOptionalLibraryError(
libname="CPLEX",
name="CplexOptimizer",
pip_install="pip install 'qiskit-optimization[cplex]'",
)

self._disp = disp
self._cplex_parameters = cplex_parameters

@staticmethod
def is_cplex_installed():
"""Returns True if cplex is installed"""
return _HAS_CPLEX
return _optionals.HAS_CPLEX

@property
def disp(self) -> bool:
Expand Down
29 changes: 9 additions & 20 deletions qiskit_optimization/algorithms/goemans_williamson_optimizer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
# (C) Copyright IBM 2021, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand All @@ -18,8 +18,8 @@
from typing import Optional, List, Tuple, Union, cast

import numpy as np
from qiskit.exceptions import MissingOptionalLibraryError

import qiskit_optimization.optionals as _optionals
from .optimization_algorithm import (
OptimizationResult,
OptimizationResultStatus,
Expand All @@ -30,15 +30,6 @@
from ..problems.quadratic_program import QuadraticProgram
from ..problems.variable import Variable

try:
import cvxpy as cvx
from cvxpy import DCPError, DGPError, SolverError

_HAS_CVXPY = True
except ImportError:
_HAS_CVXPY = False


logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -78,6 +69,7 @@ def sdp_solution(self) -> Optional[np.ndarray]:
return self._sdp_solution


@_optionals.HAS_CVXPY.require_in_instance
class GoemansWilliamsonOptimizer(OptimizationAlgorithm):
"""
Goemans-Williamson algorithm to approximate the max-cut of a problem.
Expand All @@ -103,16 +95,7 @@ def __init__(
unique_cuts: The solve method returns only unique cuts, thus there may be less cuts
than ``num_cuts``.
seed: A seed value for the random number generator.

Raises:
MissingOptionalLibraryError: CVXPY is not installed.
"""
if not _HAS_CVXPY:
raise MissingOptionalLibraryError(
libname="CVXPY",
name="GoemansWilliamsonOptimizer",
pip_install="pip install 'qiskit-optimization[cvxpy]'",
)
super().__init__()

self._num_cuts = num_cuts
Expand Down Expand Up @@ -148,6 +131,9 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:
Returns:
cuts: A list of generated cuts.
"""
# pylint: disable=import-error
from cvxpy import DCPError, DGPError, SolverError

self._verify_compatibility(problem)

min2max = MinimizeToMaximize()
Expand Down Expand Up @@ -257,6 +243,9 @@ def _solve_max_cut_sdp(self, adj_matrix: np.ndarray) -> np.ndarray:
chi: a list of length |V| where the i-th element is +1 or -1, representing which
set the it-h vertex is in. Returns None if an error occurs.
"""
# pylint: disable=import-error
import cvxpy as cvx

num_vertices = len(adj_matrix)
constraints, expr = [], 0

Expand Down
29 changes: 6 additions & 23 deletions qiskit_optimization/algorithms/gurobi_optimizer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020, 2021.
# (C) Copyright IBM 2020, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand All @@ -12,23 +12,14 @@

"""The Gurobi optimizer wrapped to be used within Qiskit's optimization module."""


from qiskit.exceptions import MissingOptionalLibraryError

import qiskit_optimization.optionals as _optionals
from ..exceptions import QiskitOptimizationError
from ..problems.quadratic_program import QuadraticProgram
from ..translators.gurobipy import to_gurobipy
from .optimization_algorithm import OptimizationAlgorithm, OptimizationResult


try:
import gurobipy as gp

_HAS_GUROBI = True
except ImportError:
_HAS_GUROBI = False


@_optionals.HAS_GUROBIPY.require_in_instance
class GurobiOptimizer(OptimizationAlgorithm):
"""The Gurobi optimizer wrapped as an Qiskit :class:`OptimizationAlgorithm`.

Expand All @@ -55,23 +46,13 @@ def __init__(self, disp: bool = False) -> None:

Args:
disp: Whether to print Gurobi output or not.

Raises:
MissingOptionalLibraryError: Gurobi is not installed.
"""
if not _HAS_GUROBI:
raise MissingOptionalLibraryError(
libname="GUROBI",
name="GurobiOptimizer",
pip_install="pip install qiskit-optimization[gurobi]",
)

self._disp = disp

@staticmethod
def is_gurobi_installed():
"""Returns True if gurobi is installed"""
return _HAS_GUROBI
return _optionals.HAS_GUROBIPY

@property
def disp(self) -> bool:
Expand Down Expand Up @@ -120,6 +101,8 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:
Raises:
QiskitOptimizationError: If the problem is incompatible with the optimizer.
"""
# pylint: disable=import-error
import gurobipy as gp

# convert to Gurobi problem
model = to_gurobipy(problem)
Expand Down
23 changes: 7 additions & 16 deletions qiskit_optimization/applications/bin_packing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
# (C) Copyright IBM 2021, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand All @@ -16,20 +16,16 @@

import numpy as np
from docplex.mp.model import Model
from qiskit.exceptions import MissingOptionalLibraryError

import qiskit_optimization.optionals as _optionals
from qiskit_optimization.algorithms import OptimizationResult
from qiskit_optimization.problems.quadratic_program import QuadraticProgram
from qiskit_optimization.translators import from_docplex_mp
from .optimization_application import OptimizationApplication

try:
import matplotlib.pyplot as plt
if _optionals.HAS_MATPLOTLIB:
from matplotlib.pyplot import Figure

_HAS_MATPLOTLIB = True
except ImportError:
_HAS_MATPLOTLIB = False
else:

class Figure: # type: ignore
"""Empty Figure class
Expand Down Expand Up @@ -109,6 +105,7 @@ def interpret(self, result: Union[OptimizationResult, np.ndarray]) -> List[List[
]
return items_in_bins

@_optionals.HAS_MATPLOTLIB.require_in_call
def get_figure(self, result: Union[OptimizationResult, np.ndarray]) -> Figure:
"""Get plot of the solution of the Bin Packing Problem.

Expand All @@ -118,15 +115,9 @@ def get_figure(self, result: Union[OptimizationResult, np.ndarray]) -> Figure:
Returns:
fig: A plot of the solution, where x and y represent the bins and
sum of the weights respectively.
Raises:
MissingOptionalLibraryError: if matplotlib is not installed.
"""
if not _HAS_MATPLOTLIB:
raise MissingOptionalLibraryError(
libname="matplotlib",
name="GraphOptimizationApplication",
pip_install="pip install 'qiskit-optimization[matplotlib]'",
)
import matplotlib.pyplot as plt

colors = plt.cm.get_cmap("jet", len(self._weights))
items_in_bins = self.interpret(result)
num_bins = len(items_in_bins)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2018, 2021.
# (C) Copyright IBM 2018, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand All @@ -17,19 +17,12 @@

import networkx as nx
import numpy as np
from qiskit.exceptions import MissingOptionalLibraryError

import qiskit_optimization.optionals as _optionals
from .optimization_application import OptimizationApplication
from ..algorithms import OptimizationResult
from ..deprecation import DeprecatedType, deprecate_method

try:
import matplotlib as _

_HAS_MATPLOTLIB = True
except ImportError:
_HAS_MATPLOTLIB = False


class GraphOptimizationApplication(OptimizationApplication):
"""
Expand All @@ -46,6 +39,7 @@ def __init__(self, graph: Union[nx.Graph, np.ndarray, List]) -> None:
# The view of the graph is stored which means the graph can not be changed.
self._graph = nx.Graph(graph).copy(as_view=True)

@_optionals.HAS_MATPLOTLIB.require_in_call
def draw(
self,
result: Optional[Union[OptimizationResult, np.ndarray]] = None,
Expand All @@ -57,16 +51,7 @@ def draw(
Args:
result: The calculated result for the problem
pos: The positions of nodes
Raises:
MissingOptionalLibraryError: if matplotlib is not installed.
"""
if not _HAS_MATPLOTLIB:
raise MissingOptionalLibraryError(
libname="matplotlib",
name="GraphOptimizationApplication",
pip_install="pip install 'qiskit-optimization[matplotlib]'",
)

if result is None:
nx.draw(self._graph, pos=pos, with_labels=True)
else:
Expand Down
49 changes: 49 additions & 0 deletions qiskit_optimization/optionals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""
Additional optional constants.
"""

from qiskit.utils import LazyImportTester

HAS_CPLEX = LazyImportTester(
{
"cplex": ("Cplex",),
},
name="CPLEX",
install="pip install 'qiskit-optimization[cplex]'",
)

HAS_CVXPY = LazyImportTester(
{
"cvxpy": ("DCPError", "DGPError", "SolverError"),
},
name="CVXPY",
install="pip install 'qiskit-optimization[cvx]'",
)

HAS_GUROBIPY = LazyImportTester(
{
"gurobipy": ("Model",),
},
name="Gurobi",
install="pip install 'qiskit-optimization[gurobi]'",
)

HAS_MATPLOTLIB = LazyImportTester(
{
"matplotlib.pyplot": ("Figure",),
},
name="Matplotlib",
install="pip install 'qiskit-optimization[matplotlib]'",
)
Loading