Skip to content

Solution Translators

Solution translators convert solver results from various formats to LunaModel Solution objects, enabling seamless integration with different optimization platforms.

Overview

LunaModel provides solution translators for:

  • NumPy: Array-based results
  • D-Wave: SampleSet from Ocean SDK
  • IBM: Qiskit optimization results
  • AWS: Amazon Braket results
  • Q-Ctrl: Q-Ctrl optimization results
  • ZIB: SCIP solver results

NumpyTranslator

Convert NumPy arrays to LunaModel solutions.

Basic Usage

Python
from luna_model.translator import NumpyTranslator
import numpy as np

# Result array (samples x variables)
result_array = np.array([
    [1, 0, 1, 0],
    [0, 1, 0, 1],
    [1, 1, 0, 0]
])

# Variable names
var_names = ["x", "y", "z", "w"]

# Objective values (optional)
obj_values = [10.0, 12.0, 8.0]

# Convert to Solution
translator = NumpyTranslator()
solution = translator.to_lm(
    result_array, 
    variable_names=var_names,
    obj_values=obj_values
)

print(f"Samples: {solution.samples}")
print(f"Best: {solution.best()}")

With Feasibility Flags

Python
feasible = [True, False, True]

solution = translator.to_lm(
    result_array,
    variable_names=var_names,
    obj_values=obj_values,
    feasible=feasible
)

DwaveTranslator

Convert D-Wave SampleSet to LunaModel solutions.

Installation

pip install luna-model[dimod]

Basic Usage

Python
from luna_model.translator import DwaveTranslator
from dimod import ExactSolver, BinaryQuadraticModel

# Create and solve BQM
bqm = BinaryQuadraticModel({'x': -1, 'y': -2}, {('x', 'y'): 1}, 0.0, 'BINARY')
sampler = ExactSolver()
sampleset = sampler.sample(bqm)

# Convert to LunaModel solution
translator = DwaveTranslator()
solution = translator.to_lm(sampleset)

print(f"Number of samples: {len(solution.samples)}")
print(f"Best solution: {solution.best()}")
print(f"Best energy: {min(solution.obj_values)}")

Complete Workflow

Python
from luna_model import Model, Vtype
from luna_model.translator import BqmTranslator, DwaveTranslator
from dwave.system import DWaveSampler, EmbeddingComposite

# Create model
model = Model()
x = model.add_variable("x", vtype=Vtype.BINARY)
y = model.add_variable("y", vtype=Vtype.BINARY)
model.objective = x * y - x - 2 * y

# Convert to BQM
bqm_translator = BqmTranslator()
bqm = bqm_translator.from_lm(model)

# Solve on D-Wave
sampler = EmbeddingComposite(DWaveSampler())
sampleset = sampler.sample(bqm, num_reads=100)

# Convert solution
solution_translator = DwaveTranslator()
solution = solution_translator.to_lm(sampleset)

# Analyze
print(f"Got {len(solution.samples)} samples")
feasible_count = sum(solution.feasible)
print(f"Feasible solutions: {feasible_count}")

IbmTranslator

Convert IBM Qiskit results to LunaModel solutions.

Installation

pip install luna-model[qiskit]

Basic Usage

Python
from luna_model.translator import IbmTranslator
from qiskit_optimization import QuadraticProgram
from qiskit_optimization.algorithms import MinimumEigenOptimizer

# Create and solve QAOA problem (pseudo-code)
# qp = QuadraticProgram()
# ... define problem ...
# result = optimizer.solve(qp)

# Convert to LunaModel
translator = IbmTranslator()
solution = translator.to_lm(result, variable_names=var_names)

print(f"Solution: {solution.samples[0]}")
print(f"Objective: {solution.obj_values[0]}")

AwsTranslator

Convert AWS Braket results to LunaModel solutions.

Installation

pip install luna-model[braket]

Basic Usage

Python
from luna_model.translator import AwsTranslator
from braket.devices import LocalSimulator
from braket.ocean_plugin import BraketSampler

# Solve on AWS Braket (pseudo-code)
# device = LocalSimulator()
# sampler = BraketSampler(device)
# result = sampler.sample_qubo(qubo)

# Convert to LunaModel
translator = AwsTranslator()
solution = translator.to_lm(result, variable_names=var_names)

print(f"Best solution: {solution.best()}")

QctrlTranslator

