Ejemplo n.º 1
0
 def test_auto_penalty(self):
     """Test auto penalty function"""
     op = QuadraticProgram()
     op.binary_var("x")
     op.binary_var("y")
     op.binary_var("z")
     op.minimize(constant=3, linear={"x": 1}, quadratic={("x", "y"): 2})
     op.linear_constraint(linear={
         "x": 1,
         "y": 1,
         "z": 1
     },
                          sense="EQ",
                          rhs=2,
                          name="xyz_eq")
     lineq2penalty = LinearEqualityToPenalty(penalty=1e5)
     lineq2penalty_auto = LinearEqualityToPenalty()
     qubo = lineq2penalty.convert(op)
     qubo_auto = lineq2penalty_auto.convert(op)
     exact_mes = NumPyMinimumEigensolver()
     exact = MinimumEigenOptimizer(exact_mes)
     result = exact.solve(qubo)
     result_auto = exact.solve(qubo_auto)
     self.assertEqual(result.fval, result_auto.fval)
     np.testing.assert_array_almost_equal(result.x, result_auto.x)
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
 def test_penalty_recalculation_when_reusing(self):
     """Test the penalty retrieval and recalculation of LinearEqualityToPenalty"""
     op = QuadraticProgram()
     op.binary_var("x")
     op.binary_var("y")
     op.binary_var("z")
     op.minimize(constant=3, linear={"x": 1}, quadratic={("x", "y"): 2})
     op.linear_constraint(linear={
         "x": 1,
         "y": 1,
         "z": 1
     },
                          sense="EQ",
                          rhs=2,
                          name="xyz_eq")
     # First, create a converter with no penalty
     lineq2penalty = LinearEqualityToPenalty()
     self.assertIsNone(lineq2penalty.penalty)
     # Then converter must calculate the penalty for the problem (should be 4.0)
     lineq2penalty.convert(op)
     self.assertEqual(4, lineq2penalty.penalty)
     # Re-use the converter with a newly defined penalty
     lineq2penalty.penalty = 3
     lineq2penalty.convert(op)
     self.assertEqual(3, lineq2penalty.penalty)
     # Re-use the converter letting the penalty be calculated again
     lineq2penalty.penalty = None
     lineq2penalty.convert(op)
     self.assertEqual(4, lineq2penalty.penalty)
Ejemplo n.º 4
0
def build_qubo_unconstrained_from_edges_dict(G, all_edges_dict, variables):
    qubo = QuadraticProgram()
    linear, quadratic = get_linear_quadratic_coeffs(G, all_edges_dict)
    for var in variables:
        qubo.binary_var(var)
    qubo.minimize(linear=linear, quadratic=quadratic)
    return qubo, linear, quadratic
    def test_feasibility(self):
        """Tests feasibility methods."""
        q_p = QuadraticProgram("test")
        _ = q_p.continuous_var(-1, 1, "x")
        _ = q_p.continuous_var(-10, 10, "y")
        q_p.minimize(linear={"x": 1, "y": 1})
        q_p.linear_constraint({"x": 1, "y": 1}, "<=", 10, "c0")
        q_p.linear_constraint({"x": 1, "y": 1}, ">=", -10, "c1")
        q_p.linear_constraint({"x": 1, "y": 1}, "==", 5, "c2")
        q_p.quadratic_constraint({"y": 1}, {("x", "x"): 1}, "<=", 10, "c3")
        q_p.quadratic_constraint({"y": 1}, {("x", "x"): 1}, ">=", 5, "c4")
        q_p.quadratic_constraint(None, {
            ("x", "x"): 1,
            ("y", "y"): 1
        }, "==", 25, "c5")

        self.assertTrue(q_p.is_feasible([0, 5]))
        self.assertFalse(q_p.is_feasible([1, 10]))
        self.assertFalse(q_p.is_feasible([1, -12]))
        self.assertFalse(q_p.is_feasible([1, 5]))
        self.assertFalse(q_p.is_feasible([5, 0]))
        self.assertFalse(q_p.is_feasible([1, 1]))
        self.assertFalse(q_p.is_feasible([0, 0]))

        feasible, variables, constraints = q_p.get_feasibility_info([10, 0])
        self.assertFalse(feasible)
        self.assertIsNotNone(variables)
        self.assertEqual(1, len(variables))
        self.assertEqual("x", variables[0].name)

        self.assertIsNotNone(constraints)
        self.assertEqual(3, len(constraints))
        self.assertEqual("c2", constraints[0].name)
        self.assertEqual("c3", constraints[1].name)
        self.assertEqual("c5", constraints[2].name)
