def next(self, state, **runopts): bqm = state.subproblem sample = random_sample(bqm) sampleset = SampleSet.from_samples(sample, vartype=bqm.vartype, energy=bqm.energy(sample)) return state.updated(subsamples=sampleset)
def test_empty(self): bqm = dimod.BinaryQuadraticModel(dimod.SPIN) state = State.from_sample(random_sample(bqm), bqm) decomposer = ComponentDecomposer() state1 = decomposer.next(state) self.assertEqual(bqm, state1.subproblem)
def test_one_component(self): bqm = dimod.BinaryQuadraticModel({ 'a': 1, 'b': -1 }, {'ab': 1}, 0, dimod.SPIN) state = State.from_sample(random_sample(bqm), bqm) decomposer = ComponentDecomposer() state1 = decomposer.next(state) self.assertEqual(bqm, state1.subproblem)
def test_auto_embedding_failure(self): counter = MockDWaveSamplerCounter() q = QPUSubproblemAutoEmbeddingSampler(qpu_sampler=counter) target_structure = q.sampler.target_structure num_vars = len(target_structure.nodelist) + 1 # source graph will be too large for the target and ensure an embedding failure bqm = dimod.BinaryQuadraticModel(num_vars, 'SPIN') init = State.from_subsample(random_sample(bqm), bqm) retries = 3 with self.assertRaises(ValueError): result = q.run(init, num_retries=retries).result() self.assertEqual(retries + 1, counter.count)
class TestComponentDecomposer(unittest.TestCase): bqm = dimod.BinaryQuadraticModel({ 'a': 2, 'b': -1, 'd': 1 }, { 'bc': 1, 'cd': 1 }, 0, dimod.SPIN) state = State.from_sample(random_sample(bqm), bqm) def test_default(self): decomposer = ComponentDecomposer() state1 = decomposer.next(self.state) self.assertIn(dict(state1.subproblem.linear), ({ 'a': 2 }, { 'b': -1, 'c': 0, 'd': 1 })) state2 = decomposer.next(state1) self.assertIn(dict(state2.subproblem.linear), ({ 'a': 2 }, { 'b': -1, 'c': 0, 'd': 1 })) self.assertNotEqual(dict(state1.subproblem.linear), dict(state2.subproblem.linear)) state3 = decomposer.next( state2) # silent_rewind=True, so rewind w/o raising an assertion self.assertIn(dict(state3.subproblem.linear), ({ 'a': 2 }, { 'b': -1, 'c': 0, 'd': 1 })) def test_sort(self): decomposer = ComponentDecomposer(key=len) state1 = decomposer.next(self.state) self.assertDictEqual(dict(state1.subproblem.linear), { 'b': -1, 'c': 0, 'd': 1 }) def test_sort_reverse(self): decomposer = ComponentDecomposer(key=len, reverse=False) state1 = decomposer.next(self.state) self.assertDictEqual(dict(state1.subproblem.linear), {'a': 2}) def test_no_silent_rewind(self): decomposer = ComponentDecomposer(silent_rewind=False) state1 = decomposer.next(self.state) state2 = decomposer.next(state1) with self.assertRaises(EndOfStream): state3 = decomposer.next(state2) def test_key_func(self): def sum_linear_biases(component): total = 0 for v in component: total += self.bqm.get_linear(v) return total decomposer = ComponentDecomposer(key=sum_linear_biases) state1 = decomposer.next(self.state) self.assertDictEqual(dict(state1.subproblem.linear), {'a': 2}) def test_no_rolling(self): decomposer = ComponentDecomposer(rolling=False, key=len) state1 = decomposer.next(self.state) self.assertDictEqual(dict(state1.subproblem.linear), { 'b': -1, 'c': 0, 'd': 1 }) state2 = decomposer.next(state1) self.assertDictEqual(dict(state2.subproblem.linear), { 'b': -1, 'c': 0, 'd': 1 }) def test_one_component(self): bqm = dimod.BinaryQuadraticModel({ 'a': 1, 'b': -1 }, {'ab': 1}, 0, dimod.SPIN) state = State.from_sample(random_sample(bqm), bqm) decomposer = ComponentDecomposer() state1 = decomposer.next(state) self.assertEqual(bqm, state1.subproblem) def test_empty(self): bqm = dimod.BinaryQuadraticModel(dimod.SPIN) state = State.from_sample(random_sample(bqm), bqm) decomposer = ComponentDecomposer() state1 = decomposer.next(state) self.assertEqual(bqm, state1.subproblem)
def sample(self, bqm, init_sample=None, max_iter=100, convergence=10, num_reads=1, sa_reads=1, sa_sweeps=1000, qpu_reads=100, qpu_sampler=None, max_subproblem_size=50): """Run Tabu search, Simulated annealing and QPU subproblem sampling (for high energy impact problem variables) in parallel and return the best samples. Args: bqm (:obj:`~dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. init_sample (:class:`~dimod.SampleSet`, callable, ``None``): Initial sample set (or sample generator) used for each "read". Use a random sample for each read by default. max_iter (int): Number of iterations in the hybrid algorithm. convergence (int): Number of iterations with no improvement that terminates sampling. num_reads (int): Number of reads. Each sample is the result of a single run of the hybrid algorithm. sa_reads (int): Number of reads in the simulated annealing branch. sa_sweeps (int): Number of sweeps in the simulated annealing branch. qpu_reads (int): Number of reads in the QPU branch. qpu_sampler (:class:`dimod.Sampler`, optional, default=DWaveSampler()): Quantum sampler such as a D-Wave system. max_subproblem_size (int): Maximum size of the subproblem selected in the QPU branch. Returns: :obj:`~dimod.SampleSet`: A `dimod` :obj:`.~dimod.SampleSet` object. """ if callable(init_sample): init_state_gen = lambda: State.from_sample(init_sample(), bqm) elif init_sample is None: init_state_gen = lambda: State.from_sample(random_sample(bqm), bqm) elif isinstance(init_sample, dimod.SampleSet): init_state_gen = lambda: State.from_sample(init_sample, bqm) else: raise TypeError( "'init_sample' should be a SampleSet or a SampleSet generator") subproblem_size = min(len(bqm), max_subproblem_size) iteration = RacingBranches( InterruptableTabuSampler(), InterruptableSimulatedAnnealingProblemSampler(num_reads=sa_reads, sweeps=sa_sweeps), EnergyImpactDecomposer(size=subproblem_size, rolling=True, rolling_history=0.3, traversal='bfs') | QPUSubproblemAutoEmbeddingSampler(num_reads=qpu_reads, qpu_sampler=qpu_sampler) | SplatComposer(), ) | ArgMin() self.runnable = Loop(iteration, max_iter=max_iter, convergence=convergence) samples = [] energies = [] for _ in range(num_reads): init_state = init_state_gen() final_state = self.runnable.run(init_state) # the best sample from each run is one "read" ss = final_state.result().samples ss.change_vartype(bqm.vartype, inplace=True) samples.append(ss.first.sample) energies.append(ss.first.energy) return dimod.SampleSet.from_samples(samples, vartype=bqm.vartype, energy=energies)