diff --git a/qiskit/optimization/algorithms/grover_optimizer.py b/qiskit/optimization/algorithms/grover_optimizer.py index 513f00852..af671fa76 100644 --- a/qiskit/optimization/algorithms/grover_optimizer.py +++ b/qiskit/optimization/algorithms/grover_optimizer.py @@ -17,11 +17,10 @@ import logging from typing import Optional, Dict, Union, Tuple import math -import random import numpy as np from qiskit import QuantumCircuit from qiskit.providers import BaseBackend -from qiskit.aqua import QuantumInstance +from qiskit.aqua import QuantumInstance, aqua_globals from qiskit.aqua.algorithms.amplitude_amplifiers.grover import Grover from ..exceptions import QiskitOptimizationError from .optimization_algorithm import OptimizationAlgorithm, OptimizationResult @@ -116,6 +115,16 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult: qubo_converter = QuadraticProgramToQubo() problem_ = qubo_converter.encode(problem) + # convert to minimization problem + sense = problem_.objective.sense + if sense == problem_.objective.Sense.MAXIMIZE: + problem_.objective.sense = problem_.objective.Sense.MINIMIZE + problem_.objective.constant = -problem_.objective.constant + for i, v in problem_.objective.linear.to_dict().items(): + problem_.objective.linear[i] = -v + for (i, j), v in problem_.objective.quadratic.to_dict().items(): + problem_.objective.quadratic[i, j] = -v + # Variables for tracking the optimum. optimum_found = False optimum_key = math.inf @@ -156,7 +165,7 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult: while not improvement_found: # Determine the number of rotations. loops_with_no_improvement += 1 - rotation_count = int(np.ceil(random.uniform(0, m-1))) + rotation_count = int(np.ceil(aqua_globals.random.uniform(0, m-1))) rotations += rotation_count # Apply Grover's Algorithm to find values below the threshold. @@ -218,7 +227,10 @@ def solve(self, problem: QuadraticProgram) -> OptimizationResult: # Build the results object. grover_results = GroverOptimizationResults(operation_count, n_key, n_value, func_dict) - result = OptimizationResult(x=opt_x, fval=solutions[optimum_key], + fval = solutions[optimum_key] + if sense == problem_.objective.Sense.MAXIMIZE: + fval = -fval + result = OptimizationResult(x=opt_x, fval=fval, results={"grover_results": grover_results, "qubo_converter": qubo_converter}) @@ -234,7 +246,7 @@ def _measure(self, circuit: QuantumCircuit, n_key: int, n_value: int) -> str: # Pick a random outcome. freq[len(freq)-1] = (freq[len(freq)-1][0], 1 - sum([x[1] for x in freq[0:len(freq)-1]])) - idx = np.random.choice(len(freq), 1, p=[x[1] for x in freq])[0] + idx = aqua_globals.random.choice(len(freq), 1, p=[x[1] for x in freq])[0] logger.info('Frequencies: %s', freq) return freq[idx][0] diff --git a/qiskit/optimization/converters/quadratic_program_to_negative_value_oracle.py b/qiskit/optimization/converters/quadratic_program_to_negative_value_oracle.py index 4007452dc..c9b763431 100644 --- a/qiskit/optimization/converters/quadratic_program_to_negative_value_oracle.py +++ b/qiskit/optimization/converters/quadratic_program_to_negative_value_oracle.py @@ -42,14 +42,14 @@ class QuadraticProgramToNegativeValueOracle: arxiv:1912.04088. """ - def __init__(self, num_output_qubits: int, measurement: bool = False) -> None: + def __init__(self, num_value_qubits: int, measurement: bool = False) -> None: """ Args: - num_output_qubits: The number of qubits required to represent the output. + num_value_qubits: The number of qubits required to represent the output. measurement: Whether the A operator contains measurements. """ self._num_key = 0 - self._num_value = num_output_qubits + self._num_value = num_value_qubits self._measurement = measurement def encode(self, problem: QuadraticProgram) -> \ diff --git a/test/optimization/test_grover_optimizer.py b/test/optimization/test_grover_optimizer.py index 2fc8bb4bf..9a50dd617 100644 --- a/test/optimization/test_grover_optimizer.py +++ b/test/optimization/test_grover_optimizer.py @@ -16,8 +16,6 @@ import unittest from test.optimization import QiskitOptimizationTestCase -import random -import numpy from docplex.mp.model import Model from qiskit import Aer from qiskit.aqua import aqua_globals, QuantumInstance @@ -31,9 +29,7 @@ class TestGroverOptimizer(QiskitOptimizationTestCase): def setUp(self): super().setUp() - random.seed = 2 - numpy.random.seed = 42 - aqua_globals.seed = 42 + aqua_globals.random_seed = 1 self.q_instance = QuantumInstance(Aer.get_backend('statevector_simulator'), seed_simulator=921, seed_transpiler=200) @@ -81,6 +77,23 @@ def test_qubo_gas_int_simple(self): results = gmf.solve(op) self.validate_results(op, results) + def test_qubo_gas_int_simple_maximize(self): + """Test for simple case, but with maximization.""" + + # Input. + model = Model() + x_0 = model.binary_var(name='x0') + x_1 = model.binary_var(name='x1') + model.maximize(-x_0+2*x_1) + op = QuadraticProgram() + op.from_docplex(model) + + # Get the optimum key and value. + n_iter = 8 + gmf = GroverOptimizer(4, num_iterations=n_iter, quantum_instance=self.q_instance) + results = gmf.solve(op) + self.validate_results(op, results) + def test_qubo_gas_int_paper_example(self): """Test the example from https://arxiv.org/abs/1912.04088."""