def test_to_ising(self):
        """test to_ising"""

        with self.subTest("minimize"):
            # minimize: x + x * y
            # subject to: x, y \in {0, 1}
            q_p = QuadraticProgram("test")
            q_p.binary_var(name="x")
            q_p.binary_var(name="y")
            q_p.minimize(linear={"x": 1}, quadratic={("x", "y"): 1})
            op, offset = to_ising(q_p)
            op_ref = PauliSumOp.from_list([("ZI", -0.25), ("IZ", -0.75), ("ZZ", 0.25)])
            np.testing.assert_allclose(op.to_matrix(), op_ref.to_matrix())
            self.assertAlmostEqual(offset, 0.75)

        with self.subTest("maximize"):
            # maximize: x + x * y
            # subject to: x, y \in {0, 1}
            q_p = QuadraticProgram("test")
            q_p.binary_var(name="x")
            q_p.binary_var(name="y")
            q_p.maximize(linear={"x": 1}, quadratic={("x", "y"): 1})
            op, offset = to_ising(q_p)
            op_ref = PauliSumOp.from_list([("ZI", 0.25), ("IZ", 0.75), ("ZZ", -0.25)])
            np.testing.assert_allclose(op.to_matrix(), op_ref.to_matrix())
            self.assertAlmostEqual(offset, -0.75)
示例#2
0
 def test_prettyprint2(self):
     """Test prettyprint with special characters (' ', '+', '-', '*')"""
     q_p = QuadraticProgram("+ test - test *")
     q_p.binary_var(" x ")
     q_p.continuous_var(1e-10, 1e10, "+y+")
     q_p.continuous_var(-1e10, -1e-10, "-y-")
     q_p.integer_var(10, 100, "*z*")
     q_p.minimize(1, [1, 2, 3, 4])
     expected = "\n".join([
         "Problem name: + test - test *",
         "",
         "Minimize",
         "   x  + 4**z* + 2*+y+ + 3*-y- + 1",
         "",
         "Subject to",
         "  No constraints",
         "",
         "  Integer variables (1)",
         "    10 <= *z* <= 100",
         "",
         "  Continuous variables (2)",
         "    1e-10 <= +y+ <= 10000000000",
         "    -10000000000 <= -y- <= -1e-10",
         "",
         "  Binary variables (1)",
         "     x ",
         "",
     ])
     self.assertEqual(prettyprint(q_p), expected)
     self.assertEqual(q_p.prettyprint(), expected)
    def test_to_ising2(self):
        """test to_ising 2"""

        with self.subTest("minimize"):
            # minimize: 1 - 2 * x1 - 2 * x2 + 4 * x1 * x2
            # subject to: x, y \in {0, 1}
            q_p = QuadraticProgram("test")
            q_p.binary_var(name="x")
            q_p.binary_var(name="y")
            q_p.minimize(constant=1, linear={"x": -2, "y": -2}, quadratic={("x", "y"): 4})
            op, offset = to_ising(q_p)
            op_ref = PauliSumOp.from_list([("ZZ", 1.0)])
            np.testing.assert_allclose(op.to_matrix(), op_ref.to_matrix())
            self.assertAlmostEqual(offset, 0.0)

        with self.subTest("maximize"):
            # maximize: 1 - 2 * x1 - 2 * x2 + 4 * x1 * x2
            # subject to: x, y \in {0, 1}
            q_p = QuadraticProgram("test")
            q_p.binary_var(name="x")
            q_p.binary_var(name="y")
            q_p.maximize(constant=1, linear={"x": -2, "y": -2}, quadratic={("x", "y"): 4})
            op, offset = to_ising(q_p)
            op_ref = PauliSumOp.from_list([("ZZ", -1.0)])
            np.testing.assert_allclose(op.to_matrix(), op_ref.to_matrix())
            self.assertAlmostEqual(offset, 0.0)
 def test_samples_and_raw_samples(self):
     """Test samples and raw_samples"""
     op = QuadraticProgram()
     op.integer_var(0, 3, 'x')
     op.binary_var('y')
     op.minimize(linear={'x': 1, 'y': 2})
     op.linear_constraint(linear={
         'x': 1,
         'y': 1
     },
                          sense='>=',
                          rhs=1,
                          name='xy')
     opt_sol = 1
     success = OptimizationResultStatus.SUCCESS
     algorithm_globals.random_seed = 1
     grover_optimizer = GroverOptimizer(
         5, num_iterations=2, quantum_instance=self.qasm_simulator)
     result = grover_optimizer.solve(op)
     self.assertEqual(len(result.samples), 8)
     self.assertEqual(len(result.raw_samples), 32)
     self.assertAlmostEqual(sum(s.probability for s in result.samples), 1)
     self.assertAlmostEqual(sum(s.probability for s in result.raw_samples),
                            1)
     self.assertAlmostEqual(min(s.fval for s in result.samples), 0)
     self.assertAlmostEqual(
         min(s.fval for s in result.samples if s.status == success),
         opt_sol)
     self.assertAlmostEqual(min(s.fval for s in result.raw_samples),
                            opt_sol)
     for sample in result.raw_samples:
         self.assertEqual(sample.status, success)
     np.testing.assert_array_almost_equal(result.x, result.samples[0].x)
     self.assertAlmostEqual(result.fval, result.samples[0].fval)
     self.assertEqual(result.status, result.samples[0].status)
示例#5
0
    def test_from_and_to(self):
        """test from_docplex_mp and to_docplex_mp"""
        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 = from_docplex_mp(to_docplex_mp(q_p))
        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())
