def construct_QAOA(G, p, minimizer_kwargs={ 'method': 'BFGS', 'options': { 'ftol': 1.0e-2, 'xtol': 1.0e-2, 'disp': True } }, init_betas=None, init_gammas=None, vqe_options={ 'disp': print, 'return_all': True }): # setting up connection with the QVM qvm_connection = api.QVMConnection() # labelling qubits according to graph qubits = [int(n) for n in list(G.nodes)] # turning unweighted graphs into weighted graph with weight wij = 1 for (u, v) in G.edges(): if G.edges[u, v] == {}: G.edges[u, v]['weight'] = 1 # constructing cost and mixer hamiltonian elements in list # N.B. This algorithm only works if all the terms in the cost Hamiltonian commute with each other. Hc = hamiltonians.cost(G) Hb = hamiltonians.mixer(G) return QAOA(qvm_connection, qubits, steps=p, cost_ham=Hc, ref_ham=Hb, minimizer_kwargs=minimizer_kwargs, vqe_options=vqe_options)
""" Created on Thu Jul 2 13:37:11 2020 @author: joost """ from hamiltonians import cost,mixer import networkx as nx import pyquil.latex import pyquil.api as api from grove.pyqaoa.qaoa import QAOA G = nx.random_regular_graph(2,3) Hc = cost(G) Hb = mixer(G) qvm_connection = api.QVMConnection() qubits = [int(n) for n in list(G.nodes)] Q = QAOA(qvm_connection, qubits, steps=2, cost_ham = Hc, ref_ham= Hb) params = [3,7,2,5] # b1, b2, g1, g2 prog = Q.get_parameterized_program() circuit = prog(params) # print to latex doc s = pyquil.latex.to_latex(circuit) print(s)
# close all earlier figures plt.close('all') # setting up connection with the QVM qvm_connection = api.QVMConnection() # constructing graph, setting p and the desired number of samples G = nx.erdos_renyi_graph(5, 0.5) qubits = [int(n) for n in list(G.nodes)] p = 4 n_samples = 1024 # constructing cost and mixer hamiltonian elements in list # N.B. This algorithm only works if all the terms in the cost Hamiltonian commute with each other. Hc = hamiltonians.cost(G) Hb = hamiltonians.mixer(G) # setting up the QAOA circuit initial_betas = 0.8 initial_gammas = 0.35 minimizer_kwargs = { 'method': 'BFGS', 'options': { 'ftol': 1.0e-2, 'xtol': 1.0e-2, 'disp': False } } if type(initial_betas) == float: p_start = 1
def interp_pyquil(G, p, initial_betas=0.8, initial_gammas=0.35, minimizer_kwargs={ 'method': 'BFGS', 'options': { 'ftol': 1.0e-2, 'xtol': 1.0e-2, 'disp': True } }, n_samples=1024, plot_hist=False): # timing start start = time.time() # setting up connection with the QVM qvm_connection = api.QVMConnection() # labelling qubits according to graph qubits = [int(n) for n in list(G.nodes)] # turning unweighted graphs into weighted graph with weight wij = 1 for (u, v) in G.edges(): if G.edges[u, v] == {}: G.edges[u, v]['weight'] = 1 # constructing cost and mixer hamiltonian elements in list # N.B. This algorithm only works if all the terms in the cost Hamiltonian commute with each other. Hc = hamiltonians.cost(G) Hb = hamiltonians.mixer(G) # saving data from all layers results = {} # Entering Loop if type(initial_betas) == float: p_start = 1 else: p_start = len(initial_betas) for i in range(p_start, p + 1): QAOA_inst = QAOA(qvm_connection, qubits, steps=i, cost_ham=Hc, ref_ham=Hb, init_betas=initial_betas, init_gammas=initial_gammas, minimizer_kwargs=minimizer_kwargs, vqe_options={ 'disp': print, 'return_all': True }) # calculating angles using VQE (simulation) print(" p =", i) betas, gammas = QAOA_inst.get_angles() print("Values of betas:", betas) print("Values of gammas:", gammas, '\n') # resulting bitstrings and the most common one print("\nAnd the most common measurement is... ") most_common_bitstring, results_counter = QAOA_inst.get_string( betas, gammas, samples=n_samples) print(most_common_bitstring) print(tuple(qubits)) # graphing distribution if plot_hist: counter_histogram(results_counter, title=" p = " + str(p)) # timing final end = time.time() print("Time ", end - start) # saving data from this layer results_i = {} results_i['p'] = i results_i['time'] = end - start results_i['graph'] = nx.to_dict_of_dicts(G) results_i['n_nodes'] = len(G.nodes) results_i['n_edges'] = len(G.edges) results_i['most_common_bistring'] = most_common_bitstring results_i['qubit_order'] = tuple(qubits) results_i['counter'] = dict(results_counter) results_i['n_Fp_evals'] = len(QAOA_inst.result['expectation_vals']) results_i['n_samples'] = n_samples results_i['Fp'] = -QAOA_inst.result['fun'] results_i['Fp_sampled'] = sum([ objective_value(G, k, qubits) * v for k, v in results_counter.items() ]) / n_samples results_i['cutvalue_best'] = cutvalue_best(G, results_counter, qubits) results_i['cutvalue_most_sampled'] = cutvalue_most_sampled( G, results_counter, qubits) results_i['minimizer_method'] = minimizer_kwargs['method'] # time symmetry if all(gammas > 0) and all(betas > 0): results_i['gammas'] = gammas.copy() results_i['betas'] = betas.copy() else: results_i['gammas'] = -gammas.copy() results_i['betas'] = -betas.copy() results[i] = results_i # setting next angles initial_betas = next_angles(betas) initial_gammas = next_angles(gammas) print("Values of betas ansatz:", initial_betas) print("Values of gammas ansatz:", initial_gammas, '\n') return results
def run_experiment(G, p, optimizer, qvm_connection, n_shots=8192, print_result=False): '''Runs (pyQuil) QAOA experiment with the given parameters Inputs Returns a dictionary with the following keys (some are yet to be implemented) - energy - time (in seconds) - iterations - max-cut objective - solution - solution objective ''' n = len(G) # number of nodes / qubits qubits = [int(n) for n in list(G.nodes)] # list of qubits # constructing cost and mixer hamiltonian elements in list Hc = hamiltonians.cost(G) Hb = hamiltonians.mixer(G) # setting up the QAOA circuit initial_beta = 0 initial_gamma = 0 QAOA_inst = QAOA(qvm_connection, qubits, steps=p, cost_ham=Hc, ref_ham=Hb, init_betas=initial_beta, init_gammas=initial_gamma, minimizer_kwargs=optimizer, vqe_options={'samples': n_shots}) # calculating angles using VQE (simulation) angles = QAOA_inst.get_angles() betas, gammas = angles # resulting bitstrings and the most common one most_common_bitstring, results_counter = QAOA_inst.get_string( betas, gammas, samples=n_shots) # Results energy = None time = None iterations = None objective = None solution = most_common_bitstring solution_objective = None distribution = results_counter angles = angles if print_result: print('energy:', energy) print('time:', time, 's') print('max-cut objective:', objective) print('solution:', solution) print('solution objective:', solution_objective) print('anlges:', angles) return { 'energy': energy, 'time': time, 'iterations': iterations, 'max-cut objective': objective, 'solution': solution, 'solution objective': solution_objective, 'distribution': distribution, 'angles': angles }