QIROProblem#

class QIROProblem(problem, replacement_routine, cost_operator, mixer, cl_cost_function, init_function)[source]#

Central structure to run QIRO algorithms. A subcalss of the QAOAProblem class. The idea is based on the paper by J. Finzgar et al..

This class encapsulates the replacement routine, cost operator, mixer operator, classical cost function and initial state preparation function for a specific QIRO problem instance.

For a quick demonstration, we compare QAOA and QIRO for solving a MaxClique problem instance:

from qrisp import QuantumVariable
from qrisp.qiro import QIROProblem, create_max_clique_replacement_routine, create_max_clique_cost_operator_reduced, qiro_RXMixer, qiro_init_function
from qrisp.qaoa import max_clique_problem, create_max_clique_cl_cost_function
import matplotlib.pyplot as plt
import networkx as nx

# Define a random graph via the number of nodes and the QuantumVariable arguments
num_nodes = 15
G = nx.erdos_renyi_graph(num_nodes, 0.7, seed = 99)
Gtwo = G.copy()

qarg = QuantumVariable(G.number_of_nodes())
qarg2 = QuantumVariable(Gtwo.number_of_nodes())

# QAOA
qaoa_instance = max_clique_problem(G)
res_qaoa = qaoa_instance.run(qarg=qarg, depth=3)

# QIRO
qiro_instance = QIROProblem(problem = Gtwo,  
                            replacement_routine = create_max_clique_replacement_routine, 
                            cost_operator = create_max_clique_cost_operator_reduced,
                            mixer = qiro_RXMixer,
                            cl_cost_function = create_max_clique_cl_cost_function,
                            init_function = qiro_init_function
                            )
res_qiro = qiro_instance.run_qiro(qarg=qarg2, depth=3, n_recursions = 2)

# The final graph that has been adjusted
final_graph = qiro_instance.problem

cl_cost = create_max_clique_cl_cost_function(G)

print("5 most likely QAOA solutions")
max_five_qaoa = sorted(res_qaoa, key=res_qaoa.get, reverse=True)[:5]
for res in max_five_qaoa:
    print([index for index, value in enumerate(res) if value == '1'])
    print(cl_cost({res : 1}))

print("5 most likely QIRO solutions")
max_five_qiro = sorted(res_qiro, key=res_qiro.get, reverse=True)[:5]
for res in max_five_qiro: 
    print([index for index, value in enumerate(res) if value == '1'])
    print(cl_cost({res : 1}))

print("Networkx solution")
print(nx.approximation.max_clique(G))

# Draw the final graph and the original graph for comparison
plt.figure(1)
nx.draw(final_graph, with_labels = True, node_color='#ADD8E6', edge_color='#D3D3D3')
plt.title('final QIRO graph')

plt.figure(2)
most_likely = [index for index, value in enumerate(max_five_qiro[0]) if value == '1']
nx.draw(G, with_labels=True,
        node_color=['#FFCCCB' if node in most_likely else '#ADD8E6' for node in G.nodes()],
        edge_color=['#FFCCCB' if edge[0] in most_likely and edge[1] in most_likely else '#D3D3D3' for edge in G.edges()])
plt.title('Original graph with most likely QIRO solution')
plt.show()  

For an in-depth tutorial, make sure to check out the QIRO tutorial!

Parameters:
problemAny

The problem structure to be considered for the algorithm. For example, in the case of MaxClique a graph, or MaxSat a list of clauses.

replacement_routinefunction

A routine for adjusting the problem after the highest correlation value was found.

cost_operatorfunction

Prepares the new cost_operator for the updated QAOAProblem instance. A function that receives a problem and a list of solutions, and returns a function that is applied to a QuantumVariable and a real parameter \(\gamma\).

mixerfunction

Prepares the new mixer for the updated QAOAProblem instance. A function that receives a list of solutions and a list of exclusions, and returns a function that is applied to a QuantumVariable and a real parameter \(\beta\).

cl_cost_functionfunction

The classical cost function for the problem instance, which takes a dictionary of measurement results as input.

init_functionfunction

Prepares the new init_function for the updated QAOAProblem instance. A function that receives a list of solutions and a list of exclusions, and returns a function that is applied to a QuantumVariable.

Methods#

QIROProblem.run_qiro(qarg, depth, n_recursions)

Run the specific QIRO problem instance with given quantum argument, depth of QAOA circuit, number of recursions, measurement keyword arguments (mes_kwargs) and maximum iterations for optimization (max_iter).