-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #90 from eclipse-qrisp/QIRO_upgrades
QIRO updates: migrated to new QAOA implementations, improved documentation. Removed deprecated QAOA implementations. Minor updates to QAOA implementations and documentation.
- Loading branch information
Showing
62 changed files
with
1,165 additions
and
2,426 deletions.
There are no files selected for viewing
222 changes: 102 additions & 120 deletions
222
documentation/source/general/tutorial/QIROtutorial.rst
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
documentation/source/reference/Algorithms/qiro/QIROImplementations.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
|
||
.. _QIROImplementations: | ||
|
||
.. currentmodule:: qrisp.qiro | ||
|
||
Implementations | ||
=============== | ||
|
||
.. toctree:: | ||
:hidden: | ||
|
||
implementations/QIROMaxClique | ||
implementations/QIROMaxIndep | ||
implementations/QIROMaxSat | ||
implementations/QIROMaxSetPack | ||
|
||
|
||
Here, you can find the QIRO implementations for specific problem instances, namely: | ||
|
||
|
||
* :ref:`MaxIndependentSet <maxIndependentSetQIRO>` | ||
* :ref:`MaxClique <maxCliqueQIRO>` | ||
* :ref:`MaxSat <maxSatQIRO>` | ||
* :ref:`MaxSetPacking <maxSetPackingQIRO>` | ||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
98 changes: 98 additions & 0 deletions
98
documentation/source/reference/Algorithms/qiro/implementations/QIROMaxClique.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
.. _maxcliqueQIRO: | ||
|
||
QIRO MaxClique | ||
============== | ||
|
||
.. currentmodule:: qrisp.qiro.qiroproblems.qiroMaxClique | ||
|
||
|
||
Problem description | ||
------------------- | ||
|
||
Given a Graph :math:`G = (V,E)` maximize the size of a clique, i.e. a subset :math:`V' \subset V` in which all pairs of vertices are adjacent. | ||
|
||
|
||
Replacement routine | ||
------------------- | ||
|
||
In this instance the replacements can be rather significant. In-depth investigation may show relaxations to be perform better on larger instances. | ||
Based on the **maximum absolute entry** of the correlation matrix M and its sign, one of the following replacements is employed: | ||
|
||
* If :math:`\text{M}_{ii} \geq 0` is the maximum absolute value, then the :math:`i`-th vertex is set to be in the clique set. In turn, all vertices that **do not share an edge with this vertex can be removed from the graph**, since including them in the solution would violate the problem constraints. | ||
|
||
* If :math:`\text{M}_{ii} < 0` is the maximum absolute value, we remove :math:`i`-th vertex from the graph. | ||
|
||
* If :math:`\text{M}_{ij} > 0, (i, j) ∈ E` was selected, we keep both vertices as part of the solution and remove all non-neighboring vertices. The likelihood of this rule failing is low, but remains to be investigated. | ||
|
||
* If :math:`\text{M}_{ij} < 0, (i, j) ∈ E` was selected, we remove all vertices that **do not** share an edge with either vertex :math:`i` or :math:`j`. Since one of the vertices :math:`i` and :math:`j` will be part of the final solution (but not both), any vertex that is **not** connected to either :math:`i` or :math:`j` (or both) is guaranteed to violate the problem constraints, and can be removed from the graph. | ||
|
||
|
||
.. autofunction:: create_max_clique_replacement_routine | ||
|
||
|
||
QIRO Cost operator | ||
------------------ | ||
|
||
.. autofunction:: create_max_clique_cost_operator_reduced | ||
|
||
|
||
Example implementation | ||
---------------------- | ||
|
||
:: | ||
|
||
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) | ||
qarg = QuantumVariable(G.number_of_nodes()) | ||
|
||
# QIRO | ||
qiro_instance = QIROProblem(problem=G, | ||
replacement_routine= reate_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=qarg, depth=3, n_recursions=2) | ||
|
||
# The final graph that has been adjusted | ||
final_graph = qiro_instance.problem | ||
|
||
That’s it! In the following, we print the 5 most likely solutions together with their cost values, and compare to the NetworkX solution. | ||
|
||
:: | ||
|
||
cl_cost = create_max_clique_cl_cost_function(G) | ||
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)) | ||
|
||
Finally, we visualize the final QIRO graph and the most likely solution. | ||
|
||
:: | ||
|
||
# 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() |
95 changes: 95 additions & 0 deletions
95
documentation/source/reference/Algorithms/qiro/implementations/QIROMaxIndep.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
.. _maxIndependentSetQIRO: | ||
|
||
QIRO MaxIndepSet | ||
================ | ||
|
||
.. currentmodule:: qrisp.qiro.qiroproblems.qiroMaxIndepSet | ||
|
||
|
||
Problem description | ||
------------------- | ||
|
||
Given a Graph :math:`G = (V,E)` maximize the size of an independent set, i.e. a subset :math:`V' \subset V` in which all pairs of vertices are mutually non-adjacent. | ||
|
||
|
||
Replacement routine | ||
------------------- | ||
|
||
Based on the **maximum absolute entry** of the correlation matrix M and its sign, one of the following replacements is employed: | ||
|
||
* If :math:`\text{M}_{ii} \geq 0` is the maximum absolute value, then the :math:`i`-th vertex is set to be in the independent set (IS). In turn, all vertices that share an edge with this vertex can be removed from the graph, since including them in the solution would violate the problem constraints. | ||
|
||
* If :math:`\text{M}_{ii} < 0` is the maximum absolute value, we remove :math:`i`-th vertex from the graph. | ||
|
||
* If :math:`\text{M}_{ij} > 0, (i, j) ∈ E` was selected, we remove both vertices from the graph with the argument, that, since both of them would be in the same state in the final solution, including both as part of the solution would violate the constraint, as they share an edge. In turn, they can be removed from the graph. | ||
|
||
* If :math:`\text{M}_{ij} < 0, (i, j) ∈ E` was selected, we remove all vertices that share an edge with both vertices :math:`i` and :math:`j`. Since one of the vertices :math:`i` and :math:`j` will be part of the final solution (but not both), any vertex that is connected to both :math:`i` and :math:`j` is guaranteed to violate the problem constraints, and can be removed from the graph. In this case, it may be possible that no vertex is found to be a canditate for being removed. We will then simply choose the second biggest absolute value of **M** for the replacement routine. | ||
|
||
|
||
.. autofunction:: create_max_indep_replacement_routine | ||
|
||
|
||
QIRO Cost operator | ||
------------------ | ||
|
||
.. autofunction:: create_max_indep_cost_operator_reduced | ||
|
||
|
||
Example implementation | ||
---------------------- | ||
:: | ||
|
||
from qrisp import QuantumVariable | ||
from qrisp.qiro import QIROProblem, create_max_indep_replacement_routine, create_max_indep_cost_operator_reduced, qiro_RXMixer, qiro_init_function | ||
from qrisp.qaoa import create_max_indep_set_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 = 13 | ||
G = nx.erdos_renyi_graph(num_nodes, 0.4, seed = 107) | ||
qarg = QuantumVariable(G.number_of_nodes()) | ||
|
||
qiro_instance = QIROProblem(G, | ||
replacement_routine=create_max_indep_replacement_routine, | ||
cost_operator=create_max_indep_cost_operator_reduced, | ||
mixer=qiro_RXMixer, | ||
cl_cost_function=create_max_indep_set_cl_cost_function, | ||
init_function=qiro_init_function | ||
) | ||
res_qiro = qiro_instance.run_qiro(qarg=qarg, depth=3, n_recursions=2) | ||
|
||
That’s it! In the following, we print the 5 most likely solutions together with their cost values, and compare to the NetworkX solution. | ||
|
||
:: | ||
cl_cost = create_max_indep_set_cl_cost_function(G) | ||
|
||
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.maximum_independent_set(G)) | ||
|
||
Finally, we visualize the final QIRO graph and the most likely solution. | ||
|
||
:: | ||
|
||
# The final graph that has been adjusted | ||
final_graph = qiro_instance.problem | ||
# 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='#D3D3D3') | ||
plt.title('Original graph with most likely QIRO solution') | ||
plt.show() |
Oops, something went wrong.