示例#6
0
 def test_samples_and_raw_samples(self, simulator):
     """Test samples and raw_samples"""
     algorithm_globals.random_seed = 2
     op = QuadraticProgram()
     op.integer_var(0, 3, "x")
     op.binary_var("y")
     op.minimize(linear={"x": 1, "y": 2})
     op.linear_constraint(linear={"x": 1, "y": 1}, sense=">=", rhs=1, name="xy")
     q_instance = self.sv_simulator if simulator == "sv" else self.qasm_simulator
     grover_optimizer = GroverOptimizer(
         8, num_iterations=self.n_iter, quantum_instance=q_instance
     )
     opt_sol = 1
     success = OptimizationResultStatus.SUCCESS
     results = grover_optimizer.solve(op)
     self.assertEqual(len(results.samples), 8)
     self.assertEqual(len(results.raw_samples), 32)
     self.assertAlmostEqual(sum(s.probability for s in results.samples), 1)
     self.assertAlmostEqual(sum(s.probability for s in results.raw_samples), 1)
     self.assertAlmostEqual(min(s.fval for s in results.samples), 0)
     self.assertAlmostEqual(min(s.fval for s in results.samples if s.status == success), opt_sol)
     self.assertAlmostEqual(min(s.fval for s in results.raw_samples), opt_sol)
     for sample in results.raw_samples:
         self.assertEqual(sample.status, success)
     np.testing.assert_array_almost_equal(results.x, results.samples[0].x)
     self.assertAlmostEqual(results.fval, results.samples[0].fval)
     self.assertEqual(results.status, results.samples[0].status)
     self.assertAlmostEqual(results.fval, results.raw_samples[0].fval)
     self.assertEqual(results.status, results.raw_samples[0].status)
     np.testing.assert_array_almost_equal([1, 0, 0, 0, 0], results.raw_samples[0].x)
    def test_to_quadratic_program(self):
        """Test to_quadratic_program"""
        portfolio_diversification = PortfolioDiversification(
            similarity_matrix=self.similarity_matrix,
            num_assets=self.n,
            num_clusters=self.q,
        )

        actual_op = portfolio_diversification.to_quadratic_program()

        expected_op = QuadraticProgram(name="Portfolio diversification")
        for i in range(self.n):
            for j in range(self.n):
                expected_op.binary_var(name="x_{0}_{1}".format(i, j))
        for i in range(self.n):
            expected_op.binary_var(name="y_{0}".format(i))
        linear = {"x_0_0": 1, "x_0_1": 0.8, "x_1_0": 0.8, "x_1_1": 1}
        expected_op.maximize(linear=linear)
        expected_op.linear_constraint(linear={"y_0": 1, "y_1": 1}, sense="==", rhs=1)
        expected_op.linear_constraint(linear={"x_0_0": 1, "x_0_1": 1}, sense="==", rhs=1)
        expected_op.linear_constraint(linear={"x_1_0": 1, "x_1_1": 1}, sense="==", rhs=1)
        expected_op.linear_constraint(linear={"x_0_0": 1, "y_0": -1}, sense="==", rhs=0)
        expected_op.linear_constraint(linear={"x_1_1": 1, "y_1": -1}, sense="==", rhs=0)
        expected_op.linear_constraint(linear={"x_0_0": 1, "y_0": -1}, sense="<=", rhs=0)
        expected_op.linear_constraint(linear={"x_0_1": 1, "y_1": -1}, sense="<=", rhs=0)
        expected_op.linear_constraint(linear={"x_1_0": 1, "y_0": -1}, sense="<=", rhs=0)
        expected_op.linear_constraint(linear={"x_1_1": 1, "y_1": -1}, sense="<=", rhs=0)
        self.assertEqualQuadraticProgram(actual_op, expected_op)
    def test_converter_list(self):
        """Test converter list"""
        op = QuadraticProgram()
        op.integer_var(0, 3, "x")
        op.binary_var('y')

        op.maximize(linear={'x': 1, 'y': 2})
        op.linear_constraint(linear={'x': 1, 'y': 1}, sense='LE', rhs=3, name='xy_leq')
        min_eigen_solver = NumPyMinimumEigensolver()
        # a single converter
        qp2qubo = QuadraticProgramToQubo()
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver, converters=qp2qubo)
        result = min_eigen_optimizer.solve(op)
        self.assertEqual(result.fval, 4)
        # a list of converters
        ineq2eq = InequalityToEquality()
        int2bin = IntegerToBinary()
        penalize = LinearEqualityToPenalty()
        converters = [ineq2eq, int2bin, penalize]
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver, converters=converters)
        result = min_eigen_optimizer.solve(op)
        self.assertEqual(result.fval, 4)
        with self.assertRaises(TypeError):
            invalid = [qp2qubo, "invalid converter"]
            MinimumEigenOptimizer(min_eigen_solver,
                                  converters=invalid)
示例#9
0
    def test_error(self):
        """Test error case due to non-printable names"""

        name = "\n"
        with self.subTest("problem name - func"), self.assertRaises(
                QiskitOptimizationError):
            q_p = QuadraticProgram(name)
            _ = prettyprint(q_p)

        with self.subTest("problem name - meth"), self.assertRaises(
                QiskitOptimizationError):
            q_p = QuadraticProgram(name)
            _ = q_p.prettyprint()

        with self.subTest("linear variable name - func"), self.assertRaises(
                QiskitOptimizationError):
            q_p = QuadraticProgram()
            q_p.binary_var(name)
            _ = prettyprint(q_p)

        with self.subTest("linear variable name - meth"), self.assertRaises(
                QiskitOptimizationError):
            q_p = QuadraticProgram()
            q_p.binary_var(name)
            _ = q_p.prettyprint()

        with self.subTest("linear constraint name - func"), self.assertRaises(
                QiskitOptimizationError):
            q_p = QuadraticProgram()
            q_p.linear_constraint(name=name)
            _ = prettyprint(q_p)

        with self.subTest("linear constraint name - meth"), self.assertRaises(
                QiskitOptimizationError):
            q_p = QuadraticProgram()
            q_p.linear_constraint(name=name)
            _ = q_p.prettyprint()

        with self.subTest("quadratic constraint name - func"
                          ), self.assertRaises(QiskitOptimizationError):
            q_p = QuadraticProgram()
            q_p.quadratic_constraint(name=name)
            _ = prettyprint(q_p)

        with self.subTest("quadratic constraint name - meth"
                          ), self.assertRaises(QiskitOptimizationError):
            q_p = QuadraticProgram()
            q_p.quadratic_constraint(name=name)
            _ = q_p.prettyprint()
    def test_to_quadratic_program(self):
        """Test to_quadratic_program"""
        portfolio_optimization = PortfolioOptimization(
            self.expected_returns, self.covariances, self.risk_factor, self.budget
        )
        actual_op = portfolio_optimization.to_quadratic_program()

        expected_op = QuadraticProgram(name="Portfolio optimization")
        for i in range(self.num_assets):
            expected_op.binary_var(name="x_{0}".format(i))
        quadratic = {
            (i, j): self.risk_factor * self.covariances[i][j]
            for i in range(self.num_assets)
            for j in range(self.num_assets)
        }
        linear = {i: -self.expected_returns[i] for i in range(self.num_assets)}
        expected_op.minimize(quadratic=quadratic, linear=linear)
        linear = {i: 1 for i in range(self.num_assets)}
        expected_op.linear_constraint(linear=linear, sense="==", rhs=self.budget)
        self.assertEqualQuadraticProgram(actual_op, expected_op)
 def test_to_quadratic_program(self):
     """Test to_quadratic_program"""
     # When bounds is None
     portfolio_optimization = PortfolioOptimization(
         self.expected_returns, self.covariances, self.risk_factor, self.budget
     )
     actual_op = portfolio_optimization.to_quadratic_program()
     expected_op = QuadraticProgram(name="Portfolio optimization")
     for i in range(self.num_assets):
         expected_op.binary_var(name=f"x_{i}")
     quadratic = {
         (i, j): self.risk_factor * self.covariances[i][j]
         for i in range(self.num_assets)
         for j in range(self.num_assets)
     }
     linear = {i: -self.expected_returns[i] for i in range(self.num_assets)}
     expected_op.minimize(quadratic=quadratic, linear=linear)
     linear = {i: 1 for i in range(self.num_assets)}
     expected_op.linear_constraint(linear=linear, sense="==", rhs=self.budget)
     self.assertEqualQuadraticProgram(actual_op, expected_op)
     # When bounds is provided
     portfolio_optimization = PortfolioOptimization(
         self.expected_returns, self.covariances, self.risk_factor, self.budget, self.bounds
     )
     actual_op = portfolio_optimization.to_quadratic_program()
     expected_op = QuadraticProgram(name="Portfolio optimization")
     for i in range(self.num_assets):
         expected_op.integer_var(
             lowerbound=self.bounds[i][0], upperbound=self.bounds[i][1], name=f"x_{i}"
         )
     quadratic = {
         (i, j): self.risk_factor * self.covariances[i][j]
         for i in range(self.num_assets)
         for j in range(self.num_assets)
     }
     linear = {i: -self.expected_returns[i] for i in range(self.num_assets)}
     expected_op.minimize(quadratic=quadratic, linear=linear)
     linear = {i: 1 for i in range(self.num_assets)}
     expected_op.linear_constraint(linear=linear, sense="==", rhs=self.budget)
     self.assertEqualQuadraticProgram(actual_op, expected_op)
    def test_converter_list(self):
        """Test converter list"""
        op = QuadraticProgram()
        op.integer_var(0, 3, "x")
        op.binary_var("y")

        op.maximize(linear={"x": 1, "y": 2})
        op.linear_constraint(linear={
            "y": 1,
            "x": 1
        },
                             sense="LE",
                             rhs=3,
                             name="xy_leq")

        # construct minimum eigen optimizer
        min_eigen_solver = NumPyMinimumEigensolver()
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver)
        # a single converter
        qp2qubo = QuadraticProgramToQubo()
        recursive_min_eigen_optimizer = RecursiveMinimumEigenOptimizer(
            min_eigen_optimizer, min_num_vars=2, converters=qp2qubo)
        result = recursive_min_eigen_optimizer.solve(op)
        self.assertEqual(result.fval, 4)
        # a list of converters
        ineq2eq = InequalityToEquality()
        int2bin = IntegerToBinary()
        penalize = LinearEqualityToPenalty()
        converters = [ineq2eq, int2bin, penalize]
        recursive_min_eigen_optimizer = RecursiveMinimumEigenOptimizer(
            min_eigen_optimizer, min_num_vars=2, converters=converters)
        result = recursive_min_eigen_optimizer.solve(op)
        self.assertEqual(result.fval, 4)
        # invalid converters
        with self.assertRaises(TypeError):
            invalid = [qp2qubo, "invalid converter"]
            RecursiveMinimumEigenOptimizer(min_eigen_optimizer,
                                           min_num_vars=2,
                                           converters=invalid)
