Exemplo n.º 1
0
    def test_bit_flip_mixer_errors(self):
        """Tests that the bit-flip mixer throws the correct errors"""

        graph = [(0, 1), (1, 2)]
        with pytest.raises(ValueError, match=r"Input graph must be a nx.Graph object"):
            qaoa.bit_flip_mixer(graph, 0)

        n = 2
        with pytest.raises(ValueError, match=r"'b' must be either 0 or 1"):
            qaoa.bit_flip_mixer(Graph(graph), n)
Exemplo n.º 2
0
def max_clique(graph, constrained=True):
    r"""Returns the QAOA cost Hamiltonian and the recommended mixer corresponding to the Maximum Clique problem,
    for a given graph.

    The goal of Maximum Clique is to find the largest `clique <https://en.wikipedia.org/wiki/Clique_(graph_theory)>`__ of a
    graph --- the largest subgraph such that all vertices are connected by an edge.

    Args:
        graph (nx.Graph): a graph whose edges define the pairs of vertices on which each term of the Hamiltonian acts
        constrained (bool): specifies the variant of QAOA that is performed (constrained or unconstrained)

    Returns:
        (.Hamiltonian, .Hamiltonian): The cost and mixer Hamiltonians

    .. UsageDetails::

        There are two variations of QAOA for this problem, constrained and unconstrained:

        **Constrained**

        .. note::

            This method of constrained QAOA was introduced by Hadfield, Wang, Gorman, Rieffel, Venturelli, and Biswas
            in arXiv:1709.03489.

        The Maximum Clique cost Hamiltonian for constrained QAOA is defined as:

        .. math:: H_C \ = \ \displaystyle\sum_{v \in V(G)} Z_{v},

        where :math:`V(G)` is the set of vertices of the input graph, and :math:`Z_i` is the Pauli-Z operator
        applied to the :math:`i`-th
        vertex.

        The returned mixer Hamiltonian is :func:`~qaoa.bit_flip_mixer` applied to :math:`\bar{G}`,
        the complement of the graph.

        .. note::

            **Recommended initialization circuit:**
                Each wire in the :math:`|0\rangle` state.

        **Unconstrained**

        The Maximum Clique cost Hamiltonian for unconstrained QAOA is defined as:

        .. math:: H_C \ = \ 3 \sum_{(i, j) \in E(\bar{G})}
                  (Z_i Z_j \ - \ Z_i \ - \ Z_j) \ + \ \displaystyle\sum_{i \in V(G)} Z_i

        where :math:`V(G)` is the set of vertices of the input graph :math:`G`, :math:`E(\bar{G})` is the set of
        edges of the complement of :math:`G`, and :math:`Z_i` is the Pauli-Z operator applied to the
        :math:`i`-th vertex.

        The returned mixer Hamiltonian is :func:`~qaoa.x_mixer` applied to all wires.

        .. note::

            **Recommended initialization circuit:**
                Even superposition over all basis states.

    """

    if not isinstance(graph, nx.Graph):
        raise ValueError("Input graph must be a nx.Graph, got {}".format(
            type(graph).__name__))

    if constrained:
        cost_h = bit_driver(graph.nodes, 1)
        cost_h.grouping_indices = [list(range(len(cost_h.ops)))]
        return (cost_h, qaoa.bit_flip_mixer(nx.complement(graph), 0))

    cost_h = 3 * edge_driver(nx.complement(graph),
                             ["10", "01", "00"]) + bit_driver(graph.nodes, 1)
    mixer_h = qaoa.x_mixer(graph.nodes)

    # store the valuable information that all observables are in one commuting group
    cost_h.grouping_indices = [list(range(len(cost_h.ops)))]

    return (cost_h, mixer_h)
Exemplo n.º 3
0
    def test_bit_flip_mixer_output(self, graph, n, target_hamiltonian):
        """Tests that the output of the bit-flip mixer is correct"""

        mixer_hamiltonian = qaoa.bit_flip_mixer(graph, n)
        assert decompose_hamiltonian(mixer_hamiltonian) == decompose_hamiltonian(target_hamiltonian)
Exemplo n.º 4
0
def min_vertex_cover(graph, constrained=True):
    r"""Returns the QAOA cost Hamiltonian and the recommended mixer corresponding to the Minimum Vertex Cover problem,
    for a given graph.

    To solve the Minimum Vertex Cover problem, we attempt to find the smallest
    `vertex cover <https://en.wikipedia.org/wiki/Vertex_cover>`__ of a graph --- a collection of vertices such that
    every edge in the graph has one of the vertices as an endpoint.

    Args:
        graph (nx.Graph): a graph whose edges define the pairs of vertices on which each term of the Hamiltonian acts
        constrained (bool): specifies the variant of QAOA that is performed (constrained or unconstrained)

    Returns:
        (.Hamiltonian, .Hamiltonian): The cost and mixer Hamiltonians

    .. UsageDetails::

        There are two variations of QAOA for this problem, constrained and unconstrained:

        **Constrained**

        .. note::

            This method of constrained QAOA was introduced by Hadfield, Wang, Gorman, Rieffel, Venturelli, and Biswas
            in arXiv:1709.03489.

        The Minimum Vertex Cover cost Hamiltonian for constrained QAOA is defined as:

        .. math:: H_C \ = \ - \displaystyle\sum_{v \in V(G)} Z_{v},

        where :math:`V(G)` is the set of vertices of the input graph, and :math:`Z_i` is the Pauli-Z operator
        applied to the :math:`i`-th vertex.

        The returned mixer Hamiltonian is :func:`~qaoa.bit_flip_mixer` applied to :math:`G`.

        .. note::

            **Recommended initialization circuit:**
                Each wire in the :math:`|1\rangle` state.

        **Unconstrained**

        The Minimum Vertex Cover cost Hamiltonian for unconstrained QAOA is defined as:

        .. math:: H_C \ = \ 3 \sum_{(i, j) \in E(G)} (Z_i Z_j \ + \ Z_i \ + \ Z_j) \ - \
                  \displaystyle\sum_{i \in V(G)} Z_i

        where :math:`E(G)` is the set of edges of :math:`G`, :math:`V(G)` is the set of vertices,
        and :math:`Z_i` is the Pauli-Z operator acting on the :math:`i`-th vertex.

        The returned mixer Hamiltonian is :func:`~qaoa.x_mixer` applied to all wires.

        .. note::

            **Recommended initialization circuit:**
                Even superposition over all basis states.

    """

    if not isinstance(graph, nx.Graph):
        raise ValueError("Input graph must be a nx.Graph, got {}".format(
            type(graph).__name__))

    if constrained:
        return (bit_driver(graph.nodes, 0), qaoa.bit_flip_mixer(graph, 1))

    cost_h = 3 * edge_driver(graph, ["11", "10", "01"]) + bit_driver(
        graph.nodes, 0)
    mixer_h = qaoa.x_mixer(graph.nodes)

    return (cost_h, mixer_h)
Exemplo n.º 5
0
def max_independent_set(graph, constrained=True):
    r"""For a given graph, returns the QAOA cost Hamiltonian and the recommended mixer corresponding to the Maximum Independent Set problem.

    Given some graph :math:`G`, an independent set is a set of vertices such that no pair of vertices in the set
    share a common edge. The Maximum Independent Set problem, is the problem of finding the largest such set.

    Args:
        graph (nx.Graph): a graph whose edges define the pairs of vertices on which each term of the Hamiltonian acts
        constrained (bool): specifies the variant of QAOA that is performed (constrained or unconstrained)

    Returns:
        (.Hamiltonian, .Hamiltonian): The cost and mixer Hamiltonians

    .. UsageDetails::

        There are two variations of QAOA for this problem, constrained and unconstrained:

        **Constrained**

        .. note::

            This method of constrained QAOA was introduced by Hadfield, Wang, Gorman, Rieffel, Venturelli, and Biswas
            in arXiv:1709.03489.

        The Maximum Independent Set cost Hamiltonian for constrained QAOA is defined as:

        .. math:: H_C \ = \ \displaystyle\sum_{v \in V(G)} Z_{v},

        where :math:`V(G)` is the set of vertices of the input graph, and :math:`Z_i` is the Pauli-Z
        operator applied to the :math:`i`-th vertex.

        The returned mixer Hamiltonian is :func:`~qaoa.bit_flip_mixer` applied to :math:`G`.

        .. note::

            **Recommended initialization circuit:**
                Each wire in the :math:`|0\rangle` state.

        **Unconstrained**

        The Maximum Independent Set cost Hamiltonian for unconstrained QAOA is defined as:

        .. math:: H_C \ = \ 3 \sum_{(i, j) \in E(G)} (Z_i Z_j \ - \ Z_i \ - \ Z_j) \ + \
                  \displaystyle\sum_{i \in V(G)} Z_i

        where :math:`E(G)` is the set of edges of :math:`G`, :math:`V(G)` is the set of vertices,
        and :math:`Z_i` is the Pauli-Z operator acting on the :math:`i`-th vertex.

        The returned mixer Hamiltonian is :func:`~qaoa.x_mixer` applied to all wires.

        .. note::

            **Recommended initialization circuit:**
                Even superposition over all basis states.

    """

    if not isinstance(graph, nx.Graph):
        raise ValueError("Input graph must be a nx.Graph, got {}".format(
            type(graph).__name__))

    if constrained:
        return (bit_driver(graph.nodes, 1), qaoa.bit_flip_mixer(graph, 0))

    cost_h = 3 * edge_driver(graph, ["10", "01", "00"]) + bit_driver(
        graph.nodes, 1)
    mixer_h = qaoa.x_mixer(graph.nodes)

    return (cost_h, mixer_h)