Skip to content

Commit

Permalink
For the Enhancement of converters of QuadraticProgram (qiskit-communi…
Browse files Browse the repository at this point in the history
…ty#1061)

* refactored converter's constructor

* added baseconverter class

* added is_compatible_with_integer_slack

* added InequalityToEquality converter to QuadraticProgramToQubo

* refactor InequalityToEquality converter

* refactored encode and decode name

* renamed encode/decode to convert/interpret

* added getter/setter for linear

* moved `name` to convert method

* fixed IsingToQuadraticProgram

* removed `name` arguments from converters

* added to_ising and from_ising

* moved converters to constructors of algorithms

* fixed deprecated msg and added conv to results

Co-authored-by: Steve Wood <40241007+woodsp-ibm@users.noreply.github.com>
Co-authored-by: Manoel Marques <manoel@us.ibm.com>
Co-authored-by: Julien Gacon <jules.gacon@googlemail.com>
  • Loading branch information
4 people authored Aug 3, 2020
1 parent e95bdb8 commit 9999b6e
Show file tree
Hide file tree
Showing 15 changed files with 610 additions and 572 deletions.
6 changes: 4 additions & 2 deletions qiskit/optimization/algorithms/admm_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def solve(self, problem: QuadraticProgram) -> ADMMOptimizationResult:
# map integer variables to binary variables
from ..converters.integer_to_binary import IntegerToBinary
int2bin = IntegerToBinary()
problem = int2bin.encode(problem)
problem = int2bin.convert(problem)

# we deal with minimization in the optimizer, so turn the problem to minimization
problem, sense = self._turn_to_minimization(problem)
Expand Down Expand Up @@ -367,10 +367,12 @@ def solve(self, problem: QuadraticProgram) -> ADMMOptimizationResult:
result = ADMMOptimizationResult(x=solution,
fval=objective_value,
state=self._state,
results={"integer_to_binary_converter": copy.deepcopy(
int2bin)},
variables=problem.variables)

# convert back integer to binary
result = cast(ADMMOptimizationResult, int2bin.decode(result))
result = cast(ADMMOptimizationResult, int2bin.interpret(result))
# debug
self._log.debug("solution=%s, objective=%s at iteration=%s",
solution, objective_value, iteration)
Expand Down
14 changes: 10 additions & 4 deletions qiskit/optimization/algorithms/grover_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@

"""GroverOptimizer module"""

import copy
import logging
from typing import Optional, Dict, Union, Tuple
import math

import numpy as np

from qiskit import QuantumCircuit
from qiskit.providers import BaseBackend
from qiskit.aqua import QuantumInstance, aqua_globals
Expand Down Expand Up @@ -47,6 +50,7 @@ def __init__(self, num_value_qubits: int, num_iterations: int = 3,
self._num_value_qubits = num_value_qubits
self._n_iterations = num_iterations
self._quantum_instance = None
self._qubo_converter = QuadraticProgramToQubo()

if quantum_instance is not None:
self.quantum_instance = quantum_instance
Expand Down Expand Up @@ -108,8 +112,7 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:
self._verify_compatibility(problem)

# convert problem to QUBO
qubo_converter = QuadraticProgramToQubo()
problem_ = qubo_converter.encode(problem)
problem_ = self._qubo_converter.convert(problem)

# convert to minimization problem
sense = problem_.objective.sense
Expand Down Expand Up @@ -228,10 +231,13 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:
fval = -fval
result = OptimizationResult(x=opt_x, variables=problem.variables, fval=fval,
results={"grover_results": grover_results,
"qubo_converter": qubo_converter})
"qubo_converter": copy.deepcopy(self._qubo_converter),
"negative_value_oracle_converter": copy.deepcopy(
opt_prob_converter)
})

# cast binaries back to integers
result = qubo_converter.decode(result)
result = self._qubo_converter.interpret(result)

return result

Expand Down
16 changes: 8 additions & 8 deletions qiskit/optimization/algorithms/minimum_eigen_optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# that they have been altered from the originals.

"""A wrapper for minimum eigen solvers from Aqua to be used within the optimization module."""

import copy
from typing import Optional, Any, Union, Tuple, List, cast
import numpy as np

Expand All @@ -24,7 +24,6 @@
from .optimization_algorithm import OptimizationAlgorithm, OptimizationResult
from ..problems.quadratic_program import QuadraticProgram
from ..problems.variable import Variable
from ..converters.quadratic_program_to_ising import QuadraticProgramToIsing
from ..converters.quadratic_program_to_qubo import QuadraticProgramToQubo


