Example #1
0
    def test_linear(self):
        """Run a set of independent variables."""
        size = 10
        qubo = {}
        solution = {}
        for ii in range(size):
            qubo[(ii, ii)] = -1
            solution[ii] = 1

        results = dwave_qbsolv.QBSolv().sample_qubo(qubo)
        self.has_solution(results, solution, -size)

        results = dwave_qbsolv.QBSolv().sample_qubo(qubo, target=-size)
        self.has_solution(results, solution, -size)
Example #2
0
    def test_easy_loop(self):
        """Run a loop of variables without frustration."""
        size = 10
        qubo = {}
        solution = {}
        for ii in range(size):
            qubo[(ii, ii)] = -1
            qubo[ii, (ii + 1) % size] = -1
            solution[ii] = 1

        results = dwave_qbsolv.QBSolv().sample_qubo(qubo)
        self.has_solution(results, solution, -2 * size)

        results = dwave_qbsolv.QBSolv().sample_qubo(qubo, target=-2 * size)
        self.has_solution(results, solution, -2 * size)
Example #3
0
    def test_qbsolv(self):
        import dwave_qbsolv as qbsolv

        h = {'a': -1, 'b': +1}
        J = {('a', 'b'): -1}

        resp = qbsolv.QBSolv().sample_ising(h, J)
Example #4
0
    def test_single_frustrated_loop(self):
        """Run a loop of variables with a frustrated link."""
        size = 10
        qubo = {}
        solution = {}
        for ii in range(size):
            qubo[(ii, ii)] = -1
            qubo[ii, (ii + 1) % size] = -1
            solution[ii] = 1
        qubo[size - 1, 0] = 1

        results = dwave_qbsolv.QBSolv().sample_qubo(qubo)
        self.has_solution(results, solution, -2 * size + 2)

        results = dwave_qbsolv.QBSolv().sample_qubo(qubo, target=-2 * size + 2)
        self.has_solution(results, solution, -2 * size + 2)
Example #5
0
def QBSolve_classical_solution(Q, times_list, print_energy=False):
    """This function use classical QBSolve to get solution dictionary"""

    Qdict = Q_dict(Q)

    start = time.clock()

    response = QBSolv.QBSolv().sample_qubo(Qdict)

    # print("ENERGY: ", str(list(response.data_vectors['energy'])))
    # print("RESPONSE: ", response)

    qb_solution = list(response.samples())

    if print_energy:
        print("energies=" + str(list(response.data_vectors['energy'])))

    end = time.clock()

    time_taken = end - start

    # print("Time taken by classical QBSolv: ", time_taken)

    times_list.append(time_taken)

    qb_solution_list = list(qb_solution[0].values())

    return qb_solution_list
Example #6
0
    def test_callable_solver(self):
        """Run a set of beasely instances with 50 variables."""
        qbsolv = dwave_qbsolv.QBSolv()
        tests_path = os.path.dirname(os.path.abspath(__file__))
        import random

        callback_called = [False]

        def _callback(Q, best):
            callback_called[0] = True
            return [random.randint(0, 1) for _ in best]

        for index, expected_energy in enumerate(self.beasley50_energies):
            index += 1
            qubo = load_qubo(self.beasley50_qubo_format.format(tests_path=tests_path, index=index))
            # Python 3 feature
            # with self.subTest(index=index, energy=energy):

            # Give each problem three shots. One should be enough.
            # But this is a non-deterministic test.
            for _ in range(3):
                results = qbsolv.sample_qubo(qubo, find_max=True,
                                             solver=_callback)
                self.assertTrue(any(abs(energy - expected_energy) < ENERGY_ERROR for energy in results.energies()))
                break
            else:
                self.fail()

        # make sure at least one call invoked the callback
        self.assertTrue(callback_called[0])
