def test_init(self):
        """test init."""

        quadratic_program = QuadraticProgram()
        for _ in range(5):
            quadratic_program.continuous_var()

        coefficients_list = [[0 for _ in range(5)] for _ in range(5)]
        for i, v in enumerate(coefficients_list):
            for j, _ in enumerate(v):
                coefficients_list[min(i, j)][max(i, j)] += i * j
        coefficients_array = np.array(coefficients_list)
        coefficients_dok = dok_matrix(coefficients_list)
        coefficients_dict_int = {(i, j): v
                                 for (i, j), v in coefficients_dok.items()}
        coefficients_dict_str = {(f"x{i}", f"x{j}"): v
                                 for (i, j), v in coefficients_dok.items()}

        for coeffs in [
                coefficients_list,
                coefficients_array,
                coefficients_dok,
                coefficients_dict_int,
                coefficients_dict_str,
        ]:
            quadratic = QuadraticExpression(quadratic_program, coeffs)
            self.assertEqual((quadratic.coefficients != coefficients_dok).nnz,
                             0)
            self.assertTrue((quadratic.to_array() == coefficients_list).all())
            self.assertDictEqual(quadratic.to_dict(use_name=False),
                                 coefficients_dict_int)
            self.assertDictEqual(quadratic.to_dict(use_name=True),
                                 coefficients_dict_str)
    def test_setters(self):
        """test setters."""

        quadratic_program = QuadraticProgram()
        for _ in range(5):
            quadratic_program.continuous_var()

        zeros = np.zeros(quadratic_program.get_num_vars())
        linear = LinearExpression(quadratic_program, zeros)

        coefficients_list = list(range(5))
        coefficients_array = np.array(coefficients_list)
        coefficients_dok = dok_matrix([coefficients_list])
        coefficients_dict_int = {i: i for i in range(1, 5)}
        coefficients_dict_str = {f"x{i}": i for i in range(1, 5)}

        for coeffs in [
            coefficients_list,
            coefficients_array,
            coefficients_dok,
            coefficients_dict_int,
            coefficients_dict_str,
        ]:
            linear.coefficients = coeffs
            self.assertEqual((linear.coefficients != coefficients_dok).nnz, 0)
            self.assertTrue((linear.to_array() == coefficients_list).all())
            self.assertDictEqual(linear.to_dict(use_name=False), coefficients_dict_int)
            self.assertDictEqual(linear.to_dict(use_name=True), coefficients_dict_str)
    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.º 4
0
    def test_setters(self):
        """ test setters. """

        quadratic_program = QuadraticProgram()
        for _ in range(5):
            quadratic_program.continuous_var()

        n = quadratic_program.get_num_vars()
        zeros = np.zeros((n, n))
        quadratic = QuadraticExpression(quadratic_program, zeros)

        coefficients_list = [[0 for _ in range(5)] for _ in range(5)]
        for i, v in enumerate(coefficients_list):
            for j, _ in enumerate(v):
                coefficients_list[min(i, j)][max(i, j)] += i * j
        coefficients_array = np.array(coefficients_list)
        coefficients_dok = dok_matrix(coefficients_list)
        coefficients_dict_int = {(i, j): v for (i, j), v in coefficients_dok.items()}
        coefficients_dict_str = {('x{}'.format(i), 'x{}'.format(j)): v for (i, j), v in
                                 coefficients_dok.items()}

        for coeffs in [coefficients_list,
                       coefficients_array,
                       coefficients_dok,
                       coefficients_dict_int,
                       coefficients_dict_str]:
            quadratic.coefficients = coeffs
            self.assertEqual((quadratic.coefficients != coefficients_dok).nnz, 0)
            self.assertTrue((quadratic.to_array() == coefficients_list).all())
            self.assertDictEqual(quadratic.to_dict(use_name=False), coefficients_dict_int)
            self.assertDictEqual(quadratic.to_dict(use_name=True), coefficients_dict_str)
    def test_init(self):
        """test init."""

        quadratic_program = QuadraticProgram()
        for _ in range(5):
            quadratic_program.continuous_var()

        coefficients_list = list(range(5))
        coefficients_array = np.array(coefficients_list)
        coefficients_dok = dok_matrix([coefficients_list])
        coefficients_dict_int = {i: i for i in range(1, 5)}
        coefficients_dict_str = {"x{}".format(i): i for i in range(1, 5)}

        for coeffs in [
                coefficients_list,
                coefficients_array,
                coefficients_dok,
                coefficients_dict_int,
                coefficients_dict_str,
        ]:
            linear = LinearExpression(quadratic_program, coeffs)
            self.assertEqual((linear.coefficients != coefficients_dok).nnz, 0)
            self.assertTrue((linear.to_array() == coefficients_list).all())
            self.assertDictEqual(linear.to_dict(use_name=False),
                                 coefficients_dict_int)
            self.assertDictEqual(linear.to_dict(use_name=True),
                                 coefficients_dict_str)
