Source code for qrisp.qaoa.problems.maxSat

"""
\********************************************************************************
* Copyright (c) 2024 the Qrisp authors
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is
* available at https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
"""

from qrisp import app_sb_phase_polynomial
import sympy as sp
import math


[docs] def create_maxsat_cost_polynomials(problem): """ Creates a list of polynomials representing the cost function for each clause, and a list of symbols. Parameters ---------- problem : tuple(int, list[list[int]]) The number of variables, and the clauses of the maximum satisfiability problem instance. Returns ------- cost_polynomials : list[sympy.Expr] A list of the cost functions for each clause as SymPy polynomials. symbols : list[sympy.Symbol] A list of SymPy symbols. """ clauses = problem[1] symbols = [sp.Symbol(f"x{i}") for i in range(1,problem[0]+1)] cost_polynomials = [] for clause in clauses: C = 1 - sp.prod((1-symbols[index-1]) if index>0 else symbols[-index-1] for index in clause) cost_polynomials.append(C) return cost_polynomials, symbols
[docs] def create_maxsat_cl_cost_function(problem): """ Creates the classical cost function for an instance of the maximum satisfiability problem. Parameters ---------- problem : tuple(int, list[list[int]]) The number of variables, and the clauses of the maximum satisfiability problem instance. Returns ------- cl_cost_function : function The classical cost function for the problem instance, which takes a dictionary of measurement results as input. """ clauses = problem[1] def cl_cost_function(res_dic): cost = 0 for state, prob in res_dic.items(): for clause in clauses: cost += -(1-math.prod((1-int(state[index-1])) if index>0 else int(state[-index-1]) for index in clause))*prob return cost return cl_cost_function
[docs] def create_maxsat_cost_operator(problem): r""" Creates the cost operator for an instance of the maximum satisfiability problem. For a given cost function .. math:: C(x) = \sum_{\alpha=1}^m C_{\alpha}(x) the cost operator is given by $e^{-i\gamma C}$ where $C=\sum_x C(x)\ket{x}\bra{x}$. Parameters ---------- problem : tuple(int, list[list[int]]) The number of variables, and the clauses of the maximum satisfiability problem instance. Returns ------- cost_operator : function A function receiving a :ref:`QuantumVariable` and a real parameter $\gamma$. This function performs the application of the cost operator. """ cost_polynomials, symbols = create_maxsat_cost_polynomials(problem) def cost_operator(qv, gamma): for P in cost_polynomials: app_sb_phase_polynomial([qv], -P, symbols, t=gamma) return cost_operator
[docs] def maxsat_problem(problem): """ Creates a QAOA problem instance with appropriate phase separator, mixer, and classical cost function. Parameters ---------- problem : tuple(int, list[list[int]]) The number of variables, and the clauses of the maximum satisfiability problem instance. Returns ------- :ref:`QAOAProblem` A QAOA problem instance for MaxSat for given a ``problem``. """ from qrisp.qaoa import QAOAProblem, RX_mixer return QAOAProblem(cost_operator=create_maxsat_cost_operator(problem), mixer=RX_mixer, cl_cost_function=create_maxsat_cl_cost_function(problem))