示例#13
0
    def test_str_repr(self):
        """test str and repr"""
        quadratic_program = QuadraticProgram()

        with self.subTest("binary"):
            bin_var = quadratic_program.binary_var(name="x")
            expected = "x (binary)"
            self.assertEqual(str(bin_var), expected)
            self.assertEqual(repr(bin_var), f"<Variable: {expected}>")

        with self.subTest("integer 1"):
            int_var = quadratic_program.integer_var(name="y1")
            expected = "0 <= y1 (integer)"
            self.assertEqual(str(int_var), expected)
            self.assertEqual(repr(int_var), f"<Variable: {expected}>")

        with self.subTest("integer 2"):
            int_var2 = quadratic_program.integer_var(lowerbound=5, upperbound=10, name="y2")
            expected = "5 <= y2 <= 10 (integer)"
            self.assertEqual(str(int_var2), expected)
            self.assertEqual(repr(int_var2), f"<Variable: {expected}>")

        with self.subTest("continuous 1"):
            con_var = quadratic_program.continuous_var(name="z1")
            expected = "0 <= z1 (continuous)"
            self.assertEqual(str(con_var), expected)
            self.assertEqual(repr(con_var), f"<Variable: {expected}>")

        with self.subTest("continuous 2"):
            con_var2 = quadratic_program.continuous_var(
                lowerbound=-10.0, upperbound=100.0, name="z2"
            )
            expected = "-10.0 <= z2 <= 100.0 (continuous)"
            self.assertEqual(str(con_var2), expected)
            self.assertEqual(repr(con_var2), f"<Variable: {expected}>")

        with self.subTest("continuous 3"):
            con_var3 = quadratic_program.continuous_var(
                lowerbound=-INFINITY, upperbound=100.0, name="z3"
            )
            expected = "z3 <= 100.0 (continuous)"
            self.assertEqual(str(con_var3), expected)
            self.assertEqual(repr(con_var3), f"<Variable: {expected}>")
    def test_to_quadratic_program(self):
        """Test to_quadratic_program"""
        portfolio_diversification = PortfolioDiversification(
            similarity_matrix=self.similarity_matrix,
            num_assets=self.n,
            num_clusters=self.q)

        actual_op = portfolio_diversification.to_quadratic_program()

        expected_op = QuadraticProgram(name='Portfolio diversification')
        for i in range(self.n):
            for j in range(self.n):
                expected_op.binary_var(name='x_{0}_{1}'.format(i, j))
        for i in range(self.n):
            expected_op.binary_var(name='y_{0}'.format(i))
        linear = {'x_0_0': 1, 'x_0_1': 0.8, 'x_1_0': 0.8, 'x_1_1': 1}
        expected_op.maximize(linear=linear)
        expected_op.linear_constraint(linear={
            'y_0': 1,
            'y_1': 1
        },
                                      sense='==',
                                      rhs=1)
        expected_op.linear_constraint(linear={
            'x_0_0': 1,
            'x_0_1': 1
        },
                                      sense='==',
                                      rhs=1)
        expected_op.linear_constraint(linear={
            'x_1_0': 1,
            'x_1_1': 1
        },
                                      sense='==',
                                      rhs=1)
        expected_op.linear_constraint(linear={
            'x_0_0': 1,
            'y_0': -1
        },
                                      sense='==',
                                      rhs=0)
        expected_op.linear_constraint(linear={
            'x_1_1': 1,
            'y_1': -1
        },
                                      sense='==',
                                      rhs=0)
        expected_op.linear_constraint(linear={
            'x_0_0': 1,
            'y_0': -1
        },
                                      sense='<=',
                                      rhs=0)
        expected_op.linear_constraint(linear={
            'x_0_1': 1,
            'y_1': -1
        },
                                      sense='<=',
                                      rhs=0)
        expected_op.linear_constraint(linear={
            'x_1_0': 1,
            'y_0': -1
        },
                                      sense='<=',
                                      rhs=0)
        expected_op.linear_constraint(linear={
            'x_1_1': 1,
            'y_1': -1
        },
                                      sense='<=',
                                      rhs=0)
        self.assertEqualQuadraticProgram(actual_op, expected_op)