Ejemplo n.º 6
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.º 7
0
    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_get_item(self):
        """test get_item."""

        quadratic_program = QuadraticProgram()
        for _ in range(5):
            quadratic_program.continuous_var()

        coefficients = list(range(5))
        linear = LinearExpression(quadratic_program, coefficients)
        for i, v in enumerate(coefficients):
            self.assertEqual(linear[i], v)
Ejemplo n.º 9
0
 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()
Ejemplo n.º 10
0
    def test_get_item(self):
        """ test get_item. """

        quadratic_program = QuadraticProgram()
        for _ in range(5):
            quadratic_program.continuous_var()

        coefficients = [[0 for _ in range(5)] for _ in range(5)]
        for i, v in enumerate(coefficients):
            for j, _ in enumerate(v):
                coefficients[min(i, j)][max(i, j)] += i * j
        quadratic = QuadraticExpression(quadratic_program, coefficients)
        for i, j_v in enumerate(coefficients):
            for j, _ in enumerate(j_v):
                if i == j:
                    self.assertEqual(quadratic[i, j], coefficients[i][j])
                else:
                    self.assertEqual(quadratic[i, j], coefficients[i][j] + coefficients[j][i])
Ejemplo n.º 11
0
    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)
Ejemplo n.º 12
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_evaluate_gradient(self):
        """ test evaluate gradient. """

        quadratic_program = QuadraticProgram()
        x = [quadratic_program.continuous_var() for _ in range(5)]

        coefficients_list = list(range(5))
        linear = LinearExpression(quadratic_program, coefficients_list)

        values_list = list(range(len(x)))
        values_array = np.array(values_list)
        values_dict_int = {i: i for i in range(len(x))}
        values_dict_str = {'x{}'.format(i): i for i in range(len(x))}

        for values in [values_list, values_array, values_dict_int, values_dict_str]:
            np.testing.assert_almost_equal(linear.evaluate_gradient(values), coefficients_list)
    def test_evaluate(self):
        """test evaluate."""

        quadratic_program = QuadraticProgram()
        x = [quadratic_program.continuous_var() for _ in range(5)]

        coefficients_list = list(range(5))
        linear = LinearExpression(quadratic_program, coefficients_list)

        values_list = list(range(len(x)))
        values_array = np.array(values_list)
        values_dict_int = {i: i for i in range(len(x))}
        values_dict_str = {f"x{i}": i for i in range(len(x))}

        for values in [values_list, values_array, values_dict_int, values_dict_str]:
            self.assertEqual(linear.evaluate(values), 30)
Ejemplo n.º 15
0
    def test_evaluate(self):
        """ test evaluate. """

        quadratic_program = QuadraticProgram()
        x = [quadratic_program.continuous_var() for _ in range(5)]

        coefficients_list = [[0 for _ in range(5)] for _ in range(5)]
        for i, v in enumerate(coefficients_list):
            for j, _ in enumerate(v):
                coefficients_list[min(i, j)][max(i, j)] += i * j
        quadratic = QuadraticExpression(quadratic_program, coefficients_list)

        values_list = list(range(len(x)))
        values_array = np.array(values_list)
        values_dict_int = {i: i for i in range(len(x))}
        values_dict_str = {'x{}'.format(i): i for i in range(len(x))}

        for values in [values_list, values_array, values_dict_int, values_dict_str]:
            self.assertEqual(quadratic.evaluate(values), 900)
Ejemplo n.º 16
0
    def test_evaluate_gradient(self):
        """ test evaluate gradient. """

        quadratic_program = QuadraticProgram()
        x = [quadratic_program.continuous_var() for _ in range(5)]

        coefficients_list = [[0 for _ in range(5)] for _ in range(5)]
        for i, v in enumerate(coefficients_list):
            for j, _ in enumerate(v):
                coefficients_list[min(i, j)][max(i, j)] += i * j
        quadratic = QuadraticExpression(quadratic_program, coefficients_list)

        values_list = list(range(len(x)))
        values_array = np.array(values_list)
        values_dict_int = {i: i for i in range(len(x))}
        values_dict_str = {'x{}'.format(i): i for i in range(len(x))}

        grad_values = [0., 60., 120., 180., 240.]
        for values in [values_list, values_array, values_dict_int, values_dict_str]:
            np.testing.assert_almost_equal(quadratic.evaluate_gradient(values), grad_values)
