def set_backend(self, backend: Union[Backend, BaseBackend], **kwargs) -> None:
        """ Sets backend with configuration.

        Raises:
            ValueError: statevector or param_qobj are True when not supported by backend.
        """
        self.quantum_instance = QuantumInstance(backend)
        self.quantum_instance.set_config(**kwargs)
Example #2
0
    def __init__(self, **kwargs):
        self.qubo = kwargs.get("qubo", None)
        if self.qubo is not None:
            self.operator, self.offset = self.qubo.to_ising()
        self.no_cars = kwargs.get("no_cars", 0)
        self.no_routes = kwargs.get("no_routes", 0)
        self.symmetrise = kwargs.get("symmetrise", False)
        self.customise = kwargs.get("customise", False)
        opt_str = kwargs.get('opt_str', "LN_BOBYQA")
        print("Optimizer: {}".format(opt_str))
        self.optimizer = NLOPT_Optimizer(opt_str)
        self.optimizer.set_options(maxeval=200)
        self.original_qubo = deepcopy(self.qubo)

        #Benchmarking, using classical result for ground state energy, and then random energy measurement.
        self.classical_result = kwargs.get("classical_result", None)
        self.solve_classically()
        self.random_instance = QuantumInstance(
            backend=Aer.get_backend("aer_simulator_matrix_product_state"),
            shots=1000)  #1000 randomly measured
        self.get_random_energy()

        #Simulation methods
        simulator = kwargs.get("simulator", None)
        noise_model = kwargs.get("noise_model", None)
        if simulator == None:
            simulator = "aer_simulator_density_matrix"
        print("Using " + simulator)

        self.quantum_instance = QuantumInstance(
            backend=Aer.get_backend(simulator),
            shots=8192,
            noise_model=noise_model,
            basis_gates=["cx", "x", "sx", "rz", "id"])

        #Symmetrise
        if self.symmetrise:
            self.symmetrise_qubo()

        #Customise QAOA
        if self.customise:
            self.construct_initial_state(symmetrise=self.symmetrise)
            self.construct_mixer()
        else:
            self.initial_state = None
            self.mixer = None

        #Results placeholder
        self.prob_s = []
        self.eval_s = []
        self.approx_s = []
Example #3
0
 def quantum_instance(
     self, quantum_instance: Union[QuantumInstance, BaseBackend,
                                   Backend]) -> None:
     """ Sets quantum instance. """
     if isinstance(quantum_instance, (BaseBackend, Backend)):
         quantum_instance = QuantumInstance(quantum_instance)
     self._quantum_instance = quantum_instance
Example #4
0
    def quantum_instance(self, quantum_instance: Union[QuantumInstance,
                                                       Backend, BaseBackend]) -> None:
        """ Sets the QuantumInstance.

        Raises:
            ValueError: statevector or param_qobj are True when not supported by backend.
        """
        if isinstance(quantum_instance, (Backend, BaseBackend)):
            quantum_instance = QuantumInstance(quantum_instance)
        self._quantum_instance = quantum_instance
        self._check_quantum_instance_and_modes_consistent()
    def __init__(
        self,
        backend: Union[Backend, BaseBackend, QuantumInstance],
        statevector: Optional[bool] = None,
        param_qobj: bool = False,
        attach_results: bool = False,
        caching: str = "last",
    ) -> None:
        """
        Args:
            backend: The quantum backend or QuantumInstance to use to sample the circuits.
            statevector: If backend is a statevector backend, whether to replace the
                CircuitStateFns with DictStateFns (from the counts) or VectorStateFns (from the
                statevector). ``None`` will set this argument automatically based on the backend.
            attach_results: Whether to attach the data from the backend ``Results`` object for
                a given ``CircuitStateFn``` to an ``execution_results`` field added the converted
                ``DictStateFn`` or ``VectorStateFn``.
            param_qobj: Whether to use Aer's parameterized Qobj capability to avoid re-assembling
                the circuits.
            caching: The caching strategy. Can be `'last'` (default) to store the last operator
                that was converted, set to `'all'` to cache all processed operators.

        Raises:
            ValueError: Set statevector or param_qobj True when not supported by backend.
        """
        self._quantum_instance = (
            backend if isinstance(backend, QuantumInstance) else QuantumInstance(backend=backend)
        )
        self._statevector = (
            statevector if statevector is not None else self.quantum_instance.is_statevector
        )
        # Set to False until https://github.com/Qiskit/qiskit-aer/issues/1249 is closed.
        param_qobj = False
        self._param_qobj = param_qobj
        self._attach_results = attach_results

        self._check_quantum_instance_and_modes_consistent()

        # Object state variables
        self._caching = caching
        self._cached_ops: Dict[int, OperatorCache] = {}

        self._last_op: Optional[OperatorBase] = None
        self._reduced_op_cache = None
        self._circuit_ops_cache: Dict[int, CircuitStateFn] = {}
        self._transpiled_circ_cache: Optional[List[Any]] = None
        self._transpiled_circ_templates: Optional[List[Any]] = None
        self._transpile_before_bind = True
