def test_maximize_to_minimize(self): """Test maximization to minimization conversion""" op_max = QuadraticProgram() op_min = QuadraticProgram() for i in range(2): op_max.binary_var(name="x{}".format(i)) op_min.binary_var(name="x{}".format(i)) op_max.integer_var(name="x{}".format(2), lowerbound=-3, upperbound=3) op_min.integer_var(name="x{}".format(2), lowerbound=-3, upperbound=3) op_max.maximize(constant=3, linear={"x0": 1}, quadratic={("x1", "x2"): 2}) op_min.minimize(constant=3, linear={"x0": 1}, quadratic={("x1", "x2"): 2}) # check conversion of maximization problem conv = MaximizeToMinimize() op_conv = conv.convert(op_max) self.assertEqual(op_conv.objective.sense, op_conv.objective.Sense.MINIMIZE) x = [0, 1, 2] fval_min = op_conv.objective.evaluate(conv.interpret(x)) self.assertAlmostEqual(fval_min, -7) self.assertAlmostEqual(op_max.objective.evaluate(x), -fval_min) # check conversion of minimization problem op_conv = conv.convert(op_min) self.assertEqual(op_conv.objective.sense, op_min.objective.sense) fval_min = op_conv.objective.evaluate(conv.interpret(x)) self.assertAlmostEqual(op_min.objective.evaluate(x), fval_min)
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_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_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_valid_variable_type(self): """Validate the types of the variables for QuadraticProgram.to_ising.""" # Integer variable with self.assertRaises(QiskitOptimizationError): op = QuadraticProgram() op.integer_var(0, 10, "int_var") _ = op.to_ising() # Continuous variable with self.assertRaises(QiskitOptimizationError): op = QuadraticProgram() op.continuous_var(0, 10, "continuous_var") _ = op.to_ising()
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_bounds(self): """test lowerbound and upperbound""" with self.subTest("bounded"): quadratic_program = QuadraticProgram() quadratic_program.continuous_var_list(3, lowerbound=-1, upperbound=2) coefficients_list = list(range(3)) bounds = LinearExpression(quadratic_program, coefficients_list).bounds self.assertAlmostEqual(bounds.lowerbound, -3) self.assertAlmostEqual(bounds.upperbound, 6) with self.subTest("bounded2"): quadratic_program = QuadraticProgram() quadratic_program.integer_var(lowerbound=-2, upperbound=-1, name="x") quadratic_program.integer_var(lowerbound=2, upperbound=4, name="y") bounds = LinearExpression(quadratic_program, {"x": 1, "y": 10}).bounds self.assertAlmostEqual(bounds.lowerbound, 18) self.assertAlmostEqual(bounds.upperbound, 39) bounds = LinearExpression(quadratic_program, {"x": -1, "y": 10}).bounds self.assertAlmostEqual(bounds.lowerbound, 21) self.assertAlmostEqual(bounds.upperbound, 42) bounds = LinearExpression(quadratic_program, {"x": 1, "y": -10}).bounds self.assertAlmostEqual(bounds.lowerbound, -42) self.assertAlmostEqual(bounds.upperbound, -21) bounds = LinearExpression(quadratic_program, {"x": -1, "y": -10}).bounds self.assertAlmostEqual(bounds.lowerbound, -39) self.assertAlmostEqual(bounds.upperbound, -18) bounds = LinearExpression(quadratic_program, {"x": 0, "y": 0}).bounds self.assertAlmostEqual(bounds.lowerbound, 0) self.assertAlmostEqual(bounds.upperbound, 0) with self.assertRaises(QiskitOptimizationError): quadratic_program = QuadraticProgram() quadratic_program.continuous_var_list(3, lowerbound=0, upperbound=INFINITY) coefficients_list = list(range(3)) _ = LinearExpression(quadratic_program, coefficients_list).bounds with self.assertRaises(QiskitOptimizationError): quadratic_program = QuadraticProgram() quadratic_program.continuous_var_list(3, lowerbound=-INFINITY, upperbound=0) coefficients_list = list(range(3)) _ = LinearExpression(quadratic_program, coefficients_list).bounds
def test_integer_to_binary(self): """ Test integer to binary """ 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 = {} for i, x in enumerate(op.variables): linear[x.name] = i + 1 op.maximize(0, linear, {}) conv = IntegerToBinary() op2 = conv.convert(op) self.assertEqual(op2.get_num_vars(), 5) self.assertListEqual([x.vartype for x in op2.variables], [Variable.Type.BINARY] * 5) self.assertListEqual([x.name for x in op2.variables], ['x0', 'x1', 'x2@0', 'x2@1', 'x2@2']) dct = op2.objective.linear.to_dict() self.assertEqual(dct[2], 3) self.assertEqual(dct[3], 6) self.assertEqual(dct[4], 6)
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_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_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_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_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( path.join('resources', 'test_quadratic_program.lp')) temp_output_file = tempfile.NamedTemporaryFile(mode='w+t', suffix='.lp') q_p.write_to_lp_file(temp_output_file.name) with open(reference_file_name) as reference: lines1 = temp_output_file.readlines() lines2 = reference.readlines() self.assertListEqual(lines1, lines2) temp_output_file.close() # automatically deleted 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')) as file1, open( reference_file_name) 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_inequality_integer(self): """Test InequalityToEqualityConverter 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.LE, 2, "x1x2") linear_constraint = {"x0": 1, "x2": 3} op.linear_constraint(linear_constraint, Constraint.Sense.GE, 2, "x0x2") # Quadratic constraints quadratic = {("x0", "x1"): 1, ("x1", "x2"): 2} op.quadratic_constraint({}, quadratic, Constraint.Sense.LE, 3, "x0x1_x1x2LE") quadratic = {("x0", "x1"): 3, ("x1", "x2"): 4} op.quadratic_constraint({}, quadratic, Constraint.Sense.GE, 3, "x0x1_x1x2GE") conv = InequalityToEquality() op2 = conv.convert(op) self.assertListEqual( [v.name for v in op2.variables], [ "x0", "x1", "x2", "x1x2@int_slack", "x0x2@int_slack", "x0x1_x1x2LE@int_slack", "x0x1_x1x2GE@int_slack", ], ) # For linear constraints lst = [ op2.linear_constraints[0].linear.to_dict()[0], op2.linear_constraints[0].linear.to_dict()[1], ] self.assertListEqual(lst, [1, 1]) self.assertEqual(op2.linear_constraints[0].sense, Constraint.Sense.EQ) lst = [ op2.linear_constraints[1].linear.to_dict()[1], op2.linear_constraints[1].linear.to_dict()[2], op2.linear_constraints[1].linear.to_dict()[3], ] self.assertListEqual(lst, [1, -1, 1]) lst = [op2.variables[3].lowerbound, op2.variables[3].upperbound] self.assertListEqual(lst, [0, 8]) self.assertEqual(op2.linear_constraints[1].sense, Constraint.Sense.EQ) lst = [ op2.linear_constraints[2].linear.to_dict()[0], op2.linear_constraints[2].linear.to_dict()[2], op2.linear_constraints[2].linear.to_dict()[4], ] self.assertListEqual(lst, [1, 3, -1]) lst = [op2.variables[4].lowerbound, op2.variables[4].upperbound] self.assertListEqual(lst, [0, 10]) self.assertEqual(op2.linear_constraints[2].sense, Constraint.Sense.EQ) # For quadratic constraints lst = [ op2.quadratic_constraints[0].quadratic.to_dict()[(0, 1)], op2.quadratic_constraints[0].quadratic.to_dict()[(1, 2)], op2.quadratic_constraints[0].linear.to_dict()[5], ] self.assertListEqual(lst, [1, 2, 1]) lst = [op2.variables[5].lowerbound, op2.variables[5].upperbound] self.assertListEqual(lst, [0, 30]) lst = [ op2.quadratic_constraints[1].quadratic.to_dict()[(0, 1)], op2.quadratic_constraints[1].quadratic.to_dict()[(1, 2)], op2.quadratic_constraints[1].linear.to_dict()[6], ] self.assertListEqual(lst, [3, 4, -1]) lst = [op2.variables[6].lowerbound, op2.variables[6].upperbound] self.assertListEqual(lst, [0, 60]) new_x = conv.interpret(np.arange(7)) np.testing.assert_array_almost_equal(new_x, np.arange(3))
def quadratibot(nb_stick: int, past: list, backend_sim: Aer) -> list: """Quadratic + QAOA function Args: nb_stick: nb of stick left past: past turn backend_sim: backend for quantum Return: Gates to use """ def get_quantum_solution_for(quadprog: QuadraticProgram, quantumInstance: QuantumInstance, optimizer=None): _eval_count = 0 def callback(eval_count, parameters, mean, std): nonlocal _eval_count _eval_count = eval_count # Create solver and optimizer solver = QAOA( optimizer=optimizer, quantum_instance=quantumInstance, callback=callback, max_evals_grouped=3, ) # Create optimizer for solver optimizer = MinimumEigenOptimizer(solver) # Get result from optimizer result = optimizer.solve(quadprog) return result, _eval_count # Check number of stick max if nb_stick >= 3: max_stick = 3 else: max_stick = nb_stick # Check the past poten_stick = nb_stick for i in range(len(past)): if past[i] == "/": poten_stick += 0.5 if past[i] == "¬": u = 1 if len(past) - 1 >= i + u: while past[i + u] == "¬": u += 1 if past[i + u] == "/": poten_stick += 0.5 # Check last turn last_st = 0 if past[0] == "¬": u = 1 while past[0 + u] == "¬": u += 1 if past[0 + u] == "/": last_st = 0.5 if past[0] == "/": last_st = 0.5 quadprog = QuadraticProgram(name="qnim") quadprog.integer_var(name="x", lowerbound=0, upperbound=max_stick) quadprog.integer_var(name="sup", lowerbound=0, upperbound=max_stick) quadprog.integer_var(name="intric", lowerbound=0, upperbound=max_stick) quadprog.maximize( linear={ "x": 1, "sup": 0.5, "intric": last_st }, quadratic={("sup", "intric"): 0.5}, ) # General constraints quadprog.linear_constraint(linear={ "x": 1, "sup": 1, "intric": 1 }, sense=">", rhs=0, name="gen_min") quadprog.linear_constraint( linear={ "x": 1, "sup": 1, "intric": 1 }, sense="<=", rhs=max_stick, name="gen_max", ) # Mod4 constraints if math.ceil(poten_stick % 4) - 0.5 > 0: quadprog.linear_constraint( linear={ "x": 1, "sup": 1 }, sense="<=", rhs=math.ceil(poten_stick % 4), name="qua_mod4", ) if nb_stick % 4 - 1 > 0: quadprog.linear_constraint( linear={ "x": 1, "sup": 1, "intric": 1 }, sense="<=", rhs=nb_stick % 4 - 1, name="cla_mod4", ) # Get QAOA result final_result = [] simulator_instance = QuantumInstance(backend=backend_sim) qaoa_result, qaoa_eval_count = get_quantum_solution_for( quadprog, simulator_instance) # Format and print result for cropHectares, cropName in zip(qaoa_result.x, qaoa_result.variable_names): for i in range(int(cropHectares)): final_result.append(cropName) return final_result
def test_bounds(self): """test lowerbound and upperbound""" with self.subTest("bounded"): q_p = QuadraticProgram() q_p.continuous_var(1, 2, "x") q_p.continuous_var(-2, -1, "y") q_p.continuous_var(-1, 2, "z") bounds = QuadraticExpression(q_p, { ("x", "y"): 1, ("y", "z"): 2, ("z", "z"): 3 }).bounds self.assertAlmostEqual(bounds.lowerbound, -12) self.assertAlmostEqual(bounds.upperbound, 15) with self.subTest("bounded2"): q_p = QuadraticProgram() q_p.integer_var(-1, 2, "x") bounds = QuadraticExpression(q_p, {("x", "x"): 1}).bounds self.assertAlmostEqual(bounds.lowerbound, 0) self.assertAlmostEqual(bounds.upperbound, 4) bounds = QuadraticExpression(q_p, {("x", "x"): -1}).bounds self.assertAlmostEqual(bounds.lowerbound, -4) self.assertAlmostEqual(bounds.upperbound, 0) bounds = QuadraticExpression(q_p, {("x", "x"): 0}).bounds self.assertAlmostEqual(bounds.lowerbound, 0) self.assertAlmostEqual(bounds.upperbound, 0) with self.subTest("bounded3"): q_p = QuadraticProgram() q_p.integer_var(-2, -1, "x") bounds = QuadraticExpression(q_p, {("x", "x"): 1}).bounds self.assertAlmostEqual(bounds.lowerbound, 1) self.assertAlmostEqual(bounds.upperbound, 4) bounds = QuadraticExpression(q_p, {("x", "x"): -1}).bounds self.assertAlmostEqual(bounds.lowerbound, -4) self.assertAlmostEqual(bounds.upperbound, -1) bounds = QuadraticExpression(q_p, {("x", "x"): 0}).bounds self.assertAlmostEqual(bounds.lowerbound, 0) self.assertAlmostEqual(bounds.upperbound, 0) with self.subTest("bounded4"): q_p = QuadraticProgram() q_p.integer_var(-2, 3, "x") q_p.integer_var(-10, 20, "y") bounds = QuadraticExpression(q_p, {("x", "y"): 1}).bounds self.assertAlmostEqual(bounds.lowerbound, -40) self.assertAlmostEqual(bounds.upperbound, 60) bounds = QuadraticExpression(q_p, {("x", "y"): -1}).bounds self.assertAlmostEqual(bounds.lowerbound, -60) self.assertAlmostEqual(bounds.upperbound, 40) bounds = QuadraticExpression(q_p, {("x", "y"): 0}).bounds self.assertAlmostEqual(bounds.lowerbound, 0) self.assertAlmostEqual(bounds.upperbound, 0) with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.continuous_var(1, 2, "x") q_p.continuous_var(-2, -1, "y") q_p.continuous_var(-INFINITY, 2, "z") _ = QuadraticExpression(q_p, { ("x", "y"): 1, ("y", "z"): 2, ("z", "z"): 3 }).bounds with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.continuous_var(1, 2, "x") q_p.continuous_var(-2, -1, "y") q_p.continuous_var(-1, INFINITY, "z") _ = QuadraticExpression(q_p, { ("x", "y"): 1, ("y", "z"): 2, ("z", "z"): 3 }).bounds
def test_inequality_to_penalty_auto_define_penalty(self): """Test _auto_define_penalty() in InequalityToPenalty""" op = QuadraticProgram() op.integer_var(name="x", lowerbound=1, upperbound=3) op.integer_var(name="y", lowerbound=-1, upperbound=4) op.integer_var(name="z", lowerbound=-5, upperbound=-1) op.maximize(linear={"x": 1, "y": 1, "z": 1}) lip = LinearInequalityToPenalty() self.assertEqual(lip._auto_define_penalty(op), 12) op = QuadraticProgram() op.integer_var(name="x", lowerbound=1, upperbound=3) op.integer_var(name="y", lowerbound=-1, upperbound=4) op.integer_var(name="z", lowerbound=-5, upperbound=-1) op.maximize(linear={"x": -1, "y": -1, "z": -1}) lip = LinearInequalityToPenalty() self.assertEqual(lip._auto_define_penalty(op), 12) op = QuadraticProgram() op.integer_var(name="x", lowerbound=1, upperbound=3) op.integer_var(name="y", lowerbound=-1, upperbound=4) op.integer_var(name="z", lowerbound=-5, upperbound=-1) op.maximize(quadratic={ (0, 0): 1, (0, 1): 1, (0, 2): 1, (1, 1): 1, (1, 2): 1, (2, 2): 1 }) lip = LinearInequalityToPenalty() self.assertEqual(lip._auto_define_penalty(op), 103) op = QuadraticProgram() op.integer_var(name="x", lowerbound=1, upperbound=3) op.integer_var(name="y", lowerbound=-1, upperbound=4) op.integer_var(name="z", lowerbound=-5, upperbound=-1) op.maximize(quadratic={ (0, 0): -1, (0, 1): -1, (0, 2): -1, (1, 1): -1, (1, 2): -1, (2, 2): -1 }) lip = LinearInequalityToPenalty() self.assertEqual(lip._auto_define_penalty(op), 103) op = QuadraticProgram() op.integer_var(lowerbound=-2, upperbound=1, name="x") op.minimize(quadratic={("x", "x"): 1}) lip = LinearInequalityToPenalty() self.assertEqual(lip._auto_define_penalty(op), 5)
def test_variables_handling(self): """ test add variables """ quadratic_program = QuadraticProgram() self.assertEqual(quadratic_program.get_num_vars(), 0) self.assertEqual(quadratic_program.get_num_continuous_vars(), 0) self.assertEqual(quadratic_program.get_num_binary_vars(), 0) self.assertEqual(quadratic_program.get_num_integer_vars(), 0) x_0 = quadratic_program.continuous_var() self.assertEqual(x_0.name, 'x0') self.assertEqual(x_0.lowerbound, 0) self.assertEqual(x_0.upperbound, INFINITY) self.assertEqual(x_0.vartype, Variable.Type.CONTINUOUS) self.assertEqual(quadratic_program.get_num_vars(), 1) self.assertEqual(quadratic_program.get_num_continuous_vars(), 1) self.assertEqual(quadratic_program.get_num_binary_vars(), 0) self.assertEqual(quadratic_program.get_num_integer_vars(), 0) x_1 = quadratic_program.continuous_var(name='x1', lowerbound=5, upperbound=10) self.assertEqual(x_1.name, 'x1') self.assertEqual(x_1.lowerbound, 5) self.assertEqual(x_1.upperbound, 10) self.assertEqual(x_1.vartype, Variable.Type.CONTINUOUS) self.assertEqual(quadratic_program.get_num_vars(), 2) self.assertEqual(quadratic_program.get_num_continuous_vars(), 2) self.assertEqual(quadratic_program.get_num_binary_vars(), 0) self.assertEqual(quadratic_program.get_num_integer_vars(), 0) x_2 = quadratic_program.binary_var() self.assertEqual(x_2.name, 'x2') self.assertEqual(x_2.lowerbound, 0) self.assertEqual(x_2.upperbound, 1) self.assertEqual(x_2.vartype, Variable.Type.BINARY) self.assertEqual(quadratic_program.get_num_vars(), 3) self.assertEqual(quadratic_program.get_num_continuous_vars(), 2) self.assertEqual(quadratic_program.get_num_binary_vars(), 1) self.assertEqual(quadratic_program.get_num_integer_vars(), 0) x_3 = quadratic_program.binary_var(name='x3') self.assertEqual(x_3.name, 'x3') self.assertEqual(x_3.lowerbound, 0) self.assertEqual(x_3.upperbound, 1) self.assertEqual(x_3.vartype, Variable.Type.BINARY) self.assertEqual(quadratic_program.get_num_vars(), 4) self.assertEqual(quadratic_program.get_num_continuous_vars(), 2) self.assertEqual(quadratic_program.get_num_binary_vars(), 2) self.assertEqual(quadratic_program.get_num_integer_vars(), 0) x_4 = quadratic_program.integer_var() self.assertEqual(x_4.name, 'x4') self.assertEqual(x_4.lowerbound, 0) self.assertEqual(x_4.upperbound, INFINITY) self.assertEqual(x_4.vartype, Variable.Type.INTEGER) self.assertEqual(quadratic_program.get_num_vars(), 5) self.assertEqual(quadratic_program.get_num_continuous_vars(), 2) self.assertEqual(quadratic_program.get_num_binary_vars(), 2) self.assertEqual(quadratic_program.get_num_integer_vars(), 1) x_5 = quadratic_program.integer_var(name='x5', lowerbound=5, upperbound=10) self.assertEqual(x_5.name, 'x5') self.assertEqual(x_5.lowerbound, 5) self.assertEqual(x_5.upperbound, 10) self.assertEqual(x_5.vartype, Variable.Type.INTEGER) self.assertEqual(quadratic_program.get_num_vars(), 6) self.assertEqual(quadratic_program.get_num_continuous_vars(), 2) self.assertEqual(quadratic_program.get_num_binary_vars(), 2) self.assertEqual(quadratic_program.get_num_integer_vars(), 2) with self.assertRaises(QiskitOptimizationError): quadratic_program.continuous_var(name='x0') with self.assertRaises(QiskitOptimizationError): quadratic_program.binary_var(name='x0') with self.assertRaises(QiskitOptimizationError): quadratic_program.integer_var(name='x0') variables = [x_0, x_1, x_2, x_3, x_4, x_5] for i, x in enumerate(variables): y = quadratic_program.get_variable(i) z = quadratic_program.get_variable(x.name) self.assertEqual(x.name, y.name) self.assertEqual(x.name, z.name) self.assertDictEqual(quadratic_program.variables_index, {'x' + str(i): i for i in range(6)})
def test_substitute_variables(self): """test substitute variables""" q_p = QuadraticProgram("test") q_p.binary_var(name="x") q_p.integer_var(name="y", lowerbound=-2, upperbound=4) q_p.continuous_var(name="z", lowerbound=-1.5, upperbound=3.2) q_p.minimize( constant=1, linear={ "x": 1, "y": 2 }, quadratic={ ("x", "y"): -1, ("z", "z"): 2 }, ) q_p.linear_constraint({"x": 2, "z": -1}, "==", 1) q_p.quadratic_constraint({"x": 2, "z": -1}, {("y", "z"): 3}, "<=", -1) with self.subTest("x <- -1"): q_p2 = substitute_variables(q_p, constants={"x": -1}) self.assertEqual(q_p2.status, QuadraticProgram.Status.INFEASIBLE) q_p2 = substitute_variables(q_p, constants={"y": -3}) self.assertEqual(q_p2.status, QuadraticProgram.Status.INFEASIBLE) q_p2 = substitute_variables(q_p, constants={"x": 1, "z": 2}) self.assertEqual(q_p2.status, QuadraticProgram.Status.INFEASIBLE) q_p2.clear() self.assertEqual(q_p2.status, QuadraticProgram.Status.VALID) with self.subTest("x <- 0"): q_p2 = substitute_variables(q_p, constants={"x": 0}) self.assertEqual(q_p2.status, QuadraticProgram.Status.VALID) self.assertDictEqual(q_p2.objective.linear.to_dict(use_name=True), {"y": 2}) self.assertDictEqual( q_p2.objective.quadratic.to_dict(use_name=True), {("z", "z"): 2}) self.assertEqual(q_p2.objective.constant, 1) self.assertEqual(len(q_p2.linear_constraints), 1) self.assertEqual(len(q_p2.quadratic_constraints), 1) cst = q_p2.linear_constraints[0] self.assertDictEqual(cst.linear.to_dict(use_name=True), {"z": -1}) self.assertEqual(cst.sense.name, "EQ") self.assertEqual(cst.rhs, 1) cst = q_p2.quadratic_constraints[0] self.assertDictEqual(cst.linear.to_dict(use_name=True), {"z": -1}) self.assertDictEqual(cst.quadratic.to_dict(use_name=True), {("y", "z"): 3}) self.assertEqual(cst.sense.name, "LE") self.assertEqual(cst.rhs, -1) with self.subTest("z <- -1"): q_p2 = substitute_variables(q_p, constants={"z": -1}) self.assertEqual(q_p2.status, QuadraticProgram.Status.VALID) self.assertDictEqual(q_p2.objective.linear.to_dict(use_name=True), { "x": 1, "y": 2 }) self.assertDictEqual( q_p2.objective.quadratic.to_dict(use_name=True), {("x", "y"): -1}) self.assertEqual(q_p2.objective.constant, 3) self.assertEqual(len(q_p2.linear_constraints), 2) self.assertEqual(len(q_p2.quadratic_constraints), 0) cst = q_p2.linear_constraints[0] self.assertDictEqual(cst.linear.to_dict(use_name=True), {"x": 2}) self.assertEqual(cst.sense.name, "EQ") self.assertEqual(cst.rhs, 0) cst = q_p2.linear_constraints[1] self.assertDictEqual(cst.linear.to_dict(use_name=True), { "x": 2, "y": -3 }) self.assertEqual(cst.sense.name, "LE") self.assertEqual(cst.rhs, -2) with self.subTest("y <- -0.5 * x"): q_p2 = substitute_variables(q_p, variables={"y": ("x", -0.5)}) self.assertEqual(q_p2.status, QuadraticProgram.Status.VALID) self.assertDictEqual(q_p2.objective.linear.to_dict(use_name=True), {}) self.assertDictEqual( q_p2.objective.quadratic.to_dict(use_name=True), { ("x", "x"): 0.5, ("z", "z"): 2 }, ) self.assertEqual(q_p2.objective.constant, 1) self.assertEqual(len(q_p2.linear_constraints), 1) self.assertEqual(len(q_p2.quadratic_constraints), 1) cst = q_p2.linear_constraints[0] self.assertDictEqual(cst.linear.to_dict(use_name=True), { "x": 2, "z": -1 }) self.assertEqual(cst.sense.name, "EQ") self.assertEqual(cst.rhs, 1) cst = q_p2.quadratic_constraints[0] self.assertDictEqual(cst.linear.to_dict(use_name=True), { "x": 2, "z": -1 }) self.assertDictEqual(cst.quadratic.to_dict(use_name=True), {("x", "z"): -1.5}) self.assertEqual(cst.sense.name, "LE") self.assertEqual(cst.rhs, -1)
def test_var_dict(self): """test {binary,integer,continuous}_var_dict""" q_p = QuadraticProgram() d_0 = q_p.continuous_var_dict(name="a", key_format="_{}", keys=3) self.assertSetEqual(set(d_0.keys()), {"a_0", "a_1", "a_2"}) self.assertSetEqual({var.name for var in q_p.variables}, {"a_0", "a_1", "a_2"}) for var in q_p.variables: self.assertAlmostEqual(var.lowerbound, 0) self.assertAlmostEqual(var.upperbound, INFINITY) self.assertEqual(var.vartype, VarType.CONTINUOUS) self.assertTupleEqual(var.as_tuple(), d_0[var.name].as_tuple()) d_1 = q_p.binary_var_dict(name="b", keys=5) self.assertSetEqual(set(d_1.keys()), {"b3", "b4", "b5", "b6", "b7"}) self.assertSetEqual( {var.name for var in q_p.variables}, {"a_0", "a_1", "a_2", "b3", "b4", "b5", "b6", "b7"}, ) for var in q_p.variables[-5:]: self.assertAlmostEqual(var.lowerbound, 0) self.assertAlmostEqual(var.upperbound, 1) self.assertEqual(var.vartype, VarType.BINARY) self.assertTupleEqual(var.as_tuple(), d_1[var.name].as_tuple()) d_2 = q_p.integer_var_dict(keys=1, key_format="-{}", lowerbound=-4, upperbound=10) self.assertSetEqual(set(d_2.keys()), {"x-8"}) self.assertSetEqual( {var.name for var in q_p.variables}, {"a_0", "a_1", "a_2", "b3", "b4", "b5", "b6", "b7", "x-8"}, ) for var in q_p.variables[-1:]: self.assertAlmostEqual(var.lowerbound, -4) self.assertAlmostEqual(var.upperbound, 10) self.assertEqual(var.vartype, VarType.INTEGER) self.assertTupleEqual(var.as_tuple(), d_2[var.name].as_tuple()) d_3 = q_p.binary_var_dict(name="c", keys=range(3)) self.assertSetEqual(set(d_3.keys()), {"c0", "c1", "c2"}) self.assertSetEqual( {var.name for var in q_p.variables}, { "a_0", "a_1", "a_2", "b3", "b4", "b5", "b6", "b7", "x-8", "c0", "c1", "c2", }, ) for var in q_p.variables[-3:]: self.assertAlmostEqual(var.lowerbound, 0) self.assertAlmostEqual(var.upperbound, 1) self.assertEqual(var.vartype, VarType.BINARY) self.assertTupleEqual(var.as_tuple(), d_3[var.name].as_tuple()) with self.assertRaises(QiskitOptimizationError): q_p.binary_var_dict(name="c", keys=range(3)) d_4 = q_p.binary_var_dict(1, "x", "_") self.assertSetEqual(set(d_4.keys()), {"x_"}) self.assertSetEqual( {var.name for var in q_p.variables}, { "a_0", "a_1", "a_2", "b3", "b4", "b5", "b6", "b7", "x-8", "c0", "c1", "c2", "x_", }, ) for var in q_p.variables[-1:]: self.assertAlmostEqual(var.lowerbound, 0) self.assertAlmostEqual(var.upperbound, 1) self.assertEqual(var.vartype, VarType.BINARY) self.assertTupleEqual(var.as_tuple(), d_4[var.name].as_tuple()) with self.assertRaises(QiskitOptimizationError): q_p.binary_var_dict(1, "x", "_") with self.assertRaises(QiskitOptimizationError): q_p.binary_var("x_") d_5 = q_p.continuous_var_dict(1, -1, 2, "", "") self.assertSetEqual(set(d_5.keys()), {""}) self.assertSetEqual( {var.name for var in q_p.variables}, { "a_0", "a_1", "a_2", "b3", "b4", "b5", "b6", "b7", "x-8", "c0", "c1", "c2", "x_", "", }, ) for var in q_p.variables[-1:]: self.assertAlmostEqual(var.lowerbound, -1) self.assertAlmostEqual(var.upperbound, 2) self.assertEqual(var.vartype, VarType.CONTINUOUS) self.assertTupleEqual(var.as_tuple(), d_5[var.name].as_tuple()) with self.assertRaises(QiskitOptimizationError): q_p.binary_var_dict(1, "", "") with self.assertRaises(QiskitOptimizationError): q_p.integer_var(0, 1, "") with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.binary_var_dict(keys=1, key_format="{}{}") with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.binary_var_dict(keys=0) with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.binary_var_dict(keys=1, key_format="_{{}}") with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.binary_var_dict(keys=2, key_format="") with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.binary_var_dict(keys=range(2), key_format="")
def test_docplex(self): """test from_docplex and to_docplex""" q_p = QuadraticProgram("test") q_p.binary_var(name="x") q_p.integer_var(name="y", lowerbound=-2, upperbound=4) q_p.continuous_var(name="z", lowerbound=-1.5, upperbound=3.2) q_p.minimize( constant=1, linear={ "x": 1, "y": 2 }, quadratic={ ("x", "y"): -1, ("z", "z"): 2 }, ) q_p.linear_constraint({"x": 2, "z": -1}, "==", 1) q_p.quadratic_constraint({"x": 2, "z": -1}, {("y", "z"): 3}, "==", 1) q_p2 = QuadraticProgram() q_p2.from_docplex(q_p.to_docplex()) self.assertEqual(q_p.export_as_lp_string(), q_p2.export_as_lp_string()) mod = Model("test") x = mod.binary_var("x") y = mod.integer_var(-2, 4, "y") z = mod.continuous_var(-1.5, 3.2, "z") mod.minimize(1 + x + 2 * y - x * y + 2 * z * z) mod.add(2 * x - z == 1, "c0") mod.add(2 * x - z + 3 * y * z == 1, "q0") self.assertEqual(q_p.export_as_lp_string(), mod.export_as_lp_string()) with self.assertRaises(QiskitOptimizationError): mod = Model() mod.semiinteger_var(lb=1, name="x") q_p.from_docplex(mod) with self.assertRaises(QiskitOptimizationError): mod = Model() x = mod.binary_var("x") mod.add_range(0, 2 * x, 1) q_p.from_docplex(mod) with self.assertRaises(QiskitOptimizationError): mod = Model() x = mod.binary_var("x") y = mod.binary_var("y") mod.add_indicator(x, x + y <= 1, 1) q_p.from_docplex(mod) with self.assertRaises(QiskitOptimizationError): mod = Model() x = mod.binary_var("x") y = mod.binary_var("y") mod.add_equivalence(x, x + y <= 1, 1) q_p.from_docplex(mod) with self.assertRaises(QiskitOptimizationError): mod = Model() x = mod.binary_var("x") y = mod.binary_var("y") mod.add(mod.not_equal_constraint(x, y + 1)) q_p.from_docplex(mod) # test from_docplex without explicit variable names mod = Model() x = mod.binary_var() y = mod.continuous_var() z = mod.integer_var() mod.minimize(x + y + z + x * y + y * z + x * z) mod.add_constraint(x + y == z) # linear EQ mod.add_constraint(x + y >= z) # linear GE mod.add_constraint(x + y <= z) # linear LE mod.add_constraint(x * y == z) # quadratic EQ mod.add_constraint(x * y >= z) # quadratic GE mod.add_constraint(x * y <= z) # quadratic LE q_p = QuadraticProgram() q_p.from_docplex(mod) var_names = [v.name for v in q_p.variables] self.assertListEqual(var_names, ["x0", "x1", "x2"]) senses = [ Constraint.Sense.EQ, Constraint.Sense.GE, Constraint.Sense.LE ] for i, c in enumerate(q_p.linear_constraints): self.assertDictEqual(c.linear.to_dict(use_name=True), { "x0": 1, "x1": 1, "x2": -1 }) self.assertEqual(c.rhs, 0) self.assertEqual(c.sense, senses[i]) for i, c in enumerate(q_p.quadratic_constraints): self.assertEqual(c.rhs, 0) self.assertDictEqual(c.linear.to_dict(use_name=True), {"x2": -1}) self.assertDictEqual(c.quadratic.to_dict(use_name=True), {("x0", "x1"): 1}) self.assertEqual(c.sense, senses[i])
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")
def test_docplex(self): """test from_docplex and to_docplex""" q_p = QuadraticProgram('test') q_p.binary_var(name='x') q_p.integer_var(name='y', lowerbound=-2, upperbound=4) q_p.continuous_var(name='z', lowerbound=-1.5, upperbound=3.2) q_p.minimize(constant=1, linear={ 'x': 1, 'y': 2 }, quadratic={ ('x', 'y'): -1, ('z', 'z'): 2 }) q_p.linear_constraint({'x': 2, 'z': -1}, '==', 1) q_p.quadratic_constraint({'x': 2, 'z': -1}, {('y', 'z'): 3}, '==', 1) q_p2 = QuadraticProgram() q_p2.from_docplex(q_p.to_docplex()) self.assertEqual(q_p.export_as_lp_string(), q_p2.export_as_lp_string()) mod = Model('test') x = mod.binary_var('x') y = mod.integer_var(-2, 4, 'y') z = mod.continuous_var(-1.5, 3.2, 'z') mod.minimize(1 + x + 2 * y - x * y + 2 * z * z) mod.add(2 * x - z == 1, 'c0') mod.add(2 * x - z + 3 * y * z == 1, 'q0') self.assertEqual(q_p.export_as_lp_string(), mod.export_as_lp_string()) with self.assertRaises(QiskitOptimizationError): mod = Model() mod.semiinteger_var(lb=1, name='x') q_p.from_docplex(mod) with self.assertRaises(QiskitOptimizationError): mod = Model() x = mod.binary_var('x') mod.add_range(0, 2 * x, 1) q_p.from_docplex(mod) with self.assertRaises(QiskitOptimizationError): mod = Model() x = mod.binary_var('x') y = mod.binary_var('y') mod.add_indicator(x, x + y <= 1, 1) q_p.from_docplex(mod) with self.assertRaises(QiskitOptimizationError): mod = Model() x = mod.binary_var('x') y = mod.binary_var('y') mod.add_equivalence(x, x + y <= 1, 1) q_p.from_docplex(mod) with self.assertRaises(QiskitOptimizationError): mod = Model() x = mod.binary_var('x') y = mod.binary_var('y') mod.add(mod.not_equal_constraint(x, y + 1)) q_p.from_docplex(mod) # test from_docplex without explicit variable names mod = Model() x = mod.binary_var() y = mod.continuous_var() z = mod.integer_var() mod.minimize(x + y + z + x * y + y * z + x * z) mod.add_constraint(x + y == z) # linear EQ mod.add_constraint(x + y >= z) # linear GE mod.add_constraint(x + y <= z) # linear LE mod.add_constraint(x * y == z) # quadratic EQ mod.add_constraint(x * y >= z) # quadratic GE mod.add_constraint(x * y <= z) # quadratic LE q_p = QuadraticProgram() q_p.from_docplex(mod) var_names = [v.name for v in q_p.variables] self.assertListEqual(var_names, ['x0', 'x1', 'x2']) senses = [ Constraint.Sense.EQ, Constraint.Sense.GE, Constraint.Sense.LE ] for i, c in enumerate(q_p.linear_constraints): self.assertDictEqual(c.linear.to_dict(use_name=True), { 'x0': 1, 'x1': 1, 'x2': -1 }) self.assertEqual(c.rhs, 0) self.assertEqual(c.sense, senses[i]) for i, c in enumerate(q_p.quadratic_constraints): self.assertEqual(c.rhs, 0) self.assertDictEqual(c.linear.to_dict(use_name=True), {'x2': -1}) self.assertDictEqual(c.quadratic.to_dict(use_name=True), {('x0', 'x1'): 1}) self.assertEqual(c.sense, senses[i])
def test_substitute_variables(self): """test substitute variables""" q_p = QuadraticProgram('test') q_p.binary_var(name='x') q_p.integer_var(name='y', lowerbound=-2, upperbound=4) q_p.continuous_var(name='z', lowerbound=-1.5, upperbound=3.2) q_p.minimize(constant=1, linear={ 'x': 1, 'y': 2 }, quadratic={ ('x', 'y'): -1, ('z', 'z'): 2 }) q_p.linear_constraint({'x': 2, 'z': -1}, '==', 1) q_p.quadratic_constraint({'x': 2, 'z': -1}, {('y', 'z'): 3}, '<=', -1) q_p2 = q_p.substitute_variables(constants={'x': -1}) self.assertEqual(q_p2.status, QuadraticProgram.Status.INFEASIBLE) q_p2 = q_p.substitute_variables(constants={'y': -3}) self.assertEqual(q_p2.status, QuadraticProgram.Status.INFEASIBLE) q_p2 = q_p.substitute_variables(constants={'x': 1, 'z': 2}) self.assertEqual(q_p2.status, QuadraticProgram.Status.INFEASIBLE) q_p2.clear() self.assertEqual(q_p2.status, QuadraticProgram.Status.VALID) q_p2 = q_p.substitute_variables(constants={'x': 0}) self.assertEqual(q_p2.status, QuadraticProgram.Status.VALID) self.assertDictEqual(q_p2.objective.linear.to_dict(use_name=True), {'y': 2}) self.assertDictEqual(q_p2.objective.quadratic.to_dict(use_name=True), {('z', 'z'): 2}) self.assertEqual(q_p2.objective.constant, 1) self.assertEqual(len(q_p2.linear_constraints), 1) self.assertEqual(len(q_p2.quadratic_constraints), 1) cst = q_p2.linear_constraints[0] self.assertDictEqual(cst.linear.to_dict(use_name=True), {'z': -1}) self.assertEqual(cst.sense.name, 'EQ') self.assertEqual(cst.rhs, 1) cst = q_p2.quadratic_constraints[0] self.assertDictEqual(cst.linear.to_dict(use_name=True), {'z': -1}) self.assertDictEqual(cst.quadratic.to_dict(use_name=True), {('y', 'z'): 3}) self.assertEqual(cst.sense.name, 'LE') self.assertEqual(cst.rhs, -1) q_p2 = q_p.substitute_variables(constants={'z': -1}) self.assertEqual(q_p2.status, QuadraticProgram.Status.VALID) self.assertDictEqual(q_p2.objective.linear.to_dict(use_name=True), { 'x': 1, 'y': 2 }) self.assertDictEqual(q_p2.objective.quadratic.to_dict(use_name=True), {('x', 'y'): -1}) self.assertEqual(q_p2.objective.constant, 3) self.assertEqual(len(q_p2.linear_constraints), 2) self.assertEqual(len(q_p2.quadratic_constraints), 0) cst = q_p2.linear_constraints[0] self.assertDictEqual(cst.linear.to_dict(use_name=True), {'x': 2}) self.assertEqual(cst.sense.name, 'EQ') self.assertEqual(cst.rhs, 0) cst = q_p2.linear_constraints[1] self.assertDictEqual(cst.linear.to_dict(use_name=True), { 'x': 2, 'y': -3 }) self.assertEqual(cst.sense.name, 'LE') self.assertEqual(cst.rhs, -2) q_p2 = q_p.substitute_variables(variables={'y': ('x', -0.5)}) self.assertEqual(q_p2.status, QuadraticProgram.Status.VALID) self.assertDictEqual(q_p2.objective.linear.to_dict(use_name=True), {}) self.assertDictEqual(q_p2.objective.quadratic.to_dict(use_name=True), { ('x', 'x'): 0.5, ('z', 'z'): 2 }) self.assertEqual(q_p2.objective.constant, 1) self.assertEqual(len(q_p2.linear_constraints), 1) self.assertEqual(len(q_p2.quadratic_constraints), 1) cst = q_p2.linear_constraints[0] self.assertDictEqual(cst.linear.to_dict(use_name=True), { 'x': 2, 'z': -1 }) self.assertEqual(cst.sense.name, 'EQ') self.assertEqual(cst.rhs, 1) cst = q_p2.quadratic_constraints[0] self.assertDictEqual(cst.linear.to_dict(use_name=True), { 'x': 2, 'z': -1 }) self.assertDictEqual(cst.quadratic.to_dict(use_name=True), {('x', 'z'): -1.5}) self.assertEqual(cst.sense.name, 'LE') self.assertEqual(cst.rhs, -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 }, )
def test_var_dict(self): """test {binary,integer,continuous}_var_dict""" q_p = QuadraticProgram() d_0 = q_p.continuous_var_dict(name='a', key_format='_{}', keys=3) self.assertSetEqual(set(d_0.keys()), {'a_0', 'a_1', 'a_2'}) self.assertSetEqual({var.name for var in q_p.variables}, {'a_0', 'a_1', 'a_2'}) for var in q_p.variables: self.assertAlmostEqual(var.lowerbound, 0) self.assertAlmostEqual(var.upperbound, INFINITY) self.assertEqual(var.vartype, VarType.CONTINUOUS) self.assertTupleEqual(var.as_tuple(), d_0[var.name].as_tuple()) d_1 = q_p.binary_var_dict(name='b', keys=5) self.assertSetEqual(set(d_1.keys()), {'b3', 'b4', 'b5', 'b6', 'b7'}) self.assertSetEqual( {var.name for var in q_p.variables}, {'a_0', 'a_1', 'a_2', 'b3', 'b4', 'b5', 'b6', 'b7'}) for var in q_p.variables[-5:]: self.assertAlmostEqual(var.lowerbound, 0) self.assertAlmostEqual(var.upperbound, 1) self.assertEqual(var.vartype, VarType.BINARY) self.assertTupleEqual(var.as_tuple(), d_1[var.name].as_tuple()) d_2 = q_p.integer_var_dict(keys=1, key_format='-{}', lowerbound=-4, upperbound=10) self.assertSetEqual(set(d_2.keys()), {'x-8'}) self.assertSetEqual( {var.name for var in q_p.variables}, {'a_0', 'a_1', 'a_2', 'b3', 'b4', 'b5', 'b6', 'b7', 'x-8'}) for var in q_p.variables[-1:]: self.assertAlmostEqual(var.lowerbound, -4) self.assertAlmostEqual(var.upperbound, 10) self.assertEqual(var.vartype, VarType.INTEGER) self.assertTupleEqual(var.as_tuple(), d_2[var.name].as_tuple()) d_3 = q_p.binary_var_dict(name='c', keys=range(3)) self.assertSetEqual(set(d_3.keys()), {'c0', 'c1', 'c2'}) self.assertSetEqual({var.name for var in q_p.variables}, { 'a_0', 'a_1', 'a_2', 'b3', 'b4', 'b5', 'b6', 'b7', 'x-8', 'c0', 'c1', 'c2' }) for var in q_p.variables[-3:]: self.assertAlmostEqual(var.lowerbound, 0) self.assertAlmostEqual(var.upperbound, 1) self.assertEqual(var.vartype, VarType.BINARY) self.assertTupleEqual(var.as_tuple(), d_3[var.name].as_tuple()) with self.assertRaises(QiskitOptimizationError): q_p.binary_var_dict(name='c', keys=range(3)) d_4 = q_p.binary_var_dict(1, 'x', '_') self.assertSetEqual(set(d_4.keys()), {'x_'}) self.assertSetEqual({var.name for var in q_p.variables}, { 'a_0', 'a_1', 'a_2', 'b3', 'b4', 'b5', 'b6', 'b7', 'x-8', 'c0', 'c1', 'c2', 'x_' }) for var in q_p.variables[-1:]: self.assertAlmostEqual(var.lowerbound, 0) self.assertAlmostEqual(var.upperbound, 1) self.assertEqual(var.vartype, VarType.BINARY) self.assertTupleEqual(var.as_tuple(), d_4[var.name].as_tuple()) with self.assertRaises(QiskitOptimizationError): q_p.binary_var_dict(1, 'x', '_') with self.assertRaises(QiskitOptimizationError): q_p.binary_var('x_') d_5 = q_p.continuous_var_dict(1, -1, 2, '', '') self.assertSetEqual(set(d_5.keys()), {''}) self.assertSetEqual({var.name for var in q_p.variables}, { 'a_0', 'a_1', 'a_2', 'b3', 'b4', 'b5', 'b6', 'b7', 'x-8', 'c0', 'c1', 'c2', 'x_', '' }) for var in q_p.variables[-1:]: self.assertAlmostEqual(var.lowerbound, -1) self.assertAlmostEqual(var.upperbound, 2) self.assertEqual(var.vartype, VarType.CONTINUOUS) self.assertTupleEqual(var.as_tuple(), d_5[var.name].as_tuple()) with self.assertRaises(QiskitOptimizationError): q_p.binary_var_dict(1, '', '') with self.assertRaises(QiskitOptimizationError): q_p.integer_var(0, 1, '') with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.binary_var_dict(keys=1, key_format='{}{}') with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.binary_var_dict(keys=0) with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.binary_var_dict(keys=1, key_format='_{{}}') with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.binary_var_dict(keys=2, key_format='') with self.assertRaises(QiskitOptimizationError): q_p = QuadraticProgram() q_p.binary_var_dict(keys=range(2), key_format='')