Ejemplo n.º 6
0
 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())
Ejemplo n.º 7
0
 def test_objective_handling(self):
     """test objective handling"""
     q_p = QuadraticProgram()
     q_p.binary_var("x")
     q_p.binary_var("y")
     q_p.binary_var("z")
     q_p.minimize()
     obj = q_p.objective
     self.assertEqual(obj.sense, QuadraticObjective.Sense.MINIMIZE)
     self.assertEqual(obj.constant, 0)
     self.assertDictEqual(obj.linear.to_dict(), {})
     self.assertDictEqual(obj.quadratic.to_dict(), {})
     q_p.maximize(1, {"y": 1}, {("z", "x"): 1, ("y", "y"): 1})
     obj = q_p.objective
     self.assertEqual(obj.sense, QuadraticObjective.Sense.MAXIMIZE)
     self.assertEqual(obj.constant, 1)
     self.assertDictEqual(obj.linear.to_dict(), {1: 1})
     self.assertDictEqual(obj.linear.to_dict(use_name=True), {"y": 1})
     self.assertListEqual(obj.linear.to_array().tolist(), [0, 1, 0])
     self.assertDictEqual(obj.quadratic.to_dict(), {(0, 2): 1, (1, 1): 1})
     self.assertDictEqual(
         obj.quadratic.to_dict(symmetric=True), {(0, 2): 0.5, (2, 0): 0.5, (1, 1): 1}
     )
     self.assertDictEqual(obj.quadratic.to_dict(use_name=True), {("x", "z"): 1, ("y", "y"): 1})
     self.assertDictEqual(
         obj.quadratic.to_dict(use_name=True, symmetric=True),
         {("x", "z"): 0.5, ("z", "x"): 0.5, ("y", "y"): 1},
     )
     self.assertListEqual(obj.quadratic.to_array().tolist(), [[0, 0, 1], [0, 1, 0], [0, 0, 0]])
     self.assertListEqual(
         obj.quadratic.to_array(symmetric=True).tolist(),
         [[0, 0, 0.5], [0, 1, 0], [0.5, 0, 0]],
     )
Ejemplo n.º 8
0
    def test_write_to_lp_file(self):
        """test write problem"""
        q_p = QuadraticProgram("my problem")
        q_p.binary_var("x")
        q_p.integer_var(-1, 5, "y")
        q_p.continuous_var(-1, 5, "z")
        q_p.minimize(1, {"x": 1, "y": -1, "z": 10}, {("x", "x"): 0.5, ("y", "z"): -1})
        q_p.linear_constraint({"x": 1, "y": 2}, "==", 1, "lin_eq")
        q_p.linear_constraint({"x": 1, "y": 2}, "<=", 1, "lin_leq")
        q_p.linear_constraint({"x": 1, "y": 2}, ">=", 1, "lin_geq")
        q_p.quadratic_constraint(
            {"x": 1, "y": 1},
            {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2},
            "==",
            1,
            "quad_eq",
        )
        q_p.quadratic_constraint(
            {"x": 1, "y": 1},
            {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2},
            "<=",
            1,
            "quad_leq",
        )
        q_p.quadratic_constraint(
            {"x": 1, "y": 1},
            {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2},
            ">=",
            1,
            "quad_geq",
        )

        reference_file_name = self.get_resource_path(
            "test_quadratic_program.lp", "problems/resources"
        )
        with tempfile.TemporaryDirectory() as tmp:
            temp_output_path = path.join(tmp, "temp.lp")
            q_p.write_to_lp_file(temp_output_path)
            with open(reference_file_name, encoding="utf8") as reference, open(
                temp_output_path, encoding="utf8"
            ) as temp_output_file:
                lines1 = temp_output_file.readlines()
                lines2 = reference.readlines()
                self.assertListEqual(lines1, lines2)

        with tempfile.TemporaryDirectory() as temp_problem_dir:
            q_p.write_to_lp_file(temp_problem_dir)
            with open(path.join(temp_problem_dir, "my_problem.lp"), encoding="utf8") as file1, open(
                reference_file_name, encoding="utf8"
            ) as file2:
                lines1 = file1.readlines()
                lines2 = file2.readlines()
                self.assertListEqual(lines1, lines2)

        with self.assertRaises(OSError):
            q_p.write_to_lp_file("/cannot/write/this/file.lp")

        with self.assertRaises(DOcplexException):
            q_p.write_to_lp_file("")
