示例#1
0
    def sample(self, bqm, **kwargs):
        """Sample from a binary quadratic model.

        Args:
            bqm (:obj:`~dimod.BinaryQuadraticModel`):
                Binary quadratic model to be sampled from.

        Returns:
            :obj:`~dimod.SampleSet`

        """
        kwargs = self.remove_unknown_kwargs(**kwargs)

        n = len(bqm.variables)
        if n == 0:
            return SampleSet.from_samples([], bqm.vartype, energy=[])

        samples = _graycode(bqm)

        if bqm.vartype is Vartype.SPIN:
            samples = 2 * samples - 1

        response = SampleSet.from_samples_bqm((samples, list(bqm.variables)),
                                              bqm)
        return response
示例#2
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.SampleSet`

        """
        M = bqm.binary.to_numpy_matrix()
        off = bqm.binary.offset

        if M.shape == (0, 0):
            return SampleSet.from_samples([], bqm.vartype, energy=[])

        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 = SampleSet.from_samples(np.array(samples, dtype='int8'), Vartype.BINARY, energies)

        # make sure the response matches the given vartype, in-place.
        response.change_vartype(bqm.vartype, inplace=True)

        return response
    def sample(self, bqm, *, components=None, **parameters):
        """Sample from the provided binary quadratic model.

        Args:
            bqm (:class:`dimod.BinaryQuadraticModel`):
                Binary quadratic model to be sampled from.

            components (list(set)):
                A list of disjoint set of variables that fully partition the variables

            **parameters:
                Parameters for the sampling method, specified by the child sampler.

        Returns:
            :class:`dimod.SampleSet`

        """
        # make sure the BQM is shapeable
        bqm = as_bqm(bqm, cls=[AdjVectorBQM, AdjDictBQM])

        # solve the problem on the child system
        child = self.child
        variables = bqm.variables
        if components is None:
            components = list(connected_components(bqm))
        if isinstance(components, set):
            components = [components]
        sampleset = None
        fixed_value = min(bqm.vartype.value)
        for component in components:
            bqm_copy = bqm.copy()
            bqm_copy.fix_variables(
                {i: fixed_value
                 for i in (variables - component)})
            if sampleset is None:
                # here .truncate(1) is used to pick the best solution only. The other options
                # for future development is to combine all sample with all.
                # This way you'd get the same behaviour as the ExactSolver
                sampleset = child.sample(bqm_copy, **parameters).truncate(1)
            else:
                sampleset = append_variables(
                    sampleset.truncate(1),
                    child.sample(bqm_copy, **parameters).truncate(1))

        if sampleset is None:
            return SampleSet.from_samples_bqm({}, bqm)
        else:
            return SampleSet.from_samples_bqm(sampleset, bqm)
示例#4
0
    def sample(self, bqm, num_reads=10):
        """Give random samples for a binary quadratic model.

        Variable assignments are chosen by coin flip.

        Args:
            bqm (:obj:`.BinaryQuadraticModel`):
                Binary quadratic model to be sampled from.

            num_reads (int, optional, default=10):
                Number of reads.

        Returns:
            :obj:`.SampleSet`

        """
        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 SampleSet.from_samples(samples, bqm.vartype, energies)
示例#5
0
    def sample(self, bqm, lower_bound=None, upper_bound=None, **parameters):
        """Clip and sample from the provided binary quadratic model.

        If lower_bound and upper_bound are given variables with value above or below are clipped.

        Args:
            bqm (:obj:`dimod.BinaryQuadraticModel`):
                Binary quadratic model to be sampled from.

            lower_bound (number):
                Value by which to clip the variables from below.

            upper_bound (number):
                Value by which to clip the variables from above.

            **parameters:
                Parameters for the sampling method, specified by the child sampler.

        Returns:
            :obj:`dimod.SampleSet`

        """
        child = self.child
        bqm_copy = _clip_bqm(bqm, lower_bound, upper_bound)
        response = child.sample(bqm_copy, **parameters)

        return SampleSet.from_samples_bqm(response, bqm, info=response.info)
示例#6
0
    def sample_cqm(self,
                   cqm: 'ConstrainedQuadraticModel',
                   rtol: float = 1e-6,
                   atol: float = 1e-8,
                   **kwargs) -> SampleSet:
        """Sample from a constrained quadratic model.

        Args:
            cqm (:class:`~dimod.ConstrainedQuadraticModel`):
                Constrained quadratic model to be sampled from.
            rtol (float):
                Relative tolerance for constraint violation. The fraction of a
                constraint's right hand side which any violation must be smaller
                than for the constraint to be satisfied.
            atol (float):
                Absolute tolerance for constraint violations. A constant any
                violation must be smaller than for the constraint to be satisfied.

        Returns:
            A sampleset of all possible samples, with the fields is_feasible
            and is_satisfied containing total and individual constraint
            violation information, respectively.

        """
        Sampler.remove_unknown_kwargs(self, **kwargs)

        if not len(cqm.variables):
            return SampleSet.from_samples([], 'INTEGER', energy=[])

        cases = _all_cases_cqm(cqm)
        energies = cqm.objective.energies(cases)

        is_satisfied = [[
            info.violation <= atol + rtol * info.rhs_energy
            for info in cqm.iter_constraint_data((c, cases[1]))
        ] for c in cases[0]]
        is_feasible = [all(satisfied) for satisfied in is_satisfied]

        # from_samples requires a single vartype argument, but QuadraticModel
        # and therefore CQM allow mixed vartypes. For now, only passing 'INTEGER'
        return SampleSet.from_samples(cases,
                                      'INTEGER',
                                      energies,
                                      is_feasible=is_feasible,
                                      is_satisfied=is_satisfied)
示例#7
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:`.SampleSet`

        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 = SampleSet.from_samples(samples, Vartype.SPIN, energies)
        response.change_vartype(bqm.vartype, offset, inplace=True)
        return response
示例#8
0
    def sample(self,
               bqm,
               beta_range=None,
               num_reads=10,
               num_sweeps=1000,
               **kwargs):
        """Sample from low-energy spin states using simulated annealing.

        Args:
            bqm (:obj:`.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, default=10):
                Number of reads. Each sample is the result of a single run of
                the simulated annealing algorithm.

            num_sweeps (int, optional, default=1000):
                Number of sweeps or steps.

        Returns:
            :obj:`.SampleSet`

        Note:
            This is a reference implementation, not optimized for speed
            and therefore not an appropriate sampler for benchmarking.

        """

        # 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")

        kwargs = self.remove_unknown_kwargs(**kwargs)

        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 = SampleSet.from_samples(samples, Vartype.SPIN, energies)
        response.change_vartype(bqm.vartype, offset, inplace=True)
        return response
示例#9
0
    def _sample(*args, **kwargs):
        # avoid circular import
        from dimod.sampleset import SampleSet

        iterator = f(*args, **kwargs)

        # do the blocking part
        next(iterator)

        return SampleSet.from_future(None, lambda _: next(iterator))
示例#10
0
    def sample_dqm(self, dqm: 'DiscreteQuadraticModel', **kwargs) -> SampleSet:
        """Sample from a discrete quadratic model.

        Args:
            dqm (:class:`~dimod.DiscreteQuadraticModel`):
                Discrete quadratic model to be sampled from.

        Returns:
            :class:`~dimod.SampleSet`

        """
        Sampler.remove_unknown_kwargs(self, **kwargs)

        if not dqm.num_variables():
            return SampleSet.from_samples([], 'DISCRETE', energy=[])

        cases = _all_cases_dqm(dqm)
        energies = dqm.energies(cases)

        return SampleSet.from_samples(cases, 'DISCRETE', energies)
示例#11
0
    def sample(self, sampler, *args, **kwargs):
        """
        Sample the integer quadratic model with the given sampler. This will sample the underlying
        binary quadratic model, reconstruct the integer variables from the sampleset, and return a
        new sampleset containing the reconstructed integer variables with their original names.

        NOTE: If you print the SampleSet object returned by this function, you will not see the correct
        integer values. This is because Dwave's printing functionality does not support integers, but
        SampleSet object does indeed contain integers, this is just an issue with printing. If you desparately
        need printing, then you can just print the record inside the SampleSet object
            >>> sampleset = iqm.sample(sampler, num_reads=10)
            >>> print(sampleset.record)

        Args:
            sampler: A D-Wave sampler.
            *args: Positional arguments to the sampler's sample() function.
            **kwargs: Keyword arguments to the sampler's sample() function.

        Returns:
            A dimod.SampleSet object containing the samples.
        """
        sampleset = sampler.sample(self._bqm, *args, **kwargs)

        record = sampleset.record
        variables = sampleset.variables
        info = sampleset.info
        vartype = sampleset.vartype

        reconstructed_samples = np.zeros(
            (record.shape[0], len(self._vartype_map)))
        original_variables = OrderedDict()
        for i, var in enumerate(variables):
            varname = var[0]
            if varname not in original_variables:
                original_variables[varname] = len(original_variables)
            ind = original_variables[varname]
            bc = self._binary_coefficients(self._vartype_map[varname])
            reconstructed_samples[:,
                                  ind] += record['sample'][:, i] * bc[var[1]]

        type = (np.record, [('sample', 'i', (len(original_variables), )),
                            ('energy', '<f8'), ('num_occurrences', '<i4')])
        new_record = np.recarray(record.shape,
                                 type,
                                 names=('sample', 'energy', 'num_occurrences'))
        new_record['sample'] = reconstructed_samples
        new_record['energy'] = record['energy']
        new_record['num_occurrences'] = record['num_occurrences']

        return SampleSet(new_record, original_variables.keys(), info, vartype)
示例#12
0
    def sample_dqm(self, dqm, **kwargs):
        """Sample from a discrete quadratic model.

        Args:
            dqm (:obj:`~dimod.DiscreteQuadraticModel`):
                Discrete quadratic model to be sampled from.

        Returns:
            :obj:`~dimod.SampleSet`

        """
        Sampler.remove_unknown_kwargs(self, **kwargs)

        n = dqm.num_variables()
        if n == 0:
            return SampleSet.from_samples([], 'DISCRETE', energy=[])

        possible_samples = as_samples(
            (_all_cases_dqm(dqm), list(dqm.variables)))
        energies = dqm.energies(possible_samples)

        response = SampleSet.from_samples(possible_samples, 'DISCRETE',
                                          energies)
        return response
示例#13
0
文件: json.py 项目: todun/dimod
def dimod_object_hook(obj):
    """JSON-decoding for dimod objects.

    See Also:
        :class:`json.JSONDecoder` for using custom decoders.

    """
    if _is_sampleset_v2(obj):
        # in the future we could handle subtypes but right now we just have the
        # one
        return SampleSet.from_serializable(obj)
    elif _is_bqm(obj):
        # in the future we could handle subtypes but right now we just have the
        # one
        return BinaryQuadraticModel.from_serializable(obj)
    return obj
示例#14
0
    def sample(self, bqm, fixed_variables=None, **parameters):
        """Sample from the provided binary quadratic model.

        Args:
            bqm (:obj:`dimod.BinaryQuadraticModel`):
                Binary quadratic model to be sampled from.

            fixed_variables (dict):
                A dictionary of variable assignments.

            **parameters:
                Parameters for the sampling method, specified by the child sampler.

        Returns:
            :obj:`dimod.SampleSet`

        """

        if not fixed_variables:  # None is falsey
            return self.child.sample(bqm, **parameters)

        # make sure that we're shapeable and that we have a BQM we can mutate
        bqm_copy = as_bqm(bqm, cls=[AdjVectorBQM, AdjDictBQM, AdjMapBQM],
                          copy=True)

        bqm_copy.fix_variables(fixed_variables)

        sampleset = self.child.sample(bqm_copy, **parameters)

        def _hook(sampleset):
            # make RoofDualityComposite non-blocking

            if sampleset.variables:
                if len(sampleset):
                    return sampleset.append_variables(fixed_variables)
                else:
                    return sampleset.from_samples_bqm((np.empty((0, len(bqm))),
                                                       bqm.variables), bqm=bqm)

            # there are only fixed variables, make sure that the correct number
            # of samples are returned
            samples = [fixed_variables]*max(len(sampleset), 1)

            return sampleset.from_samples_bqm(samples, bqm=bqm)

        return SampleSet.from_future(sampleset, _hook)
示例#15
0
    def sample(self, bqm, num_reads=10):
        """Give random samples for a binary quadratic model.

        Args:
            bqm (:obj:`.BinaryQuadraticModel`):
                Binary quadratic model to be sampled from.

            num_reads (int, optional, default=10):
                Number of reads.

        Returns:
            :obj:`.SampleSet`

        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 SampleSet.from_samples(samples, bqm.vartype, energies)
