def sample(self, bqm, beta_range=None, num_reads=10, num_sweeps=1000): """Sample from low-energy spin states using simulated annealing. Args: bqm (:obj:`~dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. beta_range (tuple, optional): Beginning and end of the beta schedule (beta is the inverse temperature) as a 2-tuple. The schedule is applied linearly in beta. Default is chosen based on the total bias associated with each node. num_reads (int, optional): Number of reads. Each sample is the result of a single run of the simulated annealing algorithm. num_sweeps (int, optional): Number of sweeps or steps. Default is 1000. Returns: :obj:`~dimod.Response`: A `dimod` :obj:`.~dimod.Response` object. Note: This is a reference implementation, not optimized for speed and therefore not an appropriate sampler for benchmarking. Examples: This example provides samples for a two-variable QUBO model. >>> import dimod ... >>> sampler = dimod.SimulatedAnnealingSampler() >>> Q = {(0, 0): -1, (1, 1): -1, (0, 1): 2} >>> bqm = dimod.BinaryQuadraticModel.from_qubo(Q, offset = 0.0) >>> response = sampler.sample(bqm, num_reads=2) >>> response.data_vectors['energy'] # doctest: +SKIP array([-1., -1.]) """ # input checking # h, J are handled by the @ising decorator # beta_range, sweeps are handled by ising_simulated_annealing if not isinstance(num_reads, int): raise TypeError("'samples' should be a positive integer") if num_reads < 1: raise ValueError("'samples' should be a positive integer") h, J, offset = bqm.to_ising() # run the simulated annealing algorithm samples = [] energies = [] for __ in range(num_reads): sample, energy = ising_simulated_annealing(h, J, beta_range, num_sweeps) samples.append(sample) energies.append(energy) response = Response.from_samples(samples, {'energy': energies}, {}, vartype=Vartype.SPIN) response.change_vartype(bqm.vartype, offset, inplace=True) return response
def sample(self, bqm, num_reads=10): """Give random samples for a binary quadratic model. Args: bqm (:obj:`~dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. num_reads (int, optional): Number of reads. Returns: :obj:`~dimod.Response`: A `dimod` :obj:`.~dimod.Response` object. Notes: For each variable in each sample, the value is chosen by a coin flip. Examples: This example provides samples for a two-variable Ising model. >>> import dimod ... >>> sampler = dimod.RandomSampler() >>> h = {0: -1, 1: -1} >>> J = {(0, 1): -1} >>> bqm = dimod.BinaryQuadraticModel(h, J, -0.5, dimod.SPIN) >>> response = sampler.sample(bqm, num_reads=3) >>> len(response) 3 >>> response.data_vectors['energy'] # doctest: +SKIP array([ 0.5, -3.5, 0.5]) """ values = tuple(bqm.vartype.value) def _itersample(): for __ in range(num_reads): sample = {v: choice(values) for v in bqm.linear} energy = bqm.energy(sample) yield sample, energy samples, energies = zip(*_itersample()) return Response.from_samples(samples, {'energy': energies}, {}, vartype=bqm.vartype)
def sample(self, bqm): """Sample from a binary quadratic model. Args: bqm (:obj:`~dimod.BinaryQuadraticModel`): Binary quadratic model to be sampled from. Returns: :obj:`~dimod.Response`: A `dimod` :obj:`.~dimod.Response` object. Examples: This example provides samples for a two-variable Ising model. >>> import dimod ... >>> sampler = dimod.ExactSolver() >>> bqm = dimod.BinaryQuadraticModel({0: 0.0, 1: 1.0}, {(0, 1): 0.5}, -0.5, dimod.SPIN) >>> response = sampler.sample(bqm) >>> response.data_vectors['energy'] array([-1., -2., 1., 0.]) """ M = bqm.binary.to_numpy_matrix() off = bqm.binary.offset if M.shape == (0, 0): return Response.from_samples([], {'energy': []}, {}, bqm.vartype) sample = np.zeros((len(bqm),), dtype=bool) # now we iterate, flipping one bit at a time until we have # traversed all samples. This is a Gray code. # https://en.wikipedia.org/wiki/Gray_code def iter_samples(): sample = np.zeros((len(bqm)), dtype=bool) energy = 0.0 yield sample.copy(), energy + off for i in range(1, 1 << len(bqm)): v = _ffs(i) # flip the bit in the sample sample[v] = not sample[v] # for now just calculate the energy, but there is a more clever way by calculating # the energy delta for the single bit flip, don't have time, pull requests # appreciated! energy = sample.dot(M).dot(sample.transpose()) yield sample.copy(), float(energy) + off samples, energies = zip(*iter_samples()) response = Response.from_samples(np.array(samples, dtype='int8'), {'energy': energies}, {}, vartype=Vartype.BINARY) # make sure the response matches the given vartype, in-place. response.change_vartype(bqm.vartype, inplace=True) return response