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)
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)
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')
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)
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')
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
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, {})