Solve

Applying (quantum) algorithms to solve optimization problems

Overall, there are four different categories of algorithms available at the moment:

  • Quantum algorithms: Algorithms that are run on real quantum hardware such as IBM or D-Wave.
  • Hybrid algorithms: Algorithms that combine both quantum and classical hardware, often running certain computations on quantum hardware. These algorithms are often used to tackle the problem of the limited size of current quantum harwdare.
  • Quantum-inspired algorithms: Algorithms that are fully run on classical hardware, but mimic certain properties of quantum algorithms during their computation.
  • Classical algorithms: Algorithms that are run on classical hardware and are used today to solve optimization problems.

You can either retrieve a recommendation using our Recommendation Engine from the previous chapter, or choose your algorithms and the corresponding hardware yourself. You will be able to find a list of all implemented algorithms on our Solvers & Algorithm page as well as a list of all available quantum hardware providers' on our Quantum Hardware page.

To solve an optimization problem, you can either use the recommendation returned from our Recommendation Engine, or simply choose the algorithm yourself.

from typing import Dict, Any

# Solve the optimization instance with the recommendation from before
solver: str = recommendation.solver
params = recommendation.solver_params

# Returns the location where the solution can be found once solving is completed
solution = luna.solution.create(
    optimization_id=optimization_id,
    solver_name=solver,
    provider="dwave",
    solver_parameters=params,
)

# Or, alternatively, define your own solver to be used. Here, we use the classical heuristic Simulated Annealing
solver = "SA"

# The parameters and their meanings can be found on our Solvers & Algorithms page from our documentation
params = {
    'beta_range': None,
    'num_reads': None,
    'num_sweeps': 200,
    'beta_schedule_type': 'geometric',
    'initial_states_generator': 'random',
    'n_init_samples': 1,
    'timeout': 5
}

# When configuring the solver yourself, solving the problem still works the same way
solution = luna.solution.create(
    id=optimization_id, 
    solver=solver, 
    provider="dwave",
    params=params
)

# When omitting parameters or the whole parameter set, the solver will fall back to the default parameter values found in our documentation
solution = luna.solution.create(
    id=optimization_id, 
    solver=solver, 
    provider="dwave",
    params={}
)

Since some algorithms, especially those run on quantum hardware, can take some time to be executed, we don't want to keep you and the execution of your code waiting during this time. Instead, when a solution is requested, we will take care of all steps necesssary in an asynchronous fashion. This means that while your solution is being computed, you are free to do anything you want - and you can simply come back later, when the execution is finished.

# After the execution of your algorithm has been finished, retrieve your raw solution
solution = luna.solution.get(
    solution_id=solution.id
)

Note that this will return the raw solution that we get from the optimization algorithm that has been applied and which is dependent on the mathematical format that has been used. In case you are interested in the solution that has an interpretable meaning, there is one final step that needs to be done.

Postprocess: Understanding raw outputs from optimization algorithms

As the raw output that we get from these algorithms is usually not too helpful if you are not familiar with optimization algorithms, we provide the possibility to map this raw output back into the domain of our initial problem formulation.

Note that this feature only works for optimization problems generated through our use case library.

from luna_sdk.schemas.solution import UseCaseRepresentation


# Retrieve the usecase-specific representation of the solver solution
representation: UseCaseRepresentation = luna.solution.get_use_case_representation(
    solution_id=solution.id
)

Your solver's solution may contain multiple results, e.g., if you created the solution with one of DWave's annealing algoritms. In this case, the domain-specific solution contains representations for every one of the results. As users are often times only intereseted in the best of these result, we provide a function to retrieve the best result from a usecase-specific solution representation.

from luna_sdk.schemas.solution import UseCaseResult

best_result: UseCaseResult = luna.solution.retrieve_best_use_case_result(representation)

Was this page helpful?