Beispiel #1
0
    def solve_qa(self, verbose=True, num_reads=100):
        assert self.token is not None
        assert self.mode == "bqm"
        if self.qubo is None:
            self.pre_process()
        if verbose:
            print(f"Solving SMTI with: {SOLVER}")
            print(f"Optimal Solution: {-(len(self.encoding) * self.p2 + self.matching.size * self.p1)}")

        chain_strength = self.get_chain_stength() + 1  # max element in qubo matrix + epsilon
        solver_limit = len(self.encoding)  # solver_limit => size of qubo matrix

        G = nx.complete_graph(solver_limit)
        dw_solver = DWaveSampler(solver=SOLVER, token=self.token, endpoint=ENDPOINT)
        embedding = minorminer.find_embedding(G.edges, dw_solver.edgelist)
        fixed_embedding = FixedEmbeddingComposite(dw_solver, embedding)
        result = fixed_embedding.sample(self.qubo, num_reads=num_reads, chain_strength=chain_strength)

        dw_solver.client.close()  # clean up all the thread mess the client creates so it does not block my code
        if verbose:
            print(result)
            for index, (sample, energy, occ, chain) in enumerate(result.record):
                match_, _ = self.encode_qa(sample.tolist())
                stable_, size_ = Solution(self.matching, match_).is_stable()
                print(f"{index}: ", match_, size_, stable_)

        samples = pd.DataFrame()
        for sample, energy, occ, chain in result.record:
            match, valid = self.encode_qa(sample.tolist())
            stable, size = Solution(self.matching, match).is_stable()
            samples = samples.append({"match": match, "sample": sample.tolist(),
                                      "energy": energy, "occ": occ, "chain": chain,
                                      "valid": valid, "stable": stable, "size": size}, ignore_index=True)
        return samples
Beispiel #2
0
    def test_problem_label_in_sampleset(self):
        """All data adapters should propagate problem label."""

        # sample bqm -> sampleset
        qpu = DWaveSampler()
        sampler = FixedEmbeddingComposite(qpu, self.embedding)
        sampleset = sampler.sample(self.bqm, label=self.label, **self.params)

        # ensure `from_bqm_sampleset` adapter propagates label
        data = from_bqm_sampleset(self.bqm,
                                  sampleset,
                                  sampler,
                                  params=self.params)
        self.assertEqual(data['details']['label'], self.label)
Beispiel #3
0
    def test_sampler_graph_validation(self):
        """All data adapters should fail on non-Chimera/Pegasus solvers."""

        # sample
        qpu = DWaveSampler()
        sampler = FixedEmbeddingComposite(qpu, self.embedding)
        sampleset = sampler.sample(self.bqm,
                                   return_embedding=True,
                                   **self.params)

        # resolve it before we mangle with it
        sampleset.info['problem_id']
        # change solver topology to non-chimera/pegasus to test solver validation
        sampler.child.solver.properties['topology']['type'] = 'unknown'

        # ensure `from_bqm_sampleset` adapter fails on unstructured solver
        with self.assertRaises(TypeError):
            from_bqm_sampleset(self.bqm,
                               sampleset,
                               sampler,
                               params=self.params)
Beispiel #4
0
    def test_sampler_type_validation(self):
        """All data adapters should fail on non-StructuredSolvers."""

        # sample
        qpu = DWaveSampler()
        sampler = FixedEmbeddingComposite(qpu, self.embedding)
        sampleset = sampler.sample(self.bqm,
                                   return_embedding=True,
                                   **self.params)

        # resolve it before we mangle with it
        sampleset.info['problem_id']
        # change solver to unstructured to test solver validation
        sampler.child.solver = unstructured_solver_mock

        # ensure `from_bqm_sampleset` adapter fails on unstructured solver
        with self.assertRaises(TypeError):
            from_bqm_sampleset(self.bqm,
                               sampleset,
                               sampler,
                               params=self.params)
Beispiel #5
0
    def _test_from_bqm_sampleset(self, bqm):
        # sample
        qpu = DWaveSampler()
        sampler = FixedEmbeddingComposite(qpu, self.embedding)
        sampleset = sampler.sample(bqm,
                                   return_embedding=True,
                                   chain_strength=self.chain_strength,
                                   **self.params)

        # convert
        data = from_bqm_sampleset(bqm, sampleset, sampler, params=self.params)

        # construct (unembedded) response with chain breaks resolved
        # NOTE: for bqm/sampleset adapter, this is the best we can expect :(

        # inverse the embedding
        var_to_idx = {var: idx for idx, var in enumerate(sampleset.variables)}
        unembedding = {
            q: var_to_idx[v]
            for v, qs in self.embedding.items() for q in qs
        }

        # embed sampleset
        solutions_without_chain_breaks = [[
            int(sample[unembedding[q]]) if q in unembedding else val
            for q, val in enumerate(solution)
        ] for solution, sample in zip(self.response['solutions'],
                                      sampleset.record.sample)]

        with mock.patch.dict(self.response._result,
                             {'solutions': solutions_without_chain_breaks}):

            # validate data encoding
            self.verify_data_encoding(problem=self.problem,
                                      response=self.response,
                                      solver=self.solver,
                                      params=self.params,
                                      data=data,
                                      embedding_context=self.embedding_context)
