Source code for qiskit_optimization.converters.flip_problem_sense
# This code is part of a Qiskit project.
#
# (C) Copyright IBM 2021, 2025.
#
# 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.
"""Converters to flip problem sense, e.g. maximization to minimization and vice versa."""
from __future__ import annotations
import copy
import numpy as np
from .quadratic_program_converter import QuadraticProgramConverter
from ..exceptions import QiskitOptimizationError
from ..problems.quadratic_objective import ObjSense
from ..problems.quadratic_program import QuadraticProgram
class _FlipProblemSense(QuadraticProgramConverter):
"""Flip the sense of a problem, e.g. converts from maximization to minimization and
vice versa, regardless of the current sense."""
def __init__(self) -> None:
self._src_num_vars: int | None = None
def convert(self, problem: QuadraticProgram) -> QuadraticProgram:
"""Flip the sense of a problem.
Args:
problem: The problem to be flipped.
Returns:
A converted problem, that has the flipped sense.
"""
# copy original number of variables as reference.
self._src_num_vars = problem.get_num_vars()
desired_sense = self._get_desired_sense(problem)
# flip the problem sense
if problem.objective.sense != desired_sense:
desired_problem = copy.deepcopy(problem)
desired_problem.objective.sense = desired_sense
desired_problem.objective.constant = (-1) * problem.objective.constant
desired_problem.objective.linear = (-1) * problem.objective.linear.coefficients
desired_problem.objective.quadratic = (-1) * problem.objective.quadratic.coefficients
else:
desired_problem = problem
return desired_problem
def _get_desired_sense(self, problem: QuadraticProgram) -> ObjSense:
"""
Computes a desired sense of the problem. By default, flip the sense.
Args:
problem: a problem to check
Returns:
A desired sense, if the problem was a minimization problem, then the sense is
maximization and vice versa.
"""
if problem.objective.sense == ObjSense.MAXIMIZE:
return ObjSense.MINIMIZE
else:
return ObjSense.MAXIMIZE
def interpret(self, x: np.ndarray | list[float]) -> np.ndarray:
"""Convert the result of the converted problem back to that of the original problem.
Args:
x: The result of the converted problem or the given result in case of FAILURE.
Returns:
The result of the original problem.
Raises:
QiskitOptimizationError: if the number of variables in the result differs from
that of the original problem.
"""
if len(x) != self._src_num_vars:
raise QiskitOptimizationError(
f"The number of variables in the passed result differs from "
f"that of the original problem, should be {self._src_num_vars}, but got {len(x)}."
)
return np.asarray(x)
[docs]
class MaximizeToMinimize(_FlipProblemSense):
"""Convert a maximization problem to a minimization problem only if it is a maximization
problem, otherwise problem's sense is unchanged."""
def _get_desired_sense(self, problem: QuadraticProgram) -> ObjSense:
return ObjSense.MINIMIZE
[docs]
class MinimizeToMaximize(_FlipProblemSense):
"""Convert a minimization problem to a maximization problem only if it is a minimization
problem, otherwise problem's sense is unchanged."""
def _get_desired_sense(self, problem: QuadraticProgram) -> ObjSense:
return ObjSense.MAXIMIZE