Convert Q-Ctrl results to LunaModel solutions.

Basic Usage

Python
from luna_model.translator import QctrlTranslator

# Q-Ctrl result (pseudo-code)
# result = qctrl_solver.solve(problem)

# Convert to LunaModel
translator = QctrlTranslator()
solution = translator.to_lm(result, variable_names=var_names)

ZibTranslator

Convert SCIP solver results to LunaModel solutions.

Installation

pip install pyscipopt

Basic Usage

Python
from luna_model.translator import ZibTranslator, LpTranslator
from pyscipopt import Model as SCIPModel

# Export LunaModel to LP
lp_translator = LpTranslator()
lp_string = lp_translator.from_lm(model)

# Solve with SCIP
scip = SCIPModel()
scip.readProblem(lp_string)
scip.optimize()

# Get solution
scip_solution = scip.getBestSol()

# Convert to LunaModel
zib_translator = ZibTranslator()
solution = zib_translator.to_lm(scip_solution, model=model)

print(f"Objective value: {solution.obj_values[0]}")
print(f"Solution: {solution.samples[0]}")

Complete Integration Example

Python
from luna_model import Model, Vtype, Sense
from luna_model.utils import quicksum
from luna_model.translator import (
    BqmTranslator,
    DwaveTranslator,
    NumpyTranslator
)
from dimod import SimulatedAnnealingSampler
import numpy as np

# Create optimization model
model = Model(name="Portfolio", sense=Sense.MIN)

n_assets = 5
allocations = [
    model.add_variable(f"a_{i}", vtype=Vtype.BINARY)
    for i in range(n_assets)
]

# Objective: minimize risk, maximize return
returns = [0.05, 0.08, 0.06, 0.07, 0.09]
risk_matrix = np.random.rand(n_assets, n_assets)

# Quadratic risk term
risk = quicksum(
    risk_matrix[i, j] * allocations[i] * allocations[j]
    for i in range(n_assets)
    for j in range(n_assets)
)

# Linear return term
expected_return = quicksum(returns[i] * allocations[i] for i in range(n_assets))

model.objective = risk - 0.5 * expected_return

# Constraint: select at least 2 assets
model.constraints += quicksum(allocations) >= 2

# Method 1: Solve with D-Wave
bqm_translator = BqmTranslator()
bqm = bqm_translator.from_lm(model)

sampler = SimulatedAnnealingSampler()
sampleset = sampler.sample(bqm, num_reads=100)

dwave_translator = DwaveTranslator()
solution_dwave = dwave_translator.to_lm(sampleset)

print("D-Wave solution:")
print(f"  Best: {solution_dwave.best()}")
print(f"  Objective: {min(solution_dwave.obj_values)}")

# Method 2: Custom solver returning NumPy
# Simulate custom solver result
result_array = np.random.randint(0, 2, size=(10, n_assets))
obj_values = np.random.rand(10) * 10

numpy_translator = NumpyTranslator()
solution_numpy = numpy_translator.to_lm(
    result_array,
    variable_names=[f"a_{i}" for i in range(n_assets)],
    obj_values=obj_values.tolist()
)

print("\nNumPy solution:")
print(f"  Best: {solution_numpy.best()}")
print(f"  Objective: {min(solution_numpy.obj_values)}")

Best Practices

Preserve Variable Names

Python
# Extract variable names from model
var_names = [var.name for var in model.variables()]

# Use when converting
solution = translator.to_lm(result, variable_names=var_names)

Validate Conversions

Python
# After conversion, validate
solution = translator.to_lm(result, variable_names=var_names)

# Check all variables present
assert len(solution.samples[0]) == len(var_names)

# Verify against model
for sample in solution.samples:
    obj_value = model.objective.eval(sample)
    # Compare with reported objective...

Handle Multiple Solutions

Python
# Many solvers return multiple solutions
solution = translator.to_lm(sampleset)

# Sort by objective
sorted_indices = sorted(
    range(len(solution.obj_values)),
    key=lambda i: solution.obj_values[i]
)

# Get top 10 solutions
top_10 = [solution.samples[i] for i in sorted_indices[:10]]

Error Handling

Python
from luna_model.errors import TranslationError

try:
    solution = translator.to_lm(result, variable_names=var_names)
except TranslationError as e:
    print(f"Solution translation failed: {e}")

See Also