Example #6
0
    def __init__(self,
                 backend: Union[Backend, BaseBackend, QuantumInstance],
                 statevector: Optional[bool] = None,
                 param_qobj: bool = False,
                 attach_results: bool = False) -> None:
        """
        Args:
            backend: The quantum backend or QuantumInstance to use to sample the circuits.
            statevector: If backend is a statevector backend, whether to replace the
                CircuitStateFns with DictStateFns (from the counts) or VectorStateFns (from the
                statevector). ``None`` will set this argument automatically based on the backend.
            attach_results: Whether to attach the data from the backend ``Results`` object for
                a given ``CircuitStateFn``` to an ``execution_results`` field added the converted
                ``DictStateFn`` or ``VectorStateFn``.
            param_qobj: Whether to use Aer's parameterized Qobj capability to avoid re-assembling
                the circuits.

        Raises:
            ValueError: Set statevector or param_qobj True when not supported by backend.
        """
        self._quantum_instance = backend if isinstance(backend, QuantumInstance) else\
            QuantumInstance(backend=backend)
        self._statevector = statevector if statevector is not None \
            else self.quantum_instance.is_statevector
        self._param_qobj = param_qobj
        self._attach_results = attach_results

        self._check_quantum_instance_and_modes_consistent()

        # Object state variables
        self._last_op = None
        self._reduced_op_cache = None
        self._circuit_ops_cache = {}  # type: Dict[int, CircuitStateFn]
        self._transpiled_circ_cache = None  # type: Optional[List[Any]]
        self._transpiled_circ_templates = None  # type: Optional[List[Any]]
        self._transpile_before_bind = True
        self._binding_mappings = None
Example #7
0
 def __init__(self, qubo, no_cars, no_routes, **kwargs):
     opt_str = kwargs.get('opt_str', "LN_SBPLX")
     self.symmetrise = kwargs.get('symmetrise', False)
     var_list = qubo.variables
     self.optimizer = NLOPT_Optimizer(opt_str)
     self.optimizer.set_options(max_eval=1000)
     self.original_qubo = qubo
     self.qubo = qubo
     self.solve_classically()
     op, offset = qubo.to_ising()
     self.operator = op
     self.offset = offset
     if self.symmetrise:
         self.symmetrise_qubo()
     self.quantum_instance = QuantumInstance(
         backend=Aer.get_backend("aer_simulator_matrix_product_state"),
         shots=4096)
     self.replacements = {var.name: None for var in var_list}
     self.no_cars = no_cars
     self.no_routes = no_routes
     self.car_blocks = np.empty(shape=(no_cars, ), dtype=object)
     for car_no in range(no_cars):
         self.car_blocks[car_no] = [
             "X_{}_{}".format(car_no, route_no)
             for route_no in range(no_routes)
         ]
     self.qaoa_result = None
     self.benchmark_energy = None
     self.var_values = {}
     self.construct_initial_state()
     self.construct_mixer()
     self.get_random_energy()
     self.get_benchmark_energy()
     self.prob_s = []
     self.approx_s = []
     self.optimal_point = None