Beispiel #6
0
    def test_transform_embedded(self):
        C = dnx.chimera_graph(1)
        nodelist = list(C.nodes())
        edgelist = list(C.edges())
        structsampler = dimod.StructureComposite(dimod.ExactSolver(),
                                                 nodelist=nodelist,
                                                 edgelist=edgelist)
        gauges_sampler = CheckerboardTransformComposite(structsampler,
                                                        C,
                                                        aggregate=True)
        sampler = FixedEmbeddingComposite(gauges_sampler, {
            'a': [0, 4],
            'b': [1, 5],
            'c': [2, 6]
        })
        h = {'a': .5, 'c': 0}
        J = {('a', 'c'): -1}
        response = sampler.sample_ising(h, J)
        # All 4 gauges must return same samples
        for datum in response.data():
            self.assertEqual(datum.num_occurrences, 4)

        dit.assert_response_energies(
            response, dimod.BinaryQuadraticModel.from_ising(h, J))
Beispiel #7
0
    def dwave_physical_DW_2000Q_5(self):
        print("\nD-wave quantum annealer....")
        from dwave.system import DWaveSampler, FixedEmbeddingComposite
        from dwave.embedding.chimera import find_clique_embedding

        qpu = DWaveSampler(token=self.token,
                           endpoint=self.endpoint,
                           solver=dict(name='DW_2000Q_5'),
                           auto_scale=False)
        self.title = "D-Wave Quantum Annealer"

        embedding = find_clique_embedding(
            self.bqm.variables,
            16,
            16,
            4,  # size of the chimera lattice
            target_edges=qpu.edgelist)

        qpu_sampler = FixedEmbeddingComposite(qpu, embedding)

        print("Maximum chain length for minor embedding is {}.".format(
            max(len(x) for x in embedding.values())))

        from hybrid.reference.kerberos import KerberosSampler
        kerberos_sampler = KerberosSampler()

        selected_features = np.zeros((len(self.features), len(self.features)))
        for k in range(1, len(self.features) + 1):
            print("Submitting for k={}".format(k))
            kbqm = dimod.generators.combinations(self.features, k, strength=6)
            kbqm.update(self.bqm)
            kbqm.normalize()

            best = kerberos_sampler.sample(kbqm,
                                           qpu_sampler=qpu_sampler,
                                           num_reads=10,
                                           max_iter=1).first.sample

            for fi, f in enumerate(self.features):
                selected_features[k - 1, fi] = best[f]
        if self.is_notebook:
            from helpers.draw import plot_feature_selection
            plot_feature_selection(self.features, selected_features)
Beispiel #8
0
                              lmbd * D_b[i][j] * D_b[i][k])
        S[(j, k)] = J[(j, k)]

bqm = dimod.BinaryQuadraticModel(linear=h,
                                 quadratic=J,
                                 offset=0.0,
                                 vartype=dimod.BINARY)

energy_true_z = get_energy(bqm, z_b)

embedding = get_embedding_with_short_chain(S,
                                           tries=5,
                                           processor=hardware_sampler.edgelist,
                                           verbose=False)

sampler = FixedEmbeddingComposite(hardware_sampler, embedding)

solver_parameters = {
    'num_reads': num_reads,
    'auto_scale': True,
    'annealing_time': annealing_time,  # default: 20 us
    #'anneal_schedule': anneal_sched_custom(id=3),
    #'num_spin_reversal_transforms': 2,  # default: 2
}