示例#16
0
    def sample(self, bqm, **kwargs):
        """Return an empty sample set.

        Args:
            bqm (:obj:`.BinaryQuadraticModel`):
                The binary quadratic model determines the variables labels in
                the sample set.

            kwargs:
                As specified when constructing the null sampler.

        Returns:
            :obj:`.SampleSet`: The empty sample set.


        """
        samples = np.empty((0, len(bqm)))
        labels = iter(bqm.variables)

        kwargs = self.remove_unknown_kwargs(**kwargs)

        return SampleSet.from_samples_bqm((samples, labels), bqm)
示例#17
0
    def sample(self, bqm, **kwargs):
        """Return an empty sample set.

        Args:
            bqm (:obj:`.BinaryQuadraticModel`):
                The binary quadratic model determines the variables labels in
                the sample set.

            kwargs:
                As specified when constructing the null sampler.

        Returns:
            :obj:`.SampleSet`: The empty sample set.


        """
        samples = np.empty((0, len(bqm)))
        labels = iter(bqm.variables)

        for kw in kwargs:
            if kw not in self.parameters:
                raise ValueError("unknown parameter {!r}".format(kw))

        return SampleSet.from_samples_bqm((samples, labels), bqm)
示例#18
0
    def sample(self, bqm, num_spin_reversal_transforms=2, spin_reversal_variables=None, **kwargs):
        """Sample from the binary quadratic model.

        Args:
            bqm (:obj:`~dimod.BinaryQuadraticModel`):
                Binary quadratic model to be sampled from.
            num_spin_reversal_transforms (integer, optional, default=2):
                Number of spin reversal transform runs.
            spin_reversal_variables (list/dict, optional, default=None):
                Variables to which to apply the spin reversal. If None, every variable
                has a 50% probability of being selected.

        Returns:
            :obj:`.SampleSet`

        Examples:
            This example runs 100 spin reversals applied to one variable of a QUBO problem.

            >>> import dimod
            ...
            >>> base_sampler = dimod.ExactSolver()
            >>> composed_sampler = dimod.SpinReversalTransformComposite(base_sampler)
            >>> Q = {('a', 'a'): -1, ('b', 'b'): -1, ('a', 'b'): 2}
            >>> response = composed_sampler.sample_qubo(Q,
            ...               num_spin_reversal_transforms=100,
            ...               spin_reversal_variables={'a'})
            >>> len(response)
            400
            >>> print(next(response.data()))           # doctest: +SKIP
            Sample(sample={'a': 0, 'b': 1}, energy=-1.0)

        """
        # make a main response
        responses = []

        for ii in range(num_spin_reversal_transforms):
            if spin_reversal_variables is None:
                # apply spin transform to each variable with 50% chance
                transform = list(v for v in bqm.linear if random() > .5)
            else:
                transform = list(spin_reversal_variables)

            flipped_bqm = bqm.copy()

            for v in transform:
                flipped_bqm.flip_variable(v)

            flipped_response = self.child.sample(bqm, **kwargs)

            tf_idxs = [flipped_response.variables.index[v] for v in flipped_response.variables]

            if bqm.vartype is Vartype.SPIN:
                flipped_response.record.sample[:, tf_idxs] = -1 * flipped_response.record.sample[:, tf_idxs]
            else:
                flipped_response.record.sample[:, tf_idxs] = 1 - flipped_response.record.sample[:, tf_idxs]

            responses.append(flipped_response)

        # # stack the records
        record = np.rec.array(np.hstack((resp.record for resp in responses)))

        vartypes = set(resp.vartype for resp in responses)
        if len(vartypes) > 1:
            raise RuntimeError("inconsistent vartypes returned")
        vartype = vartypes.pop()

        info = {}
        for resp in responses:
            info.update(resp.info)

        labels = responses[0].variables

        return SampleSet(record, labels, info, vartype)