示例#15
0
    def test_from_and_to(self):
        """test from_gurobipy and to_gurobipy"""
        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 = from_gurobipy(to_gurobipy(q_p))
        self.assertEqual(q_p.export_as_lp_string(), q_p2.export_as_lp_string())

        try:
            import gurobipy as gp
        except ImportError as ex:
            raise MissingOptionalLibraryError(
                libname="GUROBI",
                name="GurobiOptimizer",
                pip_install="pip install qiskit-optimization[gurobi]",
            ) from ex

        mod = gp.Model("test")
        x = mod.addVar(vtype=gp.GRB.BINARY, name="x")
        y = mod.addVar(vtype=gp.GRB.INTEGER, lb=-2, ub=4, name="y")
        z = mod.addVar(vtype=gp.GRB.CONTINUOUS, lb=-1.5, ub=3.2, name="z")
        mod.setObjective(1 + x + 2 * y - x * y + 2 * z * z)
        mod.addConstr(2 * x - z == 1, name="c0")
        mod.addConstr(2 * x - z + 3 * y * z == 1, name="q0")

        # Here I am unsure what to do, let's come back to it later
        # self.assertEqual(q_p.export_as_lp_string(), mod.export_as_lp_string())

        with self.assertRaises(QiskitOptimizationError):
            mod = gp.Model()
            mod.addVar(vtype=gp.GRB.SEMIINT, lb=1, name="x")
            _ = from_gurobipy(mod)

        with self.assertRaises(QiskitOptimizationError):
            mod = gp.Model()
            x = mod.addVar(vtype=gp.GRB.BINARY, name="x")
            y = mod.addVar(vtype=gp.GRB.BINARY, name="y")
            mod.addConstr((x == 1) >> (x + y <= 1))
            _ = from_gurobipy(mod)

        # test from_gurobipy without explicit variable names
        mod = gp.Model()
        x = mod.addVar(vtype=gp.GRB.BINARY)
        y = mod.addVar(vtype=gp.GRB.CONTINUOUS)
        z = mod.addVar(vtype=gp.GRB.INTEGER)
        mod.setObjective(x + y + z + x * y + y * z + x * z)
        mod.addConstr(x + y == z)  # linear EQ
        mod.addConstr(x + y >= z)  # linear GE
        mod.addConstr(x + y <= z)  # linear LE
        mod.addConstr(x * y == z)  # quadratic EQ
        mod.addConstr(x * y >= z)  # quadratic GE
        mod.addConstr(x * y <= z)  # quadratic LE
        q_p = from_gurobipy(mod)
        var_names = [v.name for v in q_p.variables]
        self.assertListEqual(var_names, ["C0", "C1", "C2"])
        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), {"C0": 1, "C1": 1, "C2": -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), {"C2": -1})
            self.assertDictEqual(c.quadratic.to_dict(use_name=True), {("C0", "C1"): 1})
            self.assertEqual(c.sense, senses[i])
示例#16
0
    def test_wrap(self):
        """Test wrap"""
        with self.subTest("minimize, wrap=15"):
            q_p = QuadraticProgram("my problem")
            q_p.binary_var("x")
            q_p.binary_var_list(10, "u")
            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",
            )
            expected = "\n".join([
                "Problem name: my problem",
                "",
                "Minimize",
                "  0.5*x^2 - y*z",
                "  + x - y",
                "  + 10*z + 1",
                "",
                "Subject to",
                "  Linear constraints (3)",
                "    x + 2*y",
                "    == 1  'lin_eq'",
                "    x + 2*y",
                "    <= 1  'lin_leq'",
                "    x + 2*y",
                "    >= 1  'lin_geq'",
                "",
                "  Quadratic constraints (3)",
                "    x^2 - y*z",
                "    + 2*z^2 + x",
                "    + y",
                "    == 1  'quad_eq'",
                "    x^2 - y*z",
                "    + 2*z^2 + x",
                "    + y",
                "    <= 1  'quad_leq'",
                "    x^2 - y*z",
                "    + 2*z^2 + x",
                "    + y",
                "    >= 1  'quad_geq'",
                "",
                "  Integer variables (1)",
                "    -1 <= y <= 5",
                "",
                "  Continuous variables (1)",
                "    -1 <= z <= 5",
                "",
                "  Binary variables (11)",
                "    x u1 u2 u3",
                "    u4 u5 u6 u7",
                "    u8 u9 u10",
                "",
            ])
            wrap = 15
            self.assertEqual(prettyprint(q_p, wrap), expected)
            self.assertEqual(q_p.prettyprint(wrap), expected)

        with self.subTest("minimize, wrap=22"):
            q_p = QuadraticProgram("my problem")
            q_p.binary_var("x")
            q_p.binary_var_list(10, "u")
            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",
            )
            expected = "\n".join([
                "Problem name: my problem",
                "",
                "Minimize",
                "  0.5*x^2 - y*z + x",
                "  - y + 10*z + 1",
                "",
                "Subject to",
                "  Linear constraints (3)",
                "    x + 2*y",
                "    == 1  'lin_eq'",
                "    x + 2*y",
                "    <= 1  'lin_leq'",
                "    x + 2*y",
                "    >= 1  'lin_geq'",
                "",
                "  Quadratic constraints (3)",
                "    x^2 - y*z + 2*z^2",
                "    + x + y",
                "    == 1  'quad_eq'",
                "    x^2 - y*z + 2*z^2",
                "    + x + y",
                "    <= 1  'quad_leq'",
                "    x^2 - y*z + 2*z^2",
                "    + x + y",
                "    >= 1  'quad_geq'",
                "",
                "  Integer variables (1)",
                "    -1 <= y <= 5",
                "",
                "  Continuous variables (1)",
                "    -1 <= z <= 5",
                "",
                "  Binary variables (11)",
                "    x u1 u2 u3 u4 u5",
                "    u6 u7 u8 u9 u10",
                "",
            ])
            wrap = 22
            self.assertEqual(prettyprint(q_p, wrap), expected)
            self.assertEqual(q_p.prettyprint(wrap), expected)

        with self.subTest("minimize, wrap=23"):
            q_p = QuadraticProgram("my problem")
            q_p.binary_var("x")
            q_p.binary_var_list(10, "u")
            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",
            )
            expected = "\n".join([
                "Problem name: my problem",
                "",
                "Minimize",
                "  0.5*x^2 - y*z + x - y",
                "  + 10*z + 1",
                "",
                "Subject to",
                "  Linear constraints (3)",
                "    x + 2*y",
                "    == 1  'lin_eq'",
                "    x + 2*y",
                "    <= 1  'lin_leq'",
                "    x + 2*y",
                "    >= 1  'lin_geq'",
                "",
                "  Quadratic constraints (3)",
                "    x^2 - y*z + 2*z^2",
                "    + x + y",
                "    == 1  'quad_eq'",
                "    x^2 - y*z + 2*z^2",
                "    + x + y",
                "    <= 1  'quad_leq'",
                "    x^2 - y*z + 2*z^2",
                "    + x + y",
                "    >= 1  'quad_geq'",
                "",
                "  Integer variables (1)",
                "    -1 <= y <= 5",
                "",
                "  Continuous variables (1)",
                "    -1 <= z <= 5",
                "",
                "  Binary variables (11)",
                "    x u1 u2 u3 u4 u5 u6",
                "    u7 u8 u9 u10",
                "",
            ])
            wrap = 23
            self.assertEqual(prettyprint(q_p, wrap), expected)
            self.assertEqual(q_p.prettyprint(wrap), expected)
