Solutions#
samplers sample from low-energy states of a problem’s objective function—BQM samplers sample from low-energy states in models such as those defined by an Ising equation or a QUBO problem—and return an iterable of samples, in order of increasing energy.
When a D‑Wave quantum computer solves a problem, it uses quantum phenomena such as superposition and tunneling to explore all possible solutions simultaneously and find a set of the best ones. At the end of the computation (anneal), a single solution is sampled from a set of good solutions, with some probability, and returned. Because the sampled solution is probabilistic, different solutions may be returned in different runs. The standard way of submitting a problem to the system requests many samples, not just one. This not only returns multiple “best” answers but also reduces the probability of settling on a suboptimal answer.
Some classical samplers might return non-probabilistic solutions; for example,
the dimod ExactSolver
deterministically returns the best solution or solutions to small problems by
calculating the result for every configuration of variable values. Such samplers
are called solvers.
Some Ocean functions might return a single best solution; for example, some dwave-networkx graph algorithms return only the lowest-energy sample.
SampleSets#
Ocean uses the dimod SampleSet
class to hold samples and some additional information (e.g., timing and
minor-embedding information from some samplers).
As a simple example, this three-variable BQM,
might be solved directly on a D-Wave quantum computer by sampling 1000 times.
Here, the EmbeddingComposite
composite maps the symbolic BQM
to qubits on the quantum processor, which is called by the
DWaveSampler
sampler:
>>> import dimod
>>> from dwave.system import DWaveSampler, EmbeddingComposite
...
>>> s0, s1, s2 = dimod.Spins(['s0', 's1', 's2'])
>>> bqm = s1*s2 - s0*s1 - s0*s2
>>> sampler = EmbeddingComposite(DWaveSampler())
>>> sampleset = sampler.sample(bqm, num_reads=1000)
>>> print(sampleset)
s0 s1 s2 energy num_oc. chain_.
0 -1 +1 -1 -1.0 183 0.0
1 -1 -1 +1 -1.0 141 0.0
2 -1 -1 -1 -1.0 206 0.0
3 +1 -1 +1 -1.0 162 0.0
4 +1 +1 +1 -1.0 123 0.0
5 +1 +1 -1 -1.0 185 0.0
['SPIN', 6 rows, 1000 samples, 3 variables]
The returned SampleSet
, in this case, shows six solutions of
equal energy \(-1.0\). Solution \(s_0=-1, s_1=+1, s_2=-1\) on the first
line occurred in 183 of the 1000 samples.
For this submission, the sampleset also contained the following additional information:
>>> print(sampleset.info.keys())
dict_keys(['timing', 'problem_id', 'embedding_context', 'warnings'])
For example, the timing information for the problem might look something like:
>>> print(sampleset.info["timing"])
{'qpu_sampling_time': 85860.0,
'qpu_anneal_time_per_sample': 20.0,
'qpu_readout_time_per_sample': 45.32,
'qpu_access_time': 101619.97,
'qpu_access_overhead_time': 2259.03,
'qpu_programming_time': 15759.97,
'qpu_delay_time_per_sample': 20.54,
'total_post_processing_time': 2277.0,
'post_processing_overhead_time': 2277.0}