Example #8
0
 def __init__(self, qubo, no_cars, no_routes):
     var_list = qubo.variables
     opt_str = "LN_SBPLX"
     print("Optimizer: {}".format(opt_str))
     self.optimizer = NLOPT_Optimizer(opt_str)
     self.original_qubo = qubo
     self.qubo = qubo
     op, offset = qubo.to_ising()
     self.operator = op
     self.offset = offset
     self.quantum_instance = QuantumInstance(backend = Aer.get_backend("aer_simulator_matrix_product_state"), shots = 1024)
     self.replacements = {var.name:None for var in var_list}
     self.no_cars = no_cars
     self.no_routes = no_routes
     self.car_blocks = np.empty(shape = (no_cars,), dtype=object)
     for car_no in range(no_cars):
         self.car_blocks[car_no] = ["X_{}_{}".format(car_no, route_no) for route_no in range(no_routes)]
     self.qaoa_result = None
     self.benchmark_energy = None
     self.var_values = {}
     self.construct_initial_state()
     self.construct_mixer()
     self.get_random_energy()
     self.get_benchmark_energy()
Example #9
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 #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
class CircuitSampler(ConverterBase):
    """
    The CircuitSampler traverses an Operator and converts any CircuitStateFns into
    approximations of the state function by a DictStateFn or VectorStateFn using a quantum
    backend. Note that in order to approximate the value of the CircuitStateFn, it must 1) send
    state function through a depolarizing channel, which will destroy all phase information and
    2) replace the sampled frequencies with **square roots** of the frequency, rather than the raw
    probability of sampling (which would be the equivalent of sampling the **square** of the
    state function, per the Born rule.

    The CircuitSampler aggressively caches transpiled circuits to handle re-parameterization of
    the same circuit efficiently. If you are converting multiple different Operators,
    you are better off using a different CircuitSampler for each Operator to avoid cache thrashing.
    """
    def __init__(self,
                 backend: Union[Backend, BaseBackend, QuantumInstance],
                 statevector: Optional[bool] = None,
                 param_qobj: bool = False,
                 attach_results: bool = False) -> None:
        """
        Args:
            backend: The quantum backend or QuantumInstance to use to sample the circuits.
            statevector: If backend is a statevector backend, whether to replace the
                CircuitStateFns with DictStateFns (from the counts) or VectorStateFns (from the
                statevector). ``None`` will set this argument automatically based on the backend.
            attach_results: Whether to attach the data from the backend ``Results`` object for
                a given ``CircuitStateFn``` to an ``execution_results`` field added the converted
                ``DictStateFn`` or ``VectorStateFn``.
            param_qobj: Whether to use Aer's parameterized Qobj capability to avoid re-assembling
                the circuits.

        Raises:
            ValueError: Set statevector or param_qobj True when not supported by backend.
        """
        self._quantum_instance = backend if isinstance(backend, QuantumInstance) else\
            QuantumInstance(backend=backend)
        self._statevector = statevector if statevector is not None \
            else self.quantum_instance.is_statevector
        self._param_qobj = param_qobj
        self._attach_results = attach_results

        self._check_quantum_instance_and_modes_consistent()

        # Object state variables
        self._last_op = None
        self._reduced_op_cache = None
        self._circuit_ops_cache = {}  # type: Dict[int, CircuitStateFn]
        self._transpiled_circ_cache = None  # type: Optional[List[Any]]
        self._transpiled_circ_templates = None  # type: Optional[List[Any]]
        self._transpile_before_bind = True
        self._binding_mappings = None

    def _check_quantum_instance_and_modes_consistent(self) -> None:
        """ Checks whether the statevector and param_qobj settings are compatible with the
        backend

        Raises:
            ValueError: statevector or param_qobj are True when not supported by backend.
        """
        if self._statevector and not is_statevector_backend(
                self.quantum_instance.backend):
            raise ValueError(
                'Statevector mode for circuit sampling requires statevector '
                'backend, not {}.'.format(self.quantum_instance.backend))

        if self._param_qobj and not is_aer_provider(
                self.quantum_instance.backend):
            raise ValueError('Parameterized Qobj mode requires Aer '
                             'backend, not {}.'.format(
                                 self.quantum_instance.backend))

    @property
    def backend(self) -> Union[Backend, BaseBackend]:
        """ Returns the backend.

        Returns:
             The backend used by the CircuitSampler
        """
        return self.quantum_instance.backend

    @backend.setter
    def backend(self, backend: Union[Backend, BaseBackend]):
        """ Sets backend without additional configuration. """
        self.set_backend(backend)

    def set_backend(self, backend: Union[Backend, BaseBackend],
                    **kwargs) -> None:
        """ Sets backend with configuration.

        Raises:
            ValueError: statevector or param_qobj are True when not supported by backend.
        """
        self.quantum_instance = QuantumInstance(backend)
        self.quantum_instance.set_config(**kwargs)

    @property
    def quantum_instance(self) -> QuantumInstance:
        """ Returns the quantum instance.

        Returns:
             The QuantumInstance used by the CircuitSampler
        """
        return self._quantum_instance

    @quantum_instance.setter
    def quantum_instance(
        self, quantum_instance: Union[QuantumInstance, Backend,
                                      BaseBackend]) -> None:
        """ Sets the QuantumInstance.

        Raises:
            ValueError: statevector or param_qobj are True when not supported by backend.
        """
        if isinstance(quantum_instance, (Backend, BaseBackend)):
            quantum_instance = QuantumInstance(quantum_instance)
        self._quantum_instance = quantum_instance
        self._check_quantum_instance_and_modes_consistent()

    # pylint: disable=arguments-differ
    def convert(
        self,
        operator: OperatorBase,
        params: Optional[Dict[Parameter, Union[float, List[float],
                                               List[List[float]]]]] = None
    ) -> OperatorBase:
        r"""
        Converts the Operator to one in which the CircuitStateFns are replaced by
        DictStateFns or VectorStateFns. Extracts the CircuitStateFns out of the Operator,
        caches them, calls ``sample_circuits`` below to get their converted replacements,
        and replaces the CircuitStateFns in operator with the replacement StateFns.

        Args:
            operator: The Operator to convert
            params: A dictionary mapping parameters to either single binding values or lists of
                binding values.

        Returns:
            The converted Operator with CircuitStateFns replaced by DictStateFns or VectorStateFns.
        Raises:
            OpflowError: if extracted circuits are empty.
        """
        if self._last_op is None or id(operator) != id(self._last_op):
            # Clear caches
            self._last_op = operator
            self._reduced_op_cache = None
            self._circuit_ops_cache = None
            self._transpiled_circ_cache = None
            self._transpile_before_bind = True

        if not self._reduced_op_cache:
            operator_dicts_replaced = operator.to_circuit_op()
            self._reduced_op_cache = operator_dicts_replaced.reduce()

        if not self._circuit_ops_cache:
            self._circuit_ops_cache = {}
            self._extract_circuitstatefns(self._reduced_op_cache)
            if not self._circuit_ops_cache:
                raise OpflowError(
                    'Circuits are empty. '
                    'Check that the operator is an instance of CircuitStateFn or its ListOp.'
                )

        if params is not None and len(params.keys()) > 0:
            p_0 = list(params.values())[0]  # type: ignore
            if isinstance(p_0, (list, np.ndarray)):
                num_parameterizations = len(cast(List, p_0))
                param_bindings = [
                    {
                        param: value_list[i]  # type: ignore
                        for (param, value_list) in params.items()
                    } for i in range(num_parameterizations)
                ]
            else:
                num_parameterizations = 1
                param_bindings = [params]  # type: ignore

        else:
            param_bindings = None
            num_parameterizations = 1

        # Don't pass circuits if we have in the cache, the sampling function knows to use the cache
        circs = list(self._circuit_ops_cache.values()
                     ) if not self._transpiled_circ_cache else None
        p_b = cast(List[Dict[Parameter, float]], param_bindings)
        sampled_statefn_dicts = self.sample_circuits(circuit_sfns=circs,
                                                     param_bindings=p_b)

        def replace_circuits_with_dicts(operator, param_index=0):
            if isinstance(operator, CircuitStateFn):
                return sampled_statefn_dicts[id(operator)][param_index]
            elif isinstance(operator, ListOp):
                return operator.traverse(
                    partial(replace_circuits_with_dicts,
                            param_index=param_index))
            else:
                return operator

        if params:
            return ListOp([
                replace_circuits_with_dicts(self._reduced_op_cache,
                                            param_index=i)
                for i in range(num_parameterizations)
            ])
        else:
            return replace_circuits_with_dicts(self._reduced_op_cache,
                                               param_index=0)

    def _extract_circuitstatefns(self, operator: OperatorBase) -> None:
        r"""
        Recursively extract the ``CircuitStateFns`` contained in operator into the
        ``_circuit_ops_cache`` field.
        """
        if isinstance(operator, CircuitStateFn):
            self._circuit_ops_cache[id(operator)] = operator
        elif isinstance(operator, ListOp):
            for op in operator.oplist:
                self._extract_circuitstatefns(op)

    def sample_circuits(
        self,
        circuit_sfns: Optional[List[CircuitStateFn]] = None,
        param_bindings: Optional[List[Dict[Parameter, float]]] = None
    ) -> Dict[int, Union[StateFn, List[StateFn]]]:
        r"""
        Samples the CircuitStateFns and returns a dict associating their ``id()`` values to their
        replacement DictStateFn or VectorStateFn. If param_bindings is provided,
        the CircuitStateFns are broken into their parameterizations, and a list of StateFns is
        returned in the dict for each circuit ``id()``. Note that param_bindings is provided here
        in a different format than in ``convert``, and lists of parameters within the dict is not
        supported, and only binding dicts which are valid to be passed into Terra can be included
        in this list.

        Args:
            circuit_sfns: The list of CircuitStateFns to sample.
            param_bindings: The parameterizations to bind to each CircuitStateFn.

        Returns:
            The dictionary mapping ids of the CircuitStateFns to their replacement StateFns.
        Raises:
            OpflowError: if extracted circuits are empty.
        """
        if not circuit_sfns and not self._transpiled_circ_cache:
            raise OpflowError('CircuitStateFn is empty and there is no cache.')

        if circuit_sfns:
            self._transpiled_circ_templates = None
            if self._statevector:
                circuits = [
                    op_c.to_circuit(meas=False) for op_c in circuit_sfns
                ]
            else:
                circuits = [
                    op_c.to_circuit(meas=True) for op_c in circuit_sfns
                ]

            try:
                self._transpiled_circ_cache = self.quantum_instance.transpile(
                    circuits)
            except QiskitError:
                logger.debug(
                    r'CircuitSampler failed to transpile circuits with unbound '
                    r'parameters. Attempting to transpile only when circuits are bound '
                    r'now, but this can hurt performance due to repeated transpilation.'
                )
                self._transpile_before_bind = False
                self._transpiled_circ_cache = circuits
        else:
            circuit_sfns = list(self._circuit_ops_cache.values())

        if param_bindings is not None:
            if self._param_qobj:
                start_time = time()
                ready_circs = self._prepare_parameterized_run_config(
                    param_bindings)
                end_time = time()
                logger.debug('Parameter conversion %.5f (ms)',
                             (end_time - start_time) * 1000)
            else:
                start_time = time()
                ready_circs = [
                    circ.assign_parameters(_filter_params(circ, binding))
                    for circ in self._transpiled_circ_cache
                    for binding in param_bindings
                ]
                end_time = time()
                logger.debug('Parameter binding %.5f (ms)',
                             (end_time - start_time) * 1000)
        else:
            ready_circs = self._transpiled_circ_cache

        results = self.quantum_instance.execute(
            ready_circs, had_transpiled=self._transpile_before_bind)

        if param_bindings is not None and self._param_qobj:
            self._clean_parameterized_run_config()

        # Wipe parameterizations, if any
        # self.quantum_instance._run_config.parameterizations = None

        sampled_statefn_dicts = {}
        for i, op_c in enumerate(circuit_sfns):
            # Taking square root because we're replacing a statevector
            # representation of probabilities.
            reps = len(param_bindings) if param_bindings is not None else 1
            c_statefns = []
            for j in range(reps):
                circ_index = (i * reps) + j
                circ_results = results.data(circ_index)

                if 'expval_measurement' in circ_results.get(
                        'snapshots', {}).get('expectation_value', {}):
                    snapshot_data = results.data(circ_index)['snapshots']
                    avg = snapshot_data['expectation_value'][
                        'expval_measurement'][0]['value']
                    if isinstance(avg, (list, tuple)):
                        # Aer versions before 0.4 use a list snapshot format
                        # which must be converted to a complex value.
                        avg = avg[0] + 1j * avg[1]
                    # Will be replaced with just avg when eval is called later
                    num_qubits = circuit_sfns[0].num_qubits
                    result_sfn = DictStateFn(
                        '0' * num_qubits,
                        is_measurement=op_c.is_measurement) * avg
                elif self._statevector:
                    result_sfn = StateFn(op_c.coeff *
                                         results.get_statevector(circ_index),
                                         is_measurement=op_c.is_measurement)
                else:
                    shots = self.quantum_instance._run_config.shots
                    result_sfn = StateFn(
                        {
                            b: (v / shots)**0.5 * op_c.coeff
                            for (b,
                                 v) in results.get_counts(circ_index).items()
                        },
                        is_measurement=op_c.is_measurement)
                if self._attach_results:
                    result_sfn.execution_results = circ_results
                c_statefns.append(result_sfn)
            sampled_statefn_dicts[id(op_c)] = c_statefns
        return sampled_statefn_dicts

    def _build_aer_params(self, circuit: QuantumCircuit,
                          building_param_tables: Dict[Tuple[int, int],
                                                      List[float]],
                          input_params: Dict[Parameter, float]) -> None:
        def resolve_param(inst_param):
            if not isinstance(inst_param, ParameterExpression):
                return None
            param_mappings = {}
            for param in inst_param._parameter_symbols.keys():
                if param not in input_params:
                    raise ValueError('unexpected parameter: {0}'.format(param))
                param_mappings[param] = input_params[param]
            return float(inst_param.bind(param_mappings))

        gate_index = 0
        for inst, _, _ in circuit.data:
            param_index = 0
            for inst_param in inst.params:
                val = resolve_param(inst_param)
                if val is not None:
                    param_key = (gate_index, param_index)
                    if param_key in building_param_tables:
                        building_param_tables[param_key].append(val)
                    else:
                        building_param_tables[param_key] = [val]
                param_index += 1
            gate_index += 1

    def _prepare_parameterized_run_config(
            self, param_bindings: List[Dict[Parameter, float]]) -> List[Any]:

        self.quantum_instance._run_config.parameterizations = []

        if self._transpiled_circ_templates is None \
                or len(self._transpiled_circ_templates) != len(self._transpiled_circ_cache):

            # temporally resolve parameters of self._transpiled_circ_cache
            # They will be overridden in Aer from the next iterations
            self._transpiled_circ_templates = [
                circ.assign_parameters(_filter_params(circ, param_bindings[0]))
                for circ in self._transpiled_circ_cache
            ]

        for circ in self._transpiled_circ_cache:
            building_param_tables = {
            }  # type: Dict[Tuple[int, int], List[float]]
            for param_binding in param_bindings:
                self._build_aer_params(circ, building_param_tables,
                                       param_binding)
            param_tables = []
            for gate_and_param_indices in building_param_tables:
                gate_index = gate_and_param_indices[0]
                param_index = gate_and_param_indices[1]
                param_tables.append([[gate_index, param_index],
                                     building_param_tables[(gate_index,
                                                            param_index)]])
            self.quantum_instance._run_config.parameterizations.append(
                param_tables)

        return self._transpiled_circ_templates

    def _clean_parameterized_run_config(self) -> None:
        self.quantum_instance._run_config.parameterizations = []
