20
20
21
21
from .. import QiskitOptimizationError
22
22
from ..problems .quadratic_program import QuadraticProgram , Variable
23
+ from ..converters .quadratic_program_to_qubo import (QuadraticProgramToQubo ,
24
+ QuadraticProgramConverter )
23
25
24
26
25
27
class OptimizationResultStatus (Enum ):
@@ -35,85 +37,6 @@ class OptimizationResultStatus(Enum):
35
37
"""the optimization algorithm obtained an infeasible solution."""
36
38
37
39
38
- class OptimizationAlgorithm (ABC ):
39
- """An abstract class for optimization algorithms in Qiskit's optimization module."""
40
-
41
- @abstractmethod
42
- def get_compatibility_msg (self , problem : QuadraticProgram ) -> str :
43
- """Checks whether a given problem can be solved with the optimizer implementing this method.
44
-
45
- Args:
46
- problem: The optimization problem to check compatibility.
47
-
48
- Returns:
49
- Returns the incompatibility message. If the message is empty no issues were found.
50
- """
51
-
52
- def is_compatible (self , problem : QuadraticProgram ) -> bool :
53
- """Checks whether a given problem can be solved with the optimizer implementing this method.
54
-
55
- Args:
56
- problem: The optimization problem to check compatibility.
57
-
58
- Returns:
59
- Returns True if the problem is compatible, False otherwise.
60
- """
61
- return len (self .get_compatibility_msg (problem )) == 0
62
-
63
- @abstractmethod
64
- def solve (self , problem : QuadraticProgram ) -> 'OptimizationResult' :
65
- """Tries to solves the given problem using the optimizer.
66
-
67
- Runs the optimizer to try to solve the optimization problem.
68
-
69
- Args:
70
- problem: The problem to be solved.
71
-
72
- Returns:
73
- The result of the optimizer applied to the problem.
74
-
75
- Raises:
76
- QiskitOptimizationError: If the problem is incompatible with the optimizer.
77
- """
78
- raise NotImplementedError
79
-
80
- def _verify_compatibility (self , problem : QuadraticProgram ) -> None :
81
- """Verifies that the problem is suitable for this optimizer. If the problem is not
82
- compatible then an exception is raised. This method is for convenience for concrete
83
- optimizers and is not intended to be used by end user.
84
-
85
- Args:
86
- problem: Problem to verify.
87
-
88
- Returns:
89
- None
90
-
91
- Raises:
92
- QiskitOptimizationError: If the problem is incompatible with the optimizer.
93
-
94
- """
95
- # check compatibility and raise exception if incompatible
96
- msg = self .get_compatibility_msg (problem )
97
- if msg :
98
- raise QiskitOptimizationError ('Incompatible problem: {}' .format (msg ))
99
-
100
- def _get_feasibility_status (self , problem : QuadraticProgram ,
101
- x : Union [List [float ], np .ndarray ]) -> OptimizationResultStatus :
102
- """Returns whether the input result is feasible or not for the given problem.
103
-
104
- Args:
105
- problem: Problem to verify.
106
- x: the input result list.
107
-
108
- Returns:
109
- The status of the result.
110
- """
111
- is_feasible = problem .is_feasible (x )
112
-
113
- return OptimizationResultStatus .SUCCESS if is_feasible \
114
- else OptimizationResultStatus .INFEASIBLE
115
-
116
-
117
40
class OptimizationResult :
118
41
"""A base class for optimization results.
119
42
@@ -279,3 +202,156 @@ def variable_names(self) -> List[str]:
279
202
The list of variable names of the optimization problem.
280
203
"""
281
204
return self ._variable_names
205
+
206
+
207
+ class OptimizationAlgorithm (ABC ):
208
+ """An abstract class for optimization algorithms in Qiskit's optimization module."""
209
+
210
+ @abstractmethod
211
+ def get_compatibility_msg (self , problem : QuadraticProgram ) -> str :
212
+ """Checks whether a given problem can be solved with the optimizer implementing this method.
213
+
214
+ Args:
215
+ problem: The optimization problem to check compatibility.
216
+
217
+ Returns:
218
+ Returns the incompatibility message. If the message is empty no issues were found.
219
+ """
220
+
221
+ def is_compatible (self , problem : QuadraticProgram ) -> bool :
222
+ """Checks whether a given problem can be solved with the optimizer implementing this method.
223
+
224
+ Args:
225
+ problem: The optimization problem to check compatibility.
226
+
227
+ Returns:
228
+ Returns True if the problem is compatible, False otherwise.
229
+ """
230
+ return len (self .get_compatibility_msg (problem )) == 0
231
+
232
+ @abstractmethod
233
+ def solve (self , problem : QuadraticProgram ) -> 'OptimizationResult' :
234
+ """Tries to solves the given problem using the optimizer.
235
+
236
+ Runs the optimizer to try to solve the optimization problem.
237
+
238
+ Args:
239
+ problem: The problem to be solved.
240
+
241
+ Returns:
242
+ The result of the optimizer applied to the problem.
243
+
244
+ Raises:
245
+ QiskitOptimizationError: If the problem is incompatible with the optimizer.
246
+ """
247
+ raise NotImplementedError
248
+
249
+ def _verify_compatibility (self , problem : QuadraticProgram ) -> None :
250
+ """Verifies that the problem is suitable for this optimizer. If the problem is not
251
+ compatible then an exception is raised. This method is for convenience for concrete
252
+ optimizers and is not intended to be used by end user.
253
+
254
+ Args:
255
+ problem: Problem to verify.
256
+
257
+ Returns:
258
+ None
259
+
260
+ Raises:
261
+ QiskitOptimizationError: If the problem is incompatible with the optimizer.
262
+
263
+ """
264
+ # check compatibility and raise exception if incompatible
265
+ msg = self .get_compatibility_msg (problem )
266
+ if msg :
267
+ raise QiskitOptimizationError ('Incompatible problem: {}' .format (msg ))
268
+
269
+ def _get_feasibility_status (self , problem : QuadraticProgram ,
270
+ x : Union [List [float ], np .ndarray ]) -> OptimizationResultStatus :
271
+ """Returns whether the input result is feasible or not for the given problem.
272
+
273
+ Args:
274
+ problem: Problem to verify.
275
+ x: the input result list.
276
+
277
+ Returns:
278
+ The status of the result.
279
+ """
280
+ is_feasible = problem .is_feasible (x )
281
+
282
+ return OptimizationResultStatus .SUCCESS if is_feasible \
283
+ else OptimizationResultStatus .INFEASIBLE
284
+
285
+ def _prepare_converters (self , converters : Optional [Union [QuadraticProgramConverter ,
286
+ List [QuadraticProgramConverter ]]],
287
+ penalty : Optional [float ] = None ) -> List [QuadraticProgramConverter ]:
288
+ """Prepare a list of converters from the input.
289
+
290
+ Args:
291
+ converters: The converters to use for converting a problem into a different form.
292
+ By default, when None is specified, an internally created instance of
293
+ :class:`~qiskit.optimization.converters.QuadraticProgramToQubo` will be used.
294
+ penalty: The penalty factor used in the default
295
+ :class:`~qiskit.optimization.converters.QuadraticProgramToQubo` converter
296
+
297
+ Returns:
298
+ The list of converters.
299
+
300
+ Raises:
301
+ TypeError: When the converters include those that are not
302
+ :class:`~qiskit.optimization.converters.QuadraticProgramConverter type.
303
+ """
304
+ converters_ = [] # type: List[QuadraticProgramConverter]
305
+ if converters is None :
306
+ converters_ = [QuadraticProgramToQubo (penalty = penalty )]
307
+ elif isinstance (converters , QuadraticProgramConverter ):
308
+ converters_ = [converters ]
309
+ elif isinstance (converters , list ) and \
310
+ all (isinstance (converter , QuadraticProgramConverter ) for converter in converters ):
311
+ converters_ = converters
312
+ else :
313
+ raise TypeError ('`converters` must all be of the QuadraticProgramConverter type' )
314
+
315
+ return converters_
316
+
317
+ def _convert (self , problem : QuadraticProgram ,
318
+ converters : Union [QuadraticProgramConverter ,
319
+ List [QuadraticProgramConverter ]]) -> QuadraticProgram :
320
+ """Convert the problem with the converters
321
+
322
+ Args:
323
+ problem: The problem to be solved
324
+ converters: The converters to use for converting a problem into a different form.
325
+
326
+ Returns:
327
+ The problem converted by the converters.
328
+ """
329
+ problem_ = problem
330
+
331
+ if not isinstance (converters , list ):
332
+ converters = [converters ]
333
+
334
+ for converter in converters :
335
+ problem_ = converter .convert (problem_ )
336
+
337
+ return problem_
338
+
339
+ def _interpret (self , result : OptimizationResult ,
340
+ converters : Union [QuadraticProgramConverter ,
341
+ List [QuadraticProgramConverter ]]) -> OptimizationResult :
342
+ """Convert back the result of the converted problem to the result of the original problem.
343
+
344
+ Args:
345
+ result: The result of the converted problem.
346
+ converters: The converters to use for converting back the result of the problem
347
+ to the result of the original problem.
348
+
349
+ Returns:
350
+ The result of the original problem.
351
+ """
352
+ if not isinstance (converters , list ):
353
+ converters = [converters ]
354
+
355
+ for converter in converters [::- 1 ]:
356
+ result = converter .interpret (result )
357
+ return result
0 commit comments