Beispiel #1
0
 def test_3path(self):
     bqm = dimod.BinaryQuadraticModel.from_ising({'a': 10}, {
         'ab': -1,
         'bc': 1
     })
     fixed = dimod.fix_variables(bqm)
     self.assertEqual(fixed, {'a': -1, 'b': -1, 'c': 1})
Beispiel #2
0
 def test_3path(self):
     bqm = dimod.BinaryQuadraticModel.from_ising({'a': 10}, {
         'ab': -1,
         'bc': 1
     })
     with self.assertWarns(DeprecationWarning):
         fixed = dimod.fix_variables(bqm)
     self.assertEqual(fixed, {'a': -1, 'b': -1, 'c': 1})
Beispiel #3
0
def solve(Q, offset, b, f1, sampler):
    bqm = dimod.BinaryQuadraticModel(Q, 'BINARY')
    bqm.fix_variables(f1)
    f2 = dimod.fix_variables(bqm)
    bqm.fix_variables(f2)
    f = {**f1, **f2}
    sampleset = sampler.sample(bqm)
    GS = sample_graph(G, b, f, sampleset.first.sample)
    return GS, sampleset, sampleset.first.energy, GS.edges
Beispiel #4
0
    def next(self, state, **runopts):
        bqm = state.problem
        sampleset = state.samples

        fixed_vars = dimod.fix_variables(bqm, sampling_mode=self.sampling_mode)

        # make a new bqm of everything not-fixed
        subbqm = bqm.copy()
        subbqm.fix_variables(fixed_vars)

        # update the existing state with the fixed variables
        newsampleset = sampleset.copy()
        for v, val in fixed_vars.items():
            # index lookups on variables are fast for SampleSets
            newsampleset.record.sample[:, newsampleset.variables.index(v)] = val

        # make sure the energies reflect the changes
        newsampleset.record.energy = bqm.energies(newsampleset)

        return state.updated(subproblem=subbqm, samples=newsampleset)