# schedule = make_reverse_anneal_schedule(s_target=0.99,
#                                        hold_time=1,
#                                        ramp_up_slope=0.2)
#schedule = [(0.0, 1.0), (1.0, 0.7), (7.0, 0.7), (10.0, 1.0)]
#schedule = [(0.0, 1.0), (2.0, 0.7), (8.0, 0.7), (10.0, 1.0)]
schedule = [(0.0, 1.0), (2.0, 0.7), (98.0, 0.7), (100.0, 1.0)]
def run_demo():
    # Read the feature-engineered data into a pandas dataframe
    # Data obtained from http://biostat.mc.vanderbilt.edu/DataSets
    demo_path = os.path.dirname(os.path.abspath(__file__))
    data_path = os.path.join(demo_path, 'data', 'formatted_titanic.csv')
    dataset = pd.read_csv(data_path)

    # Rank the MI between survival and every other variable
    scores = {}
    features = list(set(dataset.columns).difference(('survived', )))
    for feature in features:
        scores[feature] = mutual_information(
            prob(dataset[['survived', feature]].values), 0)

    labels, values = zip(
        *sorted(scores.items(), key=lambda pair: pair[1], reverse=True))

    # Plot the MI between survival and every other variable
    plt.figure()
    ax1 = plt.subplot(1, 2, 1)
    ax1.set_title("Mutual Information")
    ax1.set_ylabel('MI Between Survival and Feature')
    plt.xticks(np.arange(len(labels)), labels, rotation=90)
    plt.bar(np.arange(len(labels)), values)

    # The Titanic dataset provides a familiar, intuitive example available in the public
    # domain. In itself, however, it is not a good fit for solving by sampling. Run naively on
    # this dataset, it finds numerous good solutions but is unlikely to find the exact optimal solution.
    # There are many techniques for reformulating problems for the D-Wave system that can
    # improve performance on various metrics, some of which can help narrow down good solutions
    # to closer approach an optimal solution.
    # This demo solves the problem for just the highest-scoring features.

    # Select 8 features with the top MI ranking found above.
    keep = 8

    sorted_scores = sorted(scores.items(),
                           key=lambda pair: pair[1],
                           reverse=True)
    dataset = dataset[[column[0]
                       for column in sorted_scores[0:keep]] + ["survived"]]
    features = list(set(dataset.columns).difference(('survived', )))

    # Build a QUBO that maximizes MI between survival and a subset of features
    bqm = dimod.BinaryQuadraticModel.empty(dimod.BINARY)

    # Add biases as (negative) MI with survival for each feature
    for feature in features:
        mi = mutual_information(prob(dataset[['survived', feature]].values), 1)
        bqm.add_variable(feature, -mi)

    # Add interactions as (negative) MI with survival for each set of 2 features
    for f0, f1 in itertools.combinations(features, 2):
        cmi_01 = conditional_mutual_information(
            prob(dataset[['survived', f0, f1]].values), 1, 2)
        cmi_10 = conditional_mutual_information(
            prob(dataset[['survived', f1, f0]].values), 1, 2)
        bqm.add_interaction(f0, f1, -cmi_01)
        bqm.add_interaction(f1, f0, -cmi_10)

    bqm.normalize()  # Normalize biases & interactions to the range -1, 1

    # Set up a QPU sampler with a fully-connected graph of all the variables
    qpu_sampler = DWaveSampler(solver={'qpu': True})

    embedding = find_clique_embedding(
        bqm.variables,
        16,
        16,
        4,  # size of the chimera lattice
        target_edges=qpu_sampler.edgelist)

    sampler = FixedEmbeddingComposite(qpu_sampler, embedding)

    # For each number of features, k, penalize selection of fewer or more features
    selected_features = np.zeros((len(features), len(features)))
    for k in range(1, len(features) + 1):
        kbqm = bqm.copy()
        kbqm.update(dimod.generators.combinations(
            features, k, strength=6))  # Determines the penalty

        sample = sampler.sample(kbqm, num_reads=10000).first.sample

        for fi, f in enumerate(features):
            selected_features[k - 1, fi] = sample[f]

    # Plot the best feature set per number of selected features
    ax2 = plt.subplot(1, 2, 2)
    ax2.set_title("Best Feature Selection")
    ax2.set_ylabel('Number of Selected Features')
    ax2.set_xticks(np.arange(len(features)))
    ax2.set_xticklabels(features, rotation=90)
    ax2.set_yticks(np.arange(len(features)))
    ax2.set_yticklabels(np.arange(1, len(features) + 1))
    # Set a grid on minor ticks
    ax2.set_xticks(np.arange(-0.5, len(features)), minor=True)
    ax2.set_yticks(np.arange(-0.5, len(features)), minor=True)
    ax2.grid(which='minor', color='black')
    ax2.imshow(selected_features, cmap=colors.ListedColormap(['white', 'red']))

    plots_path = os.path.join(demo_path, "plots.png")
    plt.savefig(plots_path, bbox_inches="tight")
    print("Your plots are saved to {}".format(plots_path))
