diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e41dd12ee..7cfa1d0a53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Fixed - Boolean logic circuit construction (#819) - Measurement on actual devices for Amplitude Estimation algorithms (#841) (#842) +- Supported constant values on the left-hand side of constraints and variables on the right-hand side of constraints for the DOcplex translator (#750) [0.6.5](https://github.com/Qiskit/qiskit-aqua/compare/0.6.4...0.6.5) - 2020-03-16 ================================================================================= diff --git a/qiskit/optimization/ising/docplex.py b/qiskit/optimization/ising/docplex.py index ce7b26368f..a3113539b6 100644 --- a/qiskit/optimization/ising/docplex.py +++ b/qiskit/optimization/ising/docplex.py @@ -160,13 +160,13 @@ def get_operator(mdl: Model, auto_penalty: bool = True, # convert constraints into penalty terms. for constraint in mdl.iter_constraints(): - constant = constraint.right_expr.get_constant() + constant = constraint.cplex_num_rhs() # constant parts of penalty*(Constant-func)**2: penalty*(Constant**2) shift += penalty * constant ** 2 # linear parts of penalty*(Constant-func)**2: penalty*(-2*Constant*func) - for __l in constraint.left_expr.iter_terms(): + for __l in constraint.iter_net_linear_coefs(): z_p = np.zeros(num_nodes, dtype=np.bool) index = q_d[__l[0]] weight = __l[1] @@ -176,8 +176,8 @@ def get_operator(mdl: Model, auto_penalty: bool = True, shift += -penalty * constant * weight # quadratic parts of penalty*(Constant-func)**2: penalty*(func**2) - for __l in constraint.left_expr.iter_terms(): - for l_2 in constraint.left_expr.iter_terms(): + for __l in constraint.iter_net_linear_coefs(): + for l_2 in constraint.iter_net_linear_coefs(): index1 = q_d[__l[0]] index2 = q_d[l_2[0]] weight1 = __l[1] @@ -258,8 +258,8 @@ def _auto_define_penalty(mdl: Model, default_penalty: float = 1e5) -> float: # if a constraint has float coefficient, return 1e5 for the penalty coefficient. terms = [] for constraint in mdl.iter_constraints(): - terms.append(constraint.right_expr.get_constant()) - terms.extend(term[1] for term in constraint.left_expr.iter_terms()) + terms.append(constraint.cplex_num_rhs()) + terms.extend(term[1] for term in constraint.iter_net_linear_coefs()) if any(isinstance(term, float) and not term.is_integer() for term in terms): logger.warning('Using %f for the penalty coefficient because a float coefficient exists ' 'in constraints. \nThe value could be too small. ' diff --git a/test/optimization/test_docplex.py b/test/optimization/test_docplex.py index a37fa63d02..a07f0b64d6 100644 --- a/test/optimization/test_docplex.py +++ b/test/optimization/test_docplex.py @@ -320,3 +320,21 @@ def test_docplex_constant_and_quadratic_terms_in_object_function(self): # Compare objective self.assertEqual(result.eigenvalue.real + offset, expected_result) + + def test_constants_in_left_side_and_variables_in_right_side(self): + """ Test Constant values on the left-hand side of constraints and + variables on the right-hand side of constraints for the DOcplex translator""" + mdl = Model('left_constants_and_right_variables') + x = mdl.binary_var(name='x') + y = mdl.binary_var(name='y') + mdl.maximize(mdl.sum(x + y)) + mdl.add_constraint(x == y) + + qubit_op, offset = docplex.get_operator(mdl) + print(qubit_op.print_details()) + e_e = NumPyMinimumEigensolver(qubit_op) + result = e_e.run() + + self.assertEqual(result['eigenvalue'] + offset, -2) + actual_sol = result['eigenstate'].tolist() + self.assertListEqual(actual_sol, [0, 0, 0, 1])