Skip to content

LunaSolve

LunaSolve lets you solve complex optimization problems, offering out-of-the-box solution strategies with high control over configurability. From transforming complex problems into actionable results to fine-tuning algorithms, LunaSolve adapts to your level of customizability.


Solve Your Problem in Four Simple Steps

  1. Define Your Model – Specify the problem structure and parameters.
  2. Select an Algorithm – Choose an appropriate solver for your optimization task.
  3. Execute the Solve Step – Run the solver with a single command.
  4. Inspect the Results – Analyze the solution output, including decision variables and objective values.

In the example below, we’ll demonstrate these steps using the classic Knapsack problem.

from luna_quantum import LunaSolve
from luna_quantum.solve.parameters.algorithms import QAOA
from luna_quantum.solve.parameters.backends import IBM
from luna_quantum import Model, Variable, Vtype

# Authenticate first
LunaSolve.authenticate("<YOUR_LUNA_API_KEY>")

# Beach items
beach_items = ["surfboard", "book", "speaker", "cooler"]
fun_values = {"surfboard":40, "book":15, "speaker":25, "cooler":35}

# Interaction dictionary: positive = synergy, negative = conflict
interactions = {
    ("surfboard", "book"): -25,      # wet board ruins book!
    ("surfboard", "speaker"): 10,    # music while surfing
    ("surfboard", "cooler"): 15,     # cold drink after surfing
    ("book", "speaker"): -30,        # can't read with loud music
    ("book", "cooler"): 20,          # relaxing read with cold drink
    ("speaker", "cooler"): 30,       # perfect beach party combo
}

model = Model("beach_packing_simple")
with model.environment:
    # Create binary variables from the list
    items = {name: Variable(name, vtype=Vtype.Binary) for name in beach_items}

# Invert objective values to match minimization problem
model.objective = (-1) * sum(f_val * items[i] for i, f_val in fun_values.items())

# Invert interaction terms to match minimization problem
model.objective += (-1) * sum(val * items[i] * items[j] for (i,j), val in interactions.items())

print(model)

# Define the algorithm and backend
algorithm = QAOA(
    backend=IBM(
        backend=IBM.SimulatorBackend(
            backend_type='simulator',
            backend_name='aer'
        )
    ),
    reps=1,
    shots=1024
)

# Run your algorithm
solve_job = algorithm.run(model, name="beach-packing-with-qaoa")
solution = solve_job.result()

1. Create Your Model

To define your optimization problem for LunaSolve, you need to create a Model. You can easily create your model or load it from other industry-standard formats using convenient translator utilities. For advanced features and modeling techniques, visit the Model Documentation.

from luna_quantum import Model, Variable, Vtype, Bounds

model = Model("YourModel")
with model.environment:
    x = Variable("x", vtype=Vtype.Integer, bounds=Bounds(0, 40))
    y = Variable("y", vtype=Vtype.Integer, bounds=Bounds(0, 30))

model.objective = 3 * x + 4 * y
model.constraints += 2 * x + y <= 100
model.constraints += x + 2 * y <= 80
from pathlib import Path
from luna_quantum import LpTranslator

lp_file = Path("path/to/your_model.lp")
model = LpTranslator.to_aq(lp_file)
from luna_quantum import LpTranslator

lp_string = """
Maximize
obj: 3 x + 4 y
Subject To
c1: 2 x + y <= 100
c2: x + 2 y <= 80
Bounds
0 <= x <= 40
0 <= y <= 30
End
"""

model = LpTranslator.to_aq(lp_string)
import numpy as np
from luna_quantum import MatrixTranslator, Vtype

q = np.array([[1.0, -1.0],
            [-1.0, 2.0]])

model = MatrixTranslator.to_aq(q, name="qubo_model", vtype=Vtype.Integer)
import dimod
from luna_quantum import BqmTranslator

# Generate a random BQM with 5 variables and 10 interactions
bqm = dimod.generators.gnm_random_bqm(5, 10, "BINARY")