def annealing(instance, TEST, prob=0.25, seed=42,
              K=1, overwrite_pickles=False, draw_figures=False,
              annealing_time=[2, 20, 200],  # Microseconds
              chain_strengths=[0.1, 0.2, 0.5, 1, 2, 5, 10],
              penalties=[1.0, 2.0, 5.0],
              samples=100, sampler='Advantage_system1.1'):

    if sampler == 'Advantage_system1.1':
        chip = 'pegasus'
    else:
        chip = 'chimera'

    # Store the results in csv files
    dir_path = os.path.dirname(os.path.abspath(__file__))
    embedding_path = os.path.join(dir_path, "results/embedding/")
    if sampler == 'DW_2000Q_6':
        results_path = os.path.join(dir_path, "results/dwave_chimera/")
    elif sampler == 'Advantage_system1.1':
        results_path = os.path.join(dir_path, "results/dwave_pegasus/")

    if instance == 'spreadsheet':
        # spreadsheet_name = "erdos_" + \
        #     str(int(100*prob)) + '_graphs_with_opt.xlsx'
        # spreadsheet_name = "erdos_" + \
        #     str(int(100*prob)) + '_graphs.xlsx'
        # spreadsheet_name = "erdos_" + \
        #     str(int(100*prob)) + '_graphs_' + str(K) + '.xlsx'
        spreadsheet_name = instance + \
            str(int(100*prob)) + '_embedding_' + chip + '_' + str(K) + '.xlsx'
        spreadsheet_name = os.path.join(embedding_path, spreadsheet_name)
        input_data = pd.read_excel(spreadsheet_name)
        n0 = 0
        N = input_data.shape[0]
        file_name = instance + str(int(100*prob)) + '_annealing' + str(K)
        K = 1
    elif instance == 'erdos':
        # Parameters for random graphs
        N = 51
        n0 = 3
        K = 5  # number of graphs
        seed = 1
        instance = "erdos_" + str(int(100*prob))
        file_name = instance + '_embedding'
    elif instance == 'cycle':
        # Parameters for cycles
        N = 200
        n0 = 100
        file_name = instance + '_embedding'
    elif instance == 'devil':
        # Parameters for devil graphs
        N = 10
        n0 = 8
        file_name = instance + '_embedding'
    else:
        print("Graph type not implemented")
        return()

    # If results directory does not exist, we create it
    if not(os.path.exists(results_path)):
        print('Results directory ' + results_path +
              ' does not exist. We will create it.')
        os.makedirs(results_path)

    file_name = os.path.join(results_path, file_name)

    # time horizons and time limit in seconds
    if TEST:
        random.seed(seed)

    # Graph corresponding to D-Wave 2000Q or Pegasus
    qpu = DWaveSampler(solver=sampler)
    qpu_edges = qpu.edgelist
    qpu_nodes = qpu.nodelist
    X = nx.Graph()
    X.add_nodes_from(qpu_nodes)
    X.add_edges_from(qpu_edges)
    # nx.write_edgelist(X, os.path.join(results_path,"X.edgelist"))
    # X = dnx.chimera_graph(16, node_list=qpu_nodes, edge_list=qpu_edges)
    # X = dnx.pegasus_graph(16, node_list=qpu_nodes, edge_list=qpu_edges)

    if 'opt_obj_k_1' in input_data.columns:
        opt_sols = True
    else:
        opt_sols = False

    columns = ['formulation', 'chain_strength',
               'embedding', 'chain_breaks', 'chain_breaks_err', 'opt_fraction',
               'embedding_fixed', 'chain_breaks_fixed', 'chain_breaks_err_fixed', 'opt_fraction_fixed'
               ]
    solution = pd.DataFrame(columns=columns)

    for k in range(K):
        for n in range(n0, N):
            print(n)

            # Graph generation
            if instance == "spreadsheet":
                # Generate graph from spreadsheet
                Input = nx.Graph()
                edges = ast.literal_eval(input_data.edges[n])
                Input.add_edges_from(edges)
                alpha = 0

            elif instance == "cycle":
                # Cycle graphs
                Input = nx.cycle_graph(n)
                temp['id'] = "cycle_" + str(n)
                alpha = np.floor(n / 2)
            elif instance == "devil":
                # Devil graphs
                Input, alpha = devil_graphs(n)
                temp['id'] = "devil_rank_" + str(n)
            else:
                # Random graphs
                Input = nx.erdos_renyi_graph(n, prob)
                temp['id'] = "random_" + \
                    str(n) + "_" + str(prob) + "_" + str(k)
                alpha = 0

            # Input graph parameters

            # Define samplers: simulated annealing or Dwave (with automatic embedding)
            samplers = dict()
            samplers['simann'] = neal.SimulatedAnnealingSampler()
            samplers['dwave_embed'] = EmbeddingComposite(qpu)

            if DRY_RUN:
                pass
            else:

                # Problem reformulations
                # Nonlinear and Linear (Laserre) reformulation
                reforms = ['n', 'l']
                embeddable = dict.fromkeys(reforms, True)

                # Import embeddings
                best_embed = False

                if best_embed:
                    best_embedding = dict.fromkeys(reforms, {})
                    best_embedding['n'] = ast.literal_eval(
                        input_data.heur_best_embed_n[n])
                    if len(best_embedding['n']) == 0:
                        embeddable['n'] = False
                        print('No embedding available for nonlinear reformulation')

                    best_embedding['l'] = ast.literal_eval(
                        input_data.heur_best_embed_l[n])

                    if len(best_embedding['l']) == 0:
                        embeddable['l'] = False
                        print('No embedding available for linear reformulation')

                    experiments = ['', '_fixed']
                else:
                    experiments = ['']

                embeddable_reforms = (
                    reform for reform in reforms if embeddable[reform])

                for reform in embeddable_reforms:

                    for rho in penalties:

                        opt_matrix = np.zeros(
                            [len(annealing_time), len(chain_strengths), len(experiments)])
                        if reform == 'n':
                            Q, offset = nonlinear(Input, M=rho, draw=False)
                        elif reform == 'l':
                            Q, offset = linear(Input, M=rho, draw=False)

                        bqm = dimod.BinaryQuadraticModel.from_qubo(
                            Q, offset=offset)
                        edges = list(itertools.chain(
                            bqm.quadratic, ((v, v) for v in bqm.linear)))

                        G = nx.Graph()
                        G.add_edges_from(edges)

                        # Add fixed embedding sampler if allowed
                        if best_embed:
                            # fail = 0
                            # min_length = X.number_of_nodes()
                            # for n_h in range(n_heur):
                            #     h_embed = mm.find_embedding(
                            #         G, X, timeout=time_limit, random_seed=n_h)
                            #     count = 0
                            #     for _, value in h_embed.items():
                            #         count += len(value)
                            #     if count == 0:
                            #         fail += 1
                            #     elif count < min_length:
                            #         best_embed = h_embed
                            #         min_length = count
                            #     samplers['dwave'] = FixedEmbeddingComposite(
                            #         DWaveSampler(), embedding=best_embed)
                            # else:
                            #     samplers.pop('dwave', None)

                            samplers['dwave'] = FixedEmbeddingComposite(
                                qpu, embedding=best_embedding[reform])

                        pickle_path = os.path.join(
                            results_path, file_name, str(n), reform)
                        if not(os.path.exists(pickle_path)):
                            print('Pickled results directory ' + pickle_path +
                                  ' does not exist. We will create it.')
                            os.makedirs(pickle_path)

                        idx_i = 0
                        for ann_time in annealing_time:
                            results = pd.DataFrame(columns=columns)

                            results_name = instance + '_chains_' + \
                                reform + '_' + str(ann_time) + '.csv'
                            results_name = os.path.join(
                                results_path, results_name)

                            temp = dict()

                            idx_j = 0
                            for c in chain_strengths:

                                # Identification
                                temp['formulation'] = reform
                                temp['penalty'] = rho
                                if c == "d":
                                    from dwave.embedding.chain_strength import uniform_torque_compensation
                                    chain_strength = uniform_torque_compensation(
                                        bqm)
                                    temp['chain_strength'] = chain_strength/max(
                                        abs(min(Q.values())), abs(max(Q.values())))
                                else:
                                    # chain_strength = max(Q.min(), Q.max(), key=abs)*c
                                    chain_strength = max(
                                        abs(min(Q.values())), abs(max(Q.values())))*c
                                    temp['chain_strength'] = c

                                idx_k = 0
                                for kind in experiments:
                                    pickle_name = "chain_str_" + \
                                        str(c) + "_" + str(ann_time) + \
                                        "_" + str(int(rho)) + kind + ".p"
                                    pickle_name = os.path.join(
                                        pickle_path, pickle_name)
                                    if os.path.exists(pickle_name) and not overwrite_pickles:
                                        response = pickle.load(
                                            open(pickle_name, "rb"))
                                        if response is None:
                                            embeddable[reform] = False
                                    else:
                                        # Here is where the D-Wave run happens
                                        if kind == '_fixed' and best_embed:
                                            response = samplers['dwave'].sample(
                                                bqm, num_reads=samples, return_embedding=True, chain_strength=chain_strength, annealing_time=ann_time)
                                        elif kind == '':
                                            try:
                                                response = samplers['dwave_embed'].sample(
                                                    bqm, num_reads=samples, return_embedding=True, chain_strength=chain_strength, annealing_time=ann_time)
                                            except ValueError as e:
                                                embeddable[reform] = False
                                                response = None
                                                print(pickle_name)
                                                print(e)
                                                print('error type: ', type(e))

                                        pickle.dump(response, open(
                                            pickle_name, "wb"), protocol=pickle.HIGHEST_PROTOCOL)

                                    if embeddable[reform]:
                                        temp['embedding' +
                                             kind] = response.info['embedding_context']['embedding']

                                        # plot_energies(response, title=pickle_name)

                                        if 'chain_break_fraction' in response.record.dtype.names:
                                            temp['chain_breaks' +
                                                 kind] = np.mean(response.record.chain_break_fraction)
                                            temp['chain_breaks_err' +
                                                 kind] = np.std(response.record.chain_break_fraction)

                                        energies = response.data_vectors['energy']
                                        occurrences = response.data_vectors['num_occurrences']

                                        counts = {}
                                        for index, energy in enumerate(energies):
                                            if energy in counts.keys():
                                                counts[energy] += occurrences[index]
                                            else:
                                                counts[energy] = occurrences[index]

                                        total_counts = sum(occurrences)
                                        if opt_sols:
                                            temp['opt_fraction' + kind] = sum(counts[key] for key in [
                                                -input_data.opt_obj_k_1[n]] if key in counts.keys())/total_counts

                                            opt_matrix[idx_i, idx_j, idx_k] = sum(
                                                counts[key] for key in [-input_data.opt_obj_k_1[n]] if key in counts.keys())/total_counts

                                        else:
                                            temp['opt_fraction' + kind] = sum(
                                                counts[key] for key in [min(energies)] if key in counts.keys())/total_counts

                                            opt_matrix[idx_i, idx_j, idx_k] = sum(
                                                counts[key] for key in [min(energies)] if key in counts.keys())/total_counts

                                    idx_k += 1

                                results = results.append(
                                    temp, ignore_index=True)
                                solution = solution.append(
                                    temp, ignore_index=True)

                                solution.to_csv(file_name + ".csv")

                                idx_j += 1

                            if draw_figures:
                                plt.figure()

                                plt.errorbar(results.chain_strength, results.chain_breaks,
                                             yerr=results.chain_breaks_err, fmt='o', capsize=3)
                                plt.errorbar(results.chain_strength, results.chain_breaks_fixed,
                                             yerr=results.chain_breaks_err_fixed, fmt='o', capsize=3)
                                plt.legend(
                                    ['Random Embedding', 'Best Embedding'])
                                plt.xscale('log')
                                plt.ylabel('Chain break fraction')
                                plt.xlabel(
                                    'Chain strength (factor of maximum coefficient in Q)')
                                plt.title(
                                    'Chain break fraction vs. chain strength  \n (ref = ' + reform + ', t_ann = ' + str(ann_time) + ', rho = ' + str(int(rho)) + ')')

                                plt.figure()

                                plt.plot(results.chain_strength,
                                         results.opt_fraction, 'o', linestyle='--')
                                # plt.plot(results.chain_strength,
                                #         results.opt_fraction, 'o', linestyle='--')
                                # plt.plot(results.chain_strength,
                                #         results.feas_fraction, 's', linestyle='--')

                                plt.plot(results.chain_strength,
                                         results.opt_fraction_fixed, 'o', linestyle='-')
                                # plt.plot(results.chain_strength,
                                #         results.opt_fraction_fixed, 'o', linestyle='-')
                                # plt.plot(results.chain_strength,
                                #         results.feas_fraction_fixed, 's', linestyle='-')

                                plt.ylim([0, 1])
                                plt.xscale('log')
                                plt.ylabel('Optimal solution fraction')
                                plt.xlabel(
                                    'Chain strength (factor of maximum coefficient in Q)')
                                plt.title(
                                    'Solutions found fraction vs. chain strength  \n (ref = ' + reform + ', t_ann = ' + str(ann_time) + ', rho = ' + str(int(rho)) + ')')
                                plt.legend(['Random Embedding',
                                            'Best Embedding'])
                            idx_i += 1

                        if draw_figures:
                            for k in range(len(experiments)):
                                fig, ax = plt.subplots()

                                colormesh = ax.imshow(
                                    opt_matrix[:, 4:, k], vmin=0, vmax=1
                                )
                                ax.set_title(
                                    'Minimum solutions probability embedding' + experiments[k] + ' \n (ref=' + reform + ', ' + chip + ')')
                                plt.xlabel(
                                    'Chain strength (factor of maximum coefficient in Q)')
                                plt.ylabel('Annealing time [microseconds]')
                                fig.colorbar(colormesh, ax=ax)
                                plt.yticks([0, 1, 2])
                                fig.canvas.draw()

                                labels_x = [item.get_text()
                                            for item in ax.get_xticklabels()]
                                labels_x = chain_strengths[3:]
                                labels_y = [item.get_text()
                                            for item in ax.get_yticklabels()]
                                labels_y = annealing_time

                                ax.set_xticklabels(labels_x)
                                ax.set_yticklabels(labels_y)

                            plt.show()

    sol_total = pd.DataFrame.from_dict(solution)

    sol_total.to_excel(os.path.join(results_path, file_name + ".xlsx"))