示例#19
0
    def _sample(*args, **kwargs):
        iterator = f(*args, **kwargs)

        # resolve blocking part now, and make hook for the non-blocking part
        return SampleSet.from_future(next(iterator), lambda _: next(iterator))
示例#20
0
 def __init__(self, dimod_answer):
     solution = SampleSet.from_serializable(dimod_answer)
     Response.__init__(self, solution)
示例#21
0
    def parse_initial_states(self,
                             bqm,
                             initial_states=None,
                             initial_states_generator='random',
                             num_reads=None,
                             seed=None):
        """Parses/generates initial states for an initialized sampler.

        Args:
            bqm (:class:`~dimod.BinaryQuadraticModel`):
                The binary quadratic model.

            num_reads (int, optional, default=len(initial_states) or 1):
                Number of reads. If `num_reads` is not explicitly given, it is
                selected to match the number of initial states given.
                If no initial states are given, it defaults to 1.

            initial_states (samples-like, optional, default=None):
                One or more samples, each defining an initial state for all the
                problem variables. Initial states are given one per read, but
                if fewer than `num_reads` initial states are defined,
                additional values are generated as specified by
                `initial_states_generator`. See func:`.as_samples` for a
                description of "samples-like".

            initial_states_generator ({'none', 'tile', 'random'}, optional, default='random'):
                Defines the expansion of `initial_states` if fewer than
                `num_reads` are specified:

                * "none":
                    If the number of initial states specified is smaller than
                    `num_reads`, raises ValueError.

                * "tile":
                    Reuses the specified initial states if fewer than
                    `num_reads` or truncates if greater.

                * "random":
                    Expands the specified initial states with randomly
                    generated states if fewer than `num_reads` or truncates if
                    greater.

            seed (int (32-bit unsigned integer), optional):
                Seed to use for the PRNG. Specifying a particular seed with a
                constant set of parameters produces identical results. If not
                provided, a random seed is chosen.

        Returns:
            A named tuple with `['initial_states', 'initial_states_generator',
            'num_reads', 'seed']` as generated by this function.

        """

        num_variables = len(bqm)

        # validate/initialize initial_states
        if initial_states is None:
            initial_states_array = np.empty((0, num_variables), dtype=np.int8)
            initial_states_variables = list(bqm.variables)
            initial_states_vartype = bqm.vartype
        else:
            initial_states_array, initial_states_variables = \
                as_samples(initial_states)

            # confirm that the vartype matches and/or make it match
            if isinstance(initial_states, SampleSet):
                initial_states_vartype = initial_states.vartype
            else:
                # check based on values, defaulting to match the current bqm
                initial_states_vartype = infer_vartype(
                    initial_states_array) or bqm.vartype

            # confirm that the variables match
            if bqm.variables ^ initial_states_variables:
                raise ValueError("mismatch between variables in "
                                 "'initial_states' and 'bqm'")

        # match the vartype of the initial_states to the bqm
        if initial_states_vartype is Vartype.SPIN and bqm.vartype is Vartype.BINARY:
            initial_states_array += 1
            initial_states_array //= 2
        elif initial_states_vartype is Vartype.BINARY and bqm.vartype is Vartype.SPIN:
            initial_states_array *= 2
            initial_states_array -= 1

        # validate num_reads and/or infer them from initial_states
        if num_reads is None:
            num_reads = len(initial_states_array) or 1
        if not isinstance(num_reads, Integral):
            raise TypeError("'num_reads' should be a positive integer")
        if num_reads < 1:
            raise ValueError("'num_reads' should be a positive integer")

        # fill/generate the initial states as needed
        if initial_states_generator not in self._generators:
            raise ValueError("unknown value for 'initial_states_generator'")

        extrapolate = self._generators[initial_states_generator]
        initial_states_array = extrapolate(initial_states=initial_states_array,
                                           num_reads=num_reads,
                                           num_variables=num_variables,
                                           seed=seed,
                                           vartype=bqm.vartype)
        initial_states_array = self._truncate_filter(initial_states_array,
                                                     num_reads)

        sampleset = SampleSet.from_samples_bqm(
            (initial_states_array, initial_states_variables), bqm)

        return ParsedInputs(sampleset, initial_states_generator, num_reads,
                            seed)