Example #7
0
    def test_dimod_basic_qubo_alpha(self):
        n_variables = 50

        # all 0s
        Q = {(alpha[v], alpha[v]): 1 for v in range(n_variables)}
        response = qbs.QBSolv().sample_qubo(Q, seed=5125)
        sample = next(iter(response))
        for v in sample:
            self.assertEqual(sample[v], 0)

        # all 1s
        Q = {(alpha[u], alpha[v]): -1 for u, v in itertools.combinations(range(n_variables), 2)}
        response = qbs.QBSolv().sample_qubo(Q, seed=5342)
        sample = next(iter(response))
        for v in sample:
            self.assertEqual(sample[v], 1)
    def test_dimod_solver(self):
        """Run a set of beasely instances with 50 variables."""
        qbsolv = dwave_qbsolv.QBSolv()
        tests_path = os.path.dirname(os.path.abspath(__file__))

        for index, expected_energy in enumerate(self.beasley50_energies):
            index += 1
            qubo = load_qubo(
                self.beasley50_qubo_format.format(tests_path=tests_path,
                                                  index=index))
            # Python 3 feature
            # with self.subTest(index=index, energy=energy):

            # Give each problem three shots. One should be enough.
            # But this is a non-deterministic test.
            for _ in range(3):
                results = qbsolv.sample_qubo(qubo,
                                             find_max=True,
                                             solver=dimod.RandomSampler())
                self.assertTrue(
                    any(
                        abs(datum.energy - expected_energy) < ENERGY_ERROR
                        for datum in results.data()))
                break
            else:
                self.fail()
Example #9
0
    def test_dimod_basic_ising(self):
        n_variables = 60

        h = {v: -1 for v in range(n_variables)}
        J = {}
        response = qbs.QBSolv().sample_ising(h, J)
        sample = next(iter(response))
        for v in sample:
            self.assertEqual(sample[v], 1)
Example #10
0
    def test_dimod_basic_qubo(self):
        n_variables = 50

        # all 0s
        Q = {(v, v): 1 for v in range(n_variables)}
        response = qbs.QBSolv().sample_qubo(Q, seed=10)
        sample = next(iter(response))
        for v in sample:
            self.assertEqual(sample[v], 0)

        # all 1s
        Q = {(u, v): -1 for u, v in itertools.combinations(range(n_variables), 2)}
        response = qbs.QBSolv().sample_qubo(Q, seed=167)
        sample = next(iter(response))
        for v in sample:
            self.assertEqual(sample[v], 1)

        for sample, energy in response.data(['sample', 'energy']):
            self.assertEqual(dimod.qubo_energy(sample, Q), energy)
Example #11
0
    def test_energy_calculation(self):
        n_variables = 15

        h = {alpha[v]: random.uniform(-2, 2) for v in range(n_variables)}
        J = {(alpha[u], alpha[v]): random.uniform(-1, 1)
             for u, v in itertools.combinations(range(n_variables), 2) if random.random() > .98}

        response = qbs.QBSolv().sample_ising(h, J)

        for sample, energy in response.data(['sample', 'energy']):
            self.assertLessEqual(abs(dimod.ising_energy(sample, h, J) - energy), 10**-5)
Example #12
0
def solve_specialized_set_cover(input_sets, target_set):
    qubo = generate_qubo_specialized_set_cover(input_sets, target_set)

    actual_considered_input_sets = []
    for s in input_sets:
        if s.issubset(target_set):
            actual_considered_input_sets.append(s)
    #    N = len(actualConsideredInputSets)
    #    n = len(targetSet)
    #    print(N + N*n)
    #    print(actualConsideredInputSets)
    #    visualizeMatrix(qubo, N + N*n)

    qbsolv_params = dict(num_repeats=10, verbosity=-1)
    solutions = list(qbs.QBSolv().sample_qubo(qubo, **qbsolv_params).samples())
    solution_list = []
    for sol in solutions:
        temp = []
        for i in range(max(sol.keys()) + 1):
            temp.append(sol[i])
        solution_list.append(temp)
    # print(solution_list)
    potential_solutions = []
    for sol in solution_list:
        temp = []
        for i in range(len(actual_considered_input_sets)):
            if sol[i] == 1:
                temp.append(actual_considered_input_sets[i])
        potential_solutions.append(temp)
    # print("potential_solutions", potential_solutions)
    potential_solutions.sort(key=lambda x: len(x))
    for pot_sol in potential_solutions:
        total_set = set([])
        for s in pot_sol:
            total_set = total_set.union(s)
        if target_set == total_set:
            return pot_sol
    # print("We could not find a Solution")
    return -1
