def test_work_with_dimod(self): S = Array.create('S', 3, "SPIN") H = 0.8 * S[0] * S[1] + S[1] * S[2] + 1.1 * S[2] * S[0] + 0.5 * S[0] model = H.compile() # with index_label=False binary_bqm = model.to_bqm(index_label=False) sampler = dimod.ExactSolver() sampleset = sampler.sample(binary_bqm) decoded_samples = model.decode_sampleset(sampleset) best_sample = min(decoded_samples, key=lambda s: s.energy) self.assertTrue(best_sample.array("S", 0) == 0) self.assertTrue(best_sample.array("S", 1) == 0) self.assertTrue(best_sample.array("S", 2) == 1) self.assertTrue(np.isclose(best_sample.energy, -1.8)) # with index_label=True binary_bqm = model.to_bqm(index_label=True) sampler = dimod.ExactSolver() sampleset = sampler.sample(binary_bqm) decoded_samples = model.decode_sampleset(sampleset) best_sample = min(decoded_samples, key=lambda s: s.energy) self.assertTrue(best_sample.array("S", 0) == 0) self.assertTrue(best_sample.array("S", 1) == 0) self.assertTrue(best_sample.array("S", 2) == 1) self.assertTrue(np.isclose(best_sample.energy, -1.8))
def sample_ising(self, h, J, orig_h=None): if orig_h is not None: assert h != orig_h return dimod.ExactSolver().sample_ising(h, J) return dimod.ExactSolver().sample_qubo(Q)
def test_maximum_independent_set_basic(self): """Runs the function on some small and simple graphs, just to make sure it works in basic functionality. """ G = dnx.chimera_graph(1, 2, 2) indep_set = dnx.maximum_independent_set(G, dimod.ExactSolver()) self.assertTrue(dnx.is_independent_set(G, indep_set)) G = nx.path_graph(5) indep_set = dnx.maximum_independent_set(G, dimod.ExactSolver()) self.assertTrue(dnx.is_independent_set(G, indep_set))
def test_submit_immediate_reply(self): """Construction of and sampling from an unstructured solver works.""" # build a test problem bqm = dimod.BQM.from_ising({}, {'ab': 1}) # use a global mocked session, so we can modify it on-fly session = mock.Mock() # construct a functional solver by mocking client and api response data with mock.patch.object(Client, 'create_session', lambda self: session): with Client('endpoint', 'token') as client: solver = UnstructuredSolver(client, unstructured_solver_data()) # direct bqm sampling ss = dimod.ExactSolver().sample(bqm) session.post = lambda path, _: choose_reply( path, {'problems/': complete_reply(ss)}) fut = solver.sample_bqm(bqm) numpy.testing.assert_array_equal(fut.sampleset, ss) numpy.testing.assert_array_equal(fut.samples, ss.record.sample) numpy.testing.assert_array_equal(fut.energies, ss.record.energy) numpy.testing.assert_array_equal(fut.occurrences, ss.record.num_occurrences) # ising sampling lin, quad, _ = bqm.to_ising() ss = dimod.ExactSolver().sample_ising(lin, quad) session.post = lambda path, _: choose_reply( path, {'problems/': complete_reply(ss)}) fut = solver.sample_ising(lin, quad) numpy.testing.assert_array_equal(fut.sampleset, ss) numpy.testing.assert_array_equal(fut.samples, ss.record.sample) numpy.testing.assert_array_equal(fut.energies, ss.record.energy) numpy.testing.assert_array_equal(fut.occurrences, ss.record.num_occurrences) # qubo sampling qubo, _ = bqm.to_qubo() ss = dimod.ExactSolver().sample_qubo(qubo) session.post = lambda path, _: choose_reply( path, {'problems/': complete_reply(ss)}) fut = solver.sample_qubo(qubo) numpy.testing.assert_array_equal(fut.sampleset, ss) numpy.testing.assert_array_equal(fut.samples, ss.record.sample) numpy.testing.assert_array_equal(fut.energies, ss.record.energy) numpy.testing.assert_array_equal(fut.occurrences, ss.record.num_occurrences)
def calculate(self, G, cost_matrix, starting_node): sapi_token = '' dwave_url = 'https://cloud.dwavesys.com/sapi' dnx.traveling_salesperson(G, dimod.ExactSolver(), start=0) # doctest: +SKIP #nx.draw_networkx(G, node_color=colors, node_size=400, alpha=.8, ax=default_axes, pos=pos) # Test with https://docs.ocean.dwavesys.com/en/latest/docs_dnx/reference/algorithms/tsp.html route = dnx.traveling_salesperson(G, dimod.ExactSolver(), start=starting_node) return route
def test_TSP_basic(self): """Runs the function on some small and simple graphs, just to make sure it works in basic functionality. """ G = nx.complete_graph(4) for u, v in G.edges(): G[u][v]['weight'] = 1 route = tsp.traveling_salesman(G, dimod.ExactSolver()) self.assertTrue(tsp.is_hamiltonian_path(G, route)) G = nx.complete_graph(4) for u, v in G.edges(): G[u][v]['weight'] = u + v route = tsp.traveling_salesman(G, dimod.ExactSolver(), lagrange=10.0) self.assertTrue(tsp.is_hamiltonian_path(G, route))
def test_3path(self): sampler = RoofDualityComposite(dimod.ExactSolver()) sampleset = sampler.sample_ising({'a': 10}, {'ab': -1, 'bc': 1}) # all should be fixed, so should just see one self.assertEqual(len(sampleset), 1) self.assertEqual(set(sampleset.variables), set('abc'))
def test_one_hot_enc_integer(self): a = OneHotEncInteger("a", 0, 4, strength=Placeholder("s")) H = (a - 3) ** 2 model = H.compile() q, offset = model.to_qubo(feed_dict={"s": 10.0}) sampleset = dimod.ExactSolver().sample_qubo(q) response, broken, e = model.decode_dimod_response( sampleset, topk=1, feed_dict={"s": 10.0})[0] self.assertTrue(response["a"][0] == 0) self.assertTrue(response["a"][1] == 0) self.assertTrue(response["a"][2] == 0) self.assertTrue(response["a"][3] == 1) self.assertTrue(response["a"][4] == 0) self.assertTrue(a.interval == (0, 4)) expected_q = {('a[0]', 'a[1]'): 40.0, ('a[0]', 'a[2]'): 40.0, ('a[0]', 'a[3]'): 40.0, ('a[0]', 'a[4]'): 40.0, ('a[1]', 'a[2]'): 44.0, ('a[1]', 'a[3]'): 46.0, ('a[1]', 'a[4]'): 48.0, ('a[2]', 'a[3]'): 52.0, ('a[2]', 'a[4]'): 56.0, ('a[3]', 'a[4]'): 64.0, ('a[0]', 'a[0]'): -20.0, ('a[1]', 'a[1]'): -25.0, ('a[2]', 'a[2]'): -28.0, ('a[3]', 'a[3]'): -29.0, ('a[4]', 'a[4]'): -28.0} assert_qubo_equal(q, expected_q)
def test_minimize_energy_chain_break_method(self): # bug report https://github.com/dwavesystems/dwave-system/issues/206 Q = { (0, 1): 1, (0, 2): 1, (0, 3): 1, (1, 2): 1, (1, 3): 1, (2, 3): 1, (0, 0): 1, (1, 1): 1, (2, 2): 1, (3, 3): 1 } S = {(0, 1): 1, (0, 2): 1, (0, 3): 1, (1, 2): 1, (1, 3): 1, (2, 3): 1} bqm = dimod.BinaryQuadraticModel.from_qubo(Q) G = dnx.chimera_graph(4) sampler = dimod.StructureComposite(dimod.ExactSolver(), G.nodes, G.edges) embedding = {0: [55], 1: [48], 2: [50, 53], 3: [52, 51]} composite = FixedEmbeddingComposite(sampler, embedding) cbm = chain_breaks.MinimizeEnergy(bqm, embedding) composite.sample(bqm, chain_break_method=cbm).resolve()
def test_dimod_vs_list(self): G = nx.complete_graph(4) for u, v in G.edges(): G[u][v]['weight'] = 1 route = tsp.traveling_salesperson(G, dimod.ExactSolver()) route = tsp.traveling_salesperson(G, dimod.SimulatedAnnealingSampler())
def test_k4_equal_weights(self): # k5 with all equal weights so all paths are equally good G = nx.Graph() G.add_weighted_edges_from( (u, v, .5) for u, v in itertools.combinations(range(4), 2)) Q = tsp.traveling_salesperson_qubo(G, lagrange=10) bqm = dimod.BinaryQuadraticModel.from_qubo(Q) # all routes are min weight min_routes = list(itertools.permutations(G.nodes)) # get the min energy of the qubo sampleset = dimod.ExactSolver().sample(bqm) ground_energy = sampleset.first.energy # all possible routes are equally good for route in min_routes: sample = {v: 0 for v in bqm} for idx, city in enumerate(route): sample[(city, idx)] = 1 self.assertAlmostEqual(bqm.energy(sample), ground_energy) # all min-energy solutions are valid routes ground_count = 0 for sample, energy in sampleset.data(['sample', 'energy']): if abs(energy - ground_energy) > .001: break ground_count += 1 self.assertEqual(ground_count, len(min_routes))
def test_upload_failure(self): """Submit should gracefully fail if upload as part of submit fails.""" # build a test problem bqm = dimod.BQM.from_ising({}, {'ab': 1}) # use a global mocked session, so we can modify it on-fly session = mock.Mock() # upload is now part of submit, so we need to mock it mock_upload_exc = ValueError('error') def mock_upload(self, bqm): return Present(exception=mock_upload_exc) # construct a functional solver by mocking client and api response data with mock.patch.object(Client, 'create_session', lambda self: session): with Client('endpoint', 'token') as client: with mock.patch.object(BaseUnstructuredSolver, 'upload_problem', mock_upload): solver = UnstructuredSolver(client, unstructured_solver_data()) # direct bqm sampling ss = dimod.ExactSolver().sample(bqm) session.post = lambda path, _: choose_reply( path, {'problems/': complete_reply(ss)}) fut = solver.sample_bqm(bqm) with self.assertRaises(type(mock_upload_exc)): fut.result()
def test_disconnected_graph(self): """One edge and one disconnected node""" G = nx.path_graph(2) G.add_node(3) coloring = dnx.min_vertex_coloring(G, dimod.ExactSolver()) self.assertTrue(dnx.is_vertex_coloring(G, coloring))
def test_4cycle(self): G = nx.cycle_graph('abcd') Q = dnx.vertex_color_qubo(G, 2) sampleset = dimod.ExactSolver().sample_qubo(Q) # check that the ground state is a valid coloring ground_energy = sampleset.first.energy colorings = [] for sample, en in sampleset.data(['sample', 'energy']): if en > ground_energy: break coloring = {} for (v, c), val in sample.items(): if val: coloring[v] = c self.assertTrue(dnx.is_vertex_coloring(G, coloring)) colorings.append(coloring) # there are two valid colorings self.assertEqual(len(colorings), 2) self.assertEqual(ground_energy, -len(G))
def test_smoke(self): # test that nothing falls down or explodes, most 'tests' would be in # the doctests samples = dimod.ExactSolver().sample_ising( {v: -v - 1 for v in range(5)}, {}) str(samples)
def test_ignored_interactions(self): bqm = dimod.BQM.from_ising({ 'a': -4.0, 'b': -4.0 }, { ('a', 'b'): 3.2, ('b', 'c'): 1 }, 1.5) with self.assertWarns(DeprecationWarning): sampler = ScaleComposite( dimod.TrackingComposite(dimod.ExactSolver())) sampleset = sampler.sample(bqm, scalar=.5, ignored_interactions=[('b', 'c')]) # check that everything was restored properly dimod.testing.assert_sampleset_energies(sampleset, bqm) self.assertEqual( sampler.child.input['bqm'], dimod.BQM.from_ising({ 'a': -2.0, 'b': -2.0 }, { 'ab': 1.6, 'bc': 1 }, .75))
def solve(self, matrix, initial=()): ''' returns: a solution solution is a tuple (dict, float) representing sample and energy. ''' print("solver starts the process...") mtx = matrix.copy() print("Converting matrix to upper triangular...") mtx = mt.to_upper_triangular(mtx) #np.set_printoptions(threshold=np.inf) #print(mtx) np.savetxt("mtx.txt", mtx, fmt='%d') np.set_printoptions(threshold=6) print("matrix has %d zeros out of %d" % (np.count_nonzero(mtx == 0), mtx.shape[0] * mtx.shape[1])) print("Constructing bqm out of matrix...") bqm = dimod.BinaryQuadraticModel.from_numpy_matrix(mtx) print("Exact solver starts now!") sampler = dimod.ExactSolver() response = sampler.sample(bqm) for datum in response.data(fields=['energy', 'num_occurrences']): print(datum) return (response.first.sample, response.first.energy)
def test_weighted_complete_digraph(self): G = nx.DiGraph() G.add_weighted_edges_from([ (0, 1, 2), (1, 0, 1), (0, 2, 2), (2, 0, 2), (0, 3, 1), (3, 0, 2), (1, 2, 2), (2, 1, 1), (1, 3, 2), (3, 1, 2), (2, 3, 2), (3, 2, 1), ]) route = dnx.traveling_salesperson(G, dimod.ExactSolver(), start=1) self.assertEqual(len(route), len(G)) self.assertListEqual(route, [1, 0, 3, 2]) cost = path_weight(G, route) self.assertEqual(cost, 4)
def test_k3_bidirectional(self): G = nx.DiGraph() G.add_weighted_edges_from([('a', 'b', 0.5), ('b', 'a', 0.5), ('b', 'c', 1.0), ('c', 'b', 1.0), ('a', 'c', 2.0), ('c', 'a', 2.0)]) Q = dnx.traveling_salesperson_qubo(G, lagrange=10) bqm = dimod.BinaryQuadraticModel.from_qubo(Q) # all routes are min weight min_routes = list(itertools.permutations(G.nodes)) # get the min energy of the qubo sampleset = dimod.ExactSolver().sample(bqm) ground_energy = sampleset.first.energy # all possible routes are equally good for route in min_routes: sample = {v: 0 for v in bqm.variables} for idx, city in enumerate(route): sample[(city, idx)] = 1 self.assertAlmostEqual(bqm.energy(sample), ground_energy) # all min-energy solutions are valid routes ground_count = 0 for sample, energy in sampleset.data(['sample', 'energy']): if abs(energy - ground_energy) > .001: break ground_count += 1 self.assertEqual(ground_count, len(min_routes))
def test_returned_gap_with_aux(self): """Verify that stitch is only allowing gaps that satisfy min_classical_gap to be returned. In this case, by allowing an auxiliary variable, the min_classical_gap should be achieved and stitch should allow a bqm to be returned. """ csp = dwavebinarycsp.ConstraintSatisfactionProblem("SPIN") csp.add_constraint(operator.eq, ['a', 'b']) min_classical_gap = 3 # No aux case: max_graph_size=2 # Note: Should not be possible to satisfy min_classical_gap with self.assertRaises(dwavebinarycsp.exceptions.ImpossibleBQM): dwavebinarycsp.stitch(csp, min_classical_gap=min_classical_gap, max_graph_size=2) # One aux case: max_graph_size=3 # Note: min_classical_gap should be satisfied when we have three nodes bqm = dwavebinarycsp.stitch(csp, min_classical_gap=min_classical_gap, max_graph_size=3) # Verify one aux case sampleset = dimod.ExactSolver().sample(bqm) energy_array = sampleset.record['energy'] gap = max(energy_array) - min(energy_array) self.assertGreaterEqual(gap, min_classical_gap)
def test_one_hot_enc_integer(self): a = OneHotEncInteger("a", (0, 4), strength=Placeholder("s")) H = (a - 3) ** 2 model = H.compile() q, offset = model.to_qubo(feed_dict={"s": 10.0}) sampleset = dimod.ExactSolver().sample_qubo(q) decoded = model.decode_sampleset( sampleset, feed_dict={"s": 10.0}) best = min(decoded, key=lambda x: x.energy) self.assertTrue(best.subh["a"]==3) self.assertTrue(a.value_range == (0, 4)) expected_q = {('a[0]', 'a[1]'): 20.0, ('a[0]', 'a[2]'): 20.0, ('a[0]', 'a[3]'): 20.0, ('a[0]', 'a[4]'): 20.0, ('a[1]', 'a[2]'): 24.0, ('a[1]', 'a[3]'): 26.0, ('a[1]', 'a[4]'): 28.0, ('a[2]', 'a[3]'): 32.0, ('a[2]', 'a[4]'): 36.0, ('a[3]', 'a[4]'): 44.0, ('a[0]', 'a[0]'): -10.0, ('a[1]', 'a[1]'): -15.0, ('a[2]', 'a[2]'): -18.0, ('a[3]', 'a[3]'): -19.0, ('a[4]', 'a[4]'): -18.0} expected_offset = 19 assert_qubo_equal(q, expected_q) self.assertTrue(offset == expected_offset)
def check_generated_ising_model(self, feasible_configurations, decision_variables, linear, quadratic, ground_energy, infeasible_gap): """Check that the given Ising model has the correct energy levels""" if not feasible_configurations: return response = dimod.ExactSolver().sample_ising(linear, quadratic) # samples are returned in order of energy sample, ground = next(iter(response.data(['sample', 'energy']))) gap = float('inf') self.assertIn(tuple(sample[v] for v in decision_variables), feasible_configurations) seen_configs = set() for sample, energy in response.data(['sample', 'energy']): config = tuple(sample[v] for v in decision_variables) # we want the minimum energy for each config of the decisison variables, # so once we've seen it once we can skip if config in seen_configs: continue if config in feasible_configurations: self.assertAlmostEqual(energy, ground) seen_configs.add(config) else: gap = min(gap, energy - ground) self.assertAlmostEqual(ground_energy, ground) self.assertAlmostEqual(gap, infeasible_gap)
def test_k4(self): # good routes are 0,1,2,3 or 3,2,1,0 (and their rotations) G = nx.Graph() G.add_weighted_edges_from([(0, 1, 1), (1, 2, 1), (2, 3, 1), (3, 0, 1), (0, 2, 2), (1, 3, 2)]) Q = tsp.traveling_salesperson_qubo(G, lagrange=10) bqm = dimod.BinaryQuadraticModel.from_qubo(Q) # good routes won't have 0<->2 or 1<->3 min_routes = [(0, 1, 2, 3), (1, 2, 3, 0), (2, 3, 0, 1), (1, 2, 3, 0), (3, 2, 1, 0), (2, 1, 0, 3), (1, 0, 3, 2), (0, 3, 2, 1)] # get the min energy of the qubo sampleset = dimod.ExactSolver().sample(bqm) ground_energy = sampleset.first.energy # all possible routes are equally good for route in min_routes: sample = {v: 0 for v in bqm} for idx, city in enumerate(route): sample[(city, idx)] = 1 self.assertAlmostEqual(bqm.energy(sample), ground_energy) # all min-energy solutions are valid routes ground_count = 0 for sample, energy in sampleset.data(['sample', 'energy']): if abs(energy - ground_energy) > .001: break ground_count += 1 self.assertEqual(ground_count, len(min_routes))
def solve_qubo_exact(Q, all=False): solver = dimod.ExactSolver() response = solver.sample_qubo(Q) minE = min(response.data(['sample', 'energy']), key=lambda x: x[1]) for sample, energy in response.data(['sample', 'energy']): if all or energy == minE[1]: print(sample)
def test_weighted_complete_graph(self): G = nx.Graph() G.add_weighted_edges_from({(0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 2, 3), (1, 3, 4), (2, 3, 5)}) route = dnx.traveling_salesperson(G, dimod.ExactSolver(), lagrange=10) self.assertEqual(len(route), len(G))
def test_eight_variable_constraint_smoketest(self): csp = dwavebinarycsp.ConstraintSatisfactionProblem( dwavebinarycsp.BINARY) variables = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] # this is reducible but for our purposes here that's fine def f(a, b, c, d, e, f, g, h): if a and b: return False if c and d: return False if e and f: return False return not (g and h) csp.add_constraint(f, variables) bqm = dwavebinarycsp.stitch(csp) resp = dimod.ExactSolver().sample(bqm) ground_energy = min(resp.record['energy']) for sample, energy in resp.data(['sample', 'energy']): if energy == ground_energy: self.assertTrue(csp.check(sample)) else: if abs(energy - ground_energy) < 2: # if classical gap is less than 2 self.assertTrue(csp.check(sample))
def test_dnx(self): import dimod import dwave_networkx as dnx G = dnx.chimera_graph(1) cut = dnx.maximum_cut(G, dimod.ExactSolver())
def check_bqm_table(self, bqm, gap, table, decision): """check that the bqm has ground states matching table""" response = dimod.ExactSolver().sample(bqm) seen_gap = float('inf') seen_table = set() for sample, energy in response.data(['sample', 'energy']): self.assertAlmostEqual(bqm.energy(sample), energy) # sanity check config = tuple(sample[v] for v in decision) if energy < .001: self.assertIn(config, table) if isinstance(table, dict): self.assertAlmostEqual(table[config], energy) seen_table.add(config) elif config not in table: seen_gap = min(seen_gap, energy) for config in table: self.assertIn(config, seen_table) self.assertEqual(seen_gap, gap) self.assertGreater(gap, 0)
def test_unembed_sampleset_with_discard_matrix_typical(self): h = {'a': .1, 'b': 0, 'c': 0} J = {('a', 'b'): 1, ('b', 'c'): 1.3, ('a', 'c'): -1} bqm = dimod.BinaryQuadraticModel.from_ising(h, J, offset=1.3) embedding = {'a': {0}, 'b': {1}, 'c': {2, 3}} embedded_bqm = dwave.embedding.embed_bqm(bqm, embedding, nx.cycle_graph(4), chain_strength=1) embedded_response = dimod.ExactSolver().sample(embedded_bqm) chain_break_method = dwave.embedding.discard response = dwave.embedding.unembed_sampleset( embedded_response, embedding, bqm, chain_break_method=dwave.embedding.discard) self.assertEqual(len(embedded_response) / 2, len(response)) # half chains should be broken for sample, energy in response.data(['sample', 'energy']): self.assertEqual(bqm.energy(sample), energy)
def test_instantiation_smoketest(self): sampler = PolyCutOffComposite( dimod.HigherOrderComposite(dimod.ExactSolver()), 0) self.assertTrue(hasattr(sampler, 'sample_poly')) self.assertTrue(hasattr(sampler, 'sample_hising')) self.assertTrue(hasattr(sampler, 'sample_hubo'))