Ejemplo n.º 9
0
def build_qubo_unconstrained_from_nodes(G, routes_dict):
    all_edges_dict = get_edges_dict(routes_dict)
    qubo = QuadraticProgram()
    linear, quadratic = get_linear_quadratic_coeffs(G, all_edges_dict)
    for var in routes_dict.keys():
        qubo.binary_var(var)
    qubo.minimize(linear=linear, quadratic=quadratic)
    return qubo, linear, quadratic
    def test_linear_inequality_to_penalty7(self):
        """Test special constraint to penalty 6 x-y >= 0 -> P(y-x*y)"""

        op = QuadraticProgram()
        lip = LinearInequalityToPenalty()

        op.binary_var(name="x")
        op.binary_var(name="y")
        # Linear constraints
        linear_constraint = {"x": 1, "y": -1}
        op.linear_constraint(linear_constraint, Constraint.Sense.GE, 0,
                             "P(y-xy)")

        # Test with no max/min
        with self.subTest("No max/min"):
            self.assertEqual(op.get_num_linear_constraints(), 1)
            penalty = 1
            linear = {"y": penalty}
            quadratic = {("x", "y"): -1 * penalty}
            op2 = lip.convert(op)
            ldct = op2.objective.linear.to_dict(use_name=True)
            qdct = op2.objective.quadratic.to_dict(use_name=True)
            self.assertEqual(ldct, linear)
            self.assertEqual(qdct, quadratic)
            self.assertEqual(op2.get_num_linear_constraints(), 0)

        # Test maximize
        with self.subTest("Maximize"):
            linear = {"x": 2, "y": 1}
            op.maximize(linear=linear)
            penalty = 4
            linear["y"] = linear["y"] - penalty
            quadratic = {("x", "y"): penalty}
            op2 = lip.convert(op)
            ldct = op2.objective.linear.to_dict(use_name=True)
            qdct = op2.objective.quadratic.to_dict(use_name=True)
            self.assertEqual(ldct, linear)
            self.assertEqual(qdct, quadratic)
            self.assertEqual(op2.get_num_linear_constraints(), 0)

        # Test minimize
        with self.subTest("Minimize"):
            linear = {"x": 2, "y": 1}
            op.minimize(linear={"x": 2, "y": 1})
            penalty = 4
            linear["y"] = linear["y"] + penalty
            quadratic = {("x", "y"): -1 * penalty}
            op2 = lip.convert(op)
            ldct = op2.objective.linear.to_dict(use_name=True)
            qdct = op2.objective.quadratic.to_dict(use_name=True)
            self.assertEqual(ldct, linear)
            self.assertEqual(qdct, quadratic)
            self.assertEqual(op2.get_num_linear_constraints(), 0)
 def test_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)
Ejemplo n.º 12
0
 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(), {})
