Example #1
0
 def get_random_energy(self):
     #Get random benchmark energy for 0 layer Custom-QAOA (achieved by using layer 1 Cust-QAOA with [0,0] angles i.e. sampling from feasible states with equal prob)
     self.construct_initial_state(symmetrise=False)
     self.construct_mixer()
     random_energy, _ = CustomQAOA(
         operator=self.operator,
         quantum_instance=self.random_instance,
         optimizer=self.optimizer,
         reps=1,
         initial_state=self.initial_state,
         mixer=self.mixer,
         solve=False,
     )
     #Remove custom initial state if using BASE QAOA
     self.initial_state = None
     self.mixer = None
     temp = random_energy
     self.random_energy = temp + self.offset
     if np.round(self.random_energy - self.opt_value, 6) < 1e-7:
         print(
             "0 layer QAOA converged to exact solution. Shifting value up by |exact_ground_energy| instead to avoid dividing by 0 in approx quality."
         )
         self.random_energy += np.abs(self.random_energy)
     self.benchmark_energy = self.random_energy
     print("random energy: {}\n".format(self.random_energy))
Example #2
0
 def solve_qaoa(self, p, **kwargs):
     point = self.optimal_point if 'point' not in kwargs else kwargs['point']
     fourier_parametrise = True
     self.optimizer.set_options(maxeval = 1000)
     qaoa_results, _, _ = CustomQAOA( self.operator,
                                     self.quantum_instance,
                                     self.optimizer,
                                     reps = p,
                                     initial_state = self.initial_state,
                                     initial_point = point,
                                     mixer = self.mixer,
                                     fourier_parametrise = fourier_parametrise,
                                     qubo = self.qubo
                                     )
     point = qaoa_results.optimal_point
     qaoa_results.eigenvalue = sum( [ x[1] * x[2] for x in qaoa_results.eigenstate ] )
     self.optimal_point = QAOAEx.convert_to_fourier_point(point, len(point)) if fourier_parametrise else point
     self.qaoa_result = qaoa_results
     return qaoa_results
Example #3
0
 def get_random_energy(self):
     #Get random benchmark energy for 0 layer QAOA (achieved by using layer 1 QAOA with [0,0] angles)
     random_energy = CustomQAOA(operator = self.operator,
                 quantum_instance = self.quantum_instance,
                 optimizer = self.optimizer,
                 reps = 1,
                 initial_state = self.initial_state,
                 mixer = self.mixer,
                 solve = False,
                 )
     temp = random_energy
     self.random_energy = temp + self.offset
     print("random energy: {}".format(self.random_energy))
Example #4
0
 def solve_tqa_qaoa(self, p):
     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]
     fourier_parametrise = True
     if fourier_parametrise:
         points = [ QAOAEx.convert_to_fourier_point(point, len(point)) for point in points ]
     self.optimizer.set_options(maxeval = 1000)
     qaoa_results, _, _ = CustomQAOA( self.operator,
                                                 self.quantum_instance,
                                                 self.optimizer,
                                                 reps = p,
                                                 initial_state = self.initial_state,
                                                 mixer = self.mixer,
                                                 fourier_parametrise = fourier_parametrise,
                                                 list_points = points,
                                                 qubo = self.qubo
                                                 )
     point = qaoa_results.optimal_point
     qaoa_results.eigenvalue = sum( [ x[1] * x[2] for x in qaoa_results.eigenstate ] )
     self.optimal_point = QAOAEx.convert_to_fourier_point(point, len(point)) if fourier_parametrise else point
     self.qaoa_result = qaoa_results
     return qaoa_results
Example #5
0
 def get_benchmark_energy(self):
     #Get benchmark energy with 0-layer QAOA (just as random_energy)
     benchmark_energy = CustomQAOA(operator = self.operator,
                 quantum_instance = self.quantum_instance,
                 optimizer = self.optimizer,
                 reps = 1,
                 initial_state = self.initial_state,
                 mixer = self.mixer,
                 solve = False,
                 )
     temp = benchmark_energy + self.offset
     #Choose minimum of benchmark_energy if there already exists self.benchmark_energy
     self.benchmark_energy = min(self.benchmark_energy, temp) if self.benchmark_energy else temp
     return self.benchmark_energy
Example #6
0
 def get_random_energy(self):
     #Get random benchmark energy for 0 layer QAOA (achieved by using layer 1 QAOA with [0,0] angles)
     random_energy, _ = CustomQAOA(
         operator=self.operator,
         quantum_instance=self.quantum_instance,
         optimizer=self.optimizer,
         reps=1,
         initial_state=self.initial_state,
         mixer=self.mixer,
         solve=False,
     )
     temp = random_energy
     self.random_energy = temp + self.offset
     if np.round(self.random_energy - self.opt_value, 6) < 1e-7:
         print(
             "0 layer QAOA converged to exact solution. Shifting value up by |exact_ground_energy| instead to avoid dividing by 0 in approx quality."
         )
         self.random_energy += np.abs(self.random_energy)
     print("random energy: {}".format(self.random_energy))
