Beispiel #1
0
    def clique_battery(self,
                       g,
                       reconstruct,
                       test_python=False,
                       test_nocache=True):
        bgcg = busclique.busgraph_cache(g)
        emb0 = bgcg.largest_clique()
        size = len(emb0)
        cl = max_chainlength(emb0)
        N = range(size)
        yield size, cl
        yield g, emb0, 'g:bcg.lc', True
        yield g, bgcg.find_clique_embedding(size), 'g:bcg.fce', True
        yield g, busclique.find_clique_embedding(size, g), 'g:bc.fce', True
        if test_nocache:
            yield (g, busclique.find_clique_embedding(size, g,
                                                      use_cache=False),
                   'g:bc.fce,nc', True)
        yield g, bgcg.largest_clique_by_chainlength(cl), 'g:bc.lcbc', True
        if test_python:
            if g.graph['family'] == 'chimera':
                if g.graph['labels'] == 'int':
                    # this fails on coordinate-labeled graphs... TODO?
                    args = size, g.graph['rows']
                    kwargs = dict(target_edges=g.edges)
                    yield (g, chimera.find_clique_embedding(*args, **kwargs),
                           'g:legacy.fce', True)
            if g.graph['family'] == 'pegasus':
                kwargs = dict(target_graph=g)
                yield (g, pegasus.find_clique_embedding(size, **kwargs),
                       'g:legacy.fce', False)

        nodes = set(itertools.chain.from_iterable(emb0.values()))
        h = reconstruct(nodes)
        bgch = busclique.busgraph_cache(h)
        yield h, busclique.find_clique_embedding(N, h), 'h:bc.fce', True
        if test_nocache:
            yield (h, busclique.find_clique_embedding(N, h, use_cache=False),
                   'h:bc.fce,nc', True)
        yield h, bgch.largest_clique(), 'h:bgc.lc', True
        yield h, bgch.find_clique_embedding(N), 'h:bgc.fce', True
        yield h, bgch.largest_clique_by_chainlength(cl), 'h:bgc.lcbc', True
        if test_python:
            if g.graph['family'] == 'chimera':
                if g.graph['labels'] == 'int':
                    # this fails on coordinate-labeled graphs... TODO?
                    args = size, h.graph['rows']
                    kwargs = dict(target_edges=h.edges)
                    yield (h, chimera.find_clique_embedding(*args, **kwargs),
                           'h:legacy.fce', True)
            if g.graph['family'] == 'pegasus':
                kwargs = dict(target_graph=h)
                yield (h, pegasus.find_clique_embedding(size, **kwargs),
                       'h:legacy.fce', False)
Beispiel #2
0
    def test_perfect_z6_clique(self):
        k88 = nx.complete_graph(88)
        bgc = busclique.busgraph_cache(self.z6)
        e88_cache = bgc.largest_clique()
        verify_embedding(e88_cache, k88, self.z6)

        e88_cache2 = busclique.find_clique_embedding(88,
                                                     self.z6,
                                                     use_cache=True)
        verify_embedding(e88_cache2, k88, self.z6)

        e88 = busclique.find_clique_embedding(88, self.z6, use_cache=False)
        verify_embedding(e88, k88, self.z6)
Beispiel #3
0
    def clique(self, variables):
        """Return a clique embedding of the given size.

        Args:
            variables (int/collection):
                Source variables. If an integer, the variables  embedded are
                labelled `[0,n)`.

        Returns:
            dict: The clique embedding.
        """
        return find_clique_embedding(variables, self.target_graph)
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import matplotlib.pyplot as plt
import networkx as nx
import dwave_networkx as dnx
from minorminer.busclique import find_clique_embedding
from dwave.system.samplers import DWaveSampler

N = int(sys.argv[1])
G = nx.complete_graph(N)

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 6))

# Draw the QUBO as a networkx graph
pos = nx.spring_layout(G)
nx.draw_networkx(G, pos=pos, font_size=10, node_size=100, node_color='cyan', ax=axes[0])

