Source code for qlauncher.routines.dwave.algorithms
1"""DWave algorithms"""
2
3from collections.abc import Callable
4
5from qlauncher.base import Algorithm, Problem, Backend, Result
6from qlauncher.exceptions import DependencyError
7from qlauncher.routines.dwave.backends import BQMBackend
8try:
9 from dimod.binary.binary_quadratic_model import BinaryQuadraticModel
10 from dimod import SampleSet
11except ImportError as e:
12 raise DependencyError(e, install_hint='dwave') from e
13
14
[docs]
15class DwaveSolver(Algorithm):
16 _algorithm_format = 'bqm'
17
18 def __init__(self, chain_strength=1, num_reads=1000, **alg_kwargs) -> None:
19 self.chain_strength = chain_strength
20 self.num_reads = num_reads
21 self.label: str = 'TBD_TBD'
22 super().__init__(**alg_kwargs)
23
[docs]
24 def run(self, problem: Problem, backend: Backend, formatter: Callable) -> Result:
25 if not isinstance(backend, BQMBackend):
26 raise ValueError(f'{backend.__class__} is not supported by DwaveSolver algorithm, use BQMBackend instead')
27 self.label = f'{problem.name}_{problem.instance_name}'
28
29 bqm: BinaryQuadraticModel = formatter(problem)
30
31 res = self._solve_bqm(bqm, backend.sampler, **self.alg_kwargs)
32 return self._construct_result(res)
33
34 def _solve_bqm(self, bqm, sampler, **kwargs):
35 res = sampler.sample(
36 bqm, num_reads=self.num_reads, label=self.label, chain_strength=self.chain_strength, **kwargs)
37 return res
38
39 def _construct_result(self, result: SampleSet) -> Result:
40 distribution = {}
41 energies = {}
42 for (value, energy, occ) in zip(result.record.sample, result.record.energy, result.record.num_occurrences, strict=True):
43 bitstring = ''.join(map(str, value))
44 if bitstring in distribution:
45 distribution[bitstring] += occ
46 continue
47 distribution[bitstring] = occ
48 energies[bitstring] = energy
49
50 return Result.from_distributions(distribution, energies, result)