Example #7
0
    def solve_qaoa(self, p, **kwargs):
        print("USING CUSTOM CODE")
        point = kwargs.get(
            "point", None
        )  #Make sure point here is already in FOURIER space of length 2(p-1)
        fourier_parametrise = kwargs.get("fourier_parametrise", False)
        tqa = kwargs.get('tqa', False)
        points = kwargs.get("points", None)
        construct_circ = kwargs.get("construct_circ", False)

        if tqa:
            deltas = np.arange(0.25, 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]
            if fourier_parametrise:
                points = [
                    convert_to_fourier_point(point, len(point))
                    for point in points
                ]
            qaoa_results, circ = CustomQAOA(
                self.operator,
                self.quantum_instance,
                self.optimizer,
                reps=p,
                initial_state=self.initial_state,
                mixer=self.mixer,
                fourier_parametrise=fourier_parametrise,
                list_points=points,
                qubo=self.qubo,
                construct_circ=construct_circ)
        elif points is not None:
            if fourier_parametrise:
                points = [
                    convert_to_fourier_point(point, len(point))
                    for point in points
                ]
                if point is not None:
                    points.append(convert_to_fourier_point(point, len(point)))
            else:
                points.append(point)

            qaoa_results, circ = CustomQAOA(
                self.operator,
                self.quantum_instance,
                self.optimizer,
                reps=p,
                initial_state=self.initial_state,
                mixer=self.mixer,
                fourier_parametrise=fourier_parametrise,
                list_points=points,
                qubo=self.qubo,
                construct_circ=construct_circ)
        elif point is not None:
            if fourier_parametrise:
                initial_point = convert_to_fourier_point(point, len(point))
            qaoa_results, circ = CustomQAOA(
                self.operator,
                self.quantum_instance,
                self.optimizer,
                reps=p,
                initial_state=self.initial_state,
                initial_point=point,
                mixer=self.mixer,
                fourier_parametrise=fourier_parametrise,
                qubo=self.qubo,
                construct_circ=construct_circ)
        else:
            points = [[0] * (2 * p)] + [[
                1.98 * np.pi * (np.random.rand() - 0.5) for _ in range(2 * p)
            ] for _ in range(10)]
            qaoa_results, circ = CustomQAOA(
                self.operator,
                self.quantum_instance,
                self.optimizer,
                reps=p,
                initial_state=self.initial_state,
                list_points=points,
                mixer=self.mixer,
                fourier_parametrise=fourier_parametrise,
                qubo=self.qubo,
                construct_circ=construct_circ)
        if circ:
            print(circ.draw(fold=200))
        optimal_point = qaoa_results.optimal_point
        eigenvalue = sum([x[1] * x[2] for x in qaoa_results.eigenstate])
        qaoa_results.eigenvalue = eigenvalue
        self.optimal_point = optimal_point

        self.qaoa_result = qaoa_results

        #Sort states by decreasing probability
        sorted_eigenstate_by_prob = sorted(qaoa_results.eigenstate,
                                           key=lambda x: x[2],
                                           reverse=True)

        #print sorted state in a table
        self.print_state(sorted_eigenstate_by_prob)

        #Other print stuff
        print("Eigenvalue: {}".format(eigenvalue))
        print("Optimal point: {}".format(optimal_point))
        print("Optimizer Evals: {}".format(qaoa_results.optimizer_evals))
        scale = self.random_energy - self.opt_value

        approx_quality_2 = np.round(
            (self.random_energy - sorted_eigenstate_by_prob[0][1]) / scale, 3)
        energy_prob = {}
        for x in qaoa_results.eigenstate:
            energy_prob[np.round(
                x[1], 6)] = energy_prob.get(np.round(x[1], 6), 0) + x[2]
        prob_s = np.round(energy_prob.get(np.round(self.opt_value, 6), 0), 6)
        self.prob_s.append(prob_s)
        self.eval_s.append(eigenvalue)
        self.approx_s.append(approx_quality_2)
        print("\nQAOA most probable solution: {}".format(
            sorted_eigenstate_by_prob[0]))
        print("Approx_quality: {}".format(approx_quality_2))
