def test_ising_to_quadraticprogram_quadratic(self): """Test optimization problem to operators with linear=False""" op = QUBIT_OP_MAXIMIZE_SAMPLE offset = OFFSET_MAXIMIZE_SAMPLE quadratic = QuadraticProgram() quadratic.from_ising(op, offset, linear=False) self.assertEqual(quadratic.get_num_vars(), 4) self.assertEqual(quadratic.get_num_linear_constraints(), 0) self.assertEqual(quadratic.get_num_quadratic_constraints(), 0) self.assertEqual(quadratic.objective.sense, quadratic.objective.Sense.MINIMIZE) self.assertAlmostEqual(quadratic.objective.constant, 900000) quadratic_matrix = np.zeros((4, 4)) quadratic_matrix[0, 0] = -500001 quadratic_matrix[0, 1] = 400000 quadratic_matrix[0, 2] = 600000 quadratic_matrix[0, 3] = 800000 quadratic_matrix[1, 1] = -800001 quadratic_matrix[1, 2] = 1200000 quadratic_matrix[1, 3] = 1600000 quadratic_matrix[2, 2] = -900001 quadratic_matrix[2, 3] = 2400000 quadratic_matrix[3, 3] = -800001 np.testing.assert_array_almost_equal( quadratic.objective.quadratic.coefficients.toarray(), quadratic_matrix)
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_constructor(self): """test constructor""" quadratic_program = QuadraticProgram() self.assertEqual(quadratic_program.name, "") self.assertEqual(quadratic_program.status, QuadraticProgram.Status.VALID) self.assertEqual(quadratic_program.get_num_vars(), 0) self.assertEqual(quadratic_program.get_num_linear_constraints(), 0) self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 0) self.assertEqual(quadratic_program.objective.constant, 0) self.assertDictEqual(quadratic_program.objective.linear.to_dict(), {}) self.assertDictEqual(quadratic_program.objective.quadratic.to_dict(), {})
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_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_integer_to_binary_quadratic(self): """Test integer to binary variables with quadratic expressions""" mod = QuadraticProgram() mod.integer_var(name="x", lowerbound=10, upperbound=13) mod.minimize(quadratic={("x", "x"): 1}) mod2 = IntegerToBinary().convert(mod) self.assertListEqual([e.name for e in mod2.variables], ["x@0", "x@1"]) self.assertEqual(mod.get_num_linear_constraints(), 0) self.assertEqual(mod.get_num_quadratic_constraints(), 0) self.assertAlmostEqual(mod2.objective.constant, 100) self.assertDictEqual(mod2.objective.linear.to_dict(use_name=True), { "x@0": 20, "x@1": 40 }) self.assertDictEqual( mod2.objective.quadratic.to_dict(use_name=True), { ("x@0", "x@0"): 1, ("x@1", "x@1"): 4, ("x@0", "x@1"): 4 }, )
def test_init(self): """test init.""" quadratic_program = QuadraticProgram() for _ in range(5): quadratic_program.continuous_var() self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 0) linear_coeffs = np.array(range(5)) lst = [[0 for _ in range(5)] for _ in range(5)] for i, v in enumerate(lst): for j, _ in enumerate(v): lst[min(i, j)][max(i, j)] += i * j quadratic_coeffs = np.array(lst) # equality constraints quadratic_program.quadratic_constraint(sense="==") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 1) self.assertEqual(quadratic_program.quadratic_constraints[0].name, "q0") self.assertEqual(len(quadratic_program.quadratic_constraints[0].linear.to_dict()), 0) self.assertEqual(len(quadratic_program.quadratic_constraints[0].quadratic.to_dict()), 0) self.assertEqual(quadratic_program.quadratic_constraints[0].sense, Constraint.Sense.EQ) self.assertEqual(quadratic_program.quadratic_constraints[0].rhs, 0.0) self.assertEqual( quadratic_program.quadratic_constraints[0], quadratic_program.get_quadratic_constraint("q0"), ) self.assertEqual( quadratic_program.quadratic_constraints[0], quadratic_program.get_quadratic_constraint(0), ) self.assertEqual(quadratic_program.quadratic_constraints[0].evaluate(linear_coeffs), 0.0) with self.assertRaises(QiskitOptimizationError): quadratic_program.quadratic_constraint(name="q0", sense="==") quadratic_program.quadratic_constraint(linear_coeffs, quadratic_coeffs, "==", 1.0, "q1") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 2) self.assertEqual(quadratic_program.quadratic_constraints[1].name, "q1") self.assertTrue( (quadratic_program.quadratic_constraints[1].linear.to_array() == linear_coeffs).all() ) self.assertTrue( ( quadratic_program.quadratic_constraints[1].quadratic.to_array() == quadratic_coeffs ).all() ) self.assertEqual(quadratic_program.quadratic_constraints[1].sense, Constraint.Sense.EQ) self.assertEqual(quadratic_program.quadratic_constraints[1].rhs, 1.0) self.assertEqual( quadratic_program.quadratic_constraints[1], quadratic_program.get_quadratic_constraint("q1"), ) self.assertEqual( quadratic_program.quadratic_constraints[1], quadratic_program.get_quadratic_constraint(1), ) self.assertEqual(quadratic_program.quadratic_constraints[1].evaluate(linear_coeffs), 930.0) # geq constraints quadratic_program.quadratic_constraint(sense=">=") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 3) self.assertEqual(quadratic_program.quadratic_constraints[2].name, "q2") self.assertEqual(len(quadratic_program.quadratic_constraints[2].linear.to_dict()), 0) self.assertEqual(len(quadratic_program.quadratic_constraints[2].quadratic.to_dict()), 0) self.assertEqual(quadratic_program.quadratic_constraints[2].sense, Constraint.Sense.GE) self.assertEqual(quadratic_program.quadratic_constraints[2].rhs, 0.0) self.assertEqual( quadratic_program.quadratic_constraints[2], quadratic_program.get_quadratic_constraint("q2"), ) self.assertEqual( quadratic_program.quadratic_constraints[2], quadratic_program.get_quadratic_constraint(2), ) self.assertEqual(quadratic_program.quadratic_constraints[2].evaluate(linear_coeffs), 0.0) with self.assertRaises(QiskitOptimizationError): quadratic_program.quadratic_constraint(name="q2", sense=">=") quadratic_program.quadratic_constraint(linear_coeffs, quadratic_coeffs, ">=", 1.0, "q3") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 4) self.assertEqual(quadratic_program.quadratic_constraints[3].name, "q3") self.assertTrue( (quadratic_program.quadratic_constraints[3].linear.to_array() == linear_coeffs).all() ) self.assertTrue( ( quadratic_program.quadratic_constraints[3].quadratic.to_array() == quadratic_coeffs ).all() ) self.assertEqual(quadratic_program.quadratic_constraints[3].sense, Constraint.Sense.GE) self.assertEqual(quadratic_program.quadratic_constraints[3].rhs, 1.0) self.assertEqual( quadratic_program.quadratic_constraints[3], quadratic_program.get_quadratic_constraint("q3"), ) self.assertEqual( quadratic_program.quadratic_constraints[3], quadratic_program.get_quadratic_constraint(3), ) self.assertEqual(quadratic_program.quadratic_constraints[3].evaluate(linear_coeffs), 930.0) # leq constraints quadratic_program.quadratic_constraint(sense="<=") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 5) self.assertEqual(quadratic_program.quadratic_constraints[4].name, "q4") self.assertEqual(len(quadratic_program.quadratic_constraints[4].linear.to_dict()), 0) self.assertEqual(quadratic_program.quadratic_constraints[4].sense, Constraint.Sense.LE) self.assertEqual(quadratic_program.quadratic_constraints[4].rhs, 0.0) self.assertEqual( quadratic_program.quadratic_constraints[4], quadratic_program.get_quadratic_constraint("q4"), ) self.assertEqual( quadratic_program.quadratic_constraints[4], quadratic_program.get_quadratic_constraint(4), ) self.assertEqual(quadratic_program.quadratic_constraints[4].evaluate(linear_coeffs), 0.0) with self.assertRaises(QiskitOptimizationError): quadratic_program.quadratic_constraint(name="q4", sense="<=") quadratic_program.quadratic_constraint(linear_coeffs, quadratic_coeffs, "<=", 1.0, "q5") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 6) self.assertEqual(quadratic_program.quadratic_constraints[5].name, "q5") self.assertTrue( (quadratic_program.quadratic_constraints[5].linear.to_array() == linear_coeffs).all() ) self.assertTrue( ( quadratic_program.quadratic_constraints[5].quadratic.to_array() == quadratic_coeffs ).all() ) self.assertEqual(quadratic_program.quadratic_constraints[5].sense, Constraint.Sense.LE) self.assertEqual(quadratic_program.quadratic_constraints[5].rhs, 1.0) self.assertEqual( quadratic_program.quadratic_constraints[5], quadratic_program.get_quadratic_constraint("q5"), ) self.assertEqual( quadratic_program.quadratic_constraints[5], quadratic_program.get_quadratic_constraint(5), ) self.assertEqual(quadratic_program.quadratic_constraints[5].evaluate(linear_coeffs), 930.0)
def test_read_from_lp_file(self): """test read lp file""" try: q_p = QuadraticProgram() with self.assertRaises(FileNotFoundError): q_p.read_from_lp_file('') with self.assertRaises(FileNotFoundError): q_p.read_from_lp_file('no_file.txt') lp_file = self.get_resource_path( path.join('resources', 'test_quadratic_program.lp')) q_p.read_from_lp_file(lp_file) self.assertEqual(q_p.name, 'my problem') self.assertEqual(q_p.get_num_vars(), 3) self.assertEqual(q_p.get_num_binary_vars(), 1) self.assertEqual(q_p.get_num_integer_vars(), 1) self.assertEqual(q_p.get_num_continuous_vars(), 1) self.assertEqual(q_p.get_num_linear_constraints(), 3) self.assertEqual(q_p.get_num_quadratic_constraints(), 3) self.assertEqual(q_p.variables[0].name, 'x') self.assertEqual(q_p.variables[0].vartype, Variable.Type.BINARY) self.assertEqual(q_p.variables[0].lowerbound, 0) self.assertEqual(q_p.variables[0].upperbound, 1) self.assertEqual(q_p.variables[1].name, 'y') self.assertEqual(q_p.variables[1].vartype, Variable.Type.INTEGER) self.assertEqual(q_p.variables[1].lowerbound, -1) self.assertEqual(q_p.variables[1].upperbound, 5) self.assertEqual(q_p.variables[2].name, 'z') self.assertEqual(q_p.variables[2].vartype, Variable.Type.CONTINUOUS) self.assertEqual(q_p.variables[2].lowerbound, -1) self.assertEqual(q_p.variables[2].upperbound, 5) self.assertEqual(q_p.objective.sense, QuadraticObjective.Sense.MINIMIZE) self.assertEqual(q_p.objective.constant, 1) self.assertDictEqual(q_p.objective.linear.to_dict(use_name=True), { 'x': 1, 'y': -1, 'z': 10 }) self.assertDictEqual( q_p.objective.quadratic.to_dict(use_name=True), { ('x', 'x'): 0.5, ('y', 'z'): -1 }) cst = q_p.linear_constraints self.assertEqual(cst[0].name, 'lin_eq') self.assertDictEqual(cst[0].linear.to_dict(use_name=True), { 'x': 1, 'y': 2 }) self.assertEqual(cst[0].sense, Constraint.Sense.EQ) self.assertEqual(cst[0].rhs, 1) self.assertEqual(cst[1].name, 'lin_leq') self.assertDictEqual(cst[1].linear.to_dict(use_name=True), { 'x': 1, 'y': 2 }) self.assertEqual(cst[1].sense, Constraint.Sense.LE) self.assertEqual(cst[1].rhs, 1) self.assertEqual(cst[2].name, 'lin_geq') self.assertDictEqual(cst[2].linear.to_dict(use_name=True), { 'x': 1, 'y': 2 }) self.assertEqual(cst[2].sense, Constraint.Sense.GE) self.assertEqual(cst[2].rhs, 1) cst = q_p.quadratic_constraints self.assertEqual(cst[0].name, 'quad_eq') self.assertDictEqual(cst[0].linear.to_dict(use_name=True), { 'x': 1, 'y': 1 }) self.assertDictEqual(cst[0].quadratic.to_dict(use_name=True), { ('x', 'x'): 1, ('y', 'z'): -1, ('z', 'z'): 2 }) self.assertEqual(cst[0].sense, Constraint.Sense.EQ) self.assertEqual(cst[0].rhs, 1) self.assertEqual(cst[1].name, 'quad_leq') self.assertDictEqual(cst[1].linear.to_dict(use_name=True), { 'x': 1, 'y': 1 }) self.assertDictEqual(cst[1].quadratic.to_dict(use_name=True), { ('x', 'x'): 1, ('y', 'z'): -1, ('z', 'z'): 2 }) self.assertEqual(cst[1].sense, Constraint.Sense.LE) self.assertEqual(cst[1].rhs, 1) self.assertEqual(cst[2].name, 'quad_geq') self.assertDictEqual(cst[2].linear.to_dict(use_name=True), { 'x': 1, 'y': 1 }) self.assertDictEqual(cst[2].quadratic.to_dict(use_name=True), { ('x', 'x'): 1, ('y', 'z'): -1, ('z', 'z'): 2 }) self.assertEqual(cst[2].sense, Constraint.Sense.GE) self.assertEqual(cst[2].rhs, 1) except MissingOptionalLibraryError as ex: self.skipTest(str(ex)) except RuntimeError as ex: self.fail(str(ex))
def test_quadratic_constraints_handling(self): """test quadratic constraints handling""" q_p = QuadraticProgram() q_p.binary_var('x') q_p.binary_var('y') q_p.binary_var('z') q_p.quadratic_constraint({'x': 1}, {('x', 'y'): 1}, '==', 1) q_p.quadratic_constraint({'y': 1}, {('y', 'z'): 1}, '<=', 1) q_p.quadratic_constraint({'z': 1}, {('z', 'x'): 1}, '>=', 1) self.assertEqual(q_p.get_num_quadratic_constraints(), 3) quad = q_p.quadratic_constraints self.assertEqual(len(quad), 3) self.assertDictEqual(quad[0].linear.to_dict(), {0: 1}) self.assertDictEqual(quad[0].linear.to_dict(use_name=True), {'x': 1}) self.assertListEqual(quad[0].linear.to_array().tolist(), [1, 0, 0]) self.assertDictEqual(quad[0].quadratic.to_dict(), {(0, 1): 1}) self.assertDictEqual(quad[0].quadratic.to_dict(symmetric=True), { (0, 1): 0.5, (1, 0): 0.5 }) self.assertDictEqual(quad[0].quadratic.to_dict(use_name=True), {('x', 'y'): 1}) self.assertDictEqual( quad[0].quadratic.to_dict(use_name=True, symmetric=True), { ('x', 'y'): 0.5, ('y', 'x'): 0.5 }) self.assertListEqual(quad[0].quadratic.to_array().tolist(), [[0, 1, 0], [0, 0, 0], [0, 0, 0]]) self.assertListEqual( quad[0].quadratic.to_array(symmetric=True).tolist(), [[0, 0.5, 0], [0.5, 0, 0], [0, 0, 0]]) self.assertEqual(quad[0].sense, Constraint.Sense.EQ) self.assertEqual(quad[0].rhs, 1) self.assertEqual(quad[0].name, 'q0') self.assertEqual(q_p.get_quadratic_constraint(0).name, 'q0') self.assertEqual(q_p.get_quadratic_constraint('q0').name, 'q0') self.assertDictEqual(quad[1].linear.to_dict(), {1: 1}) self.assertDictEqual(quad[1].linear.to_dict(use_name=True), {'y': 1}) self.assertListEqual(quad[1].linear.to_array().tolist(), [0, 1, 0]) self.assertDictEqual(quad[1].quadratic.to_dict(), {(1, 2): 1}) self.assertDictEqual(quad[1].quadratic.to_dict(symmetric=True), { (1, 2): 0.5, (2, 1): 0.5 }) self.assertDictEqual(quad[1].quadratic.to_dict(use_name=True), {('y', 'z'): 1}) self.assertDictEqual( quad[1].quadratic.to_dict(use_name=True, symmetric=True), { ('y', 'z'): 0.5, ('z', 'y'): 0.5 }) self.assertListEqual(quad[1].quadratic.to_array().tolist(), [[0, 0, 0], [0, 0, 1], [0, 0, 0]]) self.assertListEqual( quad[1].quadratic.to_array(symmetric=True).tolist(), [[0, 0, 0], [0, 0, 0.5], [0, 0.5, 0]]) self.assertEqual(quad[1].sense, Constraint.Sense.LE) self.assertEqual(quad[1].rhs, 1) self.assertEqual(quad[1].name, 'q1') self.assertEqual(q_p.get_quadratic_constraint(1).name, 'q1') self.assertEqual(q_p.get_quadratic_constraint('q1').name, 'q1') self.assertDictEqual(quad[2].linear.to_dict(), {2: 1}) self.assertDictEqual(quad[2].linear.to_dict(use_name=True), {'z': 1}) self.assertListEqual(quad[2].linear.to_array().tolist(), [0, 0, 1]) self.assertDictEqual(quad[2].quadratic.to_dict(), {(0, 2): 1}) self.assertDictEqual(quad[2].quadratic.to_dict(symmetric=True), { (0, 2): 0.5, (2, 0): 0.5 }) self.assertDictEqual(quad[2].quadratic.to_dict(use_name=True), {('x', 'z'): 1}) self.assertDictEqual( quad[2].quadratic.to_dict(use_name=True, symmetric=True), { ('x', 'z'): 0.5, ('z', 'x'): 0.5 }) self.assertListEqual(quad[2].quadratic.to_array().tolist(), [[0, 0, 1], [0, 0, 0], [0, 0, 0]]) self.assertListEqual( quad[2].quadratic.to_array(symmetric=True).tolist(), [[0, 0, 0.5], [0, 0, 0], [0.5, 0, 0]]) self.assertEqual(quad[2].sense, Constraint.Sense.GE) self.assertEqual(quad[2].rhs, 1) self.assertEqual(quad[2].name, 'q2') self.assertEqual(q_p.get_quadratic_constraint(2).name, 'q2') self.assertEqual(q_p.get_quadratic_constraint('q2').name, 'q2') with self.assertRaises(QiskitOptimizationError): q_p.quadratic_constraint(name='q0') with self.assertRaises(QiskitOptimizationError): q_p.quadratic_constraint(name='q1') with self.assertRaises(QiskitOptimizationError): q_p.quadratic_constraint(name='q2') with self.assertRaises(IndexError): q_p.get_quadratic_constraint(4) with self.assertRaises(KeyError): q_p.get_quadratic_constraint('q3') q_p.remove_quadratic_constraint('q1') quad = q_p.quadratic_constraints self.assertEqual(len(quad), 2) self.assertDictEqual(quad[1].linear.to_dict(), {2: 1}) self.assertDictEqual(quad[1].linear.to_dict(use_name=True), {'z': 1}) self.assertListEqual(quad[1].linear.to_array().tolist(), [0, 0, 1]) self.assertDictEqual(quad[1].quadratic.to_dict(), {(0, 2): 1}) self.assertDictEqual(quad[1].quadratic.to_dict(symmetric=True), { (0, 2): 0.5, (2, 0): 0.5 }) self.assertDictEqual(quad[1].quadratic.to_dict(use_name=True), {('x', 'z'): 1}) self.assertDictEqual( quad[1].quadratic.to_dict(use_name=True, symmetric=True), { ('x', 'z'): 0.5, ('z', 'x'): 0.5 }) self.assertListEqual(quad[1].quadratic.to_array().tolist(), [[0, 0, 1], [0, 0, 0], [0, 0, 0]]) self.assertListEqual( quad[1].quadratic.to_array(symmetric=True).tolist(), [[0, 0, 0.5], [0, 0, 0], [0.5, 0, 0]]) self.assertEqual(quad[1].sense, Constraint.Sense.GE) self.assertEqual(quad[1].rhs, 1) self.assertEqual(quad[1].name, 'q2') self.assertEqual(q_p.get_quadratic_constraint(1).name, 'q2') self.assertEqual(q_p.get_quadratic_constraint('q2').name, 'q2') with self.assertRaises(KeyError): q_p.remove_quadratic_constraint('q1') with self.assertRaises(IndexError): q_p.remove_quadratic_constraint(9)
def test_read_from_lp_file(self): """test read lp file""" try: q_p = QuadraticProgram() with self.assertRaises(FileNotFoundError): q_p.read_from_lp_file("") with self.assertRaises(FileNotFoundError): q_p.read_from_lp_file("no_file.txt") lp_file = self.get_resource_path("test_quadratic_program.lp", "problems/resources") q_p.read_from_lp_file(lp_file) self.assertEqual(q_p.name, "my problem") self.assertEqual(q_p.get_num_vars(), 3) self.assertEqual(q_p.get_num_binary_vars(), 1) self.assertEqual(q_p.get_num_integer_vars(), 1) self.assertEqual(q_p.get_num_continuous_vars(), 1) self.assertEqual(q_p.get_num_linear_constraints(), 3) self.assertEqual(q_p.get_num_quadratic_constraints(), 3) self.assertEqual(q_p.variables[0].name, "x") self.assertEqual(q_p.variables[0].vartype, Variable.Type.BINARY) self.assertEqual(q_p.variables[0].lowerbound, 0) self.assertEqual(q_p.variables[0].upperbound, 1) self.assertEqual(q_p.variables[1].name, "y") self.assertEqual(q_p.variables[1].vartype, Variable.Type.INTEGER) self.assertEqual(q_p.variables[1].lowerbound, -1) self.assertEqual(q_p.variables[1].upperbound, 5) self.assertEqual(q_p.variables[2].name, "z") self.assertEqual(q_p.variables[2].vartype, Variable.Type.CONTINUOUS) self.assertEqual(q_p.variables[2].lowerbound, -1) self.assertEqual(q_p.variables[2].upperbound, 5) self.assertEqual(q_p.objective.sense, QuadraticObjective.Sense.MINIMIZE) self.assertEqual(q_p.objective.constant, 1) self.assertDictEqual(q_p.objective.linear.to_dict(use_name=True), { "x": 1, "y": -1, "z": 10 }) self.assertDictEqual( q_p.objective.quadratic.to_dict(use_name=True), { ("x", "x"): 0.5, ("y", "z"): -1 }, ) cst = q_p.linear_constraints self.assertEqual(cst[0].name, "lin_eq") self.assertDictEqual(cst[0].linear.to_dict(use_name=True), { "x": 1, "y": 2 }) self.assertEqual(cst[0].sense, Constraint.Sense.EQ) self.assertEqual(cst[0].rhs, 1) self.assertEqual(cst[1].name, "lin_leq") self.assertDictEqual(cst[1].linear.to_dict(use_name=True), { "x": 1, "y": 2 }) self.assertEqual(cst[1].sense, Constraint.Sense.LE) self.assertEqual(cst[1].rhs, 1) self.assertEqual(cst[2].name, "lin_geq") self.assertDictEqual(cst[2].linear.to_dict(use_name=True), { "x": 1, "y": 2 }) self.assertEqual(cst[2].sense, Constraint.Sense.GE) self.assertEqual(cst[2].rhs, 1) cst = q_p.quadratic_constraints self.assertEqual(cst[0].name, "quad_eq") self.assertDictEqual(cst[0].linear.to_dict(use_name=True), { "x": 1, "y": 1 }) self.assertDictEqual( cst[0].quadratic.to_dict(use_name=True), { ("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2 }, ) self.assertEqual(cst[0].sense, Constraint.Sense.EQ) self.assertEqual(cst[0].rhs, 1) self.assertEqual(cst[1].name, "quad_leq") self.assertDictEqual(cst[1].linear.to_dict(use_name=True), { "x": 1, "y": 1 }) self.assertDictEqual( cst[1].quadratic.to_dict(use_name=True), { ("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2 }, ) self.assertEqual(cst[1].sense, Constraint.Sense.LE) self.assertEqual(cst[1].rhs, 1) self.assertEqual(cst[2].name, "quad_geq") self.assertDictEqual(cst[2].linear.to_dict(use_name=True), { "x": 1, "y": 1 }) self.assertDictEqual( cst[2].quadratic.to_dict(use_name=True), { ("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2 }, ) self.assertEqual(cst[2].sense, Constraint.Sense.GE) self.assertEqual(cst[2].rhs, 1) except RuntimeError as ex: self.fail(str(ex))
def test_quadratic_constraints_handling(self): """test quadratic constraints handling""" q_p = QuadraticProgram() q_p.binary_var("x") q_p.binary_var("y") q_p.binary_var("z") q_p.quadratic_constraint({"x": 1}, {("x", "y"): 1}, "==", 1) q_p.quadratic_constraint({"y": 1}, {("y", "z"): 1}, "<=", 1) q_p.quadratic_constraint({"z": 1}, {("z", "x"): 1}, ">=", 1) self.assertEqual(q_p.get_num_quadratic_constraints(), 3) quad = q_p.quadratic_constraints self.assertEqual(len(quad), 3) self.assertDictEqual(quad[0].linear.to_dict(), {0: 1}) self.assertDictEqual(quad[0].linear.to_dict(use_name=True), {"x": 1}) self.assertListEqual(quad[0].linear.to_array().tolist(), [1, 0, 0]) self.assertDictEqual(quad[0].quadratic.to_dict(), {(0, 1): 1}) self.assertDictEqual(quad[0].quadratic.to_dict(symmetric=True), { (0, 1): 0.5, (1, 0): 0.5 }) self.assertDictEqual(quad[0].quadratic.to_dict(use_name=True), {("x", "y"): 1}) self.assertDictEqual( quad[0].quadratic.to_dict(use_name=True, symmetric=True), { ("x", "y"): 0.5, ("y", "x"): 0.5 }, ) self.assertListEqual(quad[0].quadratic.to_array().tolist(), [[0, 1, 0], [0, 0, 0], [0, 0, 0]]) self.assertListEqual( quad[0].quadratic.to_array(symmetric=True).tolist(), [[0, 0.5, 0], [0.5, 0, 0], [0, 0, 0]], ) self.assertEqual(quad[0].sense, Constraint.Sense.EQ) self.assertEqual(quad[0].rhs, 1) self.assertEqual(quad[0].name, "q0") self.assertEqual(q_p.get_quadratic_constraint(0).name, "q0") self.assertEqual(q_p.get_quadratic_constraint("q0").name, "q0") self.assertDictEqual(quad[1].linear.to_dict(), {1: 1}) self.assertDictEqual(quad[1].linear.to_dict(use_name=True), {"y": 1}) self.assertListEqual(quad[1].linear.to_array().tolist(), [0, 1, 0]) self.assertDictEqual(quad[1].quadratic.to_dict(), {(1, 2): 1}) self.assertDictEqual(quad[1].quadratic.to_dict(symmetric=True), { (1, 2): 0.5, (2, 1): 0.5 }) self.assertDictEqual(quad[1].quadratic.to_dict(use_name=True), {("y", "z"): 1}) self.assertDictEqual( quad[1].quadratic.to_dict(use_name=True, symmetric=True), { ("y", "z"): 0.5, ("z", "y"): 0.5 }, ) self.assertListEqual(quad[1].quadratic.to_array().tolist(), [[0, 0, 0], [0, 0, 1], [0, 0, 0]]) self.assertListEqual( quad[1].quadratic.to_array(symmetric=True).tolist(), [[0, 0, 0], [0, 0, 0.5], [0, 0.5, 0]], ) self.assertEqual(quad[1].sense, Constraint.Sense.LE) self.assertEqual(quad[1].rhs, 1) self.assertEqual(quad[1].name, "q1") self.assertEqual(q_p.get_quadratic_constraint(1).name, "q1") self.assertEqual(q_p.get_quadratic_constraint("q1").name, "q1") self.assertDictEqual(quad[2].linear.to_dict(), {2: 1}) self.assertDictEqual(quad[2].linear.to_dict(use_name=True), {"z": 1}) self.assertListEqual(quad[2].linear.to_array().tolist(), [0, 0, 1]) self.assertDictEqual(quad[2].quadratic.to_dict(), {(0, 2): 1}) self.assertDictEqual(quad[2].quadratic.to_dict(symmetric=True), { (0, 2): 0.5, (2, 0): 0.5 }) self.assertDictEqual(quad[2].quadratic.to_dict(use_name=True), {("x", "z"): 1}) self.assertDictEqual( quad[2].quadratic.to_dict(use_name=True, symmetric=True), { ("x", "z"): 0.5, ("z", "x"): 0.5 }, ) self.assertListEqual(quad[2].quadratic.to_array().tolist(), [[0, 0, 1], [0, 0, 0], [0, 0, 0]]) self.assertListEqual( quad[2].quadratic.to_array(symmetric=True).tolist(), [[0, 0, 0.5], [0, 0, 0], [0.5, 0, 0]], ) self.assertEqual(quad[2].sense, Constraint.Sense.GE) self.assertEqual(quad[2].rhs, 1) self.assertEqual(quad[2].name, "q2") self.assertEqual(q_p.get_quadratic_constraint(2).name, "q2") self.assertEqual(q_p.get_quadratic_constraint("q2").name, "q2") with self.assertRaises(QiskitOptimizationError): q_p.quadratic_constraint(name="q0") with self.assertRaises(QiskitOptimizationError): q_p.quadratic_constraint(name="q1") with self.assertRaises(QiskitOptimizationError): q_p.quadratic_constraint(name="q2") with self.assertRaises(IndexError): q_p.get_quadratic_constraint(4) with self.assertRaises(KeyError): q_p.get_quadratic_constraint("q3") q_p.remove_quadratic_constraint("q1") quad = q_p.quadratic_constraints self.assertEqual(len(quad), 2) self.assertDictEqual(quad[1].linear.to_dict(), {2: 1}) self.assertDictEqual(quad[1].linear.to_dict(use_name=True), {"z": 1}) self.assertListEqual(quad[1].linear.to_array().tolist(), [0, 0, 1]) self.assertDictEqual(quad[1].quadratic.to_dict(), {(0, 2): 1}) self.assertDictEqual(quad[1].quadratic.to_dict(symmetric=True), { (0, 2): 0.5, (2, 0): 0.5 }) self.assertDictEqual(quad[1].quadratic.to_dict(use_name=True), {("x", "z"): 1}) self.assertDictEqual( quad[1].quadratic.to_dict(use_name=True, symmetric=True), { ("x", "z"): 0.5, ("z", "x"): 0.5 }, ) self.assertListEqual(quad[1].quadratic.to_array().tolist(), [[0, 0, 1], [0, 0, 0], [0, 0, 0]]) self.assertListEqual( quad[1].quadratic.to_array(symmetric=True).tolist(), [[0, 0, 0.5], [0, 0, 0], [0.5, 0, 0]], ) self.assertEqual(quad[1].sense, Constraint.Sense.GE) self.assertEqual(quad[1].rhs, 1) self.assertEqual(quad[1].name, "q2") self.assertEqual(q_p.get_quadratic_constraint(1).name, "q2") self.assertEqual(q_p.get_quadratic_constraint("q2").name, "q2") with self.assertRaises(KeyError): q_p.remove_quadratic_constraint("q1") with self.assertRaises(IndexError): q_p.remove_quadratic_constraint(9)
def test_integer_to_binary_zero_range_variable(self): """Test integer to binary variables with zero range variables""" with self.subTest( "zero range variable in a linear expression of the objective"): mod = QuadraticProgram() mod.integer_var(name="x", lowerbound=10, upperbound=10) mod.minimize(linear={"x": 1}) mod2 = IntegerToBinary().convert(mod) self.assertListEqual([e.name for e in mod2.variables], ["x@0"]) self.assertEqual(mod.get_num_linear_constraints(), 0) self.assertEqual(mod.get_num_quadratic_constraints(), 0) self.assertAlmostEqual(mod2.objective.constant, 10) self.assertDictEqual(mod2.objective.linear.to_dict(), {}) self.assertDictEqual(mod2.objective.quadratic.to_dict(), {}) with self.subTest( "zero range variable in a quadratic expression of the objective" ): mod = QuadraticProgram() mod.integer_var(name="x", lowerbound=10, upperbound=10) mod.minimize(quadratic={("x", "x"): 1}) mod2 = IntegerToBinary().convert(mod) self.assertListEqual([e.name for e in mod2.variables], ["x@0"]) self.assertEqual(mod.get_num_linear_constraints(), 0) self.assertEqual(mod.get_num_quadratic_constraints(), 0) self.assertAlmostEqual(mod2.objective.constant, 100) self.assertDictEqual(mod2.objective.linear.to_dict(), {}) self.assertDictEqual(mod2.objective.quadratic.to_dict(), {}) with self.subTest("zero range variable in a linear constraint"): mod = QuadraticProgram() mod.integer_var(name="x", lowerbound=10, upperbound=10) mod.binary_var(name="y") mod.linear_constraint({"x": 1, "y": 1}, "<=", 100) mod2 = IntegerToBinary().convert(mod) self.assertListEqual([e.name for e in mod2.variables], ["x@0", "y"]) self.assertEqual(mod.get_num_linear_constraints(), 1) self.assertEqual(mod.get_num_quadratic_constraints(), 0) self.assertAlmostEqual(mod2.objective.constant, 0) self.assertDictEqual(mod2.objective.linear.to_dict(), {}) self.assertDictEqual(mod2.objective.quadratic.to_dict(), {}) cst = mod2.get_linear_constraint(0) self.assertDictEqual(cst.linear.to_dict(use_name=True), {"y": 1}) self.assertEqual(cst.sense, Constraint.Sense.LE) self.assertAlmostEqual(cst.rhs, 90) self.assertEqual(cst.name, "c0") with self.subTest("zero range variable in a quadratic constraint"): mod = QuadraticProgram() mod.integer_var(name="x", lowerbound=10, upperbound=10) mod.binary_var(name="y") mod.quadratic_constraint({"x": 1}, { ("x", "x"): 2, ("x", "y"): 3 }, ">=", 100) mod2 = IntegerToBinary().convert(mod) self.assertListEqual([e.name for e in mod2.variables], ["x@0", "y"]) self.assertEqual(mod.get_num_linear_constraints(), 0) self.assertEqual(mod.get_num_quadratic_constraints(), 1) self.assertAlmostEqual(mod2.objective.constant, 0) self.assertDictEqual(mod2.objective.linear.to_dict(), {}) self.assertDictEqual(mod2.objective.quadratic.to_dict(), {}) cst = mod2.get_quadratic_constraint(0) self.assertDictEqual(cst.linear.to_dict(use_name=True), {"y": 30}) self.assertEqual(cst.sense, Constraint.Sense.GE) self.assertAlmostEqual(cst.rhs, -110) self.assertEqual(cst.name, "q0")
class TestQuadraticConstraint(QiskitOptimizationTestCase): """Test QuadraticConstraint.""" def setUp(self) -> None: super().setUp() self.quadratic_program = QuadraticProgram() self.quadratic_program.binary_var_list(3, name="x") self.quadratic_program.quadratic_constraint({ "x0": 1, "x1": -2 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, "<=", 1) self.quadratic_program.quadratic_constraint({ "x0": 1, "x1": -2 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, "<", 1) self.quadratic_program.quadratic_constraint({ "x0": 1, "x1": -2 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, "LE", 1) self.quadratic_program.quadratic_constraint({ "x0": 1, "x1": -2 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, "L", 1) self.quadratic_program.quadratic_constraint({ "x0": -1, "x1": 2 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, "==", 2) self.quadratic_program.quadratic_constraint({ "x0": -1, "x1": 2 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, "=", 2) self.quadratic_program.quadratic_constraint({ "x0": -1, "x1": 2 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, "EQ", 2) self.quadratic_program.quadratic_constraint({ "x0": -1, "x1": 2 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, "E", 2) self.quadratic_program.quadratic_constraint({ "x1": 2, "x2": -1 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, ">=", 3) self.quadratic_program.quadratic_constraint({ "x1": 2, "x2": -1 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, ">", 3) self.quadratic_program.quadratic_constraint({ "x1": 2, "x2": -1 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, "GE", 3) self.quadratic_program.quadratic_constraint({ "x1": 2, "x2": -1 }, { ("x0", "x0"): -1, ("x2", "x1"): 2 }, "G", 3) def test_init(self): """test init.""" quadratic_program = QuadraticProgram() for _ in range(5): quadratic_program.continuous_var() self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 0) linear_coeffs = np.array(range(5)) lst = [[0 for _ in range(5)] for _ in range(5)] for i, v in enumerate(lst): for j, _ in enumerate(v): lst[min(i, j)][max(i, j)] += i * j quadratic_coeffs = np.array(lst) # equality constraints quadratic_program.quadratic_constraint(sense="==") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 1) self.assertEqual(quadratic_program.quadratic_constraints[0].name, "q0") self.assertEqual( len(quadratic_program.quadratic_constraints[0].linear.to_dict()), 0) self.assertEqual( len(quadratic_program.quadratic_constraints[0].quadratic.to_dict() ), 0) self.assertEqual(quadratic_program.quadratic_constraints[0].sense, Constraint.Sense.EQ) self.assertEqual(quadratic_program.quadratic_constraints[0].rhs, 0.0) self.assertEqual( quadratic_program.quadratic_constraints[0], quadratic_program.get_quadratic_constraint("q0"), ) self.assertEqual( quadratic_program.quadratic_constraints[0], quadratic_program.get_quadratic_constraint(0), ) self.assertEqual( quadratic_program.quadratic_constraints[0].evaluate(linear_coeffs), 0.0) with self.assertRaises(QiskitOptimizationError): quadratic_program.quadratic_constraint(name="q0", sense="==") quadratic_program.quadratic_constraint(linear_coeffs, quadratic_coeffs, "==", 1.0, "q1") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 2) self.assertEqual(quadratic_program.quadratic_constraints[1].name, "q1") self.assertTrue( (quadratic_program.quadratic_constraints[1].linear.to_array() == linear_coeffs).all()) self.assertTrue( (quadratic_program.quadratic_constraints[1].quadratic.to_array() == quadratic_coeffs).all()) self.assertEqual(quadratic_program.quadratic_constraints[1].sense, Constraint.Sense.EQ) self.assertEqual(quadratic_program.quadratic_constraints[1].rhs, 1.0) self.assertEqual( quadratic_program.quadratic_constraints[1], quadratic_program.get_quadratic_constraint("q1"), ) self.assertEqual( quadratic_program.quadratic_constraints[1], quadratic_program.get_quadratic_constraint(1), ) self.assertEqual( quadratic_program.quadratic_constraints[1].evaluate(linear_coeffs), 930.0) # geq constraints quadratic_program.quadratic_constraint(sense=">=") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 3) self.assertEqual(quadratic_program.quadratic_constraints[2].name, "q2") self.assertEqual( len(quadratic_program.quadratic_constraints[2].linear.to_dict()), 0) self.assertEqual( len(quadratic_program.quadratic_constraints[2].quadratic.to_dict() ), 0) self.assertEqual(quadratic_program.quadratic_constraints[2].sense, Constraint.Sense.GE) self.assertEqual(quadratic_program.quadratic_constraints[2].rhs, 0.0) self.assertEqual( quadratic_program.quadratic_constraints[2], quadratic_program.get_quadratic_constraint("q2"), ) self.assertEqual( quadratic_program.quadratic_constraints[2], quadratic_program.get_quadratic_constraint(2), ) self.assertEqual( quadratic_program.quadratic_constraints[2].evaluate(linear_coeffs), 0.0) with self.assertRaises(QiskitOptimizationError): quadratic_program.quadratic_constraint(name="q2", sense=">=") quadratic_program.quadratic_constraint(linear_coeffs, quadratic_coeffs, ">=", 1.0, "q3") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 4) self.assertEqual(quadratic_program.quadratic_constraints[3].name, "q3") self.assertTrue( (quadratic_program.quadratic_constraints[3].linear.to_array() == linear_coeffs).all()) self.assertTrue( (quadratic_program.quadratic_constraints[3].quadratic.to_array() == quadratic_coeffs).all()) self.assertEqual(quadratic_program.quadratic_constraints[3].sense, Constraint.Sense.GE) self.assertEqual(quadratic_program.quadratic_constraints[3].rhs, 1.0) self.assertEqual( quadratic_program.quadratic_constraints[3], quadratic_program.get_quadratic_constraint("q3"), ) self.assertEqual( quadratic_program.quadratic_constraints[3], quadratic_program.get_quadratic_constraint(3), ) self.assertEqual( quadratic_program.quadratic_constraints[3].evaluate(linear_coeffs), 930.0) # leq constraints quadratic_program.quadratic_constraint(sense="<=") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 5) self.assertEqual(quadratic_program.quadratic_constraints[4].name, "q4") self.assertEqual( len(quadratic_program.quadratic_constraints[4].linear.to_dict()), 0) self.assertEqual(quadratic_program.quadratic_constraints[4].sense, Constraint.Sense.LE) self.assertEqual(quadratic_program.quadratic_constraints[4].rhs, 0.0) self.assertEqual( quadratic_program.quadratic_constraints[4], quadratic_program.get_quadratic_constraint("q4"), ) self.assertEqual( quadratic_program.quadratic_constraints[4], quadratic_program.get_quadratic_constraint(4), ) self.assertEqual( quadratic_program.quadratic_constraints[4].evaluate(linear_coeffs), 0.0) with self.assertRaises(QiskitOptimizationError): quadratic_program.quadratic_constraint(name="q4", sense="<=") quadratic_program.quadratic_constraint(linear_coeffs, quadratic_coeffs, "<=", 1.0, "q5") self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 6) self.assertEqual(quadratic_program.quadratic_constraints[5].name, "q5") self.assertTrue( (quadratic_program.quadratic_constraints[5].linear.to_array() == linear_coeffs).all()) self.assertTrue( (quadratic_program.quadratic_constraints[5].quadratic.to_array() == quadratic_coeffs).all()) self.assertEqual(quadratic_program.quadratic_constraints[5].sense, Constraint.Sense.LE) self.assertEqual(quadratic_program.quadratic_constraints[5].rhs, 1.0) self.assertEqual( quadratic_program.quadratic_constraints[5], quadratic_program.get_quadratic_constraint("q5"), ) self.assertEqual( quadratic_program.quadratic_constraints[5], quadratic_program.get_quadratic_constraint(5), ) self.assertEqual( quadratic_program.quadratic_constraints[5].evaluate(linear_coeffs), 930.0) def test_str(self): """Test str""" self.assertEqual( self.quadratic_program.get_num_quadratic_constraints(), 12) for i in range(0, 4): self.assertEqual( str(self.quadratic_program.get_quadratic_constraint(i)), f"-x0^2 + 2*x1*x2 + x0 - 2*x1 <= 1 'q{i}'", ) for i in range(4, 8): self.assertEqual( str(self.quadratic_program.get_quadratic_constraint(i)), f"-x0^2 + 2*x1*x2 - x0 + 2*x1 == 2 'q{i}'", ) for i in range(8, 12): self.assertEqual( str(self.quadratic_program.get_quadratic_constraint(i)), f"-x0^2 + 2*x1*x2 + 2*x1 - x2 >= 3 'q{i}'", ) def test_repr(self): """Test repr""" self.assertEqual( self.quadratic_program.get_num_quadratic_constraints(), 12) for i in range(0, 4): self.assertEqual( repr(self.quadratic_program.get_quadratic_constraint(i)), f"<QuadraticConstraint: -x0^2 + 2*x1*x2 + x0 - 2*x1 <= 1 'q{i}'>", ) for i in range(4, 8): self.assertEqual( repr(self.quadratic_program.get_quadratic_constraint(i)), f"<QuadraticConstraint: -x0^2 + 2*x1*x2 - x0 + 2*x1 == 2 'q{i}'>", ) for i in range(8, 12): self.assertEqual( repr(self.quadratic_program.get_quadratic_constraint(i)), f"<QuadraticConstraint: -x0^2 + 2*x1*x2 + 2*x1 - x2 >= 3 'q{i}'>", )