Esempio n. 1
0
    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
Esempio n. 2
0
    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)
Esempio n. 3
0
    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