Expand Down Expand Up @@ -110,6 +109,7 @@ def __init__(self, min_eigen_solver: MinimumEigensolver, penalty: Optional[float
"""
self._min_eigen_solver = min_eigen_solver
self._penalty = penalty
self._qubo_converter = QuadraticProgramToQubo()

def get_compatibility_msg(self, problem: QuadraticProgram) -> str:
"""Checks whether a given problem can be solved with this optimizer.
Expand Down Expand Up @@ -142,12 +142,10 @@ def solve(self, problem: QuadraticProgram) -> MinimumEigenOptimizerResult:
self._verify_compatibility(problem)

# convert problem to QUBO
qubo_converter = QuadraticProgramToQubo()
problem_ = qubo_converter.encode(problem)
problem_ = self._qubo_converter.convert(problem)

# construct operator and offset
operator_converter = QuadraticProgramToIsing()
operator, offset = operator_converter.encode(problem_)
operator, offset = problem_.to_ising()

# only try to solve non-empty Ising Hamiltonians
x = None # type: Optional[Any]
Expand All @@ -174,9 +172,11 @@ def solve(self, problem: QuadraticProgram) -> MinimumEigenOptimizerResult:
samples = [(x_str, offset, 1.0)]

# translate result back to integers
opt_res = MinimumEigenOptimizerResult(x, fval, samples, qubo_converter,
opt_res = MinimumEigenOptimizerResult(x=x, fval=fval, samples=samples,
results={"qubo_converter": copy.deepcopy(
self._qubo_converter)},
variables=problem.variables)
opt_res = cast(MinimumEigenOptimizerResult, qubo_converter.decode(opt_res))
opt_res = cast(MinimumEigenOptimizerResult, self._qubo_converter.interpret(opt_res))

# translate results back to original problem
return opt_res
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def __init__(self, min_eigen_optimizer: MinimumEigenOptimizer, min_num_vars: int
else:
self._min_num_vars_optimizer = MinimumEigenOptimizer(NumPyMinimumEigensolver())
self._penalty = penalty
self._qubo_converter = QuadraticProgramToQubo()

def get_compatibility_msg(self, problem: QuadraticProgram) -> str:
"""Checks whether a given problem can be solved with this optimizer.
Expand Down Expand Up @@ -124,8 +125,7 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult:
self._verify_compatibility(problem)

# convert problem to QUBO, this implicitly checks if the problem is compatible
qubo_converter = QuadraticProgramToQubo()
problem_ = qubo_converter.encode(problem)
problem_ = self._qubo_converter.convert(problem)
problem_ref = deepcopy(problem_)

# run recursive optimization until the resulting problem is small enough
Expand Down Expand Up @@ -209,9 +209,10 @@ def find_value(x, replacements, var_values):
# construct result
x_v = [var_values[x_aux.name] for x_aux in problem_ref.variables]
fval = result.fval
results = OptimizationResult(x_v, fval, (replacements, qubo_converter),
results = OptimizationResult(x=x_v, fval=fval,
results=(replacements, deepcopy(self._qubo_converter)),
variables=problem.variables)
results = qubo_converter.decode(results)
results = self._qubo_converter.interpret(results)
return results

def _find_strongest_correlation(self, correlations):
Expand Down
8 changes: 1 addition & 7 deletions qiskit/optimization/converters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,13 @@
InequalityToEquality
IntegerToBinary
QuadraticProgramToNegativeValueOracle
QuadraticProgramToIsing
QuadraticProgramToQubo
LinearEqualityToPenalty
IsingToQuadraticProgram
"""

# no opt problem dependency
from .quadratic_program_to_ising import QuadraticProgramToIsing
from .quadratic_program_to_negative_value_oracle import QuadraticProgramToNegativeValueOracle
from .ising_to_quadratic_program import IsingToQuadraticProgram

# opt problem dependency
from .integer_to_binary import IntegerToBinary
Expand All @@ -54,8 +50,6 @@
"InequalityToEquality",
"IntegerToBinary",
"QuadraticProgramToNegativeValueOracle",
"QuadraticProgramToIsing",
"QuadraticProgramToQubo",
"LinearEqualityToPenalty",
"IsingToQuadraticProgram"
"LinearEqualityToPenalty"
]
Loading

0 comments on commit 9999b6e

Please sign in to comment.