示例#17
0
    def test_prettyprint(self):
        """Test prettyprint"""

        with self.subTest("empty"):
            q_p = QuadraticProgram()
            expected = "\n".join([
                "Problem name: ",
                "",
                "Minimize",
                "  0",
                "",
                "Subject to",
                "  No constraints",
                "",
                "  No variables",
                "",
            ])
            self.assertEqual(prettyprint(q_p), expected)
            self.assertEqual(q_p.prettyprint(), expected)

        with self.subTest("minimize 1"):
            q_p = QuadraticProgram("test")
            q_p.binary_var(name="x")
            q_p.binary_var(name="y")
            q_p.minimize(linear={"x": 1}, quadratic={("x", "y"): 1})
            expected = "\n".join([
                "Problem name: test",
                "",
                "Minimize",
                "  x*y + x",
                "",
                "Subject to",
                "  No constraints",
                "",
                "  Binary variables (2)",
                "    x y",
                "",
            ])
            self.assertEqual(prettyprint(q_p), expected)
            self.assertEqual(q_p.prettyprint(), expected)

        with self.subTest("maximize 1"):
            q_p = QuadraticProgram("test")
            q_p.integer_var(lowerbound=5, upperbound=10, name="x")
            q_p.continuous_var(lowerbound=-1, name="y")
            q_p.maximize(linear={"x": -1, "y": 2}, constant=3)
            q_p.quadratic_constraint({}, {("x", "y"): -1}, "<=", 4)
            expected = "\n".join([
                "Problem name: test",
                "",
                "Maximize",
                "  -x + 2*y + 3",
                "",
                "Subject to",
                "  Quadratic constraints (1)",
                "    -x*y <= 4  'q0'",
                "",
                "  Integer variables (1)",
                "    5 <= x <= 10",
                "",
                "  Continuous variables (1)",
                "    -1 <= y",
                "",
            ])
            self.assertEqual(prettyprint(q_p), expected)
            self.assertEqual(q_p.prettyprint(), expected)

        with self.subTest("minimize 2"):
            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",
            )
            expected = "\n".join([
                "Problem name: my problem",
                "",
                "Minimize",
                "  0.5*x^2 - y*z + x - y + 10*z + 1",
                "",
                "Subject to",
                "  Linear constraints (3)",
                "    x + 2*y == 1  'lin_eq'",
                "    x + 2*y <= 1  'lin_leq'",
                "    x + 2*y >= 1  'lin_geq'",
                "",
                "  Quadratic constraints (3)",
                "    x^2 - y*z + 2*z^2 + x + y == 1  'quad_eq'",
                "    x^2 - y*z + 2*z^2 + x + y <= 1  'quad_leq'",
                "    x^2 - y*z + 2*z^2 + x + y >= 1  'quad_geq'",
                "",
                "  Integer variables (1)",
                "    -1 <= y <= 5",
                "",
                "  Continuous variables (1)",
                "    -1 <= z <= 5",
                "",
                "  Binary variables (1)",
                "    x",
                "",
            ])
            self.assertEqual(prettyprint(q_p), expected)
            self.assertEqual(q_p.prettyprint(), expected)

        with self.subTest("maximize 2"):
            q_p = QuadraticProgram("problem 1")
            q_p.integer_var(-1, 2, "x")
            q_p.integer_var(-1, 2, "y")
            q_p.continuous_var(-1, name="z")
            q_p.binary_var("u")
            q_p.binary_var("very_long_variable")
            q_p.binary_var_list(10)
            q_p.integer_var_list(3)
            q_p.continuous_var_list(3)
            q_p.minimize(constant=3,
                         linear={
                             "x": 2,
                             "y": 3
                         },
                         quadratic={("u", "x"): -1})
            q_p.linear_constraint({"x": 1, "y": -2}, ">=", 2, name="lin_GE")
            q_p.linear_constraint({"x": 2, "y": -1}, "==", 1, name="lin_EQ")
            q_p.quadratic_constraint({
                "x": 1,
                "u": 1
            }, {
                (3, 4): 1,
                (5, 6): -1
            },
                                     "<=",
                                     1,
                                     name="quad_LE")
            q_p.quadratic_constraint({
                "x": 2,
                "y": -1
            }, {("z", "z"): -1}, "<=", 1)
            expected = "\n".join([
                "Problem name: problem 1",
                "",
                "Minimize",
                "  -x*u + 2*x + 3*y + 3",
                "",
                "Subject to",
                "  Linear constraints (2)",
                "    x - 2*y >= 2  'lin_GE'",
                "    2*x - y == 1  'lin_EQ'",
                "",
                "  Quadratic constraints (2)",
                "    u*very_long_variable - x5*x6 + u + x <= 1  'quad_LE'",
                "    -z^2 + 2*x - y <= 1  'q1'",
                "",
                "  Integer variables (5)",
                "    -1 <= x <= 2",
                "    -1 <= y <= 2",
                "    0 <= x15",
                "    0 <= x16",
                "    0 <= x17",
                "",
                "  Continuous variables (4)",
                "    -1 <= z",
                "    0 <= x18",
                "    0 <= x19",
                "    0 <= x20",
                "",
                "  Binary variables (12)",
                "    u very_long_variable x5 x6 x7 x8 x9 x10 x11 x12 x13 x14",
                "",
            ])
            self.assertEqual(prettyprint(q_p), expected)
            self.assertEqual(q_p.prettyprint(), expected)
    def test_str_repr(self):
        """Test str and repr"""
        with self.subTest("4 variables"):
            n = 4
            q_p = QuadraticProgram()
            q_p.binary_var_list(n)  # x0,...,x3
            quad = {(i, i): float(i) for i in range(n)}
            lin = [float(i) for i in range(n)]

            q_p.maximize(quadratic=quad, linear=lin, constant=n)
            expected = "maximize x1^2 + 2*x2^2 + 3*x3^2 + x1 + 2*x2 + 3*x3 + 4"
            self.assertEqual(str(q_p.objective), expected)
            self.assertEqual(repr(q_p.objective), f"<QuadraticObjective: {expected}>")

            q_p.minimize(quadratic=quad, linear=lin, constant=n)
            expected = "minimize x1^2 + 2*x2^2 + 3*x3^2 + x1 + 2*x2 + 3*x3 + 4"
            self.assertEqual(str(q_p.objective), expected)
            self.assertEqual(repr(q_p.objective), f"<QuadraticObjective: {expected}>")

            quad = {(i, (i + 1) % n): i for i in range(n)}

            q_p.maximize(quadratic=quad, linear=lin, constant=0)
            expected = "maximize 3*x0*x3 + x1*x2 + 2*x2*x3 + x1 + 2*x2 + 3*x3"
            self.assertEqual(str(q_p.objective), expected)
            self.assertEqual(repr(q_p.objective), f"<QuadraticObjective: {expected}>")

            q_p.minimize(quadratic=quad, linear=lin, constant=0)
            expected = "minimize 3*x0*x3 + x1*x2 + 2*x2*x3 + x1 + 2*x2 + 3*x3"
            self.assertEqual(str(q_p.objective), expected)
            self.assertEqual(repr(q_p.objective), f"<QuadraticObjective: {expected}>")

        with self.subTest("50 variables"):
            # pylint: disable=cyclic-import
            from qiskit_optimization.translators.prettyprint import DEFAULT_TRUNCATE

            n = 50
            q_p = QuadraticProgram()
            q_p.binary_var_list(n)
            quad = {(i, i): float(i) for i in range(n)}
            lin = [float(i) for i in range(n)]

            expected = " ".join(
                ["x1^2"]
                + sorted([f"+ {i}*x{i}^2" for i in range(2, n)], key=lambda e: e.split(" ")[1])
                + ["+ x1"]
                + sorted([f"+ {i}*x{i}" for i in range(2, n)], key=lambda e: e.split(" ")[1])
                + [f"+ {n}"]
            )
            q_p.maximize(quadratic=quad, linear=lin, constant=n)
            self.assertEqual(str(q_p.objective), f"maximize {expected}")
            self.assertEqual(
                repr(q_p.objective),
                f"<QuadraticObjective: maximize {expected[:DEFAULT_TRUNCATE]}...>",
            )

            q_p.minimize(quadratic=quad, linear=lin, constant=n)
            self.assertEqual(str(q_p.objective), f"minimize {expected}")
            self.assertEqual(
                repr(q_p.objective),
                f"<QuadraticObjective: minimize {expected[:DEFAULT_TRUNCATE]}...>",
            )

            quad = {(i + 1, i): float(i + 1) for i in range(2)}
            lin = [float(i) for i in range(n)]
            expected = " ".join(
                ["x0*x1 + 2*x1*x2"]
                + ["+ x1"]
                + sorted([f"+ {i}*x{i}" for i in range(2, n)], key=lambda e: e.split(" ")[1])
                + [f"+ {n}"]
            )
            q_p.maximize(quadratic=quad, linear=lin, constant=n)
            self.assertEqual(str(q_p.objective), f"maximize {expected}")
            self.assertEqual(
                repr(q_p.objective),
                f"<QuadraticObjective: maximize {expected[:DEFAULT_TRUNCATE]}...>",
            )

            q_p.minimize(quadratic=quad, linear=lin, constant=n)
            self.assertEqual(str(q_p.objective), f"minimize {expected}")
            self.assertEqual(
                repr(q_p.objective),
                f"<QuadraticObjective: minimize {expected[:DEFAULT_TRUNCATE]}...>",
            )

        with self.subTest("only constant"):
            q_p = QuadraticProgram()

            q_p.maximize()
            expected = "maximize 0"
            self.assertEqual(str(q_p.objective), expected)
            self.assertEqual(repr(q_p.objective), f"<QuadraticObjective: {expected}>")

            q_p.minimize()
            expected = "minimize 0"
            self.assertEqual(str(q_p.objective), expected)
            self.assertEqual(repr(q_p.objective), f"<QuadraticObjective: {expected}>")

            q_p.maximize(constant=-1.23)
            expected = "maximize -1.23"
            self.assertEqual(str(q_p.objective), expected)
            self.assertEqual(repr(q_p.objective), f"<QuadraticObjective: {expected}>")

            q_p.minimize(constant=-1.23)
            expected = "minimize -1.23"
            self.assertEqual(str(q_p.objective), expected)
            self.assertEqual(repr(q_p.objective), f"<QuadraticObjective: {expected}>")

        with self.subTest("1 variable"):
            q_p = QuadraticProgram()
            q_p.binary_var("z")

            q_p.maximize(linear=[1], quadratic={("z", "z"): -1}, constant=1)
            expected = "maximize -z^2 + z + 1"
            self.assertEqual(str(q_p.objective), expected)
            self.assertEqual(repr(q_p.objective), f"<QuadraticObjective: {expected}>")

            q_p.minimize(linear=[1], quadratic={("z", "z"): -1}, constant=1)
            expected = "minimize -z^2 + z + 1"
            self.assertEqual(str(q_p.objective), expected)
            self.assertEqual(repr(q_p.objective), f"<QuadraticObjective: {expected}>")
    def test_samples(self):
        """Test samples"""
        SUCCESS = OptimizationResultStatus.SUCCESS  # pylint: disable=invalid-name
        algorithm_globals.random_seed = 123
        quantum_instance = QuantumInstance(backend=BasicAer.get_backend('qasm_simulator'),
                                           seed_simulator=123, seed_transpiler=123,
                                           shots=1000)

        # test minimize
        op = QuadraticProgram()
        op.integer_var(0, 3, 'x')
        op.binary_var('y')
        op.minimize(linear={'x': 1, 'y': 2})
        op.linear_constraint(linear={'x': 1, 'y': 1}, sense='>=', rhs=1, name='xy')

        min_eigen_solver = NumPyMinimumEigensolver()
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver)
        result = min_eigen_optimizer.solve(op)
        opt_sol = 1
        self.assertEqual(result.fval, opt_sol)
        self.assertEqual(len(result.samples), 1)
        np.testing.assert_array_almost_equal(result.samples[0].x, [1, 0])
        self.assertAlmostEqual(result.samples[0].fval, opt_sol)
        self.assertAlmostEqual(result.samples[0].probability, 1.0)
        self.assertEqual(result.samples[0].status, SUCCESS)
        self.assertEqual(len(result.raw_samples), 1)
        np.testing.assert_array_almost_equal(result.raw_samples[0].x, [1, 0, 0, 0, 0])
        self.assertAlmostEqual(result.raw_samples[0].fval, opt_sol)
        self.assertAlmostEqual(result.raw_samples[0].probability, 1.0)
        self.assertEqual(result.raw_samples[0].status, SUCCESS)

        qaoa = QAOA(quantum_instance=quantum_instance)
        min_eigen_optimizer = MinimumEigenOptimizer(qaoa)
        result = min_eigen_optimizer.solve(op)
        self.assertEqual(len(result.samples), 8)
        self.assertEqual(len(result.raw_samples), 32)
        self.assertAlmostEqual(sum(s.probability for s in result.samples), 1)
        self.assertAlmostEqual(sum(s.probability for s in result.raw_samples), 1)
        self.assertAlmostEqual(min(s.fval for s in result.samples), 0)
        self.assertAlmostEqual(min(s.fval for s in result.samples if s.status == SUCCESS), opt_sol)
        self.assertAlmostEqual(min(s.fval for s in result.raw_samples), opt_sol)
        for sample in result.raw_samples:
            self.assertEqual(sample.status, SUCCESS)
        np.testing.assert_array_almost_equal(result.x, result.samples[0].x)
        self.assertAlmostEqual(result.fval, result.samples[0].fval)
        self.assertEqual(result.status, result.samples[0].status)

        # test maximize
        op = QuadraticProgram()
        op.integer_var(0, 3, 'x')
        op.binary_var('y')
        op.maximize(linear={'x': 1, 'y': 2})
        op.linear_constraint(linear={'x': 1, 'y': 1}, sense='<=', rhs=1, name='xy')

        min_eigen_solver = NumPyMinimumEigensolver()
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver)
        result = min_eigen_optimizer.solve(op)
        opt_sol = 2
        self.assertEqual(result.fval, opt_sol)
        self.assertEqual(len(result.samples), 1)
        np.testing.assert_array_almost_equal(result.samples[0].x, [0, 1])
        self.assertAlmostEqual(result.samples[0].fval, opt_sol)
        self.assertAlmostEqual(result.samples[0].probability, 1.0)
        self.assertEqual(result.samples[0].status, SUCCESS)
        self.assertEqual(len(result.raw_samples), 1)
        np.testing.assert_array_almost_equal(result.raw_samples[0].x, [0, 0, 1, 0])
        self.assertAlmostEqual(result.raw_samples[0].fval, opt_sol)
        self.assertAlmostEqual(result.raw_samples[0].probability, 1.0)
        self.assertEqual(result.raw_samples[0].status, SUCCESS)

        qaoa = QAOA(quantum_instance=quantum_instance)
        min_eigen_optimizer = MinimumEigenOptimizer(qaoa)
        result = min_eigen_optimizer.solve(op)
        self.assertEqual(len(result.samples), 8)
        self.assertEqual(len(result.raw_samples), 16)
        self.assertAlmostEqual(sum(s.probability for s in result.samples), 1)
        self.assertAlmostEqual(sum(s.probability for s in result.raw_samples), 1)
        self.assertAlmostEqual(max(s.fval for s in result.samples), 5)
        self.assertAlmostEqual(max(s.fval for s in result.samples if s.status == SUCCESS), opt_sol)
        self.assertAlmostEqual(max(s.fval for s in result.raw_samples), opt_sol)
        for sample in result.raw_samples:
            self.assertEqual(sample.status, SUCCESS)
        np.testing.assert_array_almost_equal(result.x, result.samples[0].x)
        self.assertAlmostEqual(result.fval, result.samples[0].fval)
        self.assertEqual(result.status, result.samples[0].status)