def main(args):
    num_reads = int(args.nreads)
    dry_run = bool(args.dry_run)
    if dry_run:
        print("WARNING: dry run. There will be no results at the end.")

    # truth-level:
    x = [5, 8, 12, 6, 2]

    # response matrix:
    R = [[1, 2, 0, 0, 0], [1, 2, 1, 1, 0], [0, 1, 3, 2, 0], [0, 2, 2, 3, 2],
         [0, 0, 0, 1, 2]]

    # pseudo-data:
    d = [12, 32, 40, 15, 10]

    # convert to numpy arrays
    x = np.array(x, dtype='uint8')
    R = np.array(R, dtype='uint8')
    b = np.array(d, dtype='uint8')

    # closure test
    b = np.dot(R, x)

    n = 4
    N = x.shape[0]

    print("INFO: N bins:", N)
    print("INFO: n-bits encoding:", n)

    lmbd = np.uint8(args.lmbd)  # regularization strength
    D = laplacian(N)

    # convert to bits
    x_b = discretize_vector(x, n)
    b_b = discretize_vector(b, n)
    R_b = discretize_matrix(R, n)
    D_b = discretize_matrix(D, n)

    print("INFO: Truth-level x:")
    print(x, x_b)
    print("INFO: pseudo-data b:")
    print(b, b_b)
    print("INFO: Response matrix:")
    print(R)
    print(R_b)
    print("INFO: Laplacian operator:")
    print(D)
    print(D_b)
    print("INFO: regularization strength:", lmbd)

    # Create QUBO operator

    # linear constraints
    h = {}
    for j in range(n * N):
        idx = (j)
        h[idx] = 0
        for i in range(N):
            h[idx] += (R_b[i][j] * R_b[i][j] - 2 * R_b[i][j] * b[i] +
                       lmbd * D_b[i][j] * D_b[i][j])

    # quadratic constraints
    J = {}
    for j in range(n * N):
        for k in range(j + 1, n * N):
            idx = (j, k)
            J[idx] = 0
            for i in range(N):
                J[idx] += 2 * (R_b[i][j] * R_b[i][k] +
                               lmbd * D_b[i][j] * D_b[i][k])

    # QUBO
    bqm = dimod.BinaryQuadraticModel(linear=h,
                                     quadratic=J,
                                     offset=0.0,
                                     vartype=dimod.BINARY)
    print("INFO: solving the QUBO model...")
    print("INFO: running on QPU")
    hardware_sampler = DWaveSampler()
    print("INFO: finding optimal minor embedding...")
    embedding = get_embedding_with_short_chain(
        J, tries=1, processor=hardware_sampler.edgelist, verbose=True)
    if embedding is None:
        raise ValueError("ERROR: could not find embedding")

    sampler = FixedEmbeddingComposite(hardware_sampler, embedding)
    print("INFO: creating DWave sampler...")
    print("INFO: annealing (n_reads=%i) ..." % num_reads)
    print("INFO: Connected to", hardware_sampler.properties['chip_id'])
    print("INFO: max anneal schedule points: {}".format(
        hardware_sampler.properties["max_anneal_schedule_points"]))
    print("INFO: annealing time range: {}".format(
        hardware_sampler.properties["annealing_time_range"]))
    schedule = make_reverse_anneal_schedule(s_target=0.99,
                                            hold_time=1,
                                            ramp_up_slope=0.2)
    neal_sampler = neal.SimulatedAnnealingSampler()
    initial_result = sampler.sample(bqm, num_reads=num_reads).aggregate()
    neal_result = neal_sampler.sample(bqm, num_reads=num_reads).aggregate()
    reverse_anneal_params = dict(anneal_schedule=schedule,
                                 initial_state=initial_result.first.sample,
                                 reinitialize_state=True)
    solver_parameters = {
        'num_reads': num_reads,
        'auto_scale': True,
        **reverse_anneal_params
    }

    print(schedule)
    result = sampler.sample(bqm, **solver_parameters)

    reverse_anneal_params = dict(anneal_schedule=schedule,
                                 initial_state=neal_result.first.sample,
                                 reinitialize_state=True)
    solver_parameters = {
        'num_reads': num_reads,
        'auto_scale': True,
        **reverse_anneal_params
    }

    result2 = sampler.sample(bqm, **solver_parameters)
    print("Neal results")
    print_results(neal_result, n)
    print("Reverse annealing on Neal results")
    print_results(result2, n)
    print("QPU results")
    print_results(initial_result, n)
    print("Reverse annealing on QPU results")
    print_results(result, n)
    Q[(i, i)] += -1
    Q[(j, j)] += -1
    Q[(i, j)] += 2