示例#22
0
 def __init__(self, fujitsu_answer):
     sampleset = SampleSet.from_serializable(fujitsu_answer)
     Response.__init__(self, sampleset)
     self.timing = self.sampleset.info["timing"]
示例#23
0
def _release_response(response, fixed_variables):
    """will add the fixed variables and their assigned values to the samples
       of the response object. Energies of the response do not change since
       in fixing step the offset is populated by the constant energy shift
       associated with fixing the variables.

    Args:
        response (:obj:`.SampleSet`):
            Samples from the bqm with fixed variables.

        fixed_variables (dict):
            The dict of fixed variables and their assigned values.
            These are the variables that will be added back to the samples
            of the response object.

    Returns:
        :obj:`dimod.SampleSet`:
            Samples for the source binary quadratic model.

    Examples:
       This example uses :class:`.FixedVariableComposite` to instantiate a
       composed sampler that submits a simple Ising problem to a sampler.
       The composed sampler fixes a variable and modifies linear and quadratic
       biases according.

       >>> import dimod
       >>> sampler = dimod.FixedVariableComposite(dimod.ExactSolver())
       >>> h = {'d': -4}
       >>> J = {('a', 'b'): 1, ('b', 'c'): 1, ('a', 'c'): 1, ('c', 'd'): -.1}
       >>> bqm = dimod.BinaryQuadraticModel.from_ising(h, J)
       >>> fixed_variables = dimod.roof_duality.fix_variables(bqm)
       >>> response = sampler.sample(bqm, fixed_variables=fixed_variables)
       >>> print(response.first)
       Sample(sample={'a': -1, 'b': 1, 'c': 1, 'd': 1}, energy=-5.1, num_occurrences=1)

    """

    record = response.record
    original_variables = list(response.variables)
    samples = np.asarray(record.sample)
    energy = np.asarray(record.energy)

    num_samples, num_variables = np.shape(samples)
    num_variables += len(fixed_variables)

    if len(fixed_variables) > 0:
        b = []
        for v, val in fixed_variables.items():
            original_variables.append(v)
            b.append([val] * num_samples)
        samples = np.concatenate((samples, np.transpose(b)), axis=1)

    datatypes = [('sample', np.dtype(np.int8), (num_variables, )),
                 ('energy', energy.dtype)]

    datatypes.extend((name, record[name].dtype, record[name].shape[1:])
                     for name in record.dtype.names
                     if name not in {'sample', 'energy'})

    data = np.rec.array(np.empty(num_samples, dtype=datatypes))

    data.sample = samples
    data.energy = energy
    for name in record.dtype.names:
        if name not in {'sample', 'energy'}:
            data[name] = record[name]

    return SampleSet(data, original_variables, response.info, response.vartype)
    def sample(self, bqm, **parameters):
        """Sample from the provided binary quadratic model.

        Args:
            bqm (:class:`dimod.BinaryQuadraticModel`):
                Binary quadratic model to be sampled from.

            fixed_variables (dict, optional, default=None):
                A dictionary of variable assignments used when ``self.algorithm`` 
                is 'explicit'.

            strict (bool, optional, default=True):
                Only used if ``self.algorithm`` is 'roof_duality'. If True, only 
                fixes variables for which assignments are true for all minimizing 
                points (strong persistency). If False, also fixes variables for 
                which the assignments are true for some but not all minimizing 
                points (weak persistency).

            **parameters:
                Parameters for the sampling method, specified by the child sampler.

        Returns:
            :class:`dimod.SampleSet`

        """

        if self.algorithm == 'explicit':
            fixed_variables = parameters.pop('fixed_variables', None)
            if fixed_variables is None:
                msg = (
                    "No fixed_variables passed in when algorithm is 'explicit'. "
                    "Passing problem to child sampler without fixing.")
                warnings.warn(msg)
                return self.child.sample(bqm, **parameters)
        elif self.algorithm == 'roof_duality':
            fixed_variables = roof_duality(bqm,
                                           strict=parameters.pop(
                                               'strict', True))

        # make sure that we're shapeable and that we have a BQM we can mutate
        bqm_copy = as_bqm(bqm, cls=[AdjVectorBQM, AdjDictBQM], copy=True)

        bqm_copy.fix_variables(fixed_variables)

        sampleset = self.child.sample(bqm_copy, **parameters)

        def _hook(sampleset):
            # make RoofDualityComposite non-blocking

            if sampleset.variables:
                if len(sampleset):
                    return append_variables(sampleset, fixed_variables)
                else:
                    return sampleset.from_samples_bqm((np.empty(
                        (0, len(bqm))), bqm.variables),
                                                      bqm=bqm)

            # there are only fixed variables, make sure that the correct number
            # of samples are returned
            samples = [fixed_variables] * max(len(sampleset), 1)

            return sampleset.from_samples_bqm(samples, bqm=bqm)

        return SampleSet.from_future(sampleset, _hook)