Ejemplo n.º 13
0
 def test_auto_penalty_warning(self):
     """ Test warnings of auto penalty function"""
     op = QuadraticProgram()
     op.binary_var('x')
     op.binary_var('y')
     op.binary_var('z')
     op.minimize(linear={'x': 1, 'y': 2})
     op.linear_constraint(linear={'x': 0.5, 'y': 0.5, 'z': 0.5}, sense='EQ', rhs=1, name='xyz')
     with self.assertLogs('qiskit_optimization', level='WARNING') as log:
         lineq2penalty = LinearEqualityToPenalty()
         _ = lineq2penalty.convert(op)
     warning = (
         'WARNING:qiskit_optimization.converters.linear_equality_to_penalty:'
         'Warning: Using 100000.000000 for the penalty coefficient because a float '
         'coefficient exists in constraints. \nThe value could be too small. If so, '
         'set the penalty coefficient manually.'
     )
     self.assertIn(warning, log.output)
Ejemplo n.º 14
0
    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])
Ejemplo n.º 15
0
 def test_str_repr(self):
     """Test str and repr"""
     q_p = QuadraticProgram("my problem")
     q_p.binary_var("x")
     q_p.integer_var(-1, 5, "y")
     q_p.continuous_var(-1, 5, "z")
     q_p.minimize(1, {"x": 1, "y": -1, "z": 10}, {("x", "x"): 0.5, ("y", "z"): -1})
     q_p.linear_constraint({"x": 1, "y": 2}, "==", 1, "lin_eq")
     q_p.linear_constraint({"x": 1, "y": 2}, "<=", 1, "lin_leq")
     q_p.linear_constraint({"x": 1, "y": 2}, ">=", 1, "lin_geq")
     q_p.quadratic_constraint(
         {"x": 1, "y": 1},
         {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2},
         "==",
         1,
         "quad_eq",
     )
     q_p.quadratic_constraint(
         {"x": 1, "y": 1},
         {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2},
         "<=",
         1,
         "quad_leq",
     )
     q_p.quadratic_constraint(
         {"x": 1, "y": 1},
         {("x", "x"): 1, ("y", "z"): -1, ("z", "z"): 2},
         ">=",
         1,
         "quad_geq",
     )
     self.assertEqual(
         str(q_p),
         "minimize 0.5*x^2 - y*z + x - y + 10*z + 1 (3 variables, 6 constraints, 'my problem')",
     )
     self.assertEqual(
         repr(q_p),
         "<QuadraticProgram: minimize 0.5*x^2 - y*z + x - y + 10*z + 1, "
         "3 variables, 6 constraints, 'my problem'>",
     )
 def test_clear(self):
     """ test clear """
     q_p = QuadraticProgram('test')
     q_p.binary_var('x')
     q_p.binary_var('y')
     q_p.minimize(constant=1,
                  linear={
                      'x': 1,
                      'y': 2
                  },
                  quadratic={('x', 'x'): 1})
     q_p.linear_constraint({'x': 1}, '==', 1)
     q_p.quadratic_constraint({'x': 1}, {('y', 'y'): 2}, '<=', 1)
     q_p.clear()
     self.assertEqual(q_p.name, '')
     self.assertEqual(q_p.status, QuadraticProgram.Status.VALID)
     self.assertEqual(q_p.get_num_vars(), 0)
     self.assertEqual(q_p.get_num_linear_constraints(), 0)
     self.assertEqual(q_p.get_num_quadratic_constraints(), 0)
     self.assertEqual(q_p.objective.constant, 0)
     self.assertDictEqual(q_p.objective.linear.to_dict(), {})
     self.assertDictEqual(q_p.objective.quadratic.to_dict(), {})
Ejemplo n.º 17
0
 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
         },
     )