# ------- Run our QUBO on the QPU -------
# Set up QPU parameters
chain_strength = 0.1
num_reads = 10

# Run the QUBO on a solver with the specified topology
QPU = DWaveSampler(solver={'topology__type__eq': 'chimera'})
embedding = find_embedding(Q, QPU.edgelist)

print("\nEmbedding found:\n", embedding)

sampler = FixedEmbeddingComposite(QPU, embedding)
response = sampler.sample_qubo(Q,
                               chain_strength=chain_strength,
                               num_reads=num_reads,
                               label='Training - Embedding')

print("\nSampleset:")
print(response)

# ------- Print results to user -------
print("\nSolutions:")
print('-' * 60)
print('{:>15s}{:>15s}{:^15s}{:^15s}'.format('Set 0', 'Set 1', 'Energy',
                                            'Cut Size'))
print('-' * 60)
for sample, E in response.data(fields=['sample', 'energy']):
Beispiel #13
0
if run_dwave != 0:
    # Sampler/Annealing parameters
    params["chainstrength_P"] = float(0.5)
    params["chainstrength"] = float(
        params["chainstrength_P"] * params["max_bias_final"]
    )  # Default 1 | Good rule of thumb is to have the same order of magnitude as Qubo.
    params["numruns"] = 10  # Default 1000
    params["anneal_time"] = 20  # Default 20
    #-----------------------------

    print(
        f"Running D-Wave w/ chainstrength {params['chainstrength_P']:.2f}|{params['chainstrength']:.2f} (%|final) & numruns {params['numruns']:d} & anneal_time {params['anneal_time']:d}"
    )

    composite = FixedEmbeddingComposite(sampler, embedding=embedding)
    response = composite.sample_qubo(Qubo,
                                     annealing_time=params["anneal_time"],
                                     chain_strength=params["chainstrength"],
                                     num_reads=params["numruns"])

    print("Results:\n")
    print_result(response, params, time=0, mute=0, file=1)

    #dwave.inspector.show(response)