Example #12
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))
Example #13
0
 def __init__(self, qubo, no_cars, no_routes, **kwargs):
     opt_str = kwargs.get('opt_str', "LN_COBYLA")
     self.symmetrise = kwargs.get('symmetrise', False)
     self.customise = kwargs.get('customise', True)
     self.classical_result = kwargs.get("classical_result", None)
     simulator = kwargs.get("simulator", "aer_simulator_matrix_product_state")
     noise_model = kwargs.get("noise_model", None)
     
     if simulator == None:
         simulator = "aer_simulator_matrix_product_state"
     
     #Initializing other algorithm required objects
     var_list = qubo.variables
     if noise_model == None:
         self.quantum_instance = QuantumInstance( backend = Aer.get_backend(simulator), shots = 4096)
     elif noise_model:
         self.quantum_instance = QuantumInstance( backend = Aer.get_backend(simulator),
                                                  shots = 4096, 
                                                  noise_model = noise_model,
                                                  basis_gates = ["cx", "x", "sx", "rz", "id"]
                                                )
                                                 
     self.random_instance = QuantumInstance(backend = Aer.get_backend("aer_simulator_matrix_product_state"), shots = 1000)
     #print backend name
     print("Quantum Instance: {}\n".format(self.quantum_instance.backend_name))
     #print backend name
     
     self.optimizer = NLOPT_Optimizer(opt_str)
     self.optimizer.set_options(max_eval = 1000)
     self.original_qubo = qubo
     self.qubo = qubo
     self.operator, self.offset = qubo.to_ising()
     
     #If no classical result, this will compute the appropriate self.classical_result, else this will simply re-organise already available result    
     self.solve_classically() 
      
     #Setup for variable replacements
     self.replacements = {var.name:None for var in var_list}
     self.no_cars = no_cars
     self.no_routes = no_routes
     self.car_blocks = np.empty(shape = (no_cars,), dtype=object)
     for car_no in range(no_cars):
         self.car_blocks[car_no] = ["X_{}_{}".format(car_no, route_no) for route_no in range(no_routes)]
     
     #Initialize variable placeholders in
     self.qaoa_result = None
     self.initial_state = None
     self.mixer = None
     self.benchmark_energy = None
     self.var_values = {}
     self.prob_s = []
     self.approx_s = []
     self.optimal_point = None
     
     #Random energy
     self.get_random_energy()
     
     #Symmetrise QUBO if required (after getting random energy WITHOUT ancilla)
     if self.symmetrise: 
         self.symmetrise_qubo()
         
     #Custom initial state and mixer if required
     if self.customise:
         if self.symmetrise:
             self.construct_initial_state(ancilla = True)
         else:
             self.construct_initial_state()
         self.construct_mixer()
Example #14
0
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))
Example #15
0
def main():
    #Must load after importing/defining Ox_Route and QAOA_Traffic classes
    with open("traffic.pkl", 'rb') as f:
        traffic = pkl.load(f)

    routing_dict = {
        var: traffic.routing_dict()[var].routing()
        for var in traffic.routing_dict()
    }
    edges_dict = get_edges_dict(routing_dict)
    new_dict = deepcopy(edges_dict)
    #Remove edges with <50m overlaps.
    for edge, value in edges_dict.items():
        weight = 0
        edge_data = traffic.obtain_map().get_edge_data(*edge,
                                                       default=[None])[0]
        if edge_data:
            weight += edge_data["length"]
        if weight < 50:
            # print(edge, value, weight)
            new_dict.pop(edge, None)
    variable_renaming = {
        "Car_{}_Route_{}".format(str(i).zfill(2), j):
        "X_{}_{}".format(str(i).zfill(2), j)
        for i, j in product(range(21), range(3))
    }
    new_edges_dict = {}
    for edge, variables in new_dict.items():
        new_edges_dict[edge] = [variable_renaming[var] for var in variables]
    del edges_dict
    del new_dict
    global qubo
    unconstrained_qubo, linear, quadratic = build_qubo_unconstrained_from_edges_dict(
        traffic.obtain_map(),
        new_edges_dict,
        variables=variable_renaming.values())
    qubo = add_qubo_constraints(unconstrained_qubo, no_cars=21, no_routes=3)
    qubo, max_coeff = convert_qubo(qubo,
                                   linear,
                                   quadratic,
                                   penalty_multiplier=1.5)
    min_results = {}
    min_total_obj = 0
    max_results = {}
    max_total_obj = 0
    for car in range(21):
        zeros = [0] * 3
        assignments = [[0] * i + [1] + [0] * (2 - i) for i in range(3)]
        assignments_obj = {}
        for assignment in assignments:
            x = zeros * (car) + assignment + zeros * (20 - car)
            var_dict = {
                "X_{}_{}".format(str(int((k - k % 3) / 3)).zfill(2), k % 3):
                x[k]
                for k in range(len(x))
            }
            obj = unconstrained_qubo.objective.evaluate(var_dict)
            assignments_obj[tuple(assignment)] = obj
        min_assignment = min(assignments_obj.items(), key=lambda x: x[1])
        max_assignment = max(assignments_obj.items(), key=lambda x: x[1])
        min_total_obj += min_assignment[1]
        max_total_obj += max_assignment[1]
        min_car_dict_assignment = {
            "X_{}_{}".format(str(car).zfill(2), k): min_assignment[0][k]
            for k in range(3)
        }
        max_car_dict_assignment = {
            "X_{}_{}".format(str(car).zfill(2), k): max_assignment[0][k]
            for k in range(3)
        }
        for var, value in min_car_dict_assignment.items():
            min_results[var] = value
        for var, value in max_car_dict_assignment.items():
            max_results[var] = value
    greedy = qubo.objective.evaluate(min_results)
    max_greedy = qubo.objective.evaluate(max_results)
    print("Zeros:", qubo.objective.evaluate([0 for _ in range(63)]))
    print("MIN GREEDY:", greedy)
    print("Total distance traversed(min):", min_total_obj)
    print(min_results)
    print("MAX GREEDY:", max_greedy)
    print("Total distance traversed(max):", max_total_obj)
    print(max_results)
    optimizer = NELDER_MEAD()
    optimizer.set_options(maxiter=1)
    backend = Aer.get_backend("aer_simulator_matrix_product_state")
    quantum_instance = QuantumInstance(backend, shots=1)
    op, offset = qubo.to_ising()
    op *= 1 / max_coeff
    print(op)
    #     initial_state = construct_initial_state(no_routes = 3, no_cars = 21)
    #     mixer = n_qbit_mixer(initial_state)

    #p=1
    start = time()
    result, qc = QiskitQAOA(operator=op,
                            quantum_instance=quantum_instance,
                            optimizer=optimizer,
                            reps=1,
                            construct_circ=True,
                            initial_state=None,
                            mixer=None,
                            initial_point=[0, 0])
    print(qc.draw())
    print(qc.depth())
    end = time()
    print(result.eigenstate)
    print(max_coeff * (result.eigenvalue) + offset)
    print("p=1, Time taken: {}s".format(end - start))
    print(result.cost_function_evals)