def test_simple_schedule_more_machines(self): jobs = {"j0": [(0, 1)], "j1": [(1, 1)], "j2": [(2, 1)]} max_time = 3 # Get JSS BQM scheduler = JobShopScheduler(jobs, max_time) bqm = scheduler.get_bqm() # Expected solution expected = {"j0_0,0": 1, "j1_0,0": 1, "j2_0,0": 1} fill_with_zeros(expected, jobs, max_time) expected_energy = get_energy(expected, bqm) # Sampled solution # response = EmbeddingComposite(DWaveSampler()).sample(bqm, num_reads=10000) # response_sample, sample_energy, _, chain_break_fraction = next(response.data()) # print("Chain Break Fraction: ", chain_break_fraction) # response = SimulatedAnnealingSampler().sample(bqm, num_reads=2000, beta_range=[0.01, 10]) response = ExactSolver().sample(bqm) response_sample, sample_energy, _ = next(response.data()) # Print response self.assertTrue(scheduler.csp.check(response_sample)) self.assertEqual(expected_energy, sample_energy) self.compare(response_sample, expected)
def test_no_bounds(self): bqm = BinaryQuadraticModel({ 0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0 }, { (0, 1): -2.0, (0, 2): -5.0, (0, 3): -2.0, (0, 4): -2.0, (1, 2): -2.0, (1, 3): -2.0, (1, 4): 4.0, (2, 3): -3.0, (2, 4): -5.0, (3, 4): -4.0 }, 0, dimod.SPIN) with self.assertWarns(DeprecationWarning): sampler = ClipComposite(ExactSolver()) solver = ExactSolver() response = sampler.sample(bqm) response_exact = solver.sample(bqm) self.assertEqual(response.first.sample, response_exact.first.sample) self.assertAlmostEqual(response.first.energy, response_exact.first.energy)
def test_vertex_cover_weighted(self): weight = 'weight' G = nx.path_graph(6) # favor even nodes nx.set_node_attributes(G, {node: node % 2 + 1 for node in G}, weight) cover = dnx.min_weighted_vertex_cover(G, weight, ExactSolver()) self.assertEqual(set(cover), {0, 2, 4}) # favor odd nodes nx.set_node_attributes(G, {node: (node + 1) % 2 + 1 for node in G}, weight) cover = dnx.min_weighted_vertex_cover(G, weight, ExactSolver()) self.assertEqual(set(cover), {1, 3, 5}) # make nodes 1 and 4 unlikely nx.set_node_attributes(G, {0: 1, 1: 3, 2: 1, 3: 1, 4: 3, 5: 1}, weight) cover = dnx.min_weighted_vertex_cover(G, weight, ExactSolver()) self.assertEqual(set(cover), {0, 2, 3, 5}) for __ in range(10): G = nx.gnp_random_graph(5, .5) nx.set_node_attributes(G, {node: random.random() for node in G}, weight) cover = dnx.min_weighted_vertex_cover(G, weight, ExactSolver()) self.vertex_cover_check(G, cover)
def test_with_labels(self): bqm = BinaryQuadraticModel( { 'a': 0.0, 'b': 0.0, 'c': 0.0, 'd': 0.0, 'e': 0.0 }, { ('a', 'b'): -2.0, ('a', 'c'): -5.0, ('a', 'd'): -2.0, ('a', 'e'): -2.0, ('b', 'c'): -2.0, ('b', 'd'): -2.0, ('b', 'e'): 4.0, ('c', 'd'): -3.0, ('c', 'e'): -5.0, ('d', 'e'): -4.0 }, 0, dimod.SPIN) sampler = ClipComposite(ExactSolver()) solver = ExactSolver() response = sampler.sample(bqm, lower_bound=-1, upper_bound=1) response_exact = solver.sample(bqm) self.assertEqual(response.first.sample, response_exact.first.sample) self.assertAlmostEqual(response.first.energy, response_exact.first.energy)
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 from dimod import ExactSolver samples = ExactSolver().sample_ising(linear, quadratic) # samples are returned in order of energy sample, ground = next(iter(samples.items())) gap = float('inf') self.assertIn(tuple(sample[v] for v in decision_variables), feasible_configurations) seen_configs = set() for sample, energy in samples.items(): 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_sample_hising_quadratic_range(self): linear = {'a': -4.0, 'b': -4.0, 'c': -4.0} quadratic = {('a', 'b', 'c'): 3.2} offset = 5 ignored_variables, ignored_interactions = _check_params(None, None) comp_parameters = dict(ignored_interactions=ignored_interactions, ignored_variables=ignored_variables, penalty_strength=5., quadratic_range=(-1, 2) ) sampler = ScaleComposite( ScalingChecker(HigherOrderComposite(ExactSolver()), h=linear, J=quadratic, offset=offset, **comp_parameters)) response = sampler.sample_ising(linear, quadratic, offset=offset, **comp_parameters) self.assertAlmostEqual(response.first.energy, -3.8) comp_parameters = dict(ignored_interactions=ignored_interactions, ignored_variables=ignored_variables, penalty_strength=5., quadratic_range=(-1, 0.4) ) sampler = ScaleComposite( ScalingChecker(HigherOrderComposite(ExactSolver()), h=linear, J=quadratic, offset=offset, **comp_parameters)) response = sampler.sample_ising(linear, quadratic, offset=offset, **comp_parameters) self.assertAlmostEqual(response.first.energy, -3.8)
def test_ub_only(self): bqm = BinaryQuadraticModel({ 0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0 }, { (0, 1): -2.0, (0, 2): -5.0, (0, 3): -2.0, (0, 4): -2.0, (1, 2): -2.0, (1, 3): -2.0, (1, 4): 4.0, (2, 3): -3.0, (2, 4): -5.0, (3, 4): -4.0 }, 0, dimod.SPIN) sampler = ClipComposite(ExactSolver()) solver = ExactSolver() response = sampler.sample(bqm, upper_bound=1) response_exact = solver.sample(bqm) self.assertEqual(response.first.sample, response_exact.first.sample) self.assertAlmostEqual(response.first.energy, response_exact.first.energy)
def test_largerSchedule(self): jobs = { 'small1': [(1, 1)], 'small2': [(2, 2)], 'longJob': [(0, 1), (1, 1), (2, 1)] } max_time = 4 # Get exact sample from Job Shop Scheduler BQM jss = JobShopScheduler(jobs, max_time) bqm = jss.get_bqm() response = ExactSolver().sample(bqm) response_sample = next(response.samples()) # Verify that response_sample obeys constraints self.assertTrue(jss.csp.check(response_sample)) # Create expected solution expected = { "small1_0,0": 1, "small2_0,0": 1, "longJob_0,0": 1, "longJob_1,1": 1, "longJob_2,2": 1 } # Compare variable values self.compare(response_sample, expected)
def test_dimod_vs_list(self): G = nx.path_graph(5) matching = dnx.min_maximal_matching(G, ExactSolver()) matching = dnx.algorithms.matching.maximal_matching(G, ExactSolver()) matching = dnx.min_maximal_matching(G, SimulatedAnnealingSampler()) matching = dnx.algorithms.matching.maximal_matching( G, SimulatedAnnealingSampler())
def test_edge_cases(self): # get the empty graph G = nx.Graph() S = dnx.maximum_cut(G, ExactSolver()) self.assertTrue(len(S) == 0) S = dnx.weighted_maximum_cut(G, ExactSolver()) self.assertTrue(len(S) == 0)
def test_maximal_matching_typical(self): G = nx.complete_graph(5) matching = dnx.algorithms.matching.maximal_matching(G, ExactSolver()) self.assertTrue(dnx.is_maximal_matching(G, matching)) for __ in range(10): G = nx.gnp_random_graph(7, .5) matching = dnx.algorithms.matching.maximal_matching( G, ExactSolver()) self.assertTrue(dnx.is_maximal_matching(G, matching))
def test_min_maximal_matching_typical(self): G = nx.complete_graph(5) matching = dnx.min_maximal_matching(G, ExactSolver()) self.assertTrue(dnx.is_maximal_matching(G, matching)) for __ in range(10): G = nx.gnp_random_graph(7, .5) matching = dnx.min_maximal_matching(G, ExactSolver()) self.assertTrue(dnx.is_maximal_matching(G, matching), "nodes: {}\nedges:{}".format(G.nodes(), G.edges()))
def test_vertex_color_basic(self): # all small enough for an exact solver to handle them reasonably G = dnx.chimera_graph(1, 2, 2) coloring = dnx.min_vertex_coloring(G, ExactSolver()) self.assertTrue(dnx.is_vertex_coloring(G, coloring)) G = nx.path_graph(5) coloring = dnx.min_vertex_coloring(G, ExactSolver()) self.assertTrue(dnx.is_vertex_coloring(G, coloring)) for __ in range(10): G = nx.gnp_random_graph(5, .5) coloring = dnx.min_vertex_coloring(G, ExactSolver()) self.assertTrue(dnx.is_vertex_coloring(G, coloring))
def test_vertex_cover_basic(self): G = dnx.chimera_graph(1, 2, 2) cover = dnx.min_vertex_cover(G, ExactSolver()) self.vertex_cover_check(G, cover) G = nx.path_graph(5) cover = dnx.min_vertex_cover(G, ExactSolver()) self.vertex_cover_check(G, cover) for __ in range(10): G = nx.gnp_random_graph(5, .5) cover = dnx.min_vertex_cover(G, ExactSolver()) self.vertex_cover_check(G, cover)
def test_path_graph(self): G = nx.path_graph(10) matching = dnx.algorithms.matching.maximal_matching(G, ExactSolver()) self.assertTrue(dnx.is_maximal_matching(G, matching)) matching = dnx.min_maximal_matching(G, ExactSolver()) self.assertTrue(dnx.is_maximal_matching(G, matching)) G.add_edge(0, 9) matching = dnx.algorithms.matching.maximal_matching(G, ExactSolver()) self.assertTrue(dnx.is_maximal_matching(G, matching)) matching = dnx.min_maximal_matching(G, ExactSolver()) self.assertTrue(dnx.is_maximal_matching(G, matching))
def test_vertex_color_disconnected_graph(self): """One edge and one disconnected node""" G = nx.path_graph(2) G.add_node(3) coloring = dnx.min_vertex_coloring(G, ExactSolver()) self.assertTrue(dnx.is_vertex_coloring(G, coloring))
def _get_sampler(self, profile, solver): "Return a dimod.Sampler object." # Handle built-in software samplers as special cases. info = {} if solver != None: info["solver_name"] = solver if solver == "exact": return ExactSolver(), info elif solver == "neal": return SimulatedAnnealingSampler(), info elif solver == "tabu": return TabuSampler(), info # In the common case, read the configuration file, either the # default or the one named by the DWAVE_CONFIG_FILE environment # variable. if profile != None: info["profile"] = profile try: with Client.from_config(profile=profile) as client: if solver == None: solver = client.default_solver else: solver = {"name": solver} sampler = DWaveSampler(profile=profile, solver=solver) info = { "solver_name": sampler.solver.name, "endpoint": client.endpoint } return sampler, info except Exception as err: self.qmasm.abend("Failed to construct a sampler (%s)" % str(err))
class TestExactSolver(unittest.TestCase, TestSamplerAPI): def setUp(self): self.sampler = ExactSolver() def test_all_samples(self): """Check that every sample is included and that they all have the correct energy.""" n = 10 # create a qubo Q = {(v, v): (v % 3) for v in range(n)} Q[(0, n - 1)] = 1.3 Q[(3, n - 2)] = -.26666666 response = self.sampler.sample_qubo(Q) self.assertEqual(len(response), 2**n, "incorrect number of samples returned") sample_tuples = set() for sample in response.samples(): stpl = tuple(sample[v] for v in range(n)) sample_tuples.add(stpl) for tpl in itertools.product((0, 1), repeat=n): self.assertIn(tpl, sample_tuples) # let's also double check the enegy for sample, energy in response.items(): self.assertTrue(abs(energy - qubo_energy(Q, sample)) < .000001)
def test_vertex_color_no_edge_graph(self): """Graph with many nodes but no edges, should be caught before QUBO""" # this should get eliminated in software so be fast to run G = nx.Graph() G.add_nodes_from(range(100)) coloring = dnx.min_vertex_coloring(G, ExactSolver()) self.assertTrue(dnx.is_vertex_coloring(G, coloring))
def test_vertex_cover_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) cover = dnx.min_vertex_cover(G, ExactSolver()) self.vertex_cover_check(G, cover) G = nx.path_graph(5) cover = dnx.min_vertex_cover(G, ExactSolver()) self.vertex_cover_check(G, cover) for __ in range(10): G = nx.gnp_random_graph(5, .5) cover = dnx.min_vertex_cover(G, ExactSolver()) self.vertex_cover_check(G, cover)
def test_structural_imbalance_basic(self): sampler = ExactSolver() blueteam = ['Alice', 'Bob', 'Carol'] redteam0 = ['Eve'] redteam1 = ['Mallory', 'Trudy'] S = nx.Graph() for p0, p1 in itertools.combinations(blueteam, 2): S.add_edge(p0, p1, sign=1) S.add_edge(*redteam1, sign=1) for p0 in blueteam: for p1 in redteam0: S.add_edge(p0, p1, sign=-1) for p1 in redteam1: S.add_edge(p0, p1, sign=-1) frustrated_edges, colors = dnx.structural_imbalance(S, sampler) self.check_bicolor(colors) greenteam = ['Ted'] for p0 in set(S.nodes): for p1 in greenteam: S.add_edge(p0, p1, sign=1) frustrated_edges, colors = dnx.structural_imbalance(S, sampler) self.check_bicolor(colors)
def test_roof_duality_3path(self): sampler = FixVariablesComposite(ExactSolver(), algorithm='roof_duality') 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_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, ExactSolver()) self.set_independence_check(G, indep_set) G = nx.path_graph(5) indep_set = dnx.maximum_independent_set(G, ExactSolver()) self.set_independence_check(G, indep_set) for __ in range(10): G = nx.gnp_random_graph(5, .5) indep_set = dnx.maximum_independent_set(G, ExactSolver()) self.set_independence_check(G, indep_set)
def test_sampleset_trim(self): h = {'a': -4.0, 'b': -4.0, 'c': 0} J = {('a', 'b'): 3.2} sampler = TruncateComposite(ExactSolver(), 6) samples = sampler.sample_ising(h, J) self.assertEqual(len(samples), 6)
def test_invalid_graph(self): """should throw an error with a graph without sign attribute""" S = nx.Graph() S.add_edge('Alice', 'Bob', sign=1) S.add_edge('Alice', 'Eve', sign=-1) S.add_edge('Bob', 'Eve') # invalid edge with self.assertRaises(ValueError): frustrated_edges, colors = dnx.structural_imbalance(S, ExactSolver())
def test_vertex_color_almost_complete(self): # this should get eliminated in software so be fast to run G = nx.complete_graph(10) mapping = dict(zip(G.nodes(), "abcdefghijklmnopqrstuvwxyz")) G = nx.relabel_nodes(G, mapping) n0, n1 = next(iter(G.edges())) G.remove_edge(n0, n1) coloring = dnx.min_vertex_coloring(G, ExactSolver()) self.assertTrue(dnx.is_vertex_coloring(G, coloring))
def test_tinySchedule(self): jobs = {"a": [(1, 1), (2, 1)], "b": [(2, 1)]} max_time = 2 # Get exact sample from Job Shop Scheduler BQM jss = JobShopScheduler(jobs, max_time) bqm = jss.get_bqm() response = ExactSolver().sample(bqm) response_sample = next(response.samples()) # Verify that response_sample obeys constraints self.assertTrue(jss.csp.check(response_sample)) # Create expected solution expected = {"a_0,0": 1, "a_1,1": 1, "b_0,0": 1} # Compare variable values self.compare(response_sample, expected)
def test_typical_cases(self): G = nx.complete_graph(10) S = dnx.maximum_cut(G, ExactSolver()) self.assertTrue(len(S) == 5) # half of the nodes with self.assertRaises(dnx.DWaveNetworkXException): S = dnx.weighted_maximum_cut(G, ExactSolver()) nx.set_edge_attributes(G, 1, 'weight') S = dnx.weighted_maximum_cut(G, ExactSolver()) self.assertTrue(len(S) == 5) # half of the nodes G = nx.Graph() G.add_edges_from([(0, 1), (0, 2), (1, 2), (1, 3), (3, 4), (2, 4)]) S = dnx.maximum_cut(G, ExactSolver()) self.assertTrue(len(S) in (2, 3))
def test_default_sampler(self): G = nx.complete_graph(5) dnx.set_default_sampler(ExactSolver()) self.assertIsNot(dnx.get_default_sampler(), None) cover = dnx.min_vertex_cover(G) dnx.unset_default_sampler() self.assertEqual(dnx.get_default_sampler(), None, "sampler did not unset correctly")
def test_sampleset_trim(self): h = {'a': -4.0, 'b': -4.0, 'c': 0} J = {('a', 'b'): 3.2} sampler = PolyTruncateComposite(HigherOrderComposite(ExactSolver()), 6) with self.assertWarns(DeprecationWarning): samples = sampler.sample_ising(h, J) self.assertEqual(len(samples), 6)