13
13
"""The CPLEX optimizer wrapped to be used within Qiskit's optimization module."""
14
14
15
15
import logging
16
+ from typing import Any , Dict , Optional
17
+ from warnings import warn
16
18
17
19
from qiskit .exceptions import MissingOptionalLibraryError
18
- from .optimization_algorithm import OptimizationAlgorithm , OptimizationResult
19
- from ..exceptions import QiskitOptimizationError
20
+
21
+ from .optimization_algorithm import (
22
+ OptimizationAlgorithm ,
23
+ OptimizationResult ,
24
+ OptimizationResultStatus ,
25
+ )
20
26
from ..problems .quadratic_program import QuadraticProgram
21
27
22
28
logger = logging .getLogger (__name__ )
23
29
24
30
try :
25
- from cplex . exceptions import CplexSolverError
31
+ from cplex import Cplex # pylint: disable=unused-import
26
32
27
33
_HAS_CPLEX = True
28
34
except ImportError :
@@ -44,11 +50,14 @@ class CplexOptimizer(OptimizationAlgorithm):
44
50
>>> if optimizer: result = optimizer.solve(problem)
45
51
"""
46
52
47
- def __init__ (self , disp : bool = False ) -> None :
53
+ def __init__ (
54
+ self , disp : bool = False , cplex_parameters : Optional [Dict [str , Any ]] = None
55
+ ) -> None :
48
56
"""Initializes the CplexOptimizer.
49
57
50
58
Args:
51
59
disp: Whether to print CPLEX output or not.
60
+ cplex_parameters: The parameters for CPLEX.
52
61
53
62
Raises:
54
63
MissingOptionalLibraryError: CPLEX is not installed.
@@ -61,6 +70,7 @@ def __init__(self, disp: bool = False) -> None:
61
70
)
62
71
63
72
self ._disp = disp
73
+ self ._cplex_parameters = cplex_parameters
64
74
65
75
@staticmethod
66
76
def is_cplex_installed ():
@@ -84,6 +94,19 @@ def disp(self, disp: bool):
84
94
"""
85
95
self ._disp = disp
86
96
97
+ @property
98
+ def cplex_parameters (self ) -> Optional [Dict [str , Any ]]:
99
+ """Returns parameters for CPLEX"""
100
+ return self ._cplex_parameters
101
+
102
+ @cplex_parameters .setter
103
+ def cplex_parameters (self , parameters : Optional [Dict [str , Any ]]):
104
+ """Set parameters for CPLEX
105
+ Args:
106
+ parameters: The parameters for CPLEX
107
+ """
108
+ self ._cplex_parameters = parameters
109
+
87
110
# pylint:disable=unused-argument
88
111
def get_compatibility_msg (self , problem : QuadraticProgram ) -> str :
89
112
"""Checks whether a given problem can be solved with this optimizer.
@@ -116,33 +139,26 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:
116
139
QiskitOptimizationError: If the problem is incompatible with the optimizer.
117
140
"""
118
141
119
- # convert to CPLEX problem
120
- cplex = problem .to_docplex ().get_cplex ()
121
-
122
- # set display setting
123
- if not self .disp :
124
- cplex .set_log_stream (None )
125
- cplex .set_error_stream (None )
126
- cplex .set_warning_stream (None )
127
- cplex .set_results_stream (None )
128
-
129
- # solve problem
130
- try :
131
- cplex .solve ()
132
- except CplexSolverError as ex :
133
- raise QiskitOptimizationError (str (ex )) from ex
134
-
135
- # process results
136
- sol = cplex .solution
137
-
138
- # create results
139
- result = OptimizationResult (
140
- x = sol .get_values (),
141
- fval = sol .get_objective_value (),
142
- variables = problem .variables ,
143
- status = self ._get_feasibility_status (problem , sol .get_values ()),
144
- raw_results = sol ,
145
- )
146
-
147
- # return solution
148
- return result
142
+ mod = problem .to_docplex ()
143
+ sol = mod .solve (log_output = self ._disp , cplex_parameters = self ._cplex_parameters )
144
+ if sol is None :
145
+ # no solution is found
146
+ warn ("CPLEX cannot solve the model" )
147
+ x = [0.0 ] * mod .number_of_variables
148
+ return OptimizationResult (
149
+ x = x ,
150
+ fval = problem .objective .evaluate (x ),
151
+ variables = problem .variables ,
152
+ status = OptimizationResultStatus .FAILURE ,
153
+ raw_results = None ,
154
+ )
155
+ else :
156
+ # a solution is found
157
+ x = sol .get_values (mod .iter_variables ())
158
+ return OptimizationResult (
159
+ x = x ,
160
+ fval = sol .get_objective_value (),
161
+ variables = problem .variables ,
162
+ status = self ._get_feasibility_status (problem , x ),
163
+ raw_results = sol ,
164
+ )
0 commit comments