# ---------------------- \| Utility Functions |/ ---------------------- #

# minimum possible energy: -283987.43787980796 |\ 173.045734368

# maximum possible energy: -2466607.9822456012  |\  480.1178932
def objective(args):
    lmdb = args['lmbd']
    num_reads = args['num_reads']
    n = args['num_bits']
    annealing_time = args['annealing_time']

    x_b = discretize_vector(x, n)
    z_b = discretize_vector(z, n)
    d_b = discretize_vector(d, n)
    R_b = discretize_matrix(R0, n)
    D_b = discretize_matrix(D, n)

    # Create QUBO operator
    #Q = np.zeros([n*N, n*N])
    S = {}
    h = {}
    J = {}

    # linear constraints
    for j in range(n * N):
        h[(j)] = 0
        for i in range(N):
            h[(j)] += (R_b[i][j] * R_b[i][j] - 2 * R_b[i][j] * d[i] +
                       lmbd * D_b[i][j] * D_b[i][j])
        S[(j, j)] = h[(j)]

    # quadratic constraints
    for j in range(n * N):
        for k in range(j + 1, n * N):
            J[(j, k)] = 0
            for i in range(N):
                J[(j, k)] += 2 * (R_b[i][j] * R_b[i][k] +
                                  lmbd * D_b[i][j] * D_b[i][k])
            S[(j, k)] = J[(j, k)]

    bqm = dimod.BinaryQuadraticModel(linear=h,
                                     quadratic=J,
                                     offset=0.0,
                                     vartype=dimod.BINARY)

    embedding = get_embedding_with_short_chain(
        S, tries=5, processor=hardware_sampler.edgelist, verbose=False)

    sampler = FixedEmbeddingComposite(hardware_sampler, embedding)
    solver_parameters = {
        'num_reads': num_reads,
        'auto_scale': True,
        'annealing_time': annealing_time,  # default: 20 us
        #'anneal_schedule': anneal_sched_custom(id=3),
        'num_spin_reversal_transforms': 2,  # default: 2
    }
    results = sampler.sample(bqm, **solver_parameters).aggregate()
    best_fit = results.first
    energy_bestfit = best_fit.energy
    q = np.array(list(best_fit.sample.values()))
    y = compact_vector(q, n)

    dof = N - 1
    chi2, p = stats.chisquare(y, z, dof)
    chi2dof = chi2 / float(dof)

    hamm = hamming(z_b, q)

    return {
        'loss': hamm,  # chi2dof,
        'status': hp.STATUS_OK,
        'diffxs': y,
        'q': q,
        'hamming': hamm,
        'lmbd': lmbd,
        'num_reads': num_reads,
        'num_bits': n,
        'annealing_time': annealing_time,
    }