示例#20
0
class TestMinEigenOptimizer(QiskitOptimizationTestCase):
    """Min Eigen Optimizer Tests."""

    def setUp(self):
        super().setUp()

        # setup minimum eigen solvers
        self.min_eigen_solvers = {}

        # exact eigen solver
        self.min_eigen_solvers["exact"] = NumPyMinimumEigensolver()

        # QAOA
        optimizer = COBYLA()
        self.min_eigen_solvers["qaoa"] = QAOA(optimizer=optimizer)
        # simulators
        self.sv_simulator = QuantumInstance(
            BasicAer.get_backend("statevector_simulator"),
            seed_simulator=123,
            seed_transpiler=123,
        )
        self.qasm_simulator = QuantumInstance(
            BasicAer.get_backend("qasm_simulator"),
            seed_simulator=123,
            seed_transpiler=123,
        )
        # test minimize
        self.op_minimize = QuadraticProgram()
        self.op_minimize.integer_var(0, 3, "x")
        self.op_minimize.binary_var("y")
        self.op_minimize.minimize(linear={"x": 1, "y": 2})
        self.op_minimize.linear_constraint(linear={"x": 1, "y": 1}, sense=">=", rhs=1, name="xy")

        # test maximize
        self.op_maximize = QuadraticProgram()
        self.op_maximize.integer_var(0, 3, "x")
        self.op_maximize.binary_var("y")
        self.op_maximize.maximize(linear={"x": 1, "y": 2})
        self.op_maximize.linear_constraint(linear={"x": 1, "y": 1}, sense="<=", rhs=1, name="xy")

        # test bit ordering
        mdl = Model("docplex model")
        x = mdl.binary_var("x")
        y = mdl.binary_var("y")
        mdl.minimize(x - 2 * y)
        self.op_ordering = QuadraticProgram()
        self.op_ordering.from_docplex(mdl)

    @data(
        ("exact", None, "op_ip1.lp"),
        ("qaoa", "statevector_simulator", "op_ip1.lp"),
        ("qaoa", "qasm_simulator", "op_ip1.lp"),
    )
    @requires_extra_library
    def test_min_eigen_optimizer(self, config):
        """Min Eigen Optimizer Test"""
        try:
            # unpack configuration
            min_eigen_solver_name, backend, filename = config

            # get minimum eigen solver
            min_eigen_solver = self.min_eigen_solvers[min_eigen_solver_name]
            if backend:
                min_eigen_solver.quantum_instance = BasicAer.get_backend(backend)

            # construct minimum eigen optimizer
            min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver)

            # load optimization problem
            problem = QuadraticProgram()
            lp_file = self.get_resource_path(filename, "algorithms/resources")
            problem.read_from_lp_file(lp_file)

            # solve problem with cplex
            cplex = CplexOptimizer()
            cplex_result = cplex.solve(problem)

            # solve problem
            result = min_eigen_optimizer.solve(problem)
            self.assertIsNotNone(result)

            # analyze results
            self.assertAlmostEqual(cplex_result.fval, result.fval)

            # check that eigensolver result is present
            self.assertIsNotNone(result.min_eigen_solver_result)
        except RuntimeError as ex:
            self.fail(str(ex))

    @data(
        ("op_ip1.lp", -470, 12, OptimizationResultStatus.SUCCESS),
        ("op_ip1.lp", np.inf, None, OptimizationResultStatus.FAILURE),
    )
    @requires_extra_library
    def test_min_eigen_optimizer_with_filter(self, config):
        """Min Eigen Optimizer Test"""
        try:
            # unpack configuration
            filename, lowerbound, fval, status = config

            # get minimum eigen solver
            min_eigen_solver = NumPyMinimumEigensolver()

            # set filter
            # pylint: disable=unused-argument
            def filter_criterion(x, v, aux):
                return v > lowerbound

            min_eigen_solver.filter_criterion = filter_criterion

            # construct minimum eigen optimizer
            min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver)

            # load optimization problem
            problem = QuadraticProgram()
            lp_file = self.get_resource_path(filename, "algorithms/resources")
            problem.read_from_lp_file(lp_file)

            # solve problem
            result = min_eigen_optimizer.solve(problem)
            self.assertIsNotNone(result)

            # analyze results
            self.assertAlmostEqual(fval, result.fval)
            self.assertEqual(status, result.status)

            # check that eigensolver result is present
            self.assertIsNotNone(result.min_eigen_solver_result)
        except RuntimeError as ex:
            self.fail(str(ex))

    def test_converter_list(self):
        """Test converter list"""
        op = QuadraticProgram()
        op.integer_var(0, 3, "x")
        op.binary_var("y")

        op.maximize(linear={"x": 1, "y": 2})
        op.linear_constraint(linear={"x": 1, "y": 1}, sense="LE", rhs=3, name="xy_leq")
        min_eigen_solver = NumPyMinimumEigensolver()
        # a single converter
        qp2qubo = QuadraticProgramToQubo()
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver, converters=qp2qubo)
        result = min_eigen_optimizer.solve(op)
        self.assertEqual(result.fval, 4)
        # a list of converters
        ineq2eq = InequalityToEquality()
        int2bin = IntegerToBinary()
        penalize = LinearEqualityToPenalty()
        converters = [ineq2eq, int2bin, penalize]
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver, converters=converters)
        result = min_eigen_optimizer.solve(op)
        self.assertEqual(result.fval, 4)
        with self.assertRaises(TypeError):
            invalid = [qp2qubo, "invalid converter"]
            MinimumEigenOptimizer(min_eigen_solver, converters=invalid)

    def test_samples_numpy_eigen_solver(self):
        """Test samples for NumPyMinimumEigensolver"""
        # test minimize
        min_eigen_solver = NumPyMinimumEigensolver()
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver)
        result = min_eigen_optimizer.solve(self.op_minimize)
        opt_sol = 1
        success = OptimizationResultStatus.SUCCESS
        self.assertEqual(result.fval, opt_sol)
        self.assertEqual(len(result.samples), 1)
        np.testing.assert_array_almost_equal(result.samples[0].x, [1, 0])
        self.assertAlmostEqual(result.samples[0].fval, opt_sol)
        self.assertAlmostEqual(result.samples[0].probability, 1.0)
        self.assertEqual(result.samples[0].status, success)
        self.assertEqual(len(result.raw_samples), 1)
        np.testing.assert_array_almost_equal(result.raw_samples[0].x, [1, 0, 0, 0, 0])
        self.assertAlmostEqual(result.raw_samples[0].fval, opt_sol)
        self.assertAlmostEqual(result.raw_samples[0].probability, 1.0)
        self.assertEqual(result.raw_samples[0].status, success)
        # test maximize
        min_eigen_solver = NumPyMinimumEigensolver()
        min_eigen_optimizer = MinimumEigenOptimizer(min_eigen_solver)
        result = min_eigen_optimizer.solve(self.op_maximize)
        opt_sol = 2
        self.assertEqual(result.fval, opt_sol)
        self.assertEqual(len(result.samples), 1)
        np.testing.assert_array_almost_equal(result.samples[0].x, [0, 1])
        self.assertAlmostEqual(result.samples[0].fval, opt_sol)
        self.assertAlmostEqual(result.samples[0].probability, 1.0)
        self.assertEqual(result.samples[0].status, success)
        self.assertEqual(len(result.raw_samples), 1)
        np.testing.assert_array_almost_equal(result.raw_samples[0].x, [0, 0, 1, 0])
        self.assertAlmostEqual(result.raw_samples[0].fval, opt_sol)
        self.assertAlmostEqual(result.raw_samples[0].probability, 1.0)
        self.assertEqual(result.raw_samples[0].status, success)

    @data("sv", "qasm")
    def test_samples_qaoa(self, simulator):
        """Test samples for QAOA"""
        # test minimize
        algorithm_globals.random_seed = 1
        quantum_instance = self.sv_simulator if simulator == "sv" else self.qasm_simulator
        qaoa = QAOA(quantum_instance=quantum_instance, reps=2)
        min_eigen_optimizer = MinimumEigenOptimizer(qaoa)
        result = min_eigen_optimizer.solve(self.op_minimize)
        success = OptimizationResultStatus.SUCCESS
        opt_sol = 1
        self.assertEqual(len(result.samples), 8)
        self.assertEqual(len(result.raw_samples), 32)
        self.assertAlmostEqual(sum(s.probability for s in result.samples), 1)
        self.assertAlmostEqual(sum(s.probability for s in result.raw_samples), 1)
        self.assertAlmostEqual(min(s.fval for s in result.samples), 0)
        self.assertAlmostEqual(min(s.fval for s in result.samples if s.status == success), opt_sol)
        self.assertAlmostEqual(min(s.fval for s in result.raw_samples), opt_sol)
        for sample in result.raw_samples:
            self.assertEqual(sample.status, success)
        np.testing.assert_array_almost_equal(result.x, [1, 0])
        self.assertAlmostEqual(result.fval, result.samples[0].fval)
        self.assertEqual(result.status, result.samples[0].status)
        self.assertAlmostEqual(result.samples[0].fval, opt_sol)
        self.assertEqual(result.samples[0].status, success)
        np.testing.assert_array_almost_equal(result.raw_samples[0].x, [1, 0, 0, 0, 0])
        self.assertAlmostEqual(result.raw_samples[0].fval, opt_sol)
        self.assertEqual(result.raw_samples[0].status, success)
        # test maximize
        opt_sol = 2
        qaoa = QAOA(quantum_instance=quantum_instance, reps=2)
        min_eigen_optimizer = MinimumEigenOptimizer(qaoa)
        result = min_eigen_optimizer.solve(self.op_maximize)
        self.assertEqual(len(result.samples), 8)
        self.assertEqual(len(result.raw_samples), 16)
        self.assertAlmostEqual(sum(s.probability for s in result.samples), 1)
        self.assertAlmostEqual(sum(s.probability for s in result.raw_samples), 1)
        self.assertAlmostEqual(max(s.fval for s in result.samples), 5)
        self.assertAlmostEqual(max(s.fval for s in result.samples if s.status == success), opt_sol)
        self.assertAlmostEqual(max(s.fval for s in result.raw_samples), opt_sol)
        for sample in result.raw_samples:
            self.assertEqual(sample.status, success)
        np.testing.assert_array_almost_equal(result.x, [0, 1])
        self.assertEqual(result.fval, opt_sol)
        self.assertEqual(result.status, success)
        np.testing.assert_array_almost_equal(result.samples[0].x, [0, 1])
        self.assertAlmostEqual(result.samples[0].fval, opt_sol)
        self.assertEqual(result.samples[0].status, success)
        np.testing.assert_array_almost_equal(result.raw_samples[0].x, [0, 0, 1, 0])
        self.assertAlmostEqual(result.raw_samples[0].fval, opt_sol)
        self.assertEqual(result.raw_samples[0].status, success)
        # test bit ordering
        opt_sol = -2
        qaoa = QAOA(quantum_instance=quantum_instance, reps=2)
        min_eigen_optimizer = MinimumEigenOptimizer(qaoa)
        result = min_eigen_optimizer.solve(self.op_ordering)
        self.assertEqual(result.fval, opt_sol)
        np.testing.assert_array_almost_equal(result.x, [0, 1])
        self.assertEqual(result.status, success)
        result.raw_samples.sort(key=lambda x: x.probability, reverse=True)
        np.testing.assert_array_almost_equal(result.x, result.raw_samples[0].x)
        self.assertAlmostEqual(sum(s.probability for s in result.samples), 1, delta=1e-5)
        self.assertAlmostEqual(sum(s.probability for s in result.raw_samples), 1, delta=1e-5)
        self.assertAlmostEqual(min(s.fval for s in result.samples), -2)
        self.assertAlmostEqual(min(s.fval for s in result.samples if s.status == success), opt_sol)
        self.assertAlmostEqual(min(s.fval for s in result.raw_samples), opt_sol)
        for sample in result.raw_samples:
            self.assertEqual(sample.status, success)
        np.testing.assert_array_almost_equal(result.samples[0].x, [0, 1])
        self.assertAlmostEqual(result.samples[0].fval, opt_sol)
        self.assertEqual(result.samples[0].status, success)
        np.testing.assert_array_almost_equal(result.raw_samples[0].x, [0, 1])
        self.assertAlmostEqual(result.raw_samples[0].fval, opt_sol)
        self.assertEqual(result.raw_samples[0].status, success)

    @data("sv", "qasm")
    def test_samples_vqe(self, simulator):
        """Test samples for VQE"""
        # test minimize
        algorithm_globals.random_seed = 1
        quantum_instance = self.sv_simulator if simulator == "sv" else self.qasm_simulator
        opt_sol = -2
        success = OptimizationResultStatus.SUCCESS
        optimizer = SPSA(maxiter=100)
        ry_ansatz = TwoLocal(5, "ry", "cz", reps=3, entanglement="full")
        vqe_mes = VQE(ry_ansatz, optimizer=optimizer, quantum_instance=quantum_instance)
        vqe = MinimumEigenOptimizer(vqe_mes)
        results = vqe.solve(self.op_ordering)
        self.assertEqual(results.fval, opt_sol)
        np.testing.assert_array_almost_equal(results.x, [0, 1])
        self.assertEqual(results.status, success)
        results.raw_samples.sort(key=lambda x: x.probability, reverse=True)
        np.testing.assert_array_almost_equal(results.x, results.raw_samples[0].x)
        self.assertAlmostEqual(sum(s.probability for s in results.samples), 1, delta=1e-5)
        self.assertAlmostEqual(sum(s.probability for s in results.raw_samples), 1, delta=1e-5)
        self.assertAlmostEqual(min(s.fval for s in results.samples), -2)
        self.assertAlmostEqual(min(s.fval for s in results.samples if s.status == success), opt_sol)
        self.assertAlmostEqual(min(s.fval for s in results.raw_samples), opt_sol)
        for sample in results.raw_samples:
            self.assertEqual(sample.status, success)
        np.testing.assert_array_almost_equal(results.samples[0].x, [0, 1])
        self.assertAlmostEqual(results.samples[0].fval, opt_sol)
        self.assertEqual(results.samples[0].status, success)
        np.testing.assert_array_almost_equal(results.raw_samples[0].x, [0, 1])
        self.assertAlmostEqual(results.raw_samples[0].fval, opt_sol)
        self.assertEqual(results.raw_samples[0].status, success)