.. _samplers_and_solvers:
==================================
Sampling: Minimizing the Objective
==================================
Having formulated an objective function that represents your problem as described
in the :ref:`gs_formulation` section, you sample this :term:`quadratic model` (QM)
for solutions. Ocean software provides quantum, classical, and quantum-classical
hybrid :term:`sampler`\ s that run either remotely (for example, in D-Wave's
`Leap `_ environment) or locally on your CPU.
These compute resources are known as :term:`solver`\ s.
.. note:: Some classical samplers actually brute-force solve small problems rather
than sample, and these are also referred to as "solvers".
Ocean's :term:`sampler`\ s enable you to submit your problem to remote or local
compute resources (:term:`solver`\ s) of different types:
* :ref:`using_hybrid` such as `Leap's `_
``hybrid_binary_quadratic_model_version`` solver or, for **discrete**
quadratic models (:term:`DQM`), ``hybrid_discrete_quadratic_model_version``
* :ref:`using_cpu` such as :class:`~dimod.reference.samplers.ExactSolver` for
exact solutions to small problems
* :ref:`using_qpu` such as the Advantage system.
.. _submitting:
Submit the QM to a Solver
=========================
The example code below submits a BQM representing a Boolean AND gate (see also the
:ref:`formulating_bqm` section) to a Leap hybrid solver.
In this case, :doc:`dwave-system `'s
:class:`~dwave.system.samplers.LeapHybridSampler` is the Ocean sampler and the
remote compute resource selected might be Leap hybrid solver
``hybrid_binary_quadratic_model_version``.
>>> from dimod.generators import and_gate
>>> from dwave.system import LeapHybridSampler
>>> bqm = and_gate('x1', 'x2', 'y1')
>>> sampler = LeapHybridSampler() # doctest: +SKIP
>>> answer = sampler.sample(bqm) # doctest: +SKIP
>>> print(answer) # doctest: +SKIP
x1 x2 y1 energy num_oc.
0 1 1 1 0.0 1
['BINARY', 1 rows, 1 samples, 3 variables]
.. _improving:
Improve the Solutions
=====================
For complex problems, you can often improve solutions and performance by applying
some of Ocean software's preprocessing, postprocessing, and diagnostic tools.
Additionally, when submitting problems directly to a D-Wave system (:ref:`using_qpu`),
you can benefit from some advanced features (for example features such as
spin-reversal transforms and anneal offsets, which reduce the impact of possible
analog and systematic errors) and the techniques described in the
:std:doc:`Problem Solving Handbook ` guide.
Example: Preprocessing
----------------------
:std:doc:`dwave-preprocessing ` provides
algorithms such as roof duality, which fixes some of a problem's variables before
submitting to a sampler.
As an illustrative example, consider the binary quadratic model, :math:`x + yz`.
Clearly :math:`x=0` for all the best solutions (variable assignments that minimize
the value of the model) because any assignment of variables that sets :math:`x=1`
adds a value of 1 compared to assignments that set :math:`x=0`. (On the other
hand, assignment :math:`y=0, z=0`, assignment :math:`y=0, z=1`, and assignment
:math:`y=1, z=0` are all equally good.) Therefore, you can fix variable :math:`x`
and solve a smaller problem.
>>> from dimod import BinaryQuadraticModel
>>> from dwave.preprocessing import roof_duality
>>> bqm = BinaryQuadraticModel({'x': 1}, {('y', 'z'): 1}, 0,'BINARY')
>>> roof_duality(bqm)
(0.0, {'x': 0})
For problems with hundreds or thousands of variables, such preprocessing can
significantly improve performance.
Example: Diagnostics
---------------------
When sampling directly on the D-Wave QPU, the mapping from problem variables to qubits,
:term:`minor-embedding`, can significantly
affect performance. Ocean tools perform this mapping heuristically so simply rerunning
a problem might improve results. Advanced users may customize the mapping by directly
using the :std:doc:`minorminer ` tool,
setting a minor-embedding themselves, or using D-Wave's
:doc:`problem-inspector ` tool.
For example, the :ref:`and` example submits the BQM representing an AND gate
to a D-Wave system, which requires mapping the problem's logical variables
to qubits on the QPU. The code below invokes D-Wave's
:doc:`problem-inspector ` tool to visualize the
minor-embedding.
>>> import dwave.inspector
>>> dwave.inspector.show(response) # doctest: +SKIP
.. figure:: ../_images/inspector_AND2.png
:name: inspector_AND2
:scale: 50 %
:alt: View rendered by Ocean's problem inspector.
View of the logical and embedded problem rendered by Ocean's problem inspector. The AND gate's original BQM is represented on the left; its embedded representation on a D-Wave system, on the right, shows a two-qubit chain (qubits 176 and 180) for variable :math:`x2`. The tool is helpful in visualizing the quality of your embedding.
Example: Postprocessing
-----------------------
Example :ref:`pp_greedy` improves samples returned from a QPU by post-processing with a
classical greedy algorthim.