Beispiel #15
0
    def solve(self):

        self.n_bins_truth = self._data.x.shape[0]
        self.n_bins_reco = self._data.d.shape[0]

        if not self._data.R.shape[1] == self.n_bins_truth:
            raise Exception(
                "Number of bins at truth level do not match between 1D spectrum (%i) and response matrix (%i)"
                % (self.n_bins_truth, self._data.R.shape[1]))
        if not self._data.R.shape[0] == self.n_bins_reco:
            raise Exception(
                "Number of bins at reco level do not match between 1D spectrum (%i) and response matrix (%i)"
                % (self.n_bins_reco, self._data.R.shape[0]))

        self.convert_to_binary()

        print("INFO: N bins:", self._data.x.shape[0])
        print("INFO: n-bits encoding:", self.rho)

        print("INFO: Signal truth-level x:")
        print(self._data.x)
        print("INFO: pseudo-data b:")
        print(self._data.d)
        print("INFO: Response matrix:")
        print(self._data.R)

        self.Q = self.make_qubo_matrix()
        self._bqm = dimod.BinaryQuadraticModel.from_numpy_matrix(self.Q)

        print("INFO: solving the QUBO model (size=%i)..." % len(self._bqm))

        if self.backend in [Backends.cpu]:
            print("INFO: running on CPU...")
            self._results = dimod.ExactSolver().sample(self._bqm)
            self._status = StatusCode.success

        elif self.backend in [Backends.sim]:
            num_reads = self.solver_parameters['num_reads']
            print("INFO: running on simulated annealer (neal), num_reads=",
                  num_reads)

            sampler = neal.SimulatedAnnealingSampler()
            self._results = sampler.sample(self._bqm,
                                           num_reads=num_reads).aggregate()
            self._status = StatusCode.success

        elif self.backend in [
                Backends.qpu, Backends.qpu_hinoise, Backends.qpu_lonoise,
                Backends.hyb, Backends.qsolv
        ]:
            print("INFO: running on QPU")

            config_file = self.get_config_file()
            self._hardware_sampler = DWaveSampler(config_file=config_file)
            print("INFO: QPU configuration file:", config_file)

            print("INFO: finding optimal minor embedding...")

            n_bits_avg = np.mean(self._encoder.rho)
            thr = 4. / float(self.n_bins_truth)
            n_tries = 5 if n_bits_avg < thr else 10

            J = qubo_quadratic_terms_from_np_array(self.Q)
            embedding = self.find_embedding(J, n_tries)

            print("INFO: creating DWave sampler...")
            sampler = FixedEmbeddingComposite(self._hardware_sampler,
                                              embedding)

            if self.backend in [
                    Backends.qpu, Backends.qpu_hinoise, Backends.qpu_lonoise
            ]:
                print("INFO: Running on QPU")
                params = self.solver_parameters
                self._results = sampler.sample(self._bqm, **params).aggregate()
                self._status = StatusCode.success

            elif self.backend in [Backends.hyb]:
                print("INFO: hybrid execution")
                import hybrid

                num_reads = self.solver_parameters['num_reads']
                # Define the workflow
                # hybrid.EnergyImpactDecomposer(size=len(bqm), rolling_history=0.15)
                iteration = hybrid.RacingBranches(
                    hybrid.InterruptableTabuSampler(),
                    hybrid.EnergyImpactDecomposer(size=len(self._bqm) // 2,
                                                  rolling=True)
                    | hybrid.QPUSubproblemAutoEmbeddingSampler(
                        num_reads=num_reads)
                    | hybrid.SplatComposer()) | hybrid.ArgMin()
                #workflow = hybrid.LoopUntilNoImprovement(iteration, convergence=3)
                workflow = hybrid.Loop(iteration, max_iter=20, convergence=3)

                init_state = hybrid.State.from_problem(self._bqm)
                self._results = workflow.run(init_state).result().samples
                self._status = StatusCode.success

                # show execution profile
                print("INFO: timing:")
                workflow.timers
                hybrid.print_structure(workflow)
                hybrid.profiling.print_counters(workflow)

            elif self.backend in [Backends.qsolv]:
                print("INFO: using QBsolve with FixedEmbeddingComposite")
                self._results = QBSolv().sample_qubo(S,
                                                     solver=sampler,
                                                     solver_limit=5)
                self._status = StatusCode.success

            else:
                raise Exception("ERROR: unknown backend", self.backend)

        print("DEBUG: status =", self._status)
        return self._status