示例#25
0
 def __init__(self, dwave_answer):
     sampleset = SampleSet.from_serializable(dwave_answer)
     Response.__init__(self, sampleset)
示例#26
0
def polymorph_response(response, poly, bqm,
                       penalty_strength=None,
                       keep_penalty_variables=True,
                       discard_unsatisfied=False):
    """ Transforms the sampleset for the higher order problem.

    Given a response of a penalized HUBO, this function creates a new sampleset
    object, taking into account penalty information and calculates the
    energies of samples for the higherorder problem.

    Args:
        response (:obj:`.SampleSet`): response for a penalized hubo.

        poly (:obj:`.BinaryPolynomial`):
            A binary polynomial.

        bqm (:obj:`dimod.BinaryQuadraticModel`): Binary quadratic model of the
            reduced problem.

        penalty_strength (float, optional): default is None, if provided,
            will be added to the info field of the returned sampleSet object.

        keep_penalty_variables (bool, optional): default is True. if False
            will remove the variables used for penalty from the samples

        discard_unsatisfied (bool, optional): default is False. If True
            will discard samples that do not satisfy the penalty conditions.

    Returns:
        (:obj:`.SampleSet'): A sampleSet object that has additional penalty
            information. The energies of samples are calculated for the HUBO
            ignoring the penalty variables.

    """
    record = response.record
    penalty_vector = penalty_satisfaction(response, bqm)
    original_variables = bqm.variables

    if discard_unsatisfied:
        samples_to_keep = list(map(bool, list(penalty_vector)))
        penalty_vector = np.array([True] * np.sum(samples_to_keep))
    else:
        samples_to_keep = list(map(bool, [1] * len(record.sample)))

    samples = record.sample[samples_to_keep]
    energy_vector = poly.energies((samples, response.variables))

    if not keep_penalty_variables:
        original_variables = poly.variables
        idxs = [response.variables.index[v] for v in original_variables]
        samples = np.asarray(samples[:, idxs])

    num_samples, num_variables = np.shape(samples)

    datatypes = [('sample', np.dtype(np.int8), (num_variables,)),
                 ('energy', energy_vector.dtype),
                 ('penalty_satisfaction',
                  penalty_vector.dtype)]
    datatypes.extend((name, record[name].dtype, record[name].shape[1:])
                     for name in record.dtype.names if
                     name not in {'sample',
                                  'energy'})

    data = np.rec.array(np.empty(num_samples, dtype=datatypes))
    data.sample = samples
    data.energy = energy_vector
    for name in record.dtype.names:
        if name not in {'sample', 'energy'}:
            data[name] = record[name][samples_to_keep]

    data['penalty_satisfaction'] = penalty_vector
    response.info['reduction'] = bqm.info['reduction']
    if penalty_strength is not None:
        response.info['penalty_strength'] = penalty_strength
    return SampleSet(data, original_variables, response.info,
                     response.vartype)