Example #13
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import networkx as nx
import dwave_networkx as dnx
import dwave_micro_client_dimod as micro
import dwave_qbsolv

urlc = 'https://cloud.dwavesys.com/sapi'
tokenc = 'SE-bb7f104b4a99cf9a10eeb9637f0806761c9fcedc'
solver_namec = 'DW_2000Q_1'

structured_samplerc = micro.DWaveSampler(solver_namec, urlc, tokenc)
samplerc = micro.EmbeddingComposite(structured_samplerc)
samplerq = dwave_qbsolv.QBSolv()
cloudsi = dnx.structural_imbalance(G, samplerc , num_reads=10000)
qbsolvsi = dnx.structural_imbalance (G, samplerq , solver= samplerc)

h = {v: node_values [v] for v in G.nodes }
J = {(u, v): eval for u, v in G.edges }

response = samplerc.sample_ising (h, J, num_reads=10000)
Example #14
0
 def test_single_bit(self):
     """Make sure the solver can tell which way to flip a single bit."""
     qubo = {(0, 0): -1}
     results = dwave_qbsolv.QBSolv().sample_qubo(qubo)
     self.has_solution(results, {0: 1}, -1)
Example #15
0
    def forward_qa(self, penalties_and_rewards: dict,
                   num_repeats: int) -> None:
        # language=rst
        """
        Runs a single simulation step.
        Only works for batch_size = 1 and DiehlAndCook-Network.
        """
        conn = self.connections
        inputs = {}  # shape: number of layers * number of neurons
        qubo = {}  # shape: (number of neurons * number of layers)^2
        encoding = {
        }  # to remember at which row_nr which layer starts, shape: number of layers
        nr_of_prev_nodes = 0

        for l in self.layers:
            l_v = self.layers[l]
            inputs[l] = torch.zeros(1, l_v.n)  # a tensor for each layer
            encoding[l] = nr_of_prev_nodes
            nr_of_prev_nodes += l_v.n

            # Decay voltages.
            if l == 'Ae':  # layer of DiehlAndCookNodes
                l_v.v = l_v.decay * (l_v.v - l_v.rest) + l_v.rest
                # and adaptive thresholds
                l_v.theta *= l_v.theta_decay
            elif l == 'Ai':  # layer of LIF-Nodes
                l_v.v = l_v.decay * (l_v.v - l_v.rest) + l_v.rest
            # else: l == 'X' -> layer of Input-Nodes -> does not have a voltage

        # prepare Quantum Annealing and get inputs
        # go through layers (and corresponding Input-connections)
        l_ae_v = self.layers['Ae']
        l_ai_v = self.layers['Ai']

        # Layer X of Input-Neurons: nothing to do

        # Layer Ae of excitatory DiehlAndCook-Nodes
        # needed later for Inputs from layers X and Ai (connections X->Ae and Ai->Ae)
        s_view_x = self.layers['X'].s.float().view(self.layers['X'].s.size(0),
                                                   -1)[0].tolist()
        s_view_ai = self.layers['Ai'].s.float().view(
            self.layers['Ai'].s.size(0), -1)[0].tolist()

        for node_ae in range(l_ae_v.n):
            # Could spike -> needs constraints
            if l_ae_v.refrac_count[0, node_ae].item() == 0:
                nr_ae = node_ae + encoding['Ae']

                # diagonal
                # = threshold + variable threshold theta - (voltage + connection-bias)
                # for c in conn: not needed in this case: always bias = 0
                # if c[1] == 'Ae':
                # l_ae_v.v[0, node] += conn[c].b[node]
                qubo[(nr_ae, nr_ae)] = l_ae_v.thresh.item(
                ) + l_ae_v.theta[node_ae].item() - l_ae_v.v[0, node_ae].item()
                # + NUDGE?

                # off-diagonal, same layer
                # l_v.one_spike is always true in this example -> ensure just one node in this layer spikes
                for other_ae_node in range((node_ae + 1), l_ae_v.n):
                    # node_column is not in refractory period either
                    if l_ae_v.refrac_count[0, other_ae_node].item() == 0:
                        other_nr = other_ae_node + encoding['Ae']
                        # penalty to make sure nodes do not spike at the same time
                        qubo[(nr_ae, other_nr)] = penalties_and_rewards['Ae']

                # off-diagonal, Inputs from layer X (connection X->Ae)
                # we work in the upper triangular matrix, connection goes from row to column
                for node_x in range(self.layers['X'].n):
                    inp = s_view_x[node_x] * conn[
                        ('X', 'Ae')].w[node_x, node_ae].item()
                    nr_x = node_x + encoding['X']
                    qubo[(nr_x, nr_ae)] = -1 * inp
                    inputs['Ae'][0, node_ae] += inp

                # off-diagonal, Inputs from layer Ai (connection Ai->Ae)
                # we work in the upper triangular matrix, connection goes from column to row
                # actual connections (where weights ≠ 0) are only where node_ae ≠ node_ai
                for node_ai in range(self.layers['Ai'].n):
                    if not node_ae == node_ai:
                        inp = s_view_ai[node_ai] * conn[
                            ('Ai', 'Ae')].w[node_ai, node_ae].item()
                        column_nr = node_ai + encoding['Ai']
                        qubo[(nr_ae, column_nr)] = -1 * inp
                        inputs['Ae'][0, node_ae] += inp

            # else: reward can be omitted for excitatory neurons -> done here for performance reasons

        # Layer Ai of inhibitory LIF-Nodes
        # needed later for Inputs from layer Ae (connection Ae->Ai)
        s_view_ae = self.layers['Ae'].s.float().view(
            self.layers['Ae'].s.size(0), -1)[0].tolist()

        for node in range(l_ai_v.n):
            # Could spike -> needs constraints
            if l_ai_v.refrac_count[0, node].item() == 0:
                nr_ai = node + encoding['Ai']

                # diagonal
                # = threshold - (voltage + connection-bias)
                # for c in conn: not needed in this case: always bias = 0
                # if c[1] == 'Ai':
                # l_ai_v.v[0, node] += conn[c].b[node]
                qubo[(nr_ai, nr_ai)] = l_ai_v.thresh.item() - l_ai_v.v[
                    0, node].item()  # + NUDGE?

                # for off-diagonal, same layer: nothing to do

                # off-diagonal, Inputs from layer Ae (connection Ae->Ai)
                # we work in the upper triangular matrix, connection goes from row to column
                # actual connections (where weights ≠ 0) are only where node_ai = node_ae
                inp = s_view_ae[node] * conn[('Ae', 'Ai')].w[node, node].item()
                nr_ae = node + encoding['Ae']
                qubo[(nr_ae, nr_ai)] = -1 * inp
                inputs['Ai'][0, node] += inp
            else:  # might just have spiked -> needs reward to clamp qubit to 1
                if s_view_ai[
                        node]:  # reward would not harm if neuron did not spike, but embedding easier without
                    nr_ai = node + encoding['Ai']
                    qubo[(nr_ai, nr_ai)] = penalties_and_rewards['Ai']

        # Wegen Hin- und Rückconnection: Verfälscht "Rüberklappen" Inhalt,
        # da connection von Ae nach Ai ≠ connection von Ai nach Ae?
        # -> Nein, denn: Wenn connection Ae->Ai existiert, dann existiert nicht wirklich Ai->Ae und umgekehrt
        # Für Situationen, wo dies doch der Fall wäre (Recurrent NN), wäre folgende Argumentation möglich,
        # solange nicht geclamped wird (da bei clamping Ae-Neuron spikt,
        # obwohl nicht in refrac-Period (in aktueller Implementierung), hält dann 1. nicht):
        # 1. Wenn Input-spike auf connection Ae->Ai, dann Ae-neuron in refrac-Period
        # -> bekommt keine Input-spikes Ai->Ae, sondern leer
        # -> ok, weil insgesamt bei Klappen der Wert dann nur der von Ae->Ai ist
        # 2. Wenn Input-spike auf connection Ai->Ae, dann Ai-neuron in refrac-Period
        # -> bekommt keine Input-spikes Ae->Ai, sondern leer
        # -> ok, weil insgesamt bei Klappen der Wert dann nur der von Ai->Ae ist
        # 3. Beide gleichzeitig Input-Spike -> beide in refrac-Period -> auch kein Problem: Wert leer
        # 4. Beide gleichzeitig kein Input-Spike -> Wert auf beiden Connections = w * 0 = 0
        # => "Rüberklappen" kein Problem, da keine Verfälschung

        # call Quantum Annealer or simulator (creates a triangular matrix out of qubo by itsself)
        # start = clock.time()
        # originally num_repeats=40, seems to work well with num_repeats=1, too (-> now default)
        solution = qbs.QBSolv().sample_qubo(qubo,
                                            num_repeats=num_repeats,
                                            verbosity=-1)
        # end = clock.time()
        # elapsed = end - start
        # print("\n Wall clock time qbsolv: %fs" % elapsed)
        print("\n Energy of qbsolv-solution: %f" % solution.first.energy)

        for l in self.layers:
            l_v = self.layers[l]
            # write spikes from (first) solution by filtering out 1s from neurons in refractory period
            if not l == 'X':  # not layer of Input-Nodes
                spikes = torch.full((1, l_v.n), False, dtype=torch.bool)
                nr = encoding[l]
                for node in range(l_v.n):
                    # is not in refractory period (has not just spiked) -> could spike
                    if l_v.refrac_count[0, node].item() == 0:
                        if solution.first.sample[nr + node] == 1:
                            spikes[0][node] = True
                l_v.s = spikes

                # Integrate inputs into voltage
                # (bias not necessary, as always = 0 in this example, inputs are zero where in refrac-period
                # -> no need to check, Input-layer does not have voltage)
                l_v.v += inputs[l]

                # Decrement refractory counters. (Input-layer does not have refrac_count)
                l_v.refrac_count = (l_v.refrac_count >
                                    0).float() * (l_v.refrac_count - l_v.dt)

                # Refractoriness, voltage reset, and adaptive thresholds.
                l_v.refrac_count.masked_fill_(l_v.s, l_v.refrac)
                l_v.v.masked_fill_(l_v.s, l_v.reset)
                if l == 'Ae':  # layer of DiehlAndCookNodes
                    l_v.theta += l_v.theta_plus * l_v.s.float().sum(0)
