Source code for qlauncher.routines.dwave.algorithms
1"""DWave algorithms"""
2
3from abc import ABC, abstractmethod
4from typing import Any
5
6from qlauncher.base import Algorithm, Result
7from qlauncher.base.models import BQM
8from qlauncher.exceptions import DependencyError
9from qlauncher.routines.dwave.backends import BQMBackend
10
11try:
12 from dimod import Sampler, SampleSet
13 from dwave.samplers import SimulatedAnnealingSampler, SteepestDescentSampler, TabuSampler
14except ImportError as e:
15 raise DependencyError(e, install_hint='dwave') from e
16
17
[docs]
18class DwaveSolver(Algorithm[BQM, BQMBackend], ABC):
19 def __init__(self, chain_strength: int = 1, num_reads: int = 1000, **alg_kwargs) -> None:
20 self.chain_strength = chain_strength
21 self.num_reads = num_reads
22 self.label: str = 'TBD_TBD'
23 super().__init__(**alg_kwargs)
24
[docs]
25 def run(self, problem: BQM, backend: BQMBackend) -> Result:
26 res = self._solve_bqm(problem.bqm, self._get_sampler(), **self.alg_kwargs)
27 return self._construct_result(res)
28
29 def _solve_bqm(self, bqm: Any, sampler: Sampler, **kwargs) -> SampleSet:
30 return sampler.sample(bqm, num_reads=self.num_reads, label=self.label, chain_strength=self.chain_strength, **kwargs)
31
32 @abstractmethod
33 def _get_sampler(self) -> Sampler:
34 pass
35
36 def _construct_result(self, result: SampleSet) -> Result:
37 distribution = {}
38 energies = {}
39 for value, energy, occ in zip(result.record.sample, result.record.energy, result.record.num_occurrences, strict=True):
40 bitstring = ''.join(map(str, value))
41 if bitstring in distribution:
42 distribution[bitstring] += occ
43 continue
44 distribution[bitstring] = occ
45 energies[bitstring] = energy
46
47 return Result.from_counts_energies(distribution, energies, result)
48
49
[docs]
50class Tabu(DwaveSolver):
51 """Tabu search simulator backend"""
52
53 def _get_sampler(self) -> Sampler:
54 return TabuSampler()
55
56
[docs]
57class SimulatedAnnealing(DwaveSolver):
58 """Simulated annealing simulator backend"""
59
60 def _get_sampler(self) -> Sampler:
61 return SimulatedAnnealingSampler()
62
63
[docs]
64class SteepestDescent(DwaveSolver):
65 """Steepest descent simulator backend"""
66
67 def _get_sampler(self) -> Sampler:
68 return SteepestDescentSampler()