def test_simple_qubo(self): """Test on a simple QUBO problem.""" model = Model() # pylint:disable=invalid-name u = model.binary_var(name="u") v = model.binary_var(name="v") model.minimize((u - v + 2)**2) problem = from_docplex_mp(model) backend = BasicAer.get_backend("statevector_simulator") qaoa = QAOA(quantum_instance=backend, reps=1) optimizer = WarmStartQAOAOptimizer( pre_solver=SlsqpOptimizer(), relax_for_pre_solver=True, qaoa=qaoa, epsilon=0.25, ) result_warm = optimizer.solve(problem) self.assertIsNotNone(result_warm) self.assertIsNotNone(result_warm.x) np.testing.assert_almost_equal([0, 1], result_warm.x, 3) self.assertIsNotNone(result_warm.fval) np.testing.assert_almost_equal(1, result_warm.fval, 3)
def test_constrained_binary(self): """Constrained binary optimization problem.""" model = Model() v = model.binary_var(name="v") w = model.binary_var(name="w") # pylint:disable=invalid-name t = model.binary_var(name="t") model.minimize(v + w + t) model.add_constraint(2 * v + 10 * w + t <= 3, "cons1") model.add_constraint(v + w + t >= 2, "cons2") problem = from_docplex_mp(model) backend = BasicAer.get_backend("statevector_simulator") qaoa = QAOA(quantum_instance=backend, reps=1) aggregator = MeanAggregator() optimizer = WarmStartQAOAOptimizer( pre_solver=SlsqpOptimizer(), relax_for_pre_solver=True, qaoa=qaoa, epsilon=0.25, aggregator=aggregator, ) result_warm = optimizer.solve(problem) self.assertIsNotNone(result_warm) self.assertIsNotNone(result_warm.x) np.testing.assert_almost_equal([1, 0, 1], result_warm.x, 3) self.assertIsNotNone(result_warm.fval) np.testing.assert_almost_equal(2, result_warm.fval, 3)
def test_admm_ex4_no_bin_var_in_objective(self): """Modified Example 4 as a unit test. See the description of the previous test. This test differs from the previous in the objective: one binary variable is omitted in objective to test a problem when a binary variable defined but is used only in constraints. """ mdl = Model("ex4") v = mdl.binary_var(name="v") w = mdl.binary_var(name="w") # pylint:disable=invalid-name t = mdl.binary_var(name="t") b = 2 mdl.minimize(v + t) mdl.add_constraint(2 * v + 10 * w + t <= 3, "cons1") mdl.add_constraint(v + w + t >= b, "cons2") op = from_docplex_mp(mdl) admm_params = ADMMParameters( rho_initial=1001, beta=1000, factor_c=900, maxiter=100, three_block=False ) solver = ADMMOptimizer(params=admm_params) solution = solver.solve(op) self.assertIsNotNone(solution) self.assertIsInstance(solution, ADMMOptimizationResult) self.assertIsNotNone(solution.x) np.testing.assert_almost_equal([1.0, 0.0, 1.0], solution.x, 3) self.assertIsNotNone(solution.fval) np.testing.assert_almost_equal(2.0, solution.fval, 3) self.assertIsNotNone(solution.state) self.assertIsInstance(solution.state, ADMMState)
def to_quadratic_program(self) -> QuadraticProgram: """Convert a traveling salesman problem instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the traveling salesman problem instance. """ mdl = Model(name="TSP") n = self._graph.number_of_nodes() x = { (i, k): mdl.binary_var(name="x_{0}_{1}".format(i, k)) for i in range(n) for k in range(n) } tsp_func = mdl.sum( self._graph.edges[i, j]["weight"] * x[(i, k)] * x[(j, (k + 1) % n)] for i in range(n) for j in range(n) for k in range(n) if i != j ) mdl.minimize(tsp_func) for i in range(n): mdl.add_constraint(mdl.sum(x[(i, k)] for k in range(n)) == 1) for k in range(n): mdl.add_constraint(mdl.sum(x[(i, k)] for i in range(n)) == 1) op = from_docplex_mp(mdl) return op
def test_bit_ordering(self, simulator): """Test bit ordering""" # test minimize algorithm_globals.random_seed = 2 q_instance = self.sv_simulator if simulator == "sv" else self.qasm_simulator mdl = Model("docplex model") x = mdl.binary_var("x") y = mdl.binary_var("y") mdl.minimize(x - 2 * y) op = from_docplex_mp(mdl) opt_sol = -2 success = OptimizationResultStatus.SUCCESS grover_optimizer = GroverOptimizer( 3, num_iterations=self.n_iter, quantum_instance=q_instance ) results = grover_optimizer.solve(op) 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) 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)
def test_admm_ex4(self): """Example 4 as a unit test. Example 4 is reported in: Gambella, C., & Simonetto, A. (2020). Multi-block ADMM Heuristics for Mixed-Binary Optimization on Classical and Quantum Computers. arXiv preprint arXiv:2001.02069.""" mdl = Model("ex4") v = mdl.binary_var(name="v") w = mdl.binary_var(name="w") # pylint:disable=invalid-name t = mdl.binary_var(name="t") b = 2 mdl.minimize(v + w + t) mdl.add_constraint(2 * v + 10 * w + t <= 3, "cons1") mdl.add_constraint(v + w + t >= b, "cons2") op = from_docplex_mp(mdl) admm_params = ADMMParameters( rho_initial=1001, beta=1000, factor_c=900, maxiter=100, three_block=False ) solver = ADMMOptimizer(params=admm_params) solution = solver.solve(op) self.assertIsNotNone(solution) self.assertIsInstance(solution, ADMMOptimizationResult) self.assertIsNotNone(solution.x) np.testing.assert_almost_equal([1.0, 0.0, 1.0], solution.x, 3) self.assertIsNotNone(solution.fval) np.testing.assert_almost_equal(2.0, solution.fval, 3) self.assertIsNotNone(solution.state) self.assertIsInstance(solution.state, ADMMState)
def test_equality_constraints_with_continuous_variables(self): """Simple example to test equality constraints with continuous variables.""" mdl = Model("eq-constraints-cts-vars") # pylint:disable=invalid-name v = mdl.binary_var(name="v") w = mdl.continuous_var(name="w", lb=0.0) t = mdl.continuous_var(name="t", lb=0.0) mdl.minimize(v + w + t) mdl.add_constraint(2 * v + w >= 2, "cons1") mdl.add_constraint(w + t == 1, "cons2") op = from_docplex_mp(mdl) admm_params = ADMMParameters( rho_initial=1001, beta=1000, factor_c=900, maxiter=100, three_block=True, ) solver = ADMMOptimizer(params=admm_params) solution = solver.solve(op) self.assertIsNotNone(solution) self.assertIsInstance(solution, ADMMOptimizationResult) self.assertIsNotNone(solution.x) np.testing.assert_almost_equal([0.0, 1.0, 0.0], solution.x, 3) self.assertIsNotNone(solution.fval) np.testing.assert_almost_equal(1.0, solution.fval, 3) self.assertIsNotNone(solution.state) self.assertIsInstance(solution.state, ADMMState)
def test_admm_maximization(self): """Tests a simple maximization problem using ADMM optimizer""" mdl = Model("simple-max") c = mdl.continuous_var(lb=0, ub=10, name="c") x = mdl.binary_var(name="x") mdl.maximize(c + x * x) op = from_docplex_mp(mdl) admm_params = ADMMParameters() solver = ADMMOptimizer(params=admm_params, continuous_optimizer=CobylaOptimizer()) solution = solver.solve(op) self.assertIsNotNone(solution) self.assertIsInstance(solution, ADMMOptimizationResult) self.assertIsNotNone(solution.x) np.testing.assert_almost_equal([10, 0], solution.x, 3) self.assertIsNotNone(solution.fval) np.testing.assert_almost_equal(10, solution.fval, 3) self.assertIsNotNone(solution.state) self.assertIsInstance(solution.state, ADMMState) self.assertEqual(len(solution.samples), 1) self.assertAlmostEqual(solution.fval, solution.samples[0].fval) np.testing.assert_almost_equal(solution.x, solution.samples[0].x) self.assertEqual(solution.status, solution.samples[0].status) self.assertAlmostEqual(solution.samples[0].probability, 1.0)
def test_quad_constraints(self): """Simple example to test quadratic constraints.""" mdl = Model("quad-constraints") v = mdl.binary_var(name="v") w = mdl.continuous_var(name="w", lb=0.0) mdl.minimize(v + w) mdl.add_constraint(v + w >= 1, "cons2") mdl.add_constraint(v**2 + w**2 <= 1, "cons2") op = from_docplex_mp(mdl) admm_params = ADMMParameters( rho_initial=1001, beta=1000, factor_c=900, maxiter=100, three_block=True, ) solver = ADMMOptimizer(params=admm_params) solution = solver.solve(op) self.assertIsNotNone(solution) self.assertIsInstance(solution, ADMMOptimizationResult) self.assertIsNotNone(solution.x) np.testing.assert_almost_equal([0.0, 1.0], solution.x, 3) self.assertIsNotNone(solution.fval) np.testing.assert_almost_equal(1.0, solution.fval, 3) self.assertIsNotNone(solution.state) self.assertIsInstance(solution.state, ADMMState)
def to_quadratic_program(self) -> QuadraticProgram: """Convert a portfolio diversification problem instance into a :class:`~qiskit_optimization.problems.QuadraticProgram`. Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the portfolio diversification problem instance. """ mdl = AdvModel(name="Portfolio diversification") x = { (i, j): mdl.binary_var(name=f"x_{i}_{j}") for i in range(self._num_assets) for j in range(self._num_assets) } y = {i: mdl.binary_var(name=f"y_{i}") for i in range(self._num_assets)} mdl.maximize( mdl.sum( self._similarity_matrix[i, j] * x[(i, j)] for i in range(self._num_assets) for j in range(self._num_assets) ) ) mdl.add_constraint(mdl.sum(y[j] for j in range(self._num_assets)) == self._num_clusters) for i in range(self._num_assets): mdl.add_constraint(mdl.sum(x[(i, j)] for j in range(self._num_assets)) == 1) for j in range(self._num_assets): mdl.add_constraint(x[(j, j)] == y[j]) for i in range(self._num_assets): for j in range(self._num_assets): mdl.add_constraint(x[(i, j)] <= y[j]) op = from_docplex_mp(mdl) return op
def to_quadratic_program(self) -> QuadraticProgram: """Convert a bin packing problem instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the bin packing problem instance. """ mdl = Model(name="BinPacking") num_bins = self._max_number_of_bins num_items = len(self._weights) y = mdl.binary_var_list(num_bins, name="y") mdl.minimize(mdl.sum(y)) x = mdl.binary_var_matrix(num_items, num_bins, name="x") for i in range(num_items): # First set of constraints: the items must be in any bin mdl.add_constraint(mdl.sum(x[i, j] for j in range(num_bins)) == 1) for j in range(num_bins): # Second set of constraints: weight constraints mdl.add_constraint( mdl.sum(self._weights[i] * x[i, j] for i in range(num_items)) <= self._max_weight * y[j] ) op = from_docplex_mp(mdl) return op
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 = from_docplex_mp(mdl)
def to_quadratic_program(self) -> QuadraticProgram: """Convert a knapsack problem instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the knapsack problem instance. """ mdl = Model(name="Knapsack") x = {i: mdl.binary_var(name="x_{0}".format(i)) for i in range(len(self._values))} mdl.maximize(mdl.sum(self._values[i] * x[i] for i in x)) mdl.add_constraint(mdl.sum(self._weights[i] * x[i] for i in x) <= self._max_weight) op = from_docplex_mp(mdl) return op
def test_qubo_gas_int_simple_maximize(self): """Test for simple case, but with maximization.""" # Input. model = Model() x_0 = model.binary_var(name="x0") x_1 = model.binary_var(name="x1") model.maximize(-x_0 + 2 * x_1) op = from_docplex_mp(model) # Get the optimum key and value. gmf = GroverOptimizer(4, num_iterations=self.n_iter, quantum_instance=self.sv_simulator) results = gmf.solve(op) self.validate_results(op, results)
def to_quadratic_program(self) -> QuadraticProgram: """Convert a vehicle routing problem instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the vehicle routing problem instance. """ mdl = Model(name="Vehicle routing") n = self._graph.number_of_nodes() x = {} for i in range(n): for j in range(n): if i != j: x[(i, j)] = mdl.binary_var(name="x_{0}_{1}".format(i, j)) mdl.minimize( mdl.sum(self._graph.edges[i, j]["weight"] * x[(i, j)] for i in range(n) for j in range(n) if i != j)) # Only 1 edge goes out from each node for i in range(n): if i != self.depot: mdl.add_constraint( mdl.sum(x[i, j] for j in range(n) if i != j) == 1) # Only 1 edge comes into each node for j in range(n): if j != self.depot: mdl.add_constraint( mdl.sum(x[i, j] for i in range(n) if i != j) == 1) # For the depot node mdl.add_constraint( mdl.sum(x[i, self.depot] for i in range(n) if i != self.depot) == self.num_vehicles) mdl.add_constraint( mdl.sum(x[self.depot, j] for j in range(n) if j != self.depot) == self.num_vehicles) # To eliminate sub-routes node_list = [i for i in range(n) if i != self.depot] clique_set = [] for i in range(2, len(node_list) + 1): for comb in itertools.combinations(node_list, i): clique_set.append(list(comb)) for clique in clique_set: mdl.add_constraint( mdl.sum(x[(i, j)] for i in clique for j in clique if i != j) <= len(clique) - 1) op = from_docplex_mp(mdl) return op
def test_qubo_gas_int_zero(self): """Test for when the answer is zero.""" # Input. model = Model() x_0 = model.binary_var(name="x0") x_1 = model.binary_var(name="x1") model.minimize(0 * x_0 + 0 * x_1) op = from_docplex_mp(model) # Will not find a negative, should return 0. gmf = GroverOptimizer(1, num_iterations=1, quantum_instance=self.sv_simulator) results = gmf.solve(op) np.testing.assert_array_almost_equal(results.x, [0, 0]) self.assertEqual(results.fval, 0.0) self.assertAlmostEqual(results.fval, results.intermediate_fval)
def to_quadratic_program(self) -> QuadraticProgram: """Convert an exact cover instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the exact cover instance. """ mdl = Model(name="Exact cover") x = {i: mdl.binary_var(name=f"x_{i}") for i in range(len(self._subsets))} mdl.minimize(mdl.sum(x[i] for i in x)) for element in self._set: mdl.add_constraint( mdl.sum(x[i] for i, sub in enumerate(self._subsets) if element in sub) == 1 ) op = from_docplex_mp(mdl) return op
def to_quadratic_program(self) -> QuadraticProgram: """Convert a vertex cover instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the vertex cover instance. """ mdl = Model(name="Vertex cover") n = self._graph.number_of_nodes() x = {i: mdl.binary_var(name="x_{0}".format(i)) for i in range(n)} objective = mdl.sum(x[i] for i in x) for w, v in self._graph.edges: mdl.add_constraint(x[w] + x[v] >= 1) mdl.minimize(objective) op = from_docplex_mp(mdl) return op
def to_quadratic_program(self) -> QuadraticProgram: """Convert a set packing instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the set packing instance. """ mdl = Model(name="Set packing") x = {i: mdl.binary_var(name="x_{0}".format(i)) for i in range(len(self._subsets))} mdl.maximize(mdl.sum(x[i] for i in x)) for element in self._set: mdl.add_constraint( mdl.sum(x[i] for i, sub in enumerate(self._subsets) if element in sub) <= 1 ) op = from_docplex_mp(mdl) return op
def test_converter_list(self): """Test converters list""" # Input. model = Model() x_0 = model.binary_var(name="x0") x_1 = model.binary_var(name="x1") model.maximize(-x_0 + 2 * x_1) op = from_docplex_mp(model) # Get the optimum key and value. # a single converter. qp2qubo = QuadraticProgramToQubo() gmf = GroverOptimizer( 4, num_iterations=self.n_iter, quantum_instance=self.sv_simulator, converters=qp2qubo, ) results = gmf.solve(op) self.validate_results(op, results) # a list of converters ineq2eq = InequalityToEquality() int2bin = IntegerToBinary() penalize = LinearEqualityToPenalty() max2min = MaximizeToMinimize() converters = [ineq2eq, int2bin, penalize, max2min] gmf = GroverOptimizer( 4, num_iterations=self.n_iter, quantum_instance=self.sv_simulator, converters=converters, ) results = gmf.solve(op) self.validate_results(op, results) # invalid converters with self.assertRaises(TypeError): invalid = [qp2qubo, "invalid converter"] GroverOptimizer( 4, num_iterations=self.n_iter, quantum_instance=self.sv_simulator, converters=invalid, )
def test_qubo_gas_int_simple(self): """Test for simple case, with 2 linear coeffs and no quadratic coeffs or constants.""" # Input. model = Model() x_0 = model.binary_var(name="x0") x_1 = model.binary_var(name="x1") model.minimize(-x_0 + 2 * x_1) op = from_docplex_mp(model) # Get the optimum key and value. gmf = GroverOptimizer(4, num_iterations=self.n_iter, quantum_instance=self.sv_simulator) results = gmf.solve(op) self.validate_results(op, results) self.assertIsNotNone(results.operation_counts) self.assertEqual(results.n_input_qubits, 2) self.assertEqual(results.n_output_qubits, 4)
def to_quadratic_program(self) -> QuadraticProgram: """Convert a number partitioning problem instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the number partitioning problem instance. """ mdl = Model(name="Number partitioning") x = { i: mdl.binary_var(name=f"x_{i}") for i in range(len(self._number_set)) } mdl.add_constraint( mdl.sum(num * (-2 * x[i] + 1) for i, num in enumerate(self._number_set)) == 0) op = from_docplex_mp(mdl) return op
def test_qubo_gas_int_paper_example(self, simulator): """ Test the example from https://arxiv.org/abs/1912.04088 using the state vector simulator and the qasm simulator """ # Input. model = Model() x_0 = model.binary_var(name="x0") x_1 = model.binary_var(name="x1") x_2 = model.binary_var(name="x2") model.minimize(-x_0 + 2 * x_1 - 3 * x_2 - 2 * x_0 * x_2 - 1 * x_1 * x_2) op = from_docplex_mp(model) # Get the optimum key and value. q_instance = self.sv_simulator if simulator == "sv" else self.qasm_simulator gmf = GroverOptimizer(6, num_iterations=self.n_iter, quantum_instance=q_instance) results = gmf.solve(op) self.validate_results(op, results)
def to_quadratic_program(self) -> QuadraticProgram: """Convert a stable set instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the stable set instance. """ mdl = Model(name="Stable set") n = self._graph.number_of_nodes() x = {i: mdl.binary_var(name=f"x_{i}") for i in range(n)} for w, v in self._graph.edges: self._graph.edges[w, v].setdefault("weight", 1) objective = mdl.sum(x[i] for i in x) for w, v in self._graph.edges: mdl.add_constraint(x[w] + x[v] <= 1) mdl.maximize(objective) op = from_docplex_mp(mdl) return op
def test_continuous_variable_decode(self): """Test decode func of IntegerToBinaryConverter for continuous variables""" mdl = Model("test_continuous_varable_decode") c = mdl.continuous_var(lb=0, ub=10.9, name="c") x = mdl.binary_var(name="x") mdl.maximize(c + x * x) op = from_docplex_mp(mdl) converter = IntegerToBinary() op = converter.convert(op) admm_params = ADMMParameters() qubo_optimizer = MinimumEigenOptimizer(NumPyMinimumEigensolver()) continuous_optimizer = CplexOptimizer() solver = ADMMOptimizer( qubo_optimizer=qubo_optimizer, continuous_optimizer=continuous_optimizer, params=admm_params, ) result = solver.solve(op) new_x = converter.interpret(result.x) self.assertEqual(new_x[0], 10.9)
def to_quadratic_program(self) -> QuadraticProgram: """Convert a graph partition instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the graph partition instance. """ mdl = Model(name="Graph partition") n = self._graph.number_of_nodes() x = {i: mdl.binary_var(name="x_{0}".format(i)) for i in range(n)} for w, v in self._graph.edges: self._graph.edges[w, v].setdefault("weight", 1) objective = mdl.sum(self._graph.edges[i, j]["weight"] * (x[i] + x[j] - 2 * x[i] * x[j]) for i, j in self._graph.edges) mdl.minimize(objective) mdl.add_constraint(mdl.sum([x[i] for i in x]) == n // 2) op = from_docplex_mp(mdl) return op
def test_integer_variables(self): """Tests ADMM with integer variables.""" mdl = Model("integer-variables") v = mdl.integer_var(lb=5, ub=20, name="v") w = mdl.continuous_var(name="w", lb=0.0) mdl.minimize(v + w) op = from_docplex_mp(mdl) solver = ADMMOptimizer() solution = solver.solve(op) self.assertIsNotNone(solution) self.assertIsInstance(solution, ADMMOptimizationResult) self.assertIsNotNone(solution.x) np.testing.assert_almost_equal([5.0, 0.0], solution.x, 3) self.assertIsNotNone(solution.fval) np.testing.assert_almost_equal(5.0, solution.fval, 3) self.assertIsNotNone(solution.state) self.assertIsInstance(solution.state, ADMMState)
def to_quadratic_program(self) -> QuadraticProgram: """Convert a Max-cut problem instance into a :class:`~qiskit_optimization.problems.QuadraticProgram` Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the Max-cut problem instance. """ mdl = Model(name="Max-cut") x = { i: mdl.binary_var(name=f"x_{i}") for i in range(self._graph.number_of_nodes()) } for w, v in self._graph.edges: self._graph.edges[w, v].setdefault("weight", 1) objective = mdl.sum( self._graph.edges[i, j]["weight"] * x[i] * (1 - x[j]) + self._graph.edges[i, j]["weight"] * x[j] * (1 - x[i]) for i, j in self._graph.edges) mdl.maximize(objective) op = from_docplex_mp(mdl) return op
def test_admm_ex6_max(self): """Example 6 as maximization""" mdl = Model("ex6-max") # pylint:disable=invalid-name v = mdl.binary_var(name="v") w = mdl.binary_var(name="w") t = mdl.binary_var(name="t") u = mdl.continuous_var(name="u") # mdl.minimize(v + w + t + 5 * (u - 2) ** 2) mdl.maximize(-v - w - t - 5 * (u - 2)**2) mdl.add_constraint(v + 2 * w + t + u <= 3, "cons1") mdl.add_constraint(v + w + t >= 1, "cons2") mdl.add_constraint(v + w == 1, "cons3") op = from_docplex_mp(mdl) admm_params = ADMMParameters( rho_initial=1001, beta=1000, factor_c=900, maxiter=100, three_block=True, tol=1.0e-6, ) solver = ADMMOptimizer(params=admm_params) solution = solver.solve(op) self.assertIsNotNone(solution) self.assertIsInstance(solution, ADMMOptimizationResult) self.assertIsNotNone(solution.x) np.testing.assert_almost_equal([1.0, 0.0, 0.0, 2.0], solution.x, 3) self.assertIsNotNone(solution.fval) np.testing.assert_almost_equal(-1.0, solution.fval, 3) self.assertIsNotNone(solution.state) self.assertIsInstance(solution.state, ADMMState)
def to_quadratic_program(self) -> QuadraticProgram: """Convert a clique problem instance into a :class:`~qiskit_optimization.problems.QuadraticProgram`. When "size" is None, this makes an optimization model for a maximal clique instead of the specified size of a clique. Returns: The :class:`~qiskit_optimization.problems.QuadraticProgram` created from the clique problem instance. """ complement_g = nx.complement(self._graph) mdl = Model(name="Clique") n = self._graph.number_of_nodes() x = {i: mdl.binary_var(name="x_{0}".format(i)) for i in range(n)} for w, v in complement_g.edges: mdl.add_constraint(x[w] + x[v] <= 1) if self.size is None: mdl.maximize(mdl.sum(x[i] for i in x)) else: mdl.add_constraint(mdl.sum(x[i] for i in x) == self.size) op = from_docplex_mp(mdl) return op