qubo = BinaryQuadraticModel.empty(dimod.BINARY)
for n in range(N):
    qubo.add_offset(1)
    for k1 in range(K):
        for k2 in range(K):
            if k1 != k2:
                qubo.add_interaction(d2tod1(n, k1, K), d2tod1(n, k2, K), 1)
    for k in range(K):
        qubo.add_variable(d2tod1(n, k, K), -1)
for (u, v) in neighbours:
    for k in range(K):
        qubo.add_interaction(d2tod1(u, k, K), d2tod1(v, k, K), 1)
print(qubo)
# Set up the solver
sampler = dimod.SimulatedAnnealingSampler()
solver = dwave_qbsolv.QBSolv()
# Solve for the minimum energy configuration
response = solver.sample(qubo, num_reads=300)
sol = list(response.samples())
# Draw the final coloring configuration
# Multiple possible minimum configurations are given as the output, here we take one of them to draw the graph
s = sol[0]
print(s)
g = nx.Graph()
g.add_nodes_from(nodes)
g.add_edges_from(neighbours)
pos = nx.spring_layout(g)
nx.draw(g,
        pos=pos,
        with_labels=True,
        nodelist=nodes,
    for var, value in fixed_variables.items():
        bqm.fix_variable(var, value)
    # 'aux1' becomes disconnected, so needs to be fixed
    bqm.fix_variable('aux1', 1)  # don't care value

    if _qpu:
        # find embedding and put on system
        print("Running using QPU\n")
        sampler = system.EmbeddingComposite(system.DWaveSampler())
        response = sampler.sample_ising(bqm.linear,
                                        bqm.quadratic,
                                        num_reads=NUM_READS)
    else:
        # if no qpu access, use qbsolv's tabu
        print("Running using qbsolv's classical tabu search\n")
        sampler = qbsolv.QBSolv()
        response = sampler.sample_ising(bqm.linear, bqm.quadratic)

    ####################################################################################################
    # output results
    ####################################################################################################

    # responses are sorted in order of increasing energy, so the first energy is the minimum
    min_energy = next(response.energies())

    best_samples = [
        datum['sample'] for datum in response.data()
        if datum['energy'] == min_energy
    ]
    for sample in best_samples:
        for variable in list(sample.keys()):