Ejemplo n.º 17
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_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_init(self):
        """test init."""

        quadratic_program = QuadraticProgram()
        for _ in range(5):
            quadratic_program.continuous_var()
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 0)

        coefficients = np.array(range(5))

        # equality constraints
        quadratic_program.linear_constraint(sense="==")
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 1)
        self.assertEqual(quadratic_program.linear_constraints[0].name, "c0")
        self.assertEqual(
            len(quadratic_program.linear_constraints[0].linear.to_dict()), 0)
        self.assertEqual(quadratic_program.linear_constraints[0].sense,
                         Constraint.Sense.EQ)
        self.assertEqual(quadratic_program.linear_constraints[0].rhs, 0.0)
        self.assertEqual(
            quadratic_program.linear_constraints[0],
            quadratic_program.get_linear_constraint("c0"),
        )
        self.assertEqual(
            quadratic_program.linear_constraints[0],
            quadratic_program.get_linear_constraint(0),
        )

        with self.assertRaises(QiskitOptimizationError):
            quadratic_program.linear_constraint(name="c0")

        quadratic_program.linear_constraint(coefficients, "==", 1.0, "c1")
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 2)
        self.assertEqual(quadratic_program.linear_constraints[1].name, "c1")
        self.assertTrue(
            (quadratic_program.linear_constraints[1].linear.to_array() ==
             coefficients).all())
        self.assertEqual(quadratic_program.linear_constraints[1].sense,
                         Constraint.Sense.EQ)
        self.assertEqual(quadratic_program.linear_constraints[1].rhs, 1.0)
        self.assertEqual(
            quadratic_program.linear_constraints[1],
            quadratic_program.get_linear_constraint("c1"),
        )
        self.assertEqual(
            quadratic_program.linear_constraints[1],
            quadratic_program.get_linear_constraint(1),
        )

        # geq constraints
        quadratic_program.linear_constraint(sense=">=")
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 3)
        self.assertEqual(quadratic_program.linear_constraints[2].name, "c2")
        self.assertEqual(
            len(quadratic_program.linear_constraints[2].linear.to_dict()), 0)
        self.assertEqual(quadratic_program.linear_constraints[2].sense,
                         Constraint.Sense.GE)
        self.assertEqual(quadratic_program.linear_constraints[2].rhs, 0.0)
        self.assertEqual(
            quadratic_program.linear_constraints[2],
            quadratic_program.get_linear_constraint("c2"),
        )
        self.assertEqual(
            quadratic_program.linear_constraints[2],
            quadratic_program.get_linear_constraint(2),
        )

        with self.assertRaises(QiskitOptimizationError):
            quadratic_program.linear_constraint(name="c2", sense=">=")

        quadratic_program.linear_constraint(coefficients, ">=", 1.0, "c3")
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 4)
        self.assertEqual(quadratic_program.linear_constraints[3].name, "c3")
        self.assertTrue(
            (quadratic_program.linear_constraints[3].linear.to_array() ==
             coefficients).all())
        self.assertEqual(quadratic_program.linear_constraints[3].sense,
                         Constraint.Sense.GE)
        self.assertEqual(quadratic_program.linear_constraints[3].rhs, 1.0)
        self.assertEqual(
            quadratic_program.linear_constraints[3],
            quadratic_program.get_linear_constraint("c3"),
        )
        self.assertEqual(
            quadratic_program.linear_constraints[3],
            quadratic_program.get_linear_constraint(3),
        )

        # leq constraints
        quadratic_program.linear_constraint(sense="<=")
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 5)
        self.assertEqual(quadratic_program.linear_constraints[4].name, "c4")
        self.assertEqual(
            len(quadratic_program.linear_constraints[4].linear.to_dict()), 0)
        self.assertEqual(quadratic_program.linear_constraints[4].sense,
                         Constraint.Sense.LE)
        self.assertEqual(quadratic_program.linear_constraints[4].rhs, 0.0)
        self.assertEqual(
            quadratic_program.linear_constraints[4],
            quadratic_program.get_linear_constraint("c4"),
        )
        self.assertEqual(
            quadratic_program.linear_constraints[4],
            quadratic_program.get_linear_constraint(4),
        )

        with self.assertRaises(QiskitOptimizationError):
            quadratic_program.linear_constraint(name="c4", sense="<=")

        quadratic_program.linear_constraint(coefficients, "<=", 1.0, "c5")
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 6)
        self.assertEqual(quadratic_program.linear_constraints[5].name, "c5")
        self.assertTrue(
            (quadratic_program.linear_constraints[5].linear.to_array() ==
             coefficients).all())
        self.assertEqual(quadratic_program.linear_constraints[5].sense,
                         Constraint.Sense.LE)
        self.assertEqual(quadratic_program.linear_constraints[5].rhs, 1.0)
        self.assertEqual(
            quadratic_program.linear_constraints[5],
            quadratic_program.get_linear_constraint("c5"),
        )
        self.assertEqual(
            quadratic_program.linear_constraints[5],
            quadratic_program.get_linear_constraint(5),
        )
    def test_init(self):
        """ test init. """

        quadratic_program = QuadraticProgram()
        for _ in range(5):
            quadratic_program.continuous_var()
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 0)

        coefficients = np.array(range(5))

        # equality constraints
        quadratic_program.linear_constraint(sense='==')
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 1)
        self.assertEqual(quadratic_program.linear_constraints[0].name, 'c0')
        self.assertEqual(
            len(quadratic_program.linear_constraints[0].linear.to_dict()), 0)
        self.assertEqual(quadratic_program.linear_constraints[0].sense,
                         Constraint.Sense.EQ)
        self.assertEqual(quadratic_program.linear_constraints[0].rhs, 0.0)
        self.assertEqual(quadratic_program.linear_constraints[0],
                         quadratic_program.get_linear_constraint('c0'))
        self.assertEqual(quadratic_program.linear_constraints[0],
                         quadratic_program.get_linear_constraint(0))

        with self.assertRaises(QiskitOptimizationError):
            quadratic_program.linear_constraint(name='c0')

        quadratic_program.linear_constraint(coefficients, '==', 1.0, 'c1')
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 2)
        self.assertEqual(quadratic_program.linear_constraints[1].name, 'c1')
        self.assertTrue(
            (quadratic_program.linear_constraints[1].linear.to_array() ==
             coefficients).all())
        self.assertEqual(quadratic_program.linear_constraints[1].sense,
                         Constraint.Sense.EQ)
        self.assertEqual(quadratic_program.linear_constraints[1].rhs, 1.0)
        self.assertEqual(quadratic_program.linear_constraints[1],
                         quadratic_program.get_linear_constraint('c1'))
        self.assertEqual(quadratic_program.linear_constraints[1],
                         quadratic_program.get_linear_constraint(1))

        # geq constraints
        quadratic_program.linear_constraint(sense='>=')
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 3)
        self.assertEqual(quadratic_program.linear_constraints[2].name, 'c2')
        self.assertEqual(
            len(quadratic_program.linear_constraints[2].linear.to_dict()), 0)
        self.assertEqual(quadratic_program.linear_constraints[2].sense,
                         Constraint.Sense.GE)
        self.assertEqual(quadratic_program.linear_constraints[2].rhs, 0.0)
        self.assertEqual(quadratic_program.linear_constraints[2],
                         quadratic_program.get_linear_constraint('c2'))
        self.assertEqual(quadratic_program.linear_constraints[2],
                         quadratic_program.get_linear_constraint(2))

        with self.assertRaises(QiskitOptimizationError):
            quadratic_program.linear_constraint(name='c2', sense='>=')

        quadratic_program.linear_constraint(coefficients, '>=', 1.0, 'c3')
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 4)
        self.assertEqual(quadratic_program.linear_constraints[3].name, 'c3')
        self.assertTrue(
            (quadratic_program.linear_constraints[3].linear.to_array() ==
             coefficients).all())
        self.assertEqual(quadratic_program.linear_constraints[3].sense,
                         Constraint.Sense.GE)
        self.assertEqual(quadratic_program.linear_constraints[3].rhs, 1.0)
        self.assertEqual(quadratic_program.linear_constraints[3],
                         quadratic_program.get_linear_constraint('c3'))
        self.assertEqual(quadratic_program.linear_constraints[3],
                         quadratic_program.get_linear_constraint(3))

        # leq constraints
        quadratic_program.linear_constraint(sense='<=')
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 5)
        self.assertEqual(quadratic_program.linear_constraints[4].name, 'c4')
        self.assertEqual(
            len(quadratic_program.linear_constraints[4].linear.to_dict()), 0)
        self.assertEqual(quadratic_program.linear_constraints[4].sense,
                         Constraint.Sense.LE)
        self.assertEqual(quadratic_program.linear_constraints[4].rhs, 0.0)
        self.assertEqual(quadratic_program.linear_constraints[4],
                         quadratic_program.get_linear_constraint('c4'))
        self.assertEqual(quadratic_program.linear_constraints[4],
                         quadratic_program.get_linear_constraint(4))

        with self.assertRaises(QiskitOptimizationError):
            quadratic_program.linear_constraint(name='c4', sense='<=')

        quadratic_program.linear_constraint(coefficients, '<=', 1.0, 'c5')
        self.assertEqual(quadratic_program.get_num_linear_constraints(), 6)
        self.assertEqual(quadratic_program.linear_constraints[5].name, 'c5')
        self.assertTrue(
            (quadratic_program.linear_constraints[5].linear.to_array() ==
             coefficients).all())
        self.assertEqual(quadratic_program.linear_constraints[5].sense,
                         Constraint.Sense.LE)
        self.assertEqual(quadratic_program.linear_constraints[5].rhs, 1.0)
        self.assertEqual(quadratic_program.linear_constraints[5],
                         quadratic_program.get_linear_constraint('c5'))
        self.assertEqual(quadratic_program.linear_constraints[5],
                         quadratic_program.get_linear_constraint(5))
    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_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_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_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_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)})
