def main(args=None): """Brings all methods together to return a traffic routing instance. Args: raw_args (list, optional): list of strings to describe arguments. Defaults to None, but function fails if required arguments are not included Returns: list: In position 0, returns the graph of problem, In position 1, a Numpy Array with shape "no_cars" by "no_routes" given by argument for the generated routes for each car with the route descibed as a sequence of nodes of the graph. """ if args == None: args = parse() G = import_map("melbourne_2.pkl") cpus = mp.cpu_count() pool = mp.Pool(cpus) while True: cars_origin_destination = generate_start_finish_points( G, args["no_cars"]) params = ( (G, start_destination, args["no_routes"]) for start_destination in list(cars_origin_destination.values())) results = pool.starmap(generate_routes, params) results = np.array(results, dtype=object) if results.shape == ( args["no_cars"], args["no_routes"] ): #If results returns "no_cars" x "no_routes" shape, then it is valid break pool.close() pool.join() if args["visual"] == True: visualise(G, results) return G, results
def main(args=None): #Generate and save valid qubos if args == None: args = parse() print("Arguments: {}".format(args)) print("Now generating QUBOs with {} cars {} routes".format( args["no_cars"], args["no_routes"])) for qubo_no in tqdm(range(args["no_samples"])): generate_valid_qubo(args, qubo_no)
def main(args=None): start = time() if args == None: args = parse() #Load QUBO and reduce, then check existing classical solution with open( 'qubos_{}_car_{}_routes/qubo_{}.pkl'.format( args["no_cars"], args["no_routes"], args["no_samples"]), 'rb') as f: load_data = pkl.load(f) if len(load_data) == 5: qubo, max_coeff, operator, offset, routes = load_data classical_result = None else: qubo, max_coeff, operator, offset, routes, classical_result = load_data qubo, normalize_factor = reduce_qubo(qubo) if classical_result: classical_result._fval /= normalize_factor #Also normalize classical result print("NO CARS: {}, NO ROUTES: {}, SAMPLE: {}\n".format( args["no_cars"], args["no_routes"], args["no_samples"])) #Noise if args["noisy"]: multiplier = args["multiplier"] print( "Simulating with noise...Error mulitplier: {}".format(multiplier)) with open('average_gate_errors.json', 'r') as f: noise_rates = json.load(f) noise_model = build_noise_model(noise_rates, multiplier) else: print("Simulating without noise...") noise_model = None #Initialize QAOA object qaoa = QAOA_Base(qubo=qubo, no_cars=args["no_cars"], no_routes=args["no_routes"], symmetrise=args["symmetrise"], customise=args["customise"], classical_result=classical_result, simulator=args["simulator"], noise_model=noise_model, opt_str=args["optimizer"]) p_max = args["p_max"] fourier_parametrise = args["fourier"] print("QAOA METHODS") print("FOURIER: {}\nINTERP: {}".format(args["fourier"], args["interp"])) print("CUSTOM: {}\nSYMMETR: {}".format(args["customise"], args["symmetrise"])) for p in range(1, p_max + 1): p_start = time() print("\nQAOA p={}. Results below:".format(p)) qaoa.optimizer.set_options(maxeval=100 * (2**p)) if p == 1: qaoa.solve_qiskit_qaoa(p, fourier_parametrise=fourier_parametrise) else: if args["interp"]: next_point = interp_point(qaoa.optimal_point) else: point = qaoa.optimal_point if not args[ "fourier"] else convert_to_fourier_point( qaoa.optimal_point, len(qaoa.optimal_point)) next_point = np.zeros(2 * p) next_point[0:p - 1] = point[0:p - 1] next_point[p:2 * p - 1] = point[p - 1:2 * p - 2] if args["fourier"]: next_point = convert_from_fourier_point(next_point, 2 * p) qaoa.solve_qiskit_qaoa(p, point=next_point, fourier_parametrise=fourier_parametrise) p_end = time() print("Time taken (for this iteration): {}s".format(p_end - p_start)) prob_s = [np.round(prob, 3) for prob in qaoa.prob_s] eval_s = [np.round(e_val, 3) for e_val in qaoa.eval_s] approx_s = [np.round(approx, 3) for approx in qaoa.approx_s] print("\nProbabilities: {}".format(prob_s)) print("Eigenvalue at each p: {}".format(eval_s)) print("Approx Qualities of most_probable_state: {}\n".format(approx_s)) filedir = 'results_{}cars{}routes/'.format(args["no_cars"], args["no_routes"]) p_max = str(args["p_max"]).zfill(2) err_multipler = '{:.2f}'.format( args["multiplier"]) if args["noisy"] else '{:.2f}'.format(0.0) sample = str(args["no_samples"]).zfill(3) if args["noisy"]: filedir += "Noisy_QAOA_p={}_s={}_err={}".format( p_max, sample, err_multipler) else: filedir += "Ideal_QAOA_p={}_s={}_err={}".format( p_max, sample, err_multipler) if args["symmetrise"]: filedir += "_Symm" else: filedir += "_Base" if args["customise"]: filedir += "_Cust" else: filedir += "_Base" if args["fourier"]: filedir += "_FOUR" else: filedir += "_NONE" if args["interp"]: filedir += "_INTP" else: filedir += "_NONE" filedir += "_{}".format(str(args["optimizer"])) print(filedir) #Save results to file save_results = np.append(qaoa.prob_s, qaoa.eval_s) save_results = np.append(save_results, qaoa.approx_s) with open(filedir, 'w') as f: np.savetxt(f, save_results, delimiter=',') result_saved_string = "Results saved in {}".format(filedir) print(result_saved_string) finish = time() print("\nTime taken: {} s".format(finish - start)) print("_" * len(result_saved_string))
def main(args=None): """[summary] Args: raw_args ([type], optional): [description]. Defaults to None. """ start = time() if args == None: args = parse() qubo_no = args["no_samples"] print_to_file("-" * 50) print_to_file("QUBO_{}".format(qubo_no)) #Load generated qubo_no with open( 'qubos_{}_car_{}_routes/qubo_{}.pkl'.format( args["no_cars"], args["no_routes"], qubo_no), 'rb') as f: qubo, max_coeff, operator, offset, routes = pkl.load(f) qubo = QuadraticProgram() qubo.from_ising(operator) x_s, opt_value, classical_result = find_all_ground_states(qubo) print_to_file(classical_result) #Set optimizer method method = args["method"] optimizer = NLOPT_Optimizer(method=method, result_message=False) # optimizer = COBYLA() backend = Aer.get_backend("statevector_simulator") quantum_instance = QuantumInstance(backend=backend) approx_ratios = [] prob_s_s = [] p_max = args["p_max"] no_routes, no_cars = (args["no_routes"], args["no_cars"]) custom = True if custom: initial_state = construct_initial_state(no_routes=no_routes, no_cars=no_cars) mixer = n_qbit_mixer(initial_state) else: initial_state, mixer = (None, None) fourier_parametrise = args["fourier"] print_to_file("-" * 50) print_to_file( "Now solving with TQA_QAOA... Fourier Parametrisation: {}".format( fourier_parametrise)) # maxeval = 125 for p in range(1, p_max + 1): construct_circ = False deltas = np.arange(0.45, 0.91, 0.05) point = np.append([(i + 1) / p for i in range(p)], [1 - (i + 1) / p for i in range(p)]) points = [delta * point for delta in deltas] print_to_file("-" * 50) print_to_file(" " + "p={}".format(p)) if fourier_parametrise: points = [ convert_to_fourier_point(point, len(point)) for point in points ] # maxeval *= 2 #Double max_allowed evals for optimizer # optimizer.set_options(maxeval = maxeval) optimizer.set_options(maxeval=1000 * p) qaoa_results, optimal_circ = CustomQAOA( operator, quantum_instance, optimizer, reps=p, initial_state=initial_state, mixer=mixer, construct_circ=construct_circ, fourier_parametrise=fourier_parametrise, list_points=points, qubo=qubo) exp_val = qaoa_results.eigenvalue * max_coeff state_solutions = { item[0][::-1]: item[1:] for item in qaoa_results.eigenstate } for item in sorted(state_solutions.items(), key=lambda x: x[1][1], reverse=True)[0:5]: print_to_file(item) prob_s = 0 for string in x_s: prob_s += state_solutions[string][ 1] if string in state_solutions else 0 prob_s /= len(x_s) #normalise optimal_point = qaoa_results.optimal_point if fourier_parametrise: optimal_point = convert_from_fourier_point(optimal_point, len(optimal_point)) approx_ratio = 1 - np.abs((opt_value - exp_val) / opt_value) nfev = qaoa_results.cost_function_evals print_to_file( " " + "Optimal_point: {}, Nfev: {}".format(optimal_point, nfev)) print_to_file(" " + "Exp_val: {}, Prob_s: {}, approx_ratio: {}".format( exp_val, prob_s, approx_ratio)) approx_ratios.append(approx_ratio) prob_s_s.append(prob_s) print_to_file("-" * 50) print_to_file("QAOA terminated") print_to_file("-" * 50) print_to_file("Approximation ratios per layer: {}".format(approx_ratios)) print_to_file("Prob_success per layer: {}".format(prob_s_s)) save_results = np.append(approx_ratios, prob_s_s) if fourier_parametrise: with open( 'results_{}cars{}routes/TQA_F_{}.csv'.format( args["no_cars"], args["no_routes"], args["no_samples"]), 'w') as f: np.savetxt(f, save_results, delimiter=',') print_to_file( "Results saved in results_{}cars{}routes/TQA_F_{}.csv".format( args["no_cars"], args["no_routes"], args["no_samples"])) else: with open( 'results_{}cars{}routes/TQA_NF_{}.csv'.format( args["no_cars"], args["no_routes"], args["no_samples"]), 'w') as f: np.savetxt(f, save_results, delimiter=',') print_to_file( "Results saved in results_{}cars{}routes/TQA_NF_{}.csv".format( args["no_cars"], args["no_routes"], args["no_samples"])) finish = time() print_to_file("Time Taken: {}".format(finish - start))
def main(args=None): start = time() if args == None: args = parse() with open( 'qubos_{}_car_{}_routes/qubo_{}.pkl'.format( args["no_cars"], args["no_routes"], args["no_samples"]), 'rb') as f: load_data = pkl.load(f) if len(load_data) == 5: qubo, max_coeff, operator, offset, routes = load_data else: qubo, max_coeff, operator, offset, routes, classical_result = load_data #Normalize qubo (Can recover original qubo via normalize_factor * qubo_objective ) qubo, normalize_factor = reduce_qubo(qubo) #Initialize RQAOA object rqaoa = RQAOA(qubo, args["no_cars"], args["no_routes"], symmetrise=args["symmetrise"]) print("Args: {}".format(args)) print("First round of TQA-QAOA...") p = args["p_max"] qaoa_results = rqaoa.solve_qaoa(p, tqa=True) rqaoa.perform_substitution_from_qaoa_results(qaoa_results, biased=args["bias"]) print( "Performed variable substition(s) and constructed new initial state and mixer." ) num_vars = rqaoa.qubo.get_num_vars() print("Remaining variables: {}".format(num_vars)) t = 1 #Recursively substitute variables to reduce qubit by one until 1 remaining while num_vars > 1: t += 1 qaoa_results = rqaoa.solve_qaoa(p, tqa=True) print("Round {} of TQA-QAOA. Results below:".format(t)) rqaoa.perform_substitution_from_qaoa_results(qaoa_results, biased=args["bias"]) print( "Performed variable substition(s) and constructed new initial state and mixer." ) num_vars = rqaoa.qubo.get_num_vars() print("Remaining variables: {}".format(num_vars)) print("Final round of QAOA Done. Eigenstate below:") p = 2 points = [[np.pi * (np.random.rand() - 0.5) for _ in range(2 * p)] for _ in range(10)] + [[0 for _ in range(2 * p)]] qaoa_results = rqaoa.solve_qaoa(p, points=points) print("Probabilities: {}".format(rqaoa.prob_s)) print("Approx Qualities of (lowest_energy_state, most_probable_state): {}". format(rqaoa.approx_s)) if args["symmetrise"]: var_last = "X_anc" #Last variable should be ancilla if Hamiltonian was initially symmetrised rqaoa.var_values[ var_last] = 0 #Now use the fact that ancilla should be in 0 state (so Z_anc = 1) else: max_state = sorted(qaoa_results.eigenstate, key=lambda x: x[2], reverse=True)[0] var_last = rqaoa.qubo.variables[0].name rqaoa.var_values[var_last] = int(max_state[0]) #Now read solution from correlations and final value var_values = rqaoa.var_values replacements = rqaoa.replacements while True: for var, replacement in replacements.items(): if replacement == None: continue elif replacement[ 0] in var_values and var not in var_values and replacement[ 1] != None: var_values[var] = var_values[replacement[0]] if replacement[ 1] == 1 else 1 - var_values[replacement[0]] if len(var_values.keys() ) == args["no_cars"] * args["no_routes"] + 1 and args[ "symmetrise"]: #1 extra value if using ancilla break elif len(var_values.keys()) == args["no_cars"] * args["no_routes"]: break #Remove Ancilla qubit in final result if it is in the variable values dict if "X_anc" in var_values: var_values.pop("X_anc") list_values = list(var_values.values()) cost = rqaoa.original_qubo.objective.evaluate(var_values) print(rqaoa.result) print(var_values) print("{}, Cost: {}".format(list_values, cost)) #Save results save_results = np.append(rqaoa.prob_s, rqaoa.approx_s) if args["bias"]: with open( 'results_{}cars{}routes_mps/Biased_RQAOA_{}_p={}.csv'.format( args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"]), 'w') as f: np.savetxt(f, save_results, delimiter=',') print( "Results saved in results_{}cars{}routes_mps/Biased_RQAOA_{}_p={}.csv" .format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"])) elif args["symmetrise"]: with open( 'results_{}cars{}routes_mps/Symmetrised_RQAOA_{}_p={}.csv'. format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"]), 'w') as f: np.savetxt(f, save_results, delimiter=',') print( "Results saved in results_{}cars{}routes_mps/Symmetrised_RQAOA_{}_p={}.csv" .format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"])) else: with open( 'results_{}cars{}routes_mps/Regular_RQAOA_{}_p={}.csv'.format( args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"]), 'w') as f: np.savetxt(f, save_results, delimiter=',') print( "Results saved in results_{}cars{}routes_mps/Regular_RQAOA_{}_p={}.csv" .format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"])) finish = time() print("Time taken: {} s".format(finish - start))
def perform_substitution_from_qaoa_results(self, qaoa_results, update_benchmark_energy=True): sorted_eigenstate_by_energy = sorted(qaoa_results.eigenstate, key = lambda x: x[1]) sorted_eigenstate_by_prob = sorted(qaoa_results.eigenstate, key = lambda x: x[2], reverse = True) scale = self.random_energy - self.result.fval approx_quality = (self.random_energy - sorted_eigenstate_by_energy[0][1])/ scale eigenstate = dict( [ (x[0], x[2]) for x in qaoa_results.eigenstate ] ) self.approx_quality = approx_quality self.eigenstate = eigenstate print( "QAOA lowest energy solution: {}".format(sorted_eigenstate_by_energy[0]) ) print( "Approx_quality: {}".format(approx_quality) print( "QAOA most probable solution: {}".format(sorted_eigenstate_by_prob[0]) ) print( "Approx_quality: {}".format((self.random_energy - sorted_eigenstate_by_prob[0][1])/ scale) ) correlations = self.get_correlations(qaoa_results.eigenstate) i, j = self.find_strongest_correlation(correlations) new_qubo = deepcopy(self.qubo) x_i, x_j = new_qubo.variables[i].name, new_qubo.variables[j].name print( "\nCorrelation: < {} {} > = {}".format(x_i, x_j, correlations[i, j])) car_block = int(x_i[2]) #If same car_block and x_i = x_j, then both must be 0 since only one 1 in a car block if x_i[2] == x_j[2] and correlations[i, j] > 0 and len(self.car_blocks[car_block]) > 2: # set x_i = x_j = 0 new_qubo = new_qubo.substitute_variables({x_i: 0, x_j:0}) if new_qubo.status == QuadraticProgram.Status.INFEASIBLE: raise QiskitOptimizationError('Infeasible due to variable substitution {} = {} = 0'.format(x_i, x_j)) self.var_values[x_i] = 0 self.var_values[x_j] = 0 self.car_blocks[car_block].remove(x_i) self.car_blocks[car_block].remove(x_j) print("Two variable substitutions were performed due to extra information from constraints.") if len(self.car_blocks[car_block]) == 1: #If only one remaining variable x_r = self.car_blocks[car_block][0] #remaining variable #Check if all other variables are 0 (then their sum should be 0) -> so x_r must be 1 check = sum( [self.var_values.get("X_{}_{}".format(car_block, route_no), 0) for route_no in range(self.no_routes)] ) if check == 0: new_qubo = new_qubo.substitute_variables({x_r: 1}) if new_qubo.status == QuadraticProgram.Status.INFEASIBLE: raise QiskitOptimizationError('Infeasible due to variable substitution {} = 1'.format(x_r)) self.car_blocks[car_block].remove(x_r) print("{} = 1 can also be determined from all other variables being 0 for car_{}".format(x_r, car_block)) elif x_i[2] != x_j[2] and correlations[i, j] > 0: # set x_i = x_j new_qubo = new_qubo.substitute_variables(variables={i: (j, 1)}) if new_qubo.status == QuadraticProgram.Status.INFEASIBLE: raise QiskitOptimizationError('Infeasible due to variable substitution {} = {}'.format(x_i, x_j)) self.replacements[x_i] = (x_j, 1) self.car_blocks[car_block].remove(x_i) else: # set x_i = 1 - x_j, this is done in two steps: # 1. set x_i = 1 + x_i # 2. set x_i = -x_j # 1a. get additional offset from the 1 on the RHS of (xi -> 1+xi) constant = new_qubo.objective.constant constant += new_qubo.objective.linear[i] constant += new_qubo.objective.quadratic[i, i] new_qubo.objective.constant = constant #1b get additional linear part from quadratic terms becoming linear due to the same 1 in the 1+xi as above for k in range(new_qubo.get_num_vars()): coeff = new_qubo.objective.linear[k] if k == i: coeff += 2*new_qubo.objective.quadratic[i, k] else: coeff += new_qubo.objective.quadratic[i, k] # set new coefficient if not too small if np.abs(coeff) > 1e-10: new_qubo.objective.linear[k] = coeff else: new_qubo.objective.linear[k] = 0 #2 set xi = -xj new_qubo = new_qubo.substitute_variables(variables={i: (j, -1)}) if new_qubo.status == QuadraticProgram.Status.INFEASIBLE: raise QiskitOptimizationError('Infeasible due to variable substitution {} = -{}'.format(x_i, x_j)) self.replacements[x_i] = (x_j, -1) self.car_blocks[car_block].remove(x_i) self.qubo = new_qubo op, offset = new_qubo.to_ising() self.operator = op self.offset = offset self.construct_initial_state() self.construct_mixer() if update_benchmark_energy: temp = self.get_benchmark_energy() def get_correlations(self, state) -> np.ndarray: """ Get <Zi x Zj> correlation matrix from the eigenstate(state: Dict). Returns: A correlation matrix. """ states = state # print(states) x, _, prob = states[0] n = len(x) correlations = np.zeros((n, n)) for x, cost, prob in states: if cost < self.benchmark_energy: scaled_approx_quality = (self.benchmark_energy - cost) for i in range(n): for j in range(i): if x[i] == x[j]: correlations[i, j] += scaled_approx_quality * prob else: correlations[i, j] -= scaled_approx_quality * prob return correlations def find_strongest_correlation(self, correlations): # get absolute values and set diagonal to -1 to make sure maximum is always on off-diagonal abs_correlations = np.abs(correlations) diagonal = np.diag( np.ones(len(correlations)) ) abs_correlations = abs_correlations - diagonal # get index of maximum (by construction on off-diagonal) m_max = np.argmax(abs_correlations.flatten()) # translate back to indices i = int(m_max // len(correlations)) j = int(m_max - i*len(correlations)) return (i, j) def main(args=None): start = time() if args == None: args = parse() with open('qubos_{}_car_{}_routes/qubo_{}.pkl'.format(args["no_cars"], args["no_routes"], args["no_samples"]), 'rb') as f: load_data = pkl.load(f) if len(load_data) == 5: qubo, max_coeff, operator, offset, routes = load_data else: qubo, max_coeff, operator, offset, routes, classical_result = load_data rqaoa = RQAOA(qubo, args["no_cars"], args["no_routes"]) rqaoa.solve_classically() print(rqaoa.result) print("First round of TQA-QAOA. Results below:") qaoa_results = rqaoa.solve_tqa_qaoa(2) rqaoa.perform_substitution_from_qaoa_results(qaoa_results) print("Performed variable substition(s) and constructed new initial state and mixer.") num_vars = rqaoa.qubo.get_num_vars() print("Remaining variables: {}".format(num_vars)) t = 1 while num_vars > 1: print("-"*50) t+=1 qaoa_results = rqaoa.solve_tqa_qaoa(2) print( "Round {} of TQA-QAOA. Results below:".format(t) ) rqaoa.perform_substitution_from_qaoa_results(qaoa_results) print("Performed variable substition(s) and constructed new initial state and mixer.") num_vars = rqaoa.qubo.get_num_vars() print("Remaining variables: {}".format(num_vars)) print("-"*50) p=2 qaoa_results = rqaoa.solve_qaoa( p, point = [0]* (2*p) ) print( "Final round of QAOA Done. Eigenstate below:" ) pprint(qaoa_results.eigenstate) print( rqaoa.prob_s ) print( rqaoa.approx_s ) max_state = sorted(qaoa_results.eigenstate, key = lambda x: x[2], reverse=True)[0] var_last = rqaoa.qubo.variables[0].name rqaoa.var_values[var_last] = int(max_state[0]) var_values = rqaoa.var_values replacements = rqaoa.replacements while True: for var, replacement in replacements.items(): if replacement == None: continue elif replacement[0] in var_values and var not in var_values and replacement[1] != None: var_values[var] = var_values[ replacement[0] ] if replacement[1] == 1 else 1 - var_values[ replacement[0] ] if len(var_values.keys()) == args["no_cars"]*args["no_routes"]: break print(rqaoa.result) print(var_values) list_values = list(var_values.values()) cost = rqaoa.original_qubo.objective.evaluate(var_values) print("{}, Cost: {}".format(list_values, cost)) if __name__ == '__main__': main() finish = time() print("Time taken: {} s".format(finish - start))
def main(args=None): """[summary] Args: raw_args ([type], optional): [description]. Defaults to None. """ start = time() if args == None: args = parse() prob_s_s = [] qubo_no = args["no_samples"] print("__" * 50, "\nQUBO NO: {}\n".format(qubo_no), "__" * 50) #Load generated qubo_no with open( 'qubos_{}_car_{}_routes/qubo_{}.pkl'.format( args["no_cars"], args["no_routes"], qubo_no), 'rb') as f: qubo, max_coeff, operator, offset, routes = pkl.load(f) print(operator) x_s = find_all_ground_states(qubo) # Visualise if args["visual"]: graph = import_map('melbourne.pkl') visualise_solution(graph, routes) # Solve QAOA from QUBO with valid solution no_couplings = count_coupling_terms(operator) print("Number of couplings: {}".format(no_couplings)) print("Solving with QAOA...") no_shots = 10000 backend = Aer.get_backend('statevector_simulator') quantum_instance = QuantumInstance(backend, shots=no_shots) optimizer_method = "LN_SBPLX" optimizer = NLOPT_Optimizer(method=optimizer_method) print("_" * 50, "\n" + optimizer.__class__.__name__) print("_" * 50) quantum_instance = QuantumInstance(backend) prob_s_s = [] initial_state = construct_initial_state(args["no_routes"], args["no_cars"]) mixer = n_qbit_mixer(initial_state) next_fourier_point, next_fourier_point_B = [0, 0], [ 0, 0 ] #Not used for p=1 then gets updated for p>1. for p in range(1, args["p_max"] + 1): print("p = {}".format(p)) if p == 1: points = [[0.75,0]] \ # + [[ np.pi*(2*np.random.rand() - 1) for _ in range(2) ] for _ in range(args["no_restarts"])] draw_circuit = True else: penalty = 0.6 points = generate_points(next_fourier_point, no_perturb=10, penalty=0.6) print(points) \ # + generate_points(next_fourier_point_B, 10, penalty) draw_circuit = False #empty lists to save following results to choose best result results = [] exp_vals = [] for r in range(len(points)): point = points[r] if np.amax(np.abs(point)) < np.pi / 2: qaoa_results, optimal_circ = CustomQAOA( operator, quantum_instance, optimizer, reps=p, initial_fourier_point=points[r], initial_state=initial_state, mixer=mixer, construct_circ=draw_circuit) if r == 0: next_fourier_point = np.array(qaoa_results.optimal_point) next_fourier_point = QAOAEx.convert_from_fourier_point( next_fourier_point, 2 * p + 2) next_fourier_point = QAOAEx.convert_to_fourier_point( next_fourier_point, 2 * p + 2) exp_val = qaoa_results.eigenvalue * max_coeff + offset exp_vals.append(exp_val) prob_s = 0 for string in x_s: prob_s += qaoa_results.eigenstate[ string] if string in qaoa_results.eigenstate else 0 results.append((qaoa_results, optimal_circ, prob_s)) print("Point_no: {}, Exp_val: {}, Prob_s: {}".format( r, exp_val, prob_s)) else: print( "Point_no: {}, was skipped because it is outside of bounds" .format(r)) minim_index = np.argmin(exp_vals) optimal_qaoa_result, optimal_circ, optimal_prob_s = results[ minim_index] # if draw_circuit: # print(optimal_circ.draw()) minim_exp_val = exp_vals[minim_index] print("Minimum: {}, prob_s: {}".format(minim_exp_val, optimal_prob_s)) prob_s_s.append(optimal_prob_s) next_fourier_point_B = np.array(optimal_qaoa_result.optimal_point) print("Optimal_point: {}".format(next_fourier_point_B)) next_fourier_point_B = QAOAEx.convert_from_fourier_point( next_fourier_point_B, 2 * p + 2) next_fourier_point_B = QAOAEx.convert_to_fourier_point( next_fourier_point_B, 2 * p + 2) print(prob_s_s) with open( 'results/{}cars{}routes_qubo{}.csv'.format(args["no_cars"], args["no_routes"], args["no_samples"]), 'w') as f: np.savetxt(f, prob_s_s, delimiter=',') finish = time() print("Time Taken: {}".format(finish - start))
def main(args = None): """[summary] Args: raw_args ([type], optional): [description]. Defaults to None. """ start = time() if args == None: args = parse() qubo_no = args["no_samples"] print_to_file("-"*50) print_to_file("QUBO_{}".format(qubo_no)) #Load generated qubo_no with open('qubos_{}_car_{}_routes/qubo_{}.pkl'.format(args["no_cars"], args["no_routes"], qubo_no), 'rb') as f: qubo, max_coeff, operator, offset, routes = pkl.load(f) qubo = QuadraticProgram() qubo.from_ising(operator) x_s, opt_value, classical_result = find_all_ground_states(qubo) print_to_file(classical_result) #Set optimizer method method = args["method"] optimizer = NLOPT_Optimizer(method = method, result_message=False) backend = Aer.get_backend("statevector_simulator") quantum_instance = QuantumInstance(backend = backend) approx_ratios = [] prob_s_s = [] p_max = args["p_max"] no_routes, no_cars = (args["no_routes"], args["no_cars"]) custom = True if custom: initial_state = construct_initial_state(no_routes = no_routes, no_cars = no_cars) mixer = n_qbit_mixer(initial_state) else: initial_state, mixer = (None, None) fourier_parametrise = args["fourier"] print_to_file("-"*50) print_to_file("Now solving with QAOA... Fourier Parametrisation: {}".format(fourier_parametrise)) for p in range(1, p_max+1): if p == 1: points = [[0,0]] + [ np.random.uniform(low = -np.pi/2+0.01, high = np.pi/2-0.01, size = 2*p) for _ in range(2**p)] next_point = [] else: penalty = 0.6 points = [next_point_l] + generate_points(next_point, no_perturb=min(2**p-1,10), penalty=penalty) construct_circ = False #empty lists to save following results to choose best result results = [] exp_vals = [] print_to_file("-"*50) print_to_file(" "+"p={}".format(p)) optimizer.set_options(maxeval = 1000*p) for r, point in enumerate(points): qaoa_results, optimal_circ = CustomQAOA(operator, quantum_instance, optimizer, reps = p, initial_fourier_point= point, initial_state = initial_state, mixer = mixer, construct_circ= construct_circ, fourier_parametrise = fourier_parametrise, qubo = qubo ) if r == 0: if fourier_parametrise: next_point_l = np.zeros(shape = 2*p + 2) next_point_l[0:p] = qaoa_results.optimal_point[0:p] next_point_l[p+1:2*p+1] = qaoa_results.optimal_point[p:2*p] else: next_point_l = interp_point(qaoa_results.optimal_point) exp_val = qaoa_results.eigenvalue * max_coeff exp_vals.append(exp_val) state_solutions = { item[0][::-1]: item[1:] for item in qaoa_results.eigenstate } for item in sorted(state_solutions.items(), key = lambda x: x[1][1], reverse = True)[0:5]: print_to_file( item ) prob_s = 0 for string in x_s: prob_s += state_solutions[string][1] if string in state_solutions else 0 prob_s /= len(x_s) #normalise results.append((qaoa_results, optimal_circ, prob_s)) print_to_file(" "+"Point_{}, Exp_val: {}, Prob_s: {}".format(r, exp_val, prob_s)) minim_index = np.argmin(exp_vals) optimal_qaoa_result, optimal_circ, optimal_prob_s = results[minim_index] if fourier_parametrise: next_point = convert_from_fourier_point( optimal_qaoa_result.optimal_point, 2*p ) next_point = convert_to_fourier_point( interp_point(next_point), 2*p + 2 ) # next_point = np.zeros(shape = 2*p + 2) # next_point[0:p] = optimal_qaoa_result.optimal_point[0:p] # next_point[p+1:2*p+1] = optimal_qaoa_result.optimal_point[p:2*p] else: next_point = interp_point(optimal_qaoa_result.optimal_point) if construct_circ: print_to_file(optimal_circ.draw(fold=150)) minim_exp_val = exp_vals[minim_index] approx_ratio = 1.0 - np.abs( (opt_value - minim_exp_val ) / opt_value ) print_to_file(" "+"Minimum: {}, prob_s: {}, approx_ratio {}".format(minim_exp_val, optimal_prob_s, approx_ratio)) approx_ratios.append(approx_ratio) prob_s_s.append(optimal_prob_s) print_to_file("-"*50) print_to_file("QAOA terminated") print_to_file("-"*50) print_to_file("Approximation ratios per layer: {}".format(approx_ratios)) print_to_file("Prob_success per layer: {}".format(prob_s_s)) save_results = np.append(approx_ratios, prob_s_s) if fourier_parametrise: with open('results_{}cars{}routes/RI_F_{}.csv'.format(args["no_cars"], args["no_routes"], args["no_samples"]), 'w') as f: np.savetxt(f, save_results, delimiter=',') print_to_file("Results saved in results_{}cars{}routes/RI_F_{}.csv".format(args["no_cars"], args["no_routes"], args["no_samples"])) else: with open('results_{}cars{}routes/RI_NF_{}.csv'.format(args["no_cars"], args["no_routes"], args["no_samples"]), 'w') as f: np.savetxt(f, save_results, delimiter=',') print_to_file("Results saved in results_{}cars{}routes/RI_NF_{}.csv".format(args["no_cars"], args["no_routes"], args["no_samples"])) finish = time() print_to_file("Time Taken: {}".format(finish - start))
def main(args=None): start = time() if args == None: args = parse() with open('qubos_{}_car_{}_routes/qubo_{}.pkl'.format(args["no_cars"], args["no_routes"], args["no_samples"]), 'rb') as f: load_data = pkl.load(f) if len(load_data) == 5: qubo, max_coeff, operator, offset, routes = load_data classical_result = None else: qubo, max_coeff, operator, offset, routes, classical_result = load_data fourier_parametrise = args["fourier"] #Normalize qubo (Can recover original qubo via normalize_factor * qubo_objective ) qubo, normalize_factor = reduce_qubo(qubo) if classical_result: classical_result._fval /= normalize_factor #Also normalize classical result #Noise if args["noisy"]: #Use symmetrised Hamiltonian and base QAOA args["symmetrise"] = True args["customise"] = False args["bias"] = False args["simulator"] = "aer_simulator_density_matrix" multiplier = args["multiplier"] print("Simulating with noise...Error mulitplier: {}".format(multiplier)) with open('average_gate_errors.json', 'r') as f: noise_rates = json.load(f) noise_model = build_noise_model(noise_rates, multiplier) else: print("Simulating without noise...") noise_model = None #Initialize RQAOA object and make sure there is a classical solution rqaoa = RQAOA(qubo, args["no_cars"], args["no_routes"], symmetrise = args["symmetrise"], customise = args["customise"], classical_result = classical_result, simulator = args["simulator"], noise_model = noise_model, opt_str = args["optimizer"] ) print("Args: {}\n".format(args)) iterate_time = time() print("First round of TQA-QAOA...") p = args["p_max"] qaoa_results = rqaoa.solve_qaoa(p, tqa=True, fourier_parametrise = fourier_parametrise) if p>1 else rqaoa.solve_qaoa(p, fourier_parametrise=fourier_parametrise) rqaoa.perform_substitution_from_qaoa_results(qaoa_results, biased = args["bias"]) print("Performed variable substition(s).") num_vars = rqaoa.qubo.get_num_vars() print("Remaining variables: {}".format(num_vars)) iterate_time_2 = time() print("Time taken (for this iteration): {}s".format(iterate_time_2 - iterate_time)) t = 1 #Recursively substitute variables to reduce qubit by one until 1 remaining while num_vars > 1: iterate_time = time() t+=1 print( "\nRound {} of TQA-QAOA. Results below:".format(t) ) qaoa_results = rqaoa.solve_qaoa(p, tqa=True, fourier_parametrise=fourier_parametrise) if p>1 else rqaoa.solve_qaoa(p, fourier_parametrise=fourier_parametrise) rqaoa.perform_substitution_from_qaoa_results(qaoa_results, biased = args["bias"]) print("Performed variable substition(s).") num_vars = rqaoa.qubo.get_num_vars() print("Remaining variables: {}".format(num_vars)) iterate_time_2 = time() print("Time taken (for this iteration): {}s".format(iterate_time_2 - iterate_time)) print( "\nFinal round of QAOA. Eigenstate below:" ) p=2 points = [ [ np.pi * (np.random.rand() - 0.5) for _ in range(2*p) ] for _ in range(10) ] + [ [ 0 for _ in range(2*p) ] ] qaoa_results = rqaoa.solve_qaoa( p, points = points ) print( "\nProbabilities: {}".format(rqaoa.prob_s) ) print( "Approx Qualities of (lowest_energy_state, most_probable_state): {}\n".format(rqaoa.approx_s) ) if args["symmetrise"]: var_last = "X_anc" #Last variable should be ancilla if Hamiltonian was initially symmetrised rqaoa.var_values[var_last] = 0 #Now use the fact that ancilla should be in 0 state (so Z_anc = 1) else: max_state = sorted(qaoa_results.eigenstate, key = lambda x: x[2], reverse=True)[0] var_last = rqaoa.qubo.variables[0].name rqaoa.var_values[var_last] = int(max_state[0]) #Now read solution from correlations and final value var_values = rqaoa.var_values replacements = rqaoa.replacements while True: for var, replacement in replacements.items(): if replacement == None: continue elif replacement[0] in var_values and var not in var_values and replacement[1] != None: var_values[var] = var_values[ replacement[0] ] if replacement[1] == 1 else 1 - var_values[ replacement[0] ] if len(var_values.keys()) == args["no_cars"]*args["no_routes"]+1 and args["symmetrise"]: #1 extra value if using ancilla break elif len(var_values.keys()) == args["no_cars"]*args["no_routes"]: break #Remove Ancilla qubit in final result if it is in the variable values dict if "X_anc" in var_values: var_values.pop("X_anc") list_values = list(var_values.values()) cost = rqaoa.original_qubo.objective.evaluate(var_values) print(rqaoa.classical_result) print("\nRQAOA Solution: {}, Cost: {}".format(list_values, cost)) #End of algorithm finish = time() print("\nTime taken: {} s".format(finish - start)) #Naming of file to save results to if args["customise"] and not args["noisy"]: #Using custom QAOA if args["bias"]: filedir = 'results_{}cars{}routes_mps/Biased_RQAOA_{}_Cust_p={}.csv'.format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"]) elif args["symmetrise"]: filedir = 'results_{}cars{}routes_mps/Symmetrised_RQAOA_{}_Cust_p={}.csv'.format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"]) else: filedir = 'results_{}cars{}routes_mps/Regular_RQAOA_{}_Cust_p={}.csv'.format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"]) elif not args["customise"] and not args["noisy"]: if args["bias"]: #Using baseline QAOA filedir = 'results_{}cars{}routes_mps/Biased_RQAOA_{}_Base_p={}.csv'.format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"]) elif args["symmetrise"]: filedir = 'results_{}cars{}routes_mps/Symmetrised_RQAOA_{}_Base_p={}.csv'.format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"]) else: filedir = 'results_{}cars{}routes_mps/Regular_RQAOA_{}_Base_p={}.csv'.format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"]) elif args["noisy"]: filedir = 'results_{}cars{}routes/Noisy_S_RQAOA_{}_Base_p={}_Error={}.csv'.format(args["no_cars"], args["no_routes"], args["no_samples"], args["p_max"], args["multiplier"]) #Save results to file save_results = np.append( rqaoa.prob_s, rqaoa.approx_s ) with open(filedir, 'w') as f: np.savetxt(f, save_results, delimiter=',') result_saved_string = "Results saved in {}".format(filedir) print(result_saved_string) print("_"*len(result_saved_string)) print("")
def main(args=None): start = time() if args == None: args = parse() prob_s_s = [] qubo_no = args["no_samples"] print("__"*50, "\nQUBO NO: {}\n".format(qubo_no), "__"*50) #Load generated qubo_no with open('qubos_{}_car_{}_routes/qubo_{}.pkl'.format(args["no_cars"], args["no_routes"], qubo_no), 'rb') as f: qubo, max_coeff, operator, offset, routes = pkl.load(f) # print(operator) classical_result = solve_classically(qubo) print(classical_result) x_arr = classical_result.x optimal_value = qubo.objective.evaluate(x_arr) # print(optimal_value) x_str = arr_to_str(x_arr) sort_values = get_costs(qubo) # print("_"*50) # up_to = 27 # print("{} lowest states:".format(up_to)) # avg = 0 # for i in range(up_to): # print(sort_values[i]) # avg += sort_values[i][1] # print("_"*50) # print("Avg: {}".format(avg/up_to)) #Remake QUBO to introduce only ZiZj terms op, offset = qubo.to_ising() new_operator = [] for i, op_1 in enumerate(op): coeff, op_1 = op_1.to_pauli_op().coeff, op_1.to_pauli_op().primitive op_1_str = op_1.to_label() Z_counts = op_1_str.count('Z') if Z_counts == 1: op_1_str = 'Z' + op_1_str else: op_1_str = 'I' + op_1_str pauli = PauliOp( primitive = Pauli(op_1_str), coeff = coeff ) new_operator.append(pauli) qubo_2 = QuadraticProgram() operator = sum(new_operator) qubo_2.from_ising(operator, offset, linear=True) print("Solving with QAOA...") no_shots = 10000 backend = Aer.get_backend('statevector_simulator') quantum_instance = QuantumInstance(backend, shots = no_shots) optimizer_method = "LN_SBPLX" optimizer = NLOPT_Optimizer(method = optimizer_method) print("_"*50,"\n"+optimizer.__class__.__name__) print("_"*50) p = 1 delta_points = [] deltas = np.arange(0.75, 0.76, 0.05) print("delta_t's: ", deltas) original_point = np.append([], [[(i+1)/p, 1-(i+1)/p] for i in range(p)]) for delta in deltas: delta_points.append(delta*original_point) # point = [ 0.60081404, 0.11785113, 0.02330747, 1.10006101, 0.46256391, # -0.96823671] draw_circuit = True initial_state = construct_initial_state_2(args["no_routes"], args["no_cars"]) mixer = n_qbit_mixer(initial_state) quantum_instance = QuantumInstance(backend) results = [] exp_vals = [] for point in delta_points: point = QAOAEx.convert_to_fourier_point(point, 2*p) qaoa_results, _ = Fourier_QAOA(operator, quantum_instance, optimizer, reps = p, initial_fourier_point=point, initial_state = initial_state, mixer = mixer, construct_circ=draw_circuit, fourier_parametrise = True ) # print(optimal_circ.draw()) results.append(qaoa_results) exp_val = qaoa_results.eigenvalue + offset print("ExpVal {}".format(exp_val)) exp_vals.append(exp_val) minim_index = np.argmin(exp_vals) qaoa_results = results[minim_index] sort_states = sorted(qaoa_results.eigenstate.items(), key=lambda x: x[1], reverse=True) correlations = get_correlations(sort_states) # print(correlations) i,j = find_strongest_correlation(correlations) if correlations[i,j] > 0: condition = "Z_{i} = Z_{j}".format(i=i,j=j) else: condition = "Z_{i} = - Z_{j}".format(i=i,j=j) print("Max: <Z_{i}Z_{j}>={maxim}, condition: ".format(i=i, j=j, maxim = correlations[i,j])+condition) ground_energy = sort_values[0][1] x_s = [x_str] for i in range(0,10): if sort_values[i][0] == x_str or np.round(sort_values[i][1], 4) != np.round(ground_energy, 4): continue else: print("Other ground state(s) found: '{}'".format(sort_values[i][0])) x_s.append(sort_values[i][0]) x_s_2 = [] print("All the possible solutions were originally: ") print("[Z0 Z1 Z2 Z3 Z4 Z5 Z6 Z7 Z8 Z9]") for string in x_s: x = '0' + string x_arr = np.array(str_to_arr(x)) # print("f({x})={obj}".format(x=x, obj = qubo_2.objective.evaluate(x_arr))) x_s_2.append(x_arr) formatted_arr = ["{} ".format(item) for item in x_arr] formatted_arr = ' '.join(formatted_arr) print("[{}]".format(formatted_arr)) finish = time() print("Time taken {time}s".format(time=finish-start))