Beispiel #5
0
def anneal(C_i, C_ij, mu, sigma, l, strength_scale, energy_fraction, ngauges,
           max_excited_states):
    #Initialising h and J as dictionnaries
    h = {}
    J = {}

    for i in range(len(C_i)):
        h_i = -2 * sigma[i] * C_i[i]
        for j in range(len(C_ij[0])):
            if j > i:
                J[(i, j)] = float(2 * C_ij[i][j] * sigma[i] * sigma[j])
            h_i += 2 * (sigma[i] * C_ij[i][j] * mu[j])
        h[i] = h_i

    #applying cutoff
    print("Number of J before : " + str(len(J)))  #J before cutoff
    float_vals = []
    for i in J.values():
        float_vals.append(i)
    cutoff = np.percentile(float_vals, AUGMENT_CUTOFF_PERCENTILE)
    to_delete = []
    for k, v in J.items():
        if v < cutoff:
            to_delete.append(k)
    for k in to_delete:
        del J[k]
    print("Number of J after : " + str(len(J)))  # J after cutof
    new_Q = {}
    isingpartial = {}

    if FIXING_VARIABLES:
        #Optimising heuristically the number of coupling terms
        Q, _ = dimod.ising_to_qubo(h, J, offset=0.0)
        bqm = dimod.BinaryQuadraticModel.from_qubo(Q, offset=0.0)
        simple = dimod.fix_variables(bqm, sampling_mode=False)
        if simple == {}:
            new_Q = Q
        else:
            Q_indices = []
            for i in Q:
                if i in simple.keys():
                    continue
                else:
                    Q_indices.append(i)
            new_Q = {key: Q[key] for key in Q_indices}
        print('new length', len(new_Q))
        isingpartial = simple

    if (not FIXING_VARIABLES) or len(new_Q) > 0:
        mapping = []
        offset = 0
        for i in range(len(C_i)):
            if i in isingpartial:
                mapping.append(None)
                offset += 1
            else:
                mapping.append(i - offset)
        if FIXING_VARIABLES:
            new_Q_mapped = {}
            for (first, second), val in new_Q.items():
                new_Q_mapped[(mapping[first], mapping[second])] = val
            h, J, _ = dimod.qubo_to_ising(new_Q_mapped)

        #Run gauges
        qaresults = []
        print("Number of variables to anneal :" + str(len(h)))
        for g in range(ngauges):
            #Finding embedding
            qaresult = []
            embedded = False
            for attempt in range(5):
                a = np.sign(np.random.rand(len(h)) - 0.5)
                float_h = []
                for i in h.values():
                    float_h.append(i)
                h_gauge = float_h * a
                J_gauge = {}
                for i in range(len(h)):
                    for j in range(len(h)):
                        if (i, j) in J:
                            J_gauge[(i, j)] = J[(i, j)] * a[i] * a[j]
                try:
                    print("Trying to find embeding")
                    sampler = EmbeddingComposite(
                        DWaveSampler(token='secret_token'))
                    embedded = True
                    break
                except ValueError:  # no embedding found
                    print('no embedding found')
                    embedded = False
                    continue

            if not embedded:
                continue
            print("emebeding found")

            print("Quantum annealing")
            try_again = True
            while try_again:
                try:
                    #Annealing, saving energy and sample list
                    sampleset = sampler.sample_ising(
                        h_gauge,
                        J_gauge,
                        chain_strength=strength_scale,
                        num_reads=200,
                        annealing_time=20)
                    try_again = False
                except:
                    print('runtime or ioerror, trying again')
                    time.sleep(10)
                    try_again = True
            print("Quantum done")

            qaresult.append(sampleset.record[0][0].tolist())
            qaresult = np.asarray(qaresult)
            qaresult = qaresult * a
            qaresults[g * nreads:(g + 1) * nreads] = qaresult

        full_strings = np.zeros((len(qaresults), len(C_i)))
        full_strings = np.asarray(full_strings)
        qaresults = np.asarray(qaresults)
        if FIXING_VARIABLES:
            j = 0
            for i in range(len(C_i)):
                if i in isingpartial:
                    full_strings[:, i] = 2 * isingpartial[i] - 1
                else:
                    full_strings[:, i] = qaresults[:, j]
                    j += 1
        else:
            full_strings = qaresults

        s = np.asarray(full_strings)
        energies = np.zeros(len(qaresults))
        s[np.where(s > 1)] = 1.0
        s[np.where(s < -1)] = -1.0
        bits = len(s[0])
        for i in range(bits):
            energies += 2 * s[:, i] * (-sigma[i] * C_i[i])
            for j in range(bits):
                if j > i:
                    energies += 2 * s[:, i] * s[:, j] * sigma[i] * sigma[
                        j] * C_ij[i][j]
                energies += 2 * s[:, i] * sigma[i] * C_ij[i][j] * mu[j]

        unique_energies, unique_indices = np.unique(energies,
                                                    return_index=True)
        ground_energy = np.amin(unique_energies)
        if ground_energy < 0:
            threshold_energy = (1 - energy_fraction) * ground_energy
        else:
            threshold_energy = (1 + energy_fraction) * ground_energy
        lowest = np.where(unique_energies < threshold_energy)
        unique_indices = unique_indices[lowest]
        if len(unique_indices) > max_excited_states:
            sorted_indices = np.argsort(
                energies[unique_indices])[-max_excited_states:]
            unique_indices = unique_indices[sorted_indices]
        print("unique indices : ", unique_indices)
        print(type(unique_indices[0]))
        print(type(full_strings))
        final_answers = full_strings[unique_indices]
        print('number of selected excited states', len(final_answers))

        return final_answers

    else:
        final_answer = []
        print("Evrything resolved by FIXING_VARIABLES")
        for i in range(len(C_i)):
            if i in isingpartial:
                final_answer.append(2 * isingpartial[i] - 1)
        final_answer = np.array(final_answer)
        return np.array([final_answer])
