def test_look_and_feel(self): br = Runnable(), Runnable() rb = RacingBranches(*br) self.assertEqual(rb.name, 'RacingBranches') self.assertEqual(str(rb), '(Runnable) !! (Runnable)') self.assertEqual(repr(rb), 'RacingBranches(Runnable(), Runnable())') self.assertEqual(tuple(rb), br)
def test_iter_walk(self): flow = Loop(RacingBranches(Runnable(), Runnable()) | ArgMin()) names = [r.name for r in iter_inorder(flow)] self.assertEqual(names, [ 'Loop', 'Branch', 'RacingBranches', 'Runnable', 'Runnable', 'ArgMin' ])
def test_callback_walk(self): flow = Loop(RacingBranches(Runnable(), Runnable()) | ArgMin()) names = [] walk_inorder(flow, visit=lambda r, _: names.append(r.name)) self.assertEqual(names, [ 'Loop', 'Branch', 'RacingBranches', 'Runnable', 'Runnable', 'ArgMin' ])
def test_stopped(self): class Fast(Runnable): def next(self, state, **runopts): time.sleep(0.1) return state.updated(x=state.x + 1) class Slow(Runnable): def init(self, state, **runopts): self.time_to_stop = threading.Event() def next(self, state, **runopts): self.time_to_stop.wait() return state.updated(x=state.x + 2) def halt(self): self.time_to_stop.set() # default case rb = RacingBranches(Slow(), Fast(), Slow()) res = rb.run(State(x=0)).result() self.assertEqual([s.x for s in res], [2, 1, 2]) # "endomorphic case" rb = RacingBranches(BlockingIdentity(), Slow(), Fast(), Slow()) res = rb.run(State(x=0)).result() self.assertEqual([s.x for s in res], [0, 2, 1, 2])
def test_stopped(self): class Fast(Runnable): def next(self, state): time.sleep(0.1) return state.updated(x=state.x + 1) class Slow(Runnable): def init(self, state): self.time_to_stop = threading.Event() def next(self, state): self.time_to_stop.wait() return state.updated(x=state.x + 2) def stop(self): self.time_to_stop.set() # standard case rb = RacingBranches(Slow(), Fast(), Slow()) res = rb.run(State(x=0)).result() self.assertEqual([s.x for s in res], [0, 2, 1, 2]) # branches' outputs are of a different type that the inputs # (i.e. non-endomorphic racing branches) rb = RacingBranches(Slow(), Fast(), Slow(), endomorphic=False) res = rb.run(State(x=0)).result() self.assertEqual([s.x for s in res], [2, 1, 2])
def test_racing_branches(self): class A(Runnable, traits.ProblemDecomposer): def next(self, state): return state.updated(subproblem=state.problem) class B(Runnable, traits.SubproblemSampler): def next(self, state): return state.updated(subsamples=state.subproblem) a, b = A(), B() race = RacingBranches(a, b) self.assertSetEqual(race.inputs, a.inputs | b.inputs) self.assertSetEqual(race.outputs, a.outputs & b.outputs)
import dimod from hybrid.samplers import (QPUSubproblemAutoEmbeddingSampler, InterruptableTabuSampler) from hybrid.decomposers import EnergyImpactDecomposer from hybrid.composers import SplatComposer from hybrid.core import State from hybrid.flow import RacingBranches, ArgMin, Loop from hybrid.utils import min_sample # load a problem problem = sys.argv[1] with open(problem) as fp: bqm = dimod.BinaryQuadraticModel.from_coo(fp) # define the solver iteration = RacingBranches( InterruptableTabuSampler(), EnergyImpactDecomposer(max_size=50, rolling=True, rolling_history=0.15) | QPUSubproblemAutoEmbeddingSampler() | SplatComposer()) | ArgMin() main = Loop(iteration, max_iter=10, convergence=3) # run solver init_state = State.from_sample(min_sample(bqm), bqm) solution = main.run(init_state).result() # show results print("Solution: sample={s.samples.first}".format(s=solution))
import dimod from hybrid.samplers import (QPUSubproblemAutoEmbeddingSampler, TabuProblemSampler, InterruptableTabuSampler) from hybrid.decomposers import EnergyImpactDecomposer from hybrid.composers import SplatComposer from hybrid.core import State, SampleSet from hybrid.flow import RacingBranches, ArgMin, Loop from hybrid.utils import min_sample, max_sample, random_sample problem = sys.argv[1] with open(problem) as fp: bqm = dimod.BinaryQuadraticModel.from_coo(fp) # Run Tabu in parallel with QPU, but post-process QPU samples with very short Tabu iteration = RacingBranches( InterruptableTabuSampler(), EnergyImpactDecomposer(size=50) | QPUSubproblemAutoEmbeddingSampler(num_reads=100) | SplatComposer() | TabuProblemSampler(timeout=1)) | ArgMin() main = Loop(iteration, max_iter=10, convergence=3) init_state = State.from_sample(min_sample(bqm), bqm) solution = main.run(init_state).result() print("Solution: energy={s.samples.first.energy}".format(s=solution))
from hybrid.samplers import (SimulatedAnnealingSubproblemSampler, TabuSubproblemSampler, InterruptableTabuSampler) from hybrid.decomposers import EnergyImpactDecomposer, IdentityDecomposer from hybrid.composers import SplatComposer from hybrid.core import State from hybrid.flow import RacingBranches, ArgMin, Loop from hybrid.utils import min_sample problem = sys.argv[1] with open(problem) as fp: bqm = dimod.BinaryQuadraticModel.from_coo(fp) iteration = RacingBranches( IdentityDecomposer() | SimulatedAnnealingSubproblemSampler() | SplatComposer(), EnergyImpactDecomposer(max_size=50) | RacingBranches(SimulatedAnnealingSubproblemSampler(sweeps=1000), TabuSubproblemSampler(tenure=20, timeout=10), endomorphic=False) | ArgMin(operator.attrgetter('subsamples.first.energy')) | SplatComposer()) | ArgMin() main = Loop(iteration, max_iter=10, convergence=3) init_state = State.from_sample(min_sample(bqm), bqm) solution = main.run(init_state).result() print("Solution: energy={s.samples.first.energy}".format(s=solution))
from hybrid.samplers import (QPUSubproblemAutoEmbeddingSampler, InterruptableTabuSampler) from hybrid.decomposers import EnergyImpactDecomposer from hybrid.composers import SplatComposer from hybrid.core import State from hybrid.flow import RacingBranches, ArgMin, Loop from hybrid.utils import min_sample # Construct a problem bqm = dimod.BinaryQuadraticModel({}, { 'ab': 1, 'bc': -1, 'ca': 1 }, 0, dimod.SPIN) # Define the solver iteration = RacingBranches( InterruptableTabuSampler(), EnergyImpactDecomposer(size=2) | QPUSubproblemAutoEmbeddingSampler() | SplatComposer()) | ArgMin() main = Loop(iteration, max_iter=10, convergence=3) # Solve the problem init_state = State.from_sample(min_sample(bqm), bqm) solution = main.run(init_state).result() # Print results print("Solution: sample={s.samples.first}".format(s=solution)) # Solution: sample=Sample(sample={'a': 1, 'b': -1, 'c': -1}, energy=-3.0, num_occurrences=1)
def test_racingbranches(self): rb = RacingBranches(self.RunnableA(), self.RunnableB()) self.assertEqual(self.children(rb), ['RunnableA', 'RunnableB'])
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)
problems = chain( sorted(glob('problems/qbsolv/bqp100_*'))[:5], sorted(glob('problems/qbsolv/bqp2500_*'))[:5], sorted(glob('problems/random-chimera/2048*'))[:5], sorted(glob('problems/random-chimera/8192*'))[:5], sorted(glob('problems/ac3/*'))[:5], ) solver_factories = [ ("10 second Tabu", lambda **kw: TabuProblemSampler(timeout=10000)), ("10k sweeps Simulated Annealing", lambda **kw: IdentityDecomposer() | SimulatedAnnealingSubproblemSampler(sweeps=10000) | SplatComposer()), ("qbsolv-like solver", lambda qpu, **kw: Loop(RacingBranches( InterruptableTabuSampler(quantum_timeout=200), EnergyImpactDecomposer(max_size=50, rolling=True, rolling_history=0.15) | QPUSubproblemAutoEmbeddingSampler(qpu_sampler=qpu) | SplatComposer()) | ArgMin(), max_iter=100, convergence=10)), ("tiling chimera solver", lambda qpu, **kw: Loop(RacingBranches( InterruptableTabuSampler(quantum_timeout=200), TilingChimeraDecomposer(size=(16, 16, 4)) | QPUSubproblemExternalEmbeddingSampler(qpu_sampler=qpu) | SplatComposer(), ) | ArgMin(), max_iter=100, convergence=10)), ("qbsolv-classic", lambda **kw: QBSolvProblemSampler()), ("qbsolv-qpu", lambda qpu, **kw: QBSolvProblemSampler(qpu_sampler=qpu)), ]