Ejemplo n.º 18
0
 def test_auto_penalty_warning(self):
     """Test warnings of auto penalty function"""
     op = QuadraticProgram()
     op.binary_var("x")
     op.binary_var("y")
     op.binary_var("z")
     op.minimize(linear={"x": 1, "y": 2})
     op.linear_constraint(linear={
         "x": 0.5,
         "y": 0.5,
         "z": 0.5
     },
                          sense="EQ",
                          rhs=1,
                          name="xyz")
     with self.assertLogs("qiskit_optimization", level="WARNING") as log:
         lineq2penalty = LinearEqualityToPenalty()
         _ = lineq2penalty.convert(op)
     warning = (
         "WARNING:qiskit_optimization.converters.linear_equality_to_penalty:"
         "Warning: Using 100000.000000 for the penalty coefficient because a float "
         "coefficient exists in constraints. \nThe value could be too small. If so, "
         "set the penalty coefficient manually.")
     self.assertIn(warning, log.output)
    def test_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_linear_inequality_to_penalty1(self):
        """Test special constraint to penalty x+y <= 1 -> P(x*y)"""

        op = QuadraticProgram()
        lip = LinearInequalityToPenalty()

        op.binary_var(name="x")
        op.binary_var(name="y")
        # Linear constraints
        linear_constraint = {"x": 1, "y": 1}
        op.linear_constraint(linear_constraint, Constraint.Sense.LE, 1,
                             "P(xy)")

        # Test with no max/min
        with self.subTest("No max/min"):
            self.assertEqual(op.get_num_linear_constraints(), 1)
            lip.penalty = 1
            quadratic = {("x", "y"): lip.penalty}
            op2 = lip.convert(op)
            qdct = op2.objective.quadratic.to_dict(use_name=True)
            self.assertEqual(qdct, quadratic)
            self.assertEqual(op2.get_num_linear_constraints(), 0)

        # Test maximize
        with self.subTest("Maximize"):
            linear = {"x": 2, "y": 1}
            op.maximize(linear=linear)
            lip.penalty = 5
            quadratic = {("x", "y"): -1 * lip.penalty}
            op2 = lip.convert(op)
            ldct = op2.objective.linear.to_dict(use_name=True)
            qdct = op2.objective.quadratic.to_dict(use_name=True)
            self.assertEqual(ldct, linear)
            self.assertEqual(qdct, quadratic)
            self.assertEqual(op2.get_num_linear_constraints(), 0)

        # Test minimize
        with self.subTest("Minimize"):
            linear = {"x": 2, "y": 1}
            op.minimize(linear=linear)
            lip.penalty = 5
            quadratic = {("x", "y"): lip.penalty}
            op2 = lip.convert(op)
            ldct = op2.objective.linear.to_dict(use_name=True)
            qdct = op2.objective.quadratic.to_dict(use_name=True)
            self.assertEqual(ldct, linear)
            self.assertEqual(qdct, quadratic)
            self.assertEqual(op2.get_num_linear_constraints(), 0)

        # Test combination
        with self.subTest("Combination"):
            op = QuadraticProgram()
            lip = LinearInequalityToPenalty()

            op.binary_var(name="x")
            op.binary_var(name="y")
            op.binary_var(name="z")
            op.binary_var(name="w")
            linear = {"x": 2, "y": 1, "z": -1, "w": 1}
            quadratic = {("y", "z"): -2, ("w", "w"): 1}
            op.minimize(linear=linear, quadratic=quadratic)

            linear_constraint = {"x": 1, "w": 1}
            op.linear_constraint(linear_constraint, Constraint.Sense.LE, 1,
                                 "P(xw)")
            linear_constraint = {"y": 1, "z": 1}
            op.linear_constraint(linear_constraint, Constraint.Sense.LE, 1,
                                 "P(yz)")
            linear_constraint = {"y": 2, "z": 1}
            op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1,
                                 "None 1")
            quadratic_constraint = {("x", "x"): -2, ("y", "w"): 1}
            op.quadratic_constraint(linear_constraint, quadratic_constraint,
                                    Constraint.Sense.LE, 1, "None 2")

            lip.penalty = 5
            op2 = lip.convert(op)
            quadratic[("x", "w")] = lip.penalty
            quadratic[("y", "z")] = quadratic[("y", "z")] + lip.penalty
            ldct = op2.objective.linear.to_dict(use_name=True)
            qdct = op2.objective.quadratic.to_dict(use_name=True)
            self.assertEqual(ldct, linear)
            self.assertEqual(qdct, quadratic)
            self.assertEqual(op2.get_num_linear_constraints(), 1)
            self.assertEqual(op2.get_num_quadratic_constraints(), 1)
Ejemplo n.º 21
0
    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")
Ejemplo n.º 22
0
    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)

        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_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_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])