# Draw the embedded graph
dwave_sampler = DWaveSampler(solver={'topology__type__eq': 'chimera'})
A = dwave_sampler.edgelist
chimera_graph = dnx.chimera_graph(16, edge_list=A)
clique_embedding = find_clique_embedding(N, chimera_graph)
dnx.draw_chimera_embedding(chimera_graph, clique_embedding, embedded_graph=G, unused_color=None, ax=axes[1])
plt.savefig('clique_embedding_chimera')
Beispiel #5
0
    def sample(self, bqm, chain_strength=None, **kwargs):
        """Sample from the specified binary quadratic model.

        Args:
            bqm (:class:`~dimod.BinaryQuadraticModel`):
                Any binary quadratic model with up to
                :attr:`.largest_clique_size` variables. This BQM is embedded
                using a clique embedding.

            chain_strength (float/mapping/callable, optional):
                Sets the coupling strength between qubits representing variables
                that form a :term:`chain`. Mappings should specify the required
                chain strength for each variable. Callables should accept the BQM
                and embedding and return a float or mapping. By default,
                `chain_strength` is calculated with
                :func:`~dwave.embedding.chain_strength.uniform_torque_compensation`.

            **kwargs:
                Optional keyword arguments for the sampling method, specified
                per solver in :attr:`.parameters`.
                D-Wave System Documentation's
                `solver guide <https://docs.dwavesys.com/docs/latest/doc_solver_ref.html>`_
                describes the parameters and properties supported on the D-Wave
                system. Note that `auto_scale` is not supported by this
                sampler, because it scales the problem as part of the embedding
                process.

        Returns:
            :class:`~dimod.SampleSet`: Sample set constructed from a (non-blocking)
            :class:`~concurrent.futures.Future`-like object.

        """

        # some arguments should not be overwritten
        if 'auto_scale' in kwargs:
            raise TypeError("sample() got an unexpected keyword argument "
                            "'auto_scale'")
        if 'bias_range' in kwargs:
            raise TypeError("sample() got an unexpected keyword argument "
                            "'bias_range'")
        if 'quadratic_range' in kwargs:
            raise TypeError("sample() got an unexpected keyword argument "
                            "'quadratic_range'")

        # handle circular import. todo: fix
        from dwave.system.composites.embedding import FixedEmbeddingComposite

        # get the embedding
        embedding = find_clique_embedding(bqm.variables,
                                          self.target_graph,
                                          use_cache=True)

        # returns an empty embedding when the BQM is too large
        if not embedding and bqm.num_variables:
            raise ValueError("Cannot embed given BQM (size {}), sampler can "
                             "only handle problems of size {}".format(
                                 len(bqm.variables), self.largest_clique_size))

        assert bqm.num_variables == len(embedding)  # sanity check

        # scaling only make sense in Ising space
        original_bqm = bqm

        if bqm.vartype is not dimod.SPIN:
            bqm = bqm.change_vartype(dimod.SPIN, inplace=False)

        sampler = FixedEmbeddingComposite(
            ScaleComposite(_QubitCouplingComposite(self.child)), embedding)

        if 'auto_scale' in self.child.parameters:
            kwargs['auto_scale'] = False

        sampleset = sampler.sample(bqm,
                                   bias_range=self.qpu_linear_range,
                                   quadratic_range=self.qpu_quadratic_range,
                                   chain_strength=chain_strength,
                                   **kwargs)

        # change_vartype is non-blocking
        return sampleset.change_vartype(original_bqm.vartype)
