Beispiel #1
0
    def next(self, states):
        """ICM between two first samples in the first two input states."""

        if len(states) > 2:
            raise ValueError("exactly two input states required")

        inp1, inp2 = states
        bqm = inp1.problem

        ss1 = inp1.samples.change_vartype(dimod.BINARY, inplace=False)
        ss2 = inp2.samples.change_vartype(dimod.BINARY, inplace=False)

        # sanity check: we operate on the same set of variables
        if ss1.variables ^ ss2.variables:
            raise ValueError(
                "input samples not over the same set of variables")

        # reorder variables, if necessary
        # (use sequence comparison, not set)
        variables = list(ss1.variables)
        if ss2.variables != variables:
            reorder = [ss2.variables.index(v) for v in variables]
            record = ss2.record[:, reorder]
            ss2 = dimod.SampleSet(record, variables, ss2.info, ss2.vartype)

        # samples' symmetric difference (XOR)
        # (form clusters of input variables with opposite values)
        sample1 = ss1.record.sample[0]
        sample2 = ss2.record.sample[0]
        symdiff = sample1 ^ sample2

        # for cluster detection we'll use a reduced problem graph
        graph = bqm.to_networkx_graph()
        # note: instead of numpy mask indexing of `notcluster`, we enumerate
        # non-cluster variables manually to avoid conversion of potentially
        # unhashable variable names to numpy types
        notcluster = [v for v, d in zip(variables, symdiff) if d == 0]
        graph.remove_nodes_from(notcluster)

        # pick a random variable that belongs to a cluster, then select the cluster
        node = self.random.choice(list(graph.nodes))
        cluster = nx.node_connected_component(graph, node)

        # flip variables from `cluster` in both input samples
        flipper = np.array([1 if v in cluster else 0 for v in variables])
        ss1.record.sample[0] ^= flipper
        ss2.record.sample[0] ^= flipper

        # change vartype back to input's type
        ss1.change_vartype(inp1.samples.vartype)
        ss2.change_vartype(inp2.samples.vartype)

        # update sampleset's energies
        ss1.record.energy = bqm.energies(ss1)
        ss2.record.energy = bqm.energies(ss2)

        return States(inp1.updated(samples=ss1), inp2.updated(samples=ss2))
    def test_embedding_superset(self):
        # source graph in the embedding is a superset of the bqm
        response = dimod.SampleSet(np.rec.array([([-1,  1, -1,  1, -1,  1, -1,  1], -1.4, 1),
                                                ([-1,  1, -1, -1, -1,  1, -1, -1], -1.4, 1),
                                                ([+1, -1, -1, -1,  1, -1, -1, -1], -1.6, 1),
                                                ([+1, -1, -1, -1,  1, -1, -1, -1], -1.6, 1)],
                                   dtype=[('sample', 'i1', (8,)), ('energy', '<f8'), ('num_occurrences', '<i8')]),
                                   [0, 1, 2, 3, 4, 5, 6, 7], {}, 'SPIN')
        embedding = {0: {0, 4}, 1: {1, 5}, 2: {2, 6}, 3: {3, 7}}
        bqm = dimod.BinaryQuadraticModel.from_ising([.1, .2], {(0, 1): 1.5}, 0.0)

        unembedded = dwave.embedding.unembed_sampleset(response, embedding, source_bqm=bqm)

        arr = np.rec.array([([-1,  1], -1.4, 1), ([-1,  1], -1.4, 1), ([+1, -1], -1.6, 1), ([+1, -1], -1.6, 1)],
                           dtype=[('sample', 'i1', (2,)), ('energy', '<f8'), ('num_occurrences', '<i8')])

        np.testing.assert_array_equal(arr, unembedded.record)
Beispiel #3
0
    def next(self, state, **runopts):
        beta = runopts.get('beta', self.beta)
        beta = state.get('beta', beta)
        if beta is None:
            raise ValueError(
                'beta must be given on construction or during run-time')

        ss = state.samples

        # calculate weights
        w = np.exp(-beta * ss.record.energy)
        p = w / sum(w)

        # resample
        idx = self.random.choice(len(ss), len(ss), p=p)
        record = ss.record[idx]
        info = ss.info.copy()
        info.update(beta=beta)
        new_samples = dimod.SampleSet(record, ss.variables, info, ss.vartype)

        return state.updated(samples=new_samples)
Beispiel #4
0
    def next(self, state, **runopts):
        delta_beta = runopts.get('delta_beta', self.delta_beta)
        delta_beta = state.get('delta_beta', delta_beta)
        if delta_beta is None:
            raise ValueError(
                'delta_beta must be given on construction or during run-time')

        ss = state.samples

        # calculate weights (note: to avoid overflow, we offset energy, as it
        # cancels out during probability calc)
        min_energy = ss.record.energy.min()
        w = np.exp(-delta_beta * (ss.record.energy - min_energy))
        p = w / sum(w)

        # resample
        idx = self.random.choice(len(ss), len(ss), p=p)
        record = ss.record[idx]
        info = ss.info.copy()
        info.update(beta=state.beta, delta_beta=delta_beta)
        new_samples = dimod.SampleSet(record, ss.variables, info, ss.vartype)

        return state.updated(samples=new_samples)