Ejemplo n.º 26
0
    def test_init(self):
        """test init."""

        quadratic_program = QuadraticProgram()
        for _ in range(5):
            quadratic_program.continuous_var()
        self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 0)

        linear_coeffs = np.array(range(5))
        lst = [[0 for _ in range(5)] for _ in range(5)]
        for i, v in enumerate(lst):
            for j, _ in enumerate(v):
                lst[min(i, j)][max(i, j)] += i * j
        quadratic_coeffs = np.array(lst)

        # equality constraints
        quadratic_program.quadratic_constraint(sense="==")
        self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 1)
        self.assertEqual(quadratic_program.quadratic_constraints[0].name, "q0")
        self.assertEqual(len(quadratic_program.quadratic_constraints[0].linear.to_dict()), 0)
        self.assertEqual(len(quadratic_program.quadratic_constraints[0].quadratic.to_dict()), 0)
        self.assertEqual(quadratic_program.quadratic_constraints[0].sense, Constraint.Sense.EQ)
        self.assertEqual(quadratic_program.quadratic_constraints[0].rhs, 0.0)
        self.assertEqual(
            quadratic_program.quadratic_constraints[0],
            quadratic_program.get_quadratic_constraint("q0"),
        )
        self.assertEqual(
            quadratic_program.quadratic_constraints[0],
            quadratic_program.get_quadratic_constraint(0),
        )

        self.assertEqual(quadratic_program.quadratic_constraints[0].evaluate(linear_coeffs), 0.0)

        with self.assertRaises(QiskitOptimizationError):
            quadratic_program.quadratic_constraint(name="q0", sense="==")

        quadratic_program.quadratic_constraint(linear_coeffs, quadratic_coeffs, "==", 1.0, "q1")
        self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 2)
        self.assertEqual(quadratic_program.quadratic_constraints[1].name, "q1")
        self.assertTrue(
            (quadratic_program.quadratic_constraints[1].linear.to_array() == linear_coeffs).all()
        )
        self.assertTrue(
            (
                quadratic_program.quadratic_constraints[1].quadratic.to_array() == quadratic_coeffs
            ).all()
        )
        self.assertEqual(quadratic_program.quadratic_constraints[1].sense, Constraint.Sense.EQ)
        self.assertEqual(quadratic_program.quadratic_constraints[1].rhs, 1.0)
        self.assertEqual(
            quadratic_program.quadratic_constraints[1],
            quadratic_program.get_quadratic_constraint("q1"),
        )
        self.assertEqual(
            quadratic_program.quadratic_constraints[1],
            quadratic_program.get_quadratic_constraint(1),
        )

        self.assertEqual(quadratic_program.quadratic_constraints[1].evaluate(linear_coeffs), 930.0)

        # geq constraints
        quadratic_program.quadratic_constraint(sense=">=")
        self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 3)
        self.assertEqual(quadratic_program.quadratic_constraints[2].name, "q2")
        self.assertEqual(len(quadratic_program.quadratic_constraints[2].linear.to_dict()), 0)
        self.assertEqual(len(quadratic_program.quadratic_constraints[2].quadratic.to_dict()), 0)
        self.assertEqual(quadratic_program.quadratic_constraints[2].sense, Constraint.Sense.GE)
        self.assertEqual(quadratic_program.quadratic_constraints[2].rhs, 0.0)
        self.assertEqual(
            quadratic_program.quadratic_constraints[2],
            quadratic_program.get_quadratic_constraint("q2"),
        )
        self.assertEqual(
            quadratic_program.quadratic_constraints[2],
            quadratic_program.get_quadratic_constraint(2),
        )

        self.assertEqual(quadratic_program.quadratic_constraints[2].evaluate(linear_coeffs), 0.0)

        with self.assertRaises(QiskitOptimizationError):
            quadratic_program.quadratic_constraint(name="q2", sense=">=")

        quadratic_program.quadratic_constraint(linear_coeffs, quadratic_coeffs, ">=", 1.0, "q3")
        self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 4)
        self.assertEqual(quadratic_program.quadratic_constraints[3].name, "q3")
        self.assertTrue(
            (quadratic_program.quadratic_constraints[3].linear.to_array() == linear_coeffs).all()
        )
        self.assertTrue(
            (
                quadratic_program.quadratic_constraints[3].quadratic.to_array() == quadratic_coeffs
            ).all()
        )
        self.assertEqual(quadratic_program.quadratic_constraints[3].sense, Constraint.Sense.GE)
        self.assertEqual(quadratic_program.quadratic_constraints[3].rhs, 1.0)
        self.assertEqual(
            quadratic_program.quadratic_constraints[3],
            quadratic_program.get_quadratic_constraint("q3"),
        )
        self.assertEqual(
            quadratic_program.quadratic_constraints[3],
            quadratic_program.get_quadratic_constraint(3),
        )

        self.assertEqual(quadratic_program.quadratic_constraints[3].evaluate(linear_coeffs), 930.0)

        # leq constraints
        quadratic_program.quadratic_constraint(sense="<=")
        self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 5)
        self.assertEqual(quadratic_program.quadratic_constraints[4].name, "q4")
        self.assertEqual(len(quadratic_program.quadratic_constraints[4].linear.to_dict()), 0)
        self.assertEqual(quadratic_program.quadratic_constraints[4].sense, Constraint.Sense.LE)
        self.assertEqual(quadratic_program.quadratic_constraints[4].rhs, 0.0)
        self.assertEqual(
            quadratic_program.quadratic_constraints[4],
            quadratic_program.get_quadratic_constraint("q4"),
        )
        self.assertEqual(
            quadratic_program.quadratic_constraints[4],
            quadratic_program.get_quadratic_constraint(4),
        )

        self.assertEqual(quadratic_program.quadratic_constraints[4].evaluate(linear_coeffs), 0.0)

        with self.assertRaises(QiskitOptimizationError):
            quadratic_program.quadratic_constraint(name="q4", sense="<=")

        quadratic_program.quadratic_constraint(linear_coeffs, quadratic_coeffs, "<=", 1.0, "q5")
        self.assertEqual(quadratic_program.get_num_quadratic_constraints(), 6)
        self.assertEqual(quadratic_program.quadratic_constraints[5].name, "q5")
        self.assertTrue(
            (quadratic_program.quadratic_constraints[5].linear.to_array() == linear_coeffs).all()
        )
        self.assertTrue(
            (
                quadratic_program.quadratic_constraints[5].quadratic.to_array() == quadratic_coeffs
            ).all()
        )
        self.assertEqual(quadratic_program.quadratic_constraints[5].sense, Constraint.Sense.LE)
        self.assertEqual(quadratic_program.quadratic_constraints[5].rhs, 1.0)
        self.assertEqual(
            quadratic_program.quadratic_constraints[5],
            quadratic_program.get_quadratic_constraint("q5"),
        )
        self.assertEqual(
            quadratic_program.quadratic_constraints[5],
            quadratic_program.get_quadratic_constraint(5),
        )

        self.assertEqual(quadratic_program.quadratic_constraints[5].evaluate(linear_coeffs), 930.0)