def test_auto_penalty(self): """Test auto penalty function""" op = QuadraticProgram() op.binary_var("x") op.binary_var("y") op.binary_var("z") op.minimize(constant=3, linear={"x": 1}, quadratic={("x", "y"): 2}) op.linear_constraint(linear={ "x": 1, "y": 1, "z": 1 }, sense="EQ", rhs=2, name="xyz_eq") lineq2penalty = LinearEqualityToPenalty(penalty=1e5) lineq2penalty_auto = LinearEqualityToPenalty() qubo = lineq2penalty.convert(op) qubo_auto = lineq2penalty_auto.convert(op) exact_mes = NumPyMinimumEigensolver() exact = MinimumEigenOptimizer(exact_mes) result = exact.solve(qubo) result_auto = exact.solve(qubo_auto) self.assertEqual(result.fval, result_auto.fval) np.testing.assert_array_almost_equal(result.x, result_auto.x)
def test_linear_equality_to_penalty_decode(self): """Test decode func of LinearEqualityToPenalty""" qprog = QuadraticProgram() qprog.binary_var("x") qprog.binary_var("y") qprog.binary_var("z") qprog.maximize(linear={"x": 3, "y": 1, "z": 1}) qprog.linear_constraint(linear={ "x": 1, "y": 1, "z": 1 }, sense="EQ", rhs=2, name="xyz_eq") lineq2penalty = LinearEqualityToPenalty() qubo = lineq2penalty.convert(qprog) exact_mes = NumPyMinimumEigensolver() exact = MinimumEigenOptimizer(exact_mes) result = exact.solve(qubo) new_x = lineq2penalty.interpret(result.x) np.testing.assert_array_almost_equal(new_x, [1, 1, 0]) infeasible_x = lineq2penalty.interpret([1, 1, 1]) np.testing.assert_array_almost_equal(infeasible_x, [1, 1, 1])
def test_penalty_recalculation_when_reusing(self): """Test the penalty retrieval and recalculation of LinearEqualityToPenalty""" op = QuadraticProgram() op.binary_var("x") op.binary_var("y") op.binary_var("z") op.minimize(constant=3, linear={"x": 1}, quadratic={("x", "y"): 2}) op.linear_constraint(linear={ "x": 1, "y": 1, "z": 1 }, sense="EQ", rhs=2, name="xyz_eq") # First, create a converter with no penalty lineq2penalty = LinearEqualityToPenalty() self.assertIsNone(lineq2penalty.penalty) # Then converter must calculate the penalty for the problem (should be 4.0) lineq2penalty.convert(op) self.assertEqual(4, lineq2penalty.penalty) # Re-use the converter with a newly defined penalty lineq2penalty.penalty = 3 lineq2penalty.convert(op) self.assertEqual(3, lineq2penalty.penalty) # Re-use the converter letting the penalty be calculated again lineq2penalty.penalty = None lineq2penalty.convert(op) self.assertEqual(4, lineq2penalty.penalty)
def qaoa(G): n = G.numberOfNodes() G = nw.nxadapter.nk2nx(G) w = nx.adjacency_matrix(G) problem = QuadraticProgram() _ = [problem.binary_var(f"x{i}") for i in range(n)] linear = w.dot(np.ones(n)) quadratic = -w problem.maximize(linear=linear, quadratic=quadratic) c = [1] for _ in range(n - 1): c.append(0) problem.linear_constraint(c, '==', 1) cobyla = COBYLA() backend = BasicAer.get_backend('qasm_simulator') qaoa = QAOA(optimizer=cobyla, reps=3, quantum_instance=backend) algorithm = MinimumEigenOptimizer(qaoa) result = algorithm.solve(problem) L = result.x i = 0 res = {} for x in L: res[i] = x i += 1 return res
def test_integer_to_binary2(self): """Test integer to binary variables 2""" mod = QuadraticProgram() mod.integer_var(name="x", lowerbound=0, upperbound=1) mod.integer_var(name="y", lowerbound=0, upperbound=1) mod.minimize(1, {"x": 1}, {("x", "y"): 2}) mod.linear_constraint({"x": 1}, "==", 1) mod.quadratic_constraint({"x": 1}, {("x", "y"): 2}, "==", 1) mod2 = IntegerToBinary().convert(mod) self.assertListEqual([e.name + "@0" for e in mod.variables], [e.name for e in mod2.variables]) self.assertDictEqual(mod.objective.linear.to_dict(), mod2.objective.linear.to_dict()) self.assertDictEqual(mod.objective.quadratic.to_dict(), mod2.objective.quadratic.to_dict()) self.assertEqual(mod.get_num_linear_constraints(), mod2.get_num_linear_constraints()) for cst, cst2 in zip(mod.linear_constraints, mod2.linear_constraints): self.assertDictEqual(cst.linear.to_dict(), cst2.linear.to_dict()) self.assertEqual(mod.get_num_quadratic_constraints(), mod2.get_num_quadratic_constraints()) for cst, cst2 in zip(mod.quadratic_constraints, mod2.quadratic_constraints): self.assertDictEqual(cst.linear.to_dict(), cst2.linear.to_dict()) self.assertDictEqual(cst.quadratic.to_dict(), cst2.quadratic.to_dict())
def test_linear_inequality_to_penalty3(self): """Test special constraint to penalty x1+x2+x3+... >= n-1 -> P(x1*x2+x1*x3+...)""" op = QuadraticProgram() lip = LinearInequalityToPenalty() op.binary_var_list(5) # Linear constraints n = 5 op.linear_constraint([1, 1, 1, 1, 1], Constraint.Sense.GE, n - 1, "") # Test with no max/min with self.subTest("No max/min"): self.assertEqual(op.get_num_linear_constraints(), 1) penalty = 5 lip.penalty = penalty constant = 10 linear = [n - 1, n - 1, n - 1, n - 1, n - 1] quadratic = [ [0, 1, 1, 1, 1], [0, 0, 1, 1, 1], [0, 0, 0, 1, 1], [0, 0, 0, 0, 1], [0, 0, 0, 0, 0], ] op2 = lip.convert(op) cnst2 = op2.objective.constant / penalty ldct2 = op2.objective.linear.to_array() / penalty * -1 qdct2 = op2.objective.quadratic.to_array() / penalty self.assertEqual(cnst2, constant) self.assertEqual(ldct2.tolist(), linear) self.assertEqual(qdct2.tolist(), quadratic) self.assertEqual(op2.get_num_linear_constraints(), 0)
def test_quadratic_program_to_qubo_inequality_to_penalty(self): """Test QuadraticProgramToQubo, passing inequality pattern""" op = QuadraticProgram() conv = QuadraticProgramToQubo() op.binary_var(name="x") op.binary_var(name="y") # Linear constraints linear_constraint = {"x": 1, "y": 1} op.linear_constraint(linear_constraint, Constraint.Sense.GE, 1, "P(1-x-y+xy)") conv.penalty = 1 constant = 1 linear = {"x": -conv.penalty, "y": -conv.penalty} quadratic = {("x", "y"): conv.penalty} op2 = conv.convert(op) cnst = op2.objective.constant ldct = op2.objective.linear.to_dict(use_name=True) qdct = op2.objective.quadratic.to_dict(use_name=True) self.assertEqual(cnst, constant) self.assertEqual(ldct, linear) self.assertEqual(qdct, quadratic) self.assertEqual(op2.get_num_linear_constraints(), 0)
def test_write_to_lp_file(self): """test write problem""" q_p = QuadraticProgram("my problem") q_p.binary_var("x") q_p.integer_var(-1, 5, "y") q_p.continuous_var(-1, 5, "z") q_p.minimize(1, {"x": 1, "y": -1, "z": 10}, {("x", "x"): 0.5, ("y", "z"): -1}) q_p.linear_constraint({"x": 1, "y": 2}, "==", 1, "lin_eq") q_p.linear_constraint({"x": 1, "y": 2}, "<=", 1, "lin_leq") q_p.linear_constraint({"x": 1, "y": 2}, ">=", 1, "lin_geq") q_p.quadratic_constraint( {"x": 1, "y": 1}, {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2}, "==", 1, "quad_eq", ) q_p.quadratic_constraint( {"x": 1, "y": 1}, {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2}, "<=", 1, "quad_leq", ) q_p.quadratic_constraint( {"x": 1, "y": 1}, {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2}, ">=", 1, "quad_geq", ) reference_file_name = self.get_resource_path( "test_quadratic_program.lp", "problems/resources" ) with tempfile.TemporaryDirectory() as tmp: temp_output_path = path.join(tmp, "temp.lp") q_p.write_to_lp_file(temp_output_path) with open(reference_file_name, encoding="utf8") as reference, open( temp_output_path, encoding="utf8" ) as temp_output_file: lines1 = temp_output_file.readlines() lines2 = reference.readlines() self.assertListEqual(lines1, lines2) with tempfile.TemporaryDirectory() as temp_problem_dir: q_p.write_to_lp_file(temp_problem_dir) with open(path.join(temp_problem_dir, "my_problem.lp"), encoding="utf8") as file1, open( reference_file_name, encoding="utf8" ) as file2: lines1 = file1.readlines() lines2 = file2.readlines() self.assertListEqual(lines1, lines2) with self.assertRaises(OSError): q_p.write_to_lp_file("/cannot/write/this/file.lp") with self.assertRaises(DOcplexException): q_p.write_to_lp_file("")
def test_linear_inequality_to_penalty7(self): """Test special constraint to penalty 6 x-y >= 0 -> P(y-x*y)""" op = QuadraticProgram() lip = LinearInequalityToPenalty() op.binary_var(name="x") op.binary_var(name="y") # Linear constraints linear_constraint = {"x": 1, "y": -1} op.linear_constraint(linear_constraint, Constraint.Sense.GE, 0, "P(y-xy)") # Test with no max/min with self.subTest("No max/min"): self.assertEqual(op.get_num_linear_constraints(), 1) penalty = 1 linear = {"y": penalty} quadratic = {("x", "y"): -1 * penalty} op2 = lip.convert(op) ldct = op2.objective.linear.to_dict(use_name=True) qdct = op2.objective.quadratic.to_dict(use_name=True) self.assertEqual(ldct, linear) self.assertEqual(qdct, quadratic) self.assertEqual(op2.get_num_linear_constraints(), 0) # Test maximize with self.subTest("Maximize"): linear = {"x": 2, "y": 1} op.maximize(linear=linear) penalty = 4 linear["y"] = linear["y"] - penalty quadratic = {("x", "y"): penalty} op2 = lip.convert(op) ldct = op2.objective.linear.to_dict(use_name=True) qdct = op2.objective.quadratic.to_dict(use_name=True) self.assertEqual(ldct, linear) self.assertEqual(qdct, quadratic) self.assertEqual(op2.get_num_linear_constraints(), 0) # Test minimize with self.subTest("Minimize"): linear = {"x": 2, "y": 1} op.minimize(linear={"x": 2, "y": 1}) penalty = 4 linear["y"] = linear["y"] + penalty quadratic = {("x", "y"): -1 * penalty} op2 = lip.convert(op) ldct = op2.objective.linear.to_dict(use_name=True) qdct = op2.objective.quadratic.to_dict(use_name=True) self.assertEqual(ldct, linear) self.assertEqual(qdct, quadratic) self.assertEqual(op2.get_num_linear_constraints(), 0)
def test_linear_inequality_to_penalty4(self): """Test special constraint to penalty x1+x2+x3+... <= 1 -> P(x1*x2+x1*x3+...)""" op = QuadraticProgram() lip = LinearInequalityToPenalty() op.binary_var(name="x") op.binary_var(name="y") op.binary_var(name="z") # Linear constraints linear_constraint = {"x": 1, "y": 1, "z": 1} op.linear_constraint(linear_constraint, Constraint.Sense.LE, 1, "P(xy+yz+zx)") # Test with no max/min with self.subTest("No max/min"): self.assertEqual(op.get_num_linear_constraints(), 1) penalty = 1 quadratic = { ("x", "y"): penalty, ("x", "z"): penalty, ("y", "z"): penalty } op2 = lip.convert(op) qdct = op2.objective.quadratic.to_dict(use_name=True) self.assertEqual(qdct, quadratic) self.assertEqual(op2.get_num_linear_constraints(), 0) # Test maximize op = QuadraticProgram() op.binary_var_list(5) linear2 = [1, 1, 0, 0, 0] op.maximize(linear=linear2) op.linear_constraint([1, 1, 1, 1, 1], Constraint.Sense.LE, 1, "") with self.subTest("Maximum"): self.assertEqual(op.get_num_linear_constraints(), 1) lip.penalty = 5 quadratic2 = [ [0, 1, 1, 1, 1], [0, 0, 1, 1, 1], [0, 0, 0, 1, 1], [0, 0, 0, 0, 1], [0, 0, 0, 0, 0], ] op2 = lip.convert(op) ldct2 = op2.objective.linear.to_array() qdct2 = op2.objective.quadratic.to_array() / lip.penalty * -1 self.assertEqual(ldct2.tolist(), linear2) self.assertEqual(qdct2.tolist(), quadratic2) self.assertEqual(op2.get_num_linear_constraints(), 0)
def _sample_code(self): def print(*args): """ overloads print to log values """ if args: self.log.debug(args[0], *args[1:]) # --- Exact copy of sample code ---------------------------------------- import networkx as nx import numpy as np from qiskit_optimization import QuadraticProgram from qiskit_optimization.algorithms import MinimumEigenOptimizer from qiskit import BasicAer from qiskit.algorithms import QAOA from qiskit.algorithms.optimizers import SPSA # Generate a graph of 4 nodes n = 4 graph = nx.Graph() graph.add_nodes_from(np.arange(0, n, 1)) elist = [(0, 1, 1.0), (0, 2, 1.0), (0, 3, 1.0), (1, 2, 1.0), (2, 3, 1.0)] graph.add_weighted_edges_from(elist) # Compute the weight matrix from the graph w = nx.adjacency_matrix(graph) # Formulate the problem as quadratic program problem = QuadraticProgram() _ = [problem.binary_var('x{}'.format(i)) for i in range(n)] # create n binary variables linear = w.dot(np.ones(n)) quadratic = -w problem.maximize(linear=linear, quadratic=quadratic) # Fix node 0 to be 1 to break the symmetry of the max-cut solution problem.linear_constraint([1, 0, 0, 0], '==', 1) # Run quantum algorithm QAOA on qasm simulator spsa = SPSA(maxiter=250) backend = BasicAer.get_backend('qasm_simulator') qaoa = QAOA(optimizer=spsa, p=5, quantum_instance=backend) algorithm = MinimumEigenOptimizer(qaoa) result = algorithm.solve(problem) print(result) # prints solution, x=[1, 0, 1, 0], the cost, fval=4 # ---------------------------------------------------------------------- return result
def test_binary_to_integer(self): """Test binary to integer""" op = QuadraticProgram() for i in range(0, 2): op.binary_var(name="x{}".format(i)) op.integer_var(name="x2", lowerbound=0, upperbound=5) linear = {"x0": 1, "x1": 2, "x2": 1} op.maximize(0, linear, {}) linear = {} for x in op.variables: linear[x.name] = 1 op.linear_constraint(linear, Constraint.Sense.EQ, 6, "x0x1x2") conv = IntegerToBinary() _ = conv.convert(op) new_x = conv.interpret([0, 1, 1, 1, 1]) np.testing.assert_array_almost_equal(new_x, [0, 1, 5])
def test_0var_range_inequality(self): """ Test InequalityToEquality converter when the var_rang of the slack variable is 0""" op = QuadraticProgram() op.binary_var('x') op.binary_var('y') op.linear_constraint(linear={'x': 1, 'y': 1}, sense='LE', rhs=0, name='xy_leq1') op.linear_constraint(linear={'x': 1, 'y': 1}, sense='GE', rhs=2, name='xy_geq1') op.quadratic_constraint(quadratic={('x', 'x'): 1}, sense='LE', rhs=0, name='xy_leq2') op.quadratic_constraint(quadratic={('x', 'y'): 1}, sense='GE', rhs=1, name='xy_geq2') ineq2eq = InequalityToEquality() new_op = ineq2eq.convert(op) self.assertEqual(new_op.get_num_vars(), 2) self.assertTrue(all(l_const.sense == Constraint.Sense.EQ for l_const in new_op.linear_constraints)) self.assertTrue(all(q_const.sense == Constraint.Sense.EQ for q_const in new_op.quadratic_constraints))
def test_clear(self): """test clear""" q_p = QuadraticProgram("test") q_p.binary_var("x") q_p.binary_var("y") q_p.minimize(constant=1, linear={"x": 1, "y": 2}, quadratic={("x", "x"): 1}) q_p.linear_constraint({"x": 1}, "==", 1) q_p.quadratic_constraint({"x": 1}, {("y", "y"): 2}, "<=", 1) q_p.clear() self.assertEqual(q_p.name, "") self.assertEqual(q_p.status, QuadraticProgram.Status.VALID) self.assertEqual(q_p.get_num_vars(), 0) self.assertEqual(q_p.get_num_linear_constraints(), 0) self.assertEqual(q_p.get_num_quadratic_constraints(), 0) self.assertEqual(q_p.objective.constant, 0) self.assertDictEqual(q_p.objective.linear.to_dict(), {}) self.assertDictEqual(q_p.objective.quadratic.to_dict(), {})
def test_empty_name(self): """Test empty names""" with self.subTest("problem name"): q_p = QuadraticProgram("") self.assertEqual(q_p.name, "") with self.subTest("variable name"): q_p = QuadraticProgram() x = q_p.binary_var(name="") y = q_p.integer_var(name="") z = q_p.continuous_var(name="") self.assertEqual(x.name, "x0") self.assertEqual(y.name, "x1") self.assertEqual(z.name, "x2") with self.subTest("variable name 2"): q_p = QuadraticProgram() w = q_p.binary_var(name="w") x = q_p.binary_var(name="") y = q_p.integer_var(name="") z = q_p.continuous_var(name="") self.assertEqual(w.name, "w") self.assertEqual(x.name, "x1") self.assertEqual(y.name, "x2") self.assertEqual(z.name, "x3") with self.subTest("variable name list"): q_p = QuadraticProgram() x = q_p.binary_var_list(2, name="") y = q_p.integer_var_list(2, name="") z = q_p.continuous_var_list(2, name="") self.assertListEqual([v.name for v in x], ["x0", "x1"]) self.assertListEqual([v.name for v in y], ["x2", "x3"]) self.assertListEqual([v.name for v in z], ["x4", "x5"]) with self.subTest("variable name dict"): q_p = QuadraticProgram() x = q_p.binary_var_dict(2, name="") y = q_p.integer_var_dict(2, name="") z = q_p.continuous_var_dict(2, name="") self.assertDictEqual({k: v.name for k, v in x.items()}, {"x0": "x0", "x1": "x1"}) self.assertDictEqual({k: v.name for k, v in y.items()}, {"x2": "x2", "x3": "x3"}) self.assertDictEqual({k: v.name for k, v in z.items()}, {"x4": "x4", "x5": "x5"}) with self.subTest("linear constraint name"): q_p = QuadraticProgram() x = q_p.linear_constraint(name="") y = q_p.linear_constraint(name="") self.assertEqual(x.name, "c0") self.assertEqual(y.name, "c1") with self.subTest("quadratic constraint name"): q_p = QuadraticProgram() x = q_p.quadratic_constraint(name="") y = q_p.quadratic_constraint(name="") self.assertEqual(x.name, "q0") self.assertEqual(y.name, "q1")
def test_optimizationproblem_to_ising(self): """Test optimization problem to operators""" op = QuadraticProgram() for i in range(4): op.binary_var(name="x{}".format(i)) linear = {} for x in op.variables: linear[x.name] = 1 op.maximize(0, linear, {}) linear = {} for i, x in enumerate(op.variables): linear[x.name] = i + 1 op.linear_constraint(linear, Constraint.Sense.EQ, 3, "sum1") penalize = LinearEqualityToPenalty(penalty=1e5) op2 = penalize.convert(op) qubitop, offset = op2.to_ising() self.assertEqual(qubitop, QUBIT_OP_MAXIMIZE_SAMPLE) self.assertEqual(offset, OFFSET_MAXIMIZE_SAMPLE)
def test_auto_penalty_warning(self): """ Test warnings of auto penalty function""" op = QuadraticProgram() op.binary_var('x') op.binary_var('y') op.binary_var('z') op.minimize(linear={'x': 1, 'y': 2}) op.linear_constraint(linear={'x': 0.5, 'y': 0.5, 'z': 0.5}, sense='EQ', rhs=1, name='xyz') with self.assertLogs('qiskit_optimization', level='WARNING') as log: lineq2penalty = LinearEqualityToPenalty() _ = lineq2penalty.convert(op) warning = ( 'WARNING:qiskit_optimization.converters.linear_equality_to_penalty:' 'Warning: Using 100000.000000 for the penalty coefficient because a float ' 'coefficient exists in constraints. \nThe value could be too small. If so, ' 'set the penalty coefficient manually.' ) self.assertIn(warning, log.output)
def test_printable_name(self): """Test non-printable names""" name = "\n" with self.assertWarns(UserWarning): _ = QuadraticProgram(name) q_p = QuadraticProgram() with self.assertWarns(UserWarning): q_p.binary_var(name + "bin") with self.assertWarns(UserWarning): q_p.binary_var_list(10, name) with self.assertWarns(UserWarning): q_p.binary_var_dict(10, name) with self.assertWarns(UserWarning): q_p.integer_var(0, 1, name + "int") with self.assertWarns(UserWarning): q_p.integer_var_list(10, 0, 1, name) with self.assertWarns(UserWarning): q_p.integer_var_dict(10, 0, 1, name) with self.assertWarns(UserWarning): q_p.continuous_var(0, 1, name + "cont") with self.assertWarns(UserWarning): q_p.continuous_var_list(10, 0, 1, name) with self.assertWarns(UserWarning): q_p.continuous_var_dict(10, 0, 1, name) with self.assertWarns(UserWarning): q_p.linear_constraint(name=name) with self.assertWarns(UserWarning): q_p.quadratic_constraint(name=name)
def test_feasibility(self): """Tests feasibility methods.""" q_p = QuadraticProgram("test") _ = q_p.continuous_var(-1, 1, "x") _ = q_p.continuous_var(-10, 10, "y") q_p.minimize(linear={"x": 1, "y": 1}) q_p.linear_constraint({"x": 1, "y": 1}, "<=", 10, "c0") q_p.linear_constraint({"x": 1, "y": 1}, ">=", -10, "c1") q_p.linear_constraint({"x": 1, "y": 1}, "==", 5, "c2") q_p.quadratic_constraint({"y": 1}, {("x", "x"): 1}, "<=", 10, "c3") q_p.quadratic_constraint({"y": 1}, {("x", "x"): 1}, ">=", 5, "c4") q_p.quadratic_constraint(None, { ("x", "x"): 1, ("y", "y"): 1 }, "==", 25, "c5") self.assertTrue(q_p.is_feasible([0, 5])) self.assertFalse(q_p.is_feasible([1, 10])) self.assertFalse(q_p.is_feasible([1, -12])) self.assertFalse(q_p.is_feasible([1, 5])) self.assertFalse(q_p.is_feasible([5, 0])) self.assertFalse(q_p.is_feasible([1, 1])) self.assertFalse(q_p.is_feasible([0, 0])) feasible, variables, constraints = q_p.get_feasibility_info([10, 0]) self.assertFalse(feasible) self.assertIsNotNone(variables) self.assertEqual(1, len(variables)) self.assertEqual("x", variables[0].name) self.assertIsNotNone(constraints) self.assertEqual(3, len(constraints)) self.assertEqual("c2", constraints[0].name) self.assertEqual("c3", constraints[1].name) self.assertEqual("c5", constraints[2].name)
def test_str_repr(self): """Test str and repr""" q_p = QuadraticProgram("my problem") q_p.binary_var("x") q_p.integer_var(-1, 5, "y") q_p.continuous_var(-1, 5, "z") q_p.minimize(1, {"x": 1, "y": -1, "z": 10}, {("x", "x"): 0.5, ("y", "z"): -1}) q_p.linear_constraint({"x": 1, "y": 2}, "==", 1, "lin_eq") q_p.linear_constraint({"x": 1, "y": 2}, "<=", 1, "lin_leq") q_p.linear_constraint({"x": 1, "y": 2}, ">=", 1, "lin_geq") q_p.quadratic_constraint( {"x": 1, "y": 1}, {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2}, "==", 1, "quad_eq", ) q_p.quadratic_constraint( {"x": 1, "y": 1}, {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2}, "<=", 1, "quad_leq", ) q_p.quadratic_constraint( {"x": 1, "y": 1}, {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2}, ">=", 1, "quad_geq", ) self.assertEqual( str(q_p), "minimize 0.5*x^2 - y*z + x - y + 10*z + 1 (3 variables, 6 constraints, 'my problem')", ) self.assertEqual( repr(q_p), "<QuadraticProgram: minimize 0.5*x^2 - y*z + x - y + 10*z + 1, " "3 variables, 6 constraints, 'my problem'>", )
def test_clear(self): """ test clear """ q_p = QuadraticProgram('test') q_p.binary_var('x') q_p.binary_var('y') q_p.minimize(constant=1, linear={ 'x': 1, 'y': 2 }, quadratic={('x', 'x'): 1}) q_p.linear_constraint({'x': 1}, '==', 1) q_p.quadratic_constraint({'x': 1}, {('y', 'y'): 2}, '<=', 1) q_p.clear() self.assertEqual(q_p.name, '') self.assertEqual(q_p.status, QuadraticProgram.Status.VALID) self.assertEqual(q_p.get_num_vars(), 0) self.assertEqual(q_p.get_num_linear_constraints(), 0) self.assertEqual(q_p.get_num_quadratic_constraints(), 0) self.assertEqual(q_p.objective.constant, 0) self.assertDictEqual(q_p.objective.linear.to_dict(), {}) self.assertDictEqual(q_p.objective.quadratic.to_dict(), {})
def test_0var_range_inequality(self): """Test InequalityToEquality converter when the var_rang of the slack variable is 0""" op = QuadraticProgram() op.binary_var("x") op.binary_var("y") op.linear_constraint(linear={ "x": 1, "y": 1 }, sense="LE", rhs=0, name="xy_leq1") op.linear_constraint(linear={ "x": 1, "y": 1 }, sense="GE", rhs=2, name="xy_geq1") op.quadratic_constraint(quadratic={("x", "x"): 1}, sense="LE", rhs=0, name="xy_leq2") op.quadratic_constraint(quadratic={("x", "y"): 1}, sense="GE", rhs=1, name="xy_geq2") ineq2eq = InequalityToEquality() new_op = ineq2eq.convert(op) self.assertEqual(new_op.get_num_vars(), 2) self.assertTrue( all(l_const.sense == Constraint.Sense.EQ for l_const in new_op.linear_constraints)) self.assertTrue( all(q_const.sense == Constraint.Sense.EQ for q_const in new_op.quadratic_constraints))
def test_auto_penalty_warning(self): """Test warnings of auto penalty function""" op = QuadraticProgram() op.binary_var("x") op.binary_var("y") op.binary_var("z") op.minimize(linear={"x": 1, "y": 2}) op.linear_constraint(linear={ "x": 0.5, "y": 0.5, "z": 0.5 }, sense="EQ", rhs=1, name="xyz") with self.assertLogs("qiskit_optimization", level="WARNING") as log: lineq2penalty = LinearEqualityToPenalty() _ = lineq2penalty.convert(op) warning = ( "WARNING:qiskit_optimization.converters.linear_equality_to_penalty:" "Warning: Using 100000.000000 for the penalty coefficient because a float " "coefficient exists in constraints. \nThe value could be too small. If so, " "set the penalty coefficient manually.") self.assertIn(warning, log.output)
def test_penalize_sense(self): """Test PenalizeLinearEqualityConstraints with senses""" op = QuadraticProgram() for i in range(3): op.binary_var(name="x{}".format(i)) # Linear constraints linear_constraint = {"x0": 1, "x1": 1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, "x0x1") linear_constraint = {"x1": 1, "x2": -1} op.linear_constraint(linear_constraint, Constraint.Sense.LE, 2, "x1x2") linear_constraint = {"x0": 1, "x2": 3} op.linear_constraint(linear_constraint, Constraint.Sense.GE, 2, "x0x2") self.assertEqual(op.get_num_linear_constraints(), 3) conv = LinearEqualityToPenalty() with self.assertRaises(QiskitOptimizationError): conv.convert(op)
def test_inequality_mode_auto(self): """ Test auto mode of InequalityToEqualityConverter() """ op = QuadraticProgram() for i in range(3): op.binary_var(name='x{}'.format(i)) # Linear constraints linear_constraint = {'x0': 1, 'x1': 1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, 'x0x1') linear_constraint = {'x1': 1, 'x2': -1} op.linear_constraint(linear_constraint, Constraint.Sense.LE, 2, 'x1x2') linear_constraint = {'x0': 1.1, 'x2': 2.2} op.linear_constraint(linear_constraint, Constraint.Sense.GE, 3.3, 'x0x2') conv = InequalityToEquality(mode='auto') op2 = conv.convert(op) lst = [op2.variables[3].vartype, op2.variables[4].vartype] self.assertListEqual(lst, [Variable.Type.INTEGER, Variable.Type.CONTINUOUS])
def test_inequality_mode_continuous(self): """Test continuous mode of InequalityToEqualityConverter()""" op = QuadraticProgram() for i in range(3): op.binary_var(name="x{}".format(i)) # Linear constraints linear_constraint = {"x0": 1, "x1": 1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, "x0x1") linear_constraint = {"x1": 1, "x2": -1} op.linear_constraint(linear_constraint, Constraint.Sense.LE, 2, "x1x2") linear_constraint = {"x0": 1, "x2": 3} op.linear_constraint(linear_constraint, Constraint.Sense.GE, 2, "x0x2") conv = InequalityToEquality(mode="continuous") op2 = conv.convert(op) lst = [op2.variables[3].vartype, op2.variables[4].vartype] self.assertListEqual( lst, [Variable.Type.CONTINUOUS, Variable.Type.CONTINUOUS])
def test_inequality_mode_integer(self): """Test integer mode of InequalityToEqualityConverter()""" op = QuadraticProgram() for i in range(3): op.binary_var(name=f"x{i}") # Linear constraints linear_constraint = {"x0": 1, "x1": 1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, "x0x1") linear_constraint = {"x1": 1, "x2": -1} op.linear_constraint(linear_constraint, Constraint.Sense.LE, 2, "x1x2") linear_constraint = {"x0": 1, "x2": 3} op.linear_constraint(linear_constraint, Constraint.Sense.GE, 2, "x0x2") conv = InequalityToEquality(mode="integer") op2 = conv.convert(op) lst = [op2.variables[3].vartype, op2.variables[4].vartype] self.assertListEqual(lst, [Variable.Type.INTEGER, Variable.Type.INTEGER])
def test_penalize_binary(self): """Test PenalizeLinearEqualityConstraints with binary variables""" op = QuadraticProgram() for i in range(3): op.binary_var(name="x{}".format(i)) # Linear constraints linear_constraint = {"x0": 1, "x1": 1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, "x0x1") linear_constraint = {"x1": 1, "x2": -1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 2, "x1x2") linear_constraint = {"x0": 1, "x2": 3} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 2, "x0x2") self.assertEqual(op.get_num_linear_constraints(), 3) conv = LinearEqualityToPenalty() op2 = conv.convert(op) self.assertEqual(op2.get_num_linear_constraints(), 0) new_x = conv.interpret(np.arange(3)) np.testing.assert_array_almost_equal(new_x, np.arange(3))
def test_penalize_integer(self): """Test PenalizeLinearEqualityConstraints with integer variables""" op = QuadraticProgram() for i in range(3): op.integer_var(name="x{}".format(i), lowerbound=-3, upperbound=3) # Linear constraints linear_constraint = {"x0": 1, "x1": 1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, "x0x1") linear_constraint = {"x1": 1, "x2": -1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 2, "x1x2") linear_constraint = {"x0": 1, "x2": -1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, "x0x2") op.minimize(constant=3, linear={"x0": 1}, quadratic={("x1", "x2"): 2}) self.assertEqual(op.get_num_linear_constraints(), 3) conv = LinearEqualityToPenalty() op2 = conv.convert(op) self.assertEqual(op2.get_num_linear_constraints(), 0) new_x = conv.interpret([0, 1, -1]) np.testing.assert_array_almost_equal(new_x, [0, 1, -1])
def test_linear_inequality_to_penalty8(self): """Test combinations of inequality constraints""" with self.subTest("minimize 1"): op = QuadraticProgram() op.binary_var("x") op.binary_var("y") op.binary_var("z") op.integer_var(-1, 4, "q") op.minimize(linear={ "x": 1, "y": 1, "z": 1 }, quadratic={("q", "q"): -1}) op.linear_constraint({"x": 1, "y": -1}, "<=", 0) op.linear_constraint({"x": 1, "y": 1, "z": 1}, "<=", 1) op2 = LinearInequalityToPenalty().convert(op) self.assertEqual(op2.get_num_vars(), 4) self.assertEqual(op2.get_num_binary_vars(), 3) self.assertEqual(op2.get_num_integer_vars(), 1) self.assertEqual(op2.get_num_continuous_vars(), 0) self.assertEqual(op2.get_num_linear_constraints(), 0) self.assertEqual(op2.get_num_quadratic_constraints(), 0) obj = op2.objective self.assertEqual(obj.constant, 0) self.assertDictEqual(obj.linear.to_dict(use_name=True), { "x": 21, "y": 1, "z": 1 }) self.assertDictEqual( obj.quadratic.to_dict(use_name=True), { ("x", "z"): 20, ("y", "z"): 20, ("q", "q"): -1 }, ) with self.subTest("maximize 1"): op = QuadraticProgram() op.binary_var("x") op.binary_var("y") op.binary_var("z") op.integer_var(-1, 4, "q") op.maximize(linear={ "x": 1, "y": 1, "z": 1 }, quadratic={("q", "q"): -1}) op.linear_constraint({"x": 1, "y": -1}, "<=", 0) op.linear_constraint({"x": 1, "y": 1, "z": 1}, "<=", 1) op2 = LinearInequalityToPenalty().convert(op) self.assertEqual(op2.get_num_vars(), 4) self.assertEqual(op2.get_num_binary_vars(), 3) self.assertEqual(op2.get_num_integer_vars(), 1) self.assertEqual(op2.get_num_continuous_vars(), 0) self.assertEqual(op2.get_num_linear_constraints(), 0) self.assertEqual(op2.get_num_quadratic_constraints(), 0) obj = op2.objective self.assertEqual(obj.constant, 0) self.assertDictEqual(obj.linear.to_dict(use_name=True), { "x": -19, "y": 1, "z": 1 }) self.assertDictEqual( obj.quadratic.to_dict(use_name=True), { ("x", "z"): -20, ("y", "z"): -20, ("q", "q"): -1 }, ) with self.subTest("minimize 2"): op = QuadraticProgram() op.binary_var("x") op.binary_var("y") op.binary_var("z") op.integer_var(-1, 4, "q") op.minimize(linear={ "x": 1, "y": 1, "z": 1 }, quadratic={("q", "q"): -1}) op.linear_constraint({"x": 1, "y": -1}, ">=", 0) op.linear_constraint({"x": 1, "y": 1, "z": 1}, ">=", 2) op2 = LinearInequalityToPenalty().convert(op) self.assertEqual(op2.get_num_vars(), 4) self.assertEqual(op2.get_num_binary_vars(), 3) self.assertEqual(op2.get_num_integer_vars(), 1) self.assertEqual(op2.get_num_continuous_vars(), 0) self.assertEqual(op2.get_num_linear_constraints(), 0) self.assertEqual(op2.get_num_quadratic_constraints(), 0) obj = op2.objective self.assertEqual(obj.constant, 60) self.assertDictEqual(obj.linear.to_dict(use_name=True), { "x": -39, "y": -19, "z": -39 }) self.assertDictEqual( obj.quadratic.to_dict(use_name=True), { ("x", "z"): 20, ("y", "z"): 20, ("q", "q"): -1 }, ) with self.subTest("maximize 2"): op = QuadraticProgram() op.binary_var("x") op.binary_var("y") op.binary_var("z") op.integer_var(-1, 4, "q") op.maximize(linear={ "x": 1, "y": 1, "z": 1 }, quadratic={("q", "q"): -1}) op.linear_constraint({"x": 1, "y": -1}, ">=", 0) op.linear_constraint({"x": 1, "y": 1, "z": 1}, ">=", 2) op2 = LinearInequalityToPenalty().convert(op) self.assertEqual(op2.get_num_vars(), 4) self.assertEqual(op2.get_num_binary_vars(), 3) self.assertEqual(op2.get_num_integer_vars(), 1) self.assertEqual(op2.get_num_continuous_vars(), 0) self.assertEqual(op2.get_num_linear_constraints(), 0) self.assertEqual(op2.get_num_quadratic_constraints(), 0) obj = op2.objective self.assertEqual(obj.constant, -60) self.assertDictEqual(obj.linear.to_dict(use_name=True), { "x": 41, "y": 21, "z": 41 }) self.assertDictEqual( obj.quadratic.to_dict(use_name=True), { ("x", "z"): -20, ("y", "z"): -20, ("q", "q"): -1 }, )