Example #8
0
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))
Example #9
0
    def solve_qaoa(self, p, **kwargs):
        if self.optimal_point and 'point' not in kwargs:
            point = self.optimal_point
        else:
            point = kwargs.get("point", None)
        fourier_parametrise = True
        self.optimizer.set_options(maxeval=1000)
        tqa = kwargs.get('tqa', False)
        points = kwargs.get("points", None)
        symmetrised = self.symmetrise

        #Can sometimes end up with zero operator when substituting variables when we only have ZZ terms (symmetrised qubo),
        #e.g. if H = ZIZ (=Z1Z3 for 3 qubit system) and we know <Z1 Z3> = 1, so after substition H = II for the 2 qubit system.
        #H = II is then treated as an offset and not a Pauli operator, so the QUBO results to a zero (pauli) operator.
        #In such cases it means the QUBO is fully solved and any solution will do, so chose "0" string as the solution.
        #This also makes sure that ancilla bit is in 0 state. (we could equivalently choose something like "100" instead the "000" for 3 remaining variables)solve
        def valid_operator(qubo):
            num_vars = qubo.get_num_vars()
            operator, _ = qubo.to_ising()
            valid = False
            operator = [operator] if isinstance(
                operator,
                PauliOp) else operator  #Make a list if only one single PauliOp
            for op_1 in operator:
                coeff, op_1 = op_1.to_pauli_op().coeff, op_1.to_pauli_op(
                ).primitive
                if coeff >= 1e-6 and op_1 != "I" * num_vars:  #if at least one non-zero then return valid ( valid = True )
                    valid = True
            return valid

        valid_op = valid_operator(self.qubo)
        num_vars = self.qubo.get_num_vars()

        if num_vars >= 1 and symmetrised and not valid_op:
            qaoa_results = self.qaoa_result
            qaoa_results.eigenstate = [
                ('0' * num_vars, self.qubo.objective.evaluate([0] * num_vars),
                 1)
            ]
            qaoa_results.optimizer_evals = 0
            qaoa_results.eigenvalue = self.qubo.objective.evaluate([0] *
                                                                   num_vars)
            qc = QuantumCircuit(num_vars)

        elif tqa:
            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]
            fourier_parametrise = True
            if fourier_parametrise:
                points = [
                    QAOAEx.convert_to_fourier_point(point, len(point))
                    for point in points
                ]
            qaoa_results, _ = CustomQAOA(
                self.operator,
                self.quantum_instance,
                self.optimizer,
                reps=p,
                initial_state=self.initial_state,
                mixer=self.mixer,
                fourier_parametrise=fourier_parametrise,
                list_points=points,
                qubo=self.qubo)

        elif points is not None:
            fourier_parametrise = True
            if fourier_parametrise:
                points = [
                    QAOAEx.convert_to_fourier_point(point, len(point))
                    for point in points
                ]
            qaoa_results, _ = CustomQAOA(
                self.operator,
                self.quantum_instance,
                self.optimizer,
                reps=p,
                initial_state=self.initial_state,
                mixer=self.mixer,
                fourier_parametrise=fourier_parametrise,
                list_points=points,
                qubo=self.qubo)

        elif point is None:
            list_points = [0] * (2 * p) + [[
                2 * np.pi * (np.random.rand() - 0.5) for _ in range(2 * p)
            ] for _ in range(5)]
            fourier_parametrise = True
            if fourier_parametrise:
                points = [
                    QAOAEx.convert_to_fourier_point(point, len(point))
                    for point in points
                ]
            qaoa_results, _ = CustomQAOA(
                self.operator,
                self.quantum_instance,
                self.optimizer,
                reps=p,
                initial_state=self.initial_state,
                list_points=points,
                mixer=self.mixer,
                fourier_parametrise=fourier_parametrise,
                qubo=self.qubo)
        else:
            fourier_parametrise = True
            if fourier_parametrise:
                point = QAOAEx.convert_to_fourier_point(point, len(point))
            qaoa_results, _ = CustomQAOA(
                self.operator,
                self.quantum_instance,
                self.optimizer,
                reps=p,
                initial_state=self.initial_state,
                initial_point=point,
                mixer=self.mixer,
                fourier_parametrise=fourier_parametrise,
                qubo=self.qubo)

        point = qaoa_results.optimal_point
        qaoa_results.eigenvalue = sum(
            [x[1] * x[2] for x in qaoa_results.eigenstate])
        self.optimal_point = QAOAEx.convert_to_fourier_point(
            point, len(point)) if fourier_parametrise else point
        self.qaoa_result = qaoa_results

        #Sort states by increasing energy and decreasing probability
        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)

        #print energy-sorted state in a table
        self.print_state(sorted_eigenstate_by_energy)

        #Other print stuff
        print("Eigenvalue: {}".format(qaoa_results.eigenvalue))
        print("Optimal point: {}".format(qaoa_results.optimal_point))
        print("Optimizer Evals: {}".format(qaoa_results.optimizer_evals))
        scale = self.random_energy - self.result.fval
        approx_quality = np.round(
            (self.random_energy - sorted_eigenstate_by_energy[0][1]) / scale,
            3)
        approx_quality_2 = np.round(
            (self.random_energy - sorted_eigenstate_by_prob[0][1]) / scale, 3)
        energy_prob = {}
        for x in qaoa_results.eigenstate:
            energy_prob[np.round(
                x[1], 6)] = energy_prob.get(np.round(x[1], 6), 0) + x[2]
        prob_s = np.round(energy_prob.get(np.round(self.result.fval, 6), 0), 6)
        self.prob_s.append(prob_s)
        self.approx_s.append([approx_quality, approx_quality_2])
        print("\nQAOA lowest energy solution: {}".format(
            sorted_eigenstate_by_energy[0]))
        print("Approx_quality: {}".format(approx_quality))
        print("\nQAOA most probable solution: {}".format(
            sorted_eigenstate_by_prob[0]))
        print("Approx_quality: {}".format(approx_quality_2))

        return qaoa_results
Example #10
0
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))
Example #11
0
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))