Beispiel #6
0
def main():
    # Note: for the purposes of a code example, main() is written as a script

    # Read user input
    if len(sys.argv) > 1:
        filename = sys.argv[1]
    else:
        filename = "problem.txt"
        print("Warning: using default problem file, '{}'. Usage: python "
              "{} <sudoku filepath>".format(filename, sys.argv[0]))

    # Read sudoku problem
    matrix = get_matrix(filename)

    # Set up
    n = len(matrix)  # Number of rows/columns in sudoku
    m = int(math.sqrt(n))  # Number of rows/columns in sudoku subsquare
    digits = range(1, n + 1)

    bqm = dimod.BinaryQuadraticModel({}, {}, 0.0, dimod.SPIN)

    # Constraint: Each node can only select one digit
    for row in range(n):
        for col in range(n):
            node_digits = [get_label(row, col, digit) for digit in digits]
            one_digit_bqm = combinations(node_digits, 1)
            bqm.update(one_digit_bqm)

    # Constraint: Each row of nodes cannot have duplicate digits
    for row in range(n):
        for digit in digits:
            row_nodes = [get_label(row, col, digit) for col in range(n)]
            row_bqm = combinations(row_nodes, 1)
            bqm.update(row_bqm)

    # Constraint: Each column of nodes cannot have duplicate digits
    for col in range(n):
        for digit in digits:
            col_nodes = [get_label(row, col, digit) for row in range(n)]
            col_bqm = combinations(col_nodes, 1)
            bqm.update(col_bqm)

    # Constraint: Each sub-square cannot have duplicates
    # Build indices of a basic subsquare
    subsquare_indices = [(row, col) for row in range(3) for col in range(3)]

    # Build full sudoku array
    for r_scalar in range(m):
        for c_scalar in range(m):
            for digit in digits:
                # Shifts for moving subsquare inside sudoku matrix
                row_shift = r_scalar * m
                col_shift = c_scalar * m

                # Build the labels for a subsquare
                subsquare = [
                    get_label(row + row_shift, col + col_shift, digit)
                    for row, col in subsquare_indices
                ]
                subsquare_bqm = combinations(subsquare, 1)
                bqm.update(subsquare_bqm)

    # Constraint: Fix known values
    for row, line in enumerate(matrix):
        for col, value in enumerate(line):
            if value > 0:
                # Recall that in the "Each node can only select one digit"
                # constraint, for a given cell at row r and column c, we
                # produced 'n' labels. Namely,
                # ["r,c_1", "r,c_2", ..., "r,c_(n-1)", "r,c_n"]
                #
                # Due to this same constraint, we can only select one of these
                # 'n' labels (achieved by 'generators.combinations(..)').
                #
                # The 1 below indicates that we are selecting the label
                # produced by 'get_label(row, col, value)'. All other labels
                # with the same 'row' and 'col' will be discouraged from being
                # selected.
                bqm.fix_variable(get_label(row, col, value), 1)

    # Solve BQM
    fixed = fix_variables(bqm, sampling_mode=False)
    bqm.fix_variables(fixed)
    solution = KerberosSampler().sample(bqm, max_iter=10, convergence=3)
    best_solution = solution.first.sample

    # Print solution
    solution_list = [k for k, v in best_solution.items() if v == 1]
    solution_list.extend([k for k, v in fixed.items() if v == 1])
    for label in solution_list:
        coord, digit = label.split('_')
        row, col = map(int, coord.split(','))
        matrix[row][col] = int(digit)

    for line in matrix:
        print(*line, sep=" ")  # Print list without commas or brackets

    # Verify
    if is_correct(matrix):
        print("The solution is correct")
    else:
        print("The solution is incorrect")
Beispiel #7
0
    G = generate_graph(**opts['generate'])
else:
    print('Input data is not specified.')
    raise

for e in nx.selfloop_edges(G):
    G.remove_edge(*e)

# Generate QUBO
Q, offset, b, f1 = hamilton_qubo(G, True, False)
bqm = dimod.BinaryQuadraticModel(Q, 'BINARY')
bqm.offset = offset

# Fix variables
bqm.fix_variables(f1)
f2 = dimod.fix_variables(bqm)
bqm.fix_variables(f2)
f0 = {**f1, **f2}

print(
    '# of nodes, edges, variables, fixed 1, 2 & total, energy, node with no inedge, multi inedges, no outedges, multi outedges, cycles'
)
print(G.number_of_nodes(),
      G.number_of_edges(),
      bqm.num_variables,
      len(f1),
      len(f2),
      len(f0),
      end=' ')

# Choose one of the solvers below.