Beispiel #6
0
    def sample(self, bqm, chain_strength=None, **kwargs):
        """Sample from the specified binary quadratic model.

        Args:
            bqm (:class:`~dimod.BinaryQuadraticModel`):
                Any binary quadratic model with up to
                :attr:`.largest_clique_size` variables. This BQM is embedded
                using a dense clique embedding.

            chain_strength (float, optional):
                The (relative) chain strength to use in the embedding. By
                default a chain strength of `1.5sqrt(N)` where `N` is the size
                of the largest clique, as returned by
                :attr:`.largest_clique_size`.

            **kwargs:
                Optional keyword arguments for the sampling method, specified
                per solver in :attr:`.DWaveCliqueSampler.parameters`.
                D-Wave System Documentation's
                `solver guide <https://docs.dwavesys.com/docs/latest/doc_solver_ref.html>`_
                describes the parameters and properties supported on the D-Wave
                system. Note that `auto_scale` is not supported by this
                sampler, because it scales the problem as part of the embedding
                process.

        """

        # some arguments should not be overwritten
        if 'auto_scale' in kwargs:
            raise TypeError("sample() got an unexpected keyword argument "
                            "'auto_scale'")
        if 'bias_range' in kwargs:
            raise TypeError("sample() got an unexpected keyword argument "
                            "'bias_range'")
        if 'quadratic_range' in kwargs:
            raise TypeError("sample() got an unexpected keyword argument "
                            "'quadratic_range'")

        # handle circular import. todo: fix
        from dwave.system.composites.embedding import FixedEmbeddingComposite

        # get the embedding
        embedding = find_clique_embedding(bqm.variables, self.target_graph,
                                          use_cache=True)

        # returns an empty embedding when the BQM is too large
        if not embedding and bqm.num_variables:
            raise ValueError("Cannot embed given BQM (size {}), sampler can "
                             "only handle problems of size {}".format(
                                len(bqm.variables), self.largest_clique_size))

        assert bqm.num_variables == len(embedding)  # sanity check

        if chain_strength is None:
            # chain length determines chain strength
            if embedding and bqm.num_interactions > 0:
                squared_j = (j ** 2 for j in bqm.quadratic.values())
                rms = math.sqrt(sum(squared_j)/bqm.num_interactions)
       
                chain_strength = 1.5 * rms * math.sqrt(bqm.num_variables)
            else:
                chain_strength = 1  # doesn't matter

        # scaling only make sense in Ising space
        original_bqm = bqm

        if bqm.vartype is not dimod.SPIN:
            bqm = bqm.change_vartype(dimod.SPIN, inplace=False)

        sampler = FixedEmbeddingComposite(
            dimod.ScaleComposite(self.child),
            embedding)

        if 'auto_scale' in self.child.parameters:
            kwargs['auto_scale'] = False

        sampleset = sampler.sample(bqm,
                                   bias_range=self.qpu_linear_range,
                                   quadratic_range=self.qpu_quadratic_range,
                                   chain_strength=chain_strength,
                                   **kwargs
                                   )

        # change_vartype is non-blocking
        return sampleset.change_vartype(original_bqm.vartype)
except ImportError:
    matplotlib.use("agg")
    import matplotlib.pyplot as plt

N = int(sys.argv[1])
G = nx.complete_graph(N)

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 6))

node_color_list = [(random(), random(), random()) for i in range(N)]
chain_color_list = {i: node_color_list[i] for i in range(N)}

# Draw the QUBO as a networkx graph
pos = nx.spring_layout(G)
nx.draw_networkx(G, pos=pos, font_size=10, node_size=300, node_color=node_color_list, edge_color='gray', ax=axes[0])

# Draw the embedded graph
dwave_sampler = DWaveSampler(solver={'topology__type__eq': 'pegasus'})
A = dwave_sampler.edgelist
pegasus_graph = dnx.pegasus_graph(16, edge_list=A)
clique_embedding = find_clique_embedding(N, pegasus_graph)

qubits = 0
for chain in clique_embedding.values():
    qubits += len(chain)

print("\nEmbedding for", N, "clique found using", qubits, "qubits.")

dnx.draw_pegasus_embedding(pegasus_graph, clique_embedding, embedded_graph=G, chain_color=chain_color_list, unused_color=None, ax=axes[1])
plt.savefig('clique_embedding_pegasus')
Beispiel #8
0
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(12, 6))

# Draw the QUBO as a networkx graph
pos = nx.spring_layout(G)
nx.draw_networkx(G,
                 pos=pos,
                 font_size=10,
                 node_size=100,
                 node_color='cyan',
                 ax=axes[0])

# Embed the graph on Chimera
dwave_sampler_chimera = DWaveSampler(solver={'topology__type': 'chimera'})
chimera_edges = dwave_sampler_chimera.edgelist
chimera_graph = dnx.chimera_graph(16, edge_list=chimera_edges)
clique_embedding_chimera = find_clique_embedding(N, chimera_graph)

# Draw the graph embedded on Chimera
dnx.draw_chimera_embedding(chimera_graph,
                           clique_embedding_chimera,
                           embedded_graph=G,
                           unused_color=None,
                           ax=axes[1])

# Embed the graph on Pegasus
dwave_sampler_pegasus = DWaveSampler(solver={'topology__type': 'pegasus'})
pegasus_edges = dwave_sampler_pegasus.edgelist
pegasus_graph = dnx.pegasus_graph(16, edge_list=pegasus_edges)
clique_embedding_pegasus = find_clique_embedding(N, pegasus_graph)

# Draw the graph embedded on Pegasus
Beispiel #9
0
    def test_k4_bug(self):
        edges = [30, 2940], [30, 2955], [45, 2940], [45, 2955], [2940, 2955]
        p = dnx.pegasus_graph(16, edge_list=edges)
        k4 = busclique.find_clique_embedding(4, p)

        self.assertEquals(k4, {})