# Convert it into a Model
model = BqmTranslator.to_aq(bqm, name="bqm_model")
from dimod import ConstrainedQuadraticModel, Binary
from luna_quantum import CqmTranslator

# Define 3 toppings
toppings = {    
    'pepperoni': {'cost': 8, 'happiness': 9},    
    'pineapple': {'cost': 6, 'happiness': 6},    
    'cheese': {'cost': 4, 'happiness': 8}
}

# Create binary variables
vars = {name: Binary(name) for name in toppings.keys()}

# Create CQM
cqm = ConstrainedQuadraticModel()

# Objective: maximize happiness (minimize negative happiness)
objective = -sum(toppings[name]['happiness'] * var for name, var in vars.items())
cqm.set_objective(objective)

# Constraint 1: Budget limit ($15)
budget = sum(toppings[name]['cost'] * var for name, var in vars.items())
cqm.add_constraint(budget <= 15, label="budget")

# Constraint 2: Joey's ultimatum - pineapple XOR pepperoni
joey_rule = vars['pineapple'] + vars['pepperoni']
cqm.add_constraint(joey_rule == 1, label="joey_xor")

# Convert to Luna model
model = CqmTranslator.to_aq(cqm, name="pizza_party_cqm")
import networkx as nx
from luna_quantum import LunaSolve
from luna_quantum.solve.use_cases import HamiltonianCycle

# Instantiate LunaSolve
ls = LunaSolve()

# Prepare the input data of your problem. The input type is problem dependent
hamiltonian_cycle_graph = nx.gnm_random_graph(n=5, m=15)
hamiltonian_cycle_graph = nx.relabel_nodes(hamiltonian_cycle_graph, lambda x: str(x))
for u, v in hamiltonian_cycle_graph.edges:
    hamiltonian_cycle_graph[u][v]["weight"] = round(np.random.uniform(1, 10), 2)

# Create a HamiltonianCycle object
hamiltonian_cycle = HamiltonianCycle(graph=nx.to_dict_of_dicts(hamiltonian_cycle_graph))

# Convert the usecase instance into a Model
model = ls.model.create_from_use_case(use_case=hamiltonian_cycle)

Prefer to build models programmatically?

You can build your optimization problem using the Model component.
Learn more in the Model Introduction.

Effortless Modeling with the Use Case Library

Explore our curated collection of use cases designed to simplify modeling of common optimization problems. Visit our Tutorials to learn how to get started.

2. Instantiate an Algorithm

You need to instantiate an algorithm to solve the optimization problem. In this example, we run the QAOA with default configuration on a simulated IBM backend. For more information on configuration of algorithms and backends, please refer to the Algorithm and Backend documentation.

from luna_quantum.solve.parameters.algorithms import QAOA
from luna_quantum.solve.parameters.backends import IBM

algorithm = QAOA(
    backend=IBM(
        backend=IBM.SimulatorBackend(
            backend_type='simulator',
            backend_name='aer'
        )
    ),
    reps=1,
    shots=1024
)

3. Run the Algorithm

To run the algorithm, you need to call the run method on the algorithm instance. You can also provide a name for the solve job to help you identify it later.

solve_job = algorithm.run(model, name="beach-packing-with-qaoa")

Model Upload

If your model hasn't been uploaded yet, running a solver will automatically upload it to the Luna platform. This ensures it's securely stored and available for future use. You can also upload models manually. See the Models documentation for details on automatic and manual uploads.

Retrieving Job information

Please refer to SolveJob Documentation for further information on how to inspect your submitted solve job.

4. Analyze the Result

To retrieve the result of the optimization, you can call the result method on the solve job instance to retrieve a Solution.

solution = solve_job.result()

best_solution = solution.best()
best_value = best_solution.obj_value

print(f"Best solution: {best_solution}")
print(f"Objective value of best solution: {best_value}")

Analyzing the Solution

Please refer to Solution Documentation for further information on how to analyze your results.

Congratulations! You have successfully created and solved an optimization problem using LunaSolve. You can now use the result to make informed decisions and optimize your business processes.