Model Translators
Model translators convert optimization models between LunaModel and various external formats. This enables integration with different solvers and optimization platforms.
Overview
LunaModel provides translators for:
- LP files: CPLEX LP format for linear/mixed-integer programming
- QUBO: Quadratic Unconstrained Binary Optimization
- BQM: D-Wave Binary Quadratic Models
- CQM: D-Wave Constrained Quadratic Models
LpTranslator
The LpTranslator converts models to and from CPLEX LP file format.
Basic Usage
from luna_model import Model, Vtype, Sense
from luna_model.utils import quicksum
from luna_model.translator import LpTranslator
# Create a model
model = Model(name="Production", sense=Sense.MAX)
# Add variables
x = model.add_variable("x", vtype=Vtype.INTEGER, lower=0, upper=100)
y = model.add_variable("y", vtype=Vtype.INTEGER, lower=0, upper=50)
# Set objective
model.objective = 3 * x + 2 * y
# Add constraints
model.constraints += 2 * x + y <= 150
model.constraints += x + 2 * y <= 120
# Translate to LP format
translator = LpTranslator()
lp_string = translator.from_lm(model)
print(lp_string)
Output:
\Problem name: Production
Maximize
obj: 3 x + 2 y
Subject To
c0: 2 x + y <= 150
c1: x + 2 y <= 120
Bounds
0 <= x <= 100
0 <= y <= 50
General
x y
End
Importing from LP
# Read LP file
with open("model.lp", "r") as f:
lp_content = f.read()
# Convert to LunaModel
translator = LpTranslator()
model = translator.to_lm(lp_content)
# Use the imported model
print(f"Imported model: {model.name}")
print(f"Variables: {model.num_variables()}")
print(f"Constraints: {model.num_constraints()}")
Exporting to File
# Export to LP file
lp_string = translator.from_lm(model)
with open("output.lp", "w") as f:
f.write(lp_string)
Supported Features
- Linear and quadratic objectives
- Linear and quadratic constraints
- Binary, integer, and continuous variables
- Minimization and maximization
- Variable bounds
Limitations
- Does not support higher-order (degree > 2) expressions
- Spin variables are converted to binary
QuboTranslator
The QuboTranslator converts models to and from QUBO (Quadratic Unconstrained Binary Optimization) format.
Basic Usage
from luna_model import Model, Vtype
from luna_model.translator import QuboTranslator
# Create a binary quadratic model
model = Model()
# Binary variables only
x = model.add_variable("x", vtype=Vtype.BINARY)
y = model.add_variable("y", vtype=Vtype.BINARY)
z = model.add_variable("z", vtype=Vtype.BINARY)
# Quadratic objective
model.objective = x * y + 2 * y * z - x - 2 * y
# Translate to QUBO
translator = QuboTranslator()
qubo = translator.from_lm(model)
print(qubo)
# {(0, 1): 1.0, (1, 2): 2.0, (0, 0): -1.0, (1, 1): -2.0}
QUBO Format
QUBO is represented as a dictionary where:
- Keys are tuples (i, j) representing variable indices
- Values are coefficients
- Diagonal terms (i, i) are linear coefficients
- Off-diagonal terms (i, j) where i < j are quadratic coefficients
Importing from QUBO
# QUBO dictionary
qubo_dict = {
(0, 0): -1.0, # Linear term for variable 0
(1, 1): -2.0, # Linear term for variable 1
(0, 1): 1.0, # Quadratic term x0*x1
}
# Variable names
var_names = ["x", "y"]
# Convert to LunaModel
translator = QuboTranslator()
model = translator.to_lm(qubo_dict, variable_names=var_names)
Constraint Handling
QUBO is unconstrained, so constraints must be penalized into the objective:
# Model with constraint
model = Model()
x = model.add_variable("x", vtype=Vtype.BINARY)
y = model.add_variable("y", vtype=Vtype.BINARY)
model.objective = x + y
model.constraints += x + y <= 1 # Constraint
# Translate with penalty
translator = QuboTranslator(penalty_weight=10.0)
qubo = translator.from_lm(model)
# Constraint is penalized in objective
Supported Features
- Binary variables only
- Quadratic objectives
- Constraint penalization
Limitations
- Only binary variables supported
- Constraints converted to penalties
- Higher-order terms not supported
BqmTranslator
The BqmTranslator converts to and from D-Wave's Binary Quadratic Model format (requires dimod).
Installation
Basic Usage
from luna_model import Model, Vtype
from luna_model.translator import BqmTranslator
# 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 + 3
# Convert to BQM
translator = BqmTranslator()
bqm = translator.from_lm(model)
print(f"BQM type: {type(bqm)}")
print(f"Linear: {bqm.linear}")
print(f"Quadratic: {bqm.quadratic}")
print(f"Offset: {bqm.offset}")
Integration with D-Wave
from dimod import ExactSolver
from luna_model.translator import BqmTranslator, DwaveTranslator
# Create and translate model
model = Model()
# ... define model ...
# To BQM
bqm_translator = BqmTranslator()
bqm = bqm_translator.from_lm(model)
# Solve with D-Wave sampler
sampler = ExactSolver()
sampleset = sampler.sample(bqm)
# Convert solution back
solution_translator = DwaveTranslator()
solution = solution_translator.to_lm(sampleset)
print(f"Best solution: {solution.best()}")
print(f"Best energy: {min(solution.obj_values)}")
Importing from BQM
from dimod import BinaryQuadraticModel
# Create a BQM
bqm = BinaryQuadraticModel(
{'x': -1, 'y': -2}, # Linear terms
{('x', 'y'): 1}, # Quadratic terms
0.0, # Offset
'BINARY'
)
# Convert to LunaModel
translator = BqmTranslator()
model = translator.to_lm(bqm)
Supported Features
- Binary and spin variables
- Quadratic objectives
- Full dimod BQM compatibility
Limitations
- Requires dimod package
- Constraints not supported (use CQM for constraints)
CqmTranslator
The CqmTranslator converts to and from D-Wave's Constrained Quadratic Model format.
Installation
Basic Usage
from luna_model import Model, Vtype, Sense
from luna_model.utils import quicksum
from luna_model.translator import CqmTranslator
# Create model with constraints
model = Model(sense=Sense.MIN)
# Variables
x = [model.add_variable(f"x_{i}", vtype=Vtype.BINARY) for i in range(5)]
# Objective
model.objective = quicksum(i * x[i] for i in range(5))
# Constraints
model.constraints += quicksum(x) <= 2
model.constraints += x[0] + x[1] >= 1
# Convert to CQM
translator = CqmTranslator()
cqm = translator.from_lm(model)
print(f"CQM variables: {len(cqm.variables)}")
print(f"CQM constraints: {len(cqm.constraints)}")
Integration with D-Wave Hybrid
from dwave.system import LeapHybridCQMSampler
from luna_model.translator import CqmTranslator, DwaveTranslator
# Create model
model = Model()
# ... define constrained model ...
# Convert to CQM
cqm_translator = CqmTranslator()
cqm = cqm_translator.from_lm(model)
# Solve with hybrid sampler
sampler = LeapHybridCQMSampler()
sampleset = sampler.sample_cqm(cqm)
# Convert solution
solution_translator = DwaveTranslator()
solution = solution_translator.to_lm(sampleset)
Importing from CQM
from dimod import ConstrainedQuadraticModel, Binary
# Create CQM
cqm = ConstrainedQuadraticModel()
x = Binary('x')
y = Binary('y')
cqm.set_objective(x + 2*y)
cqm.add_constraint(x + y <= 1, label="c0")
# Convert to LunaModel
translator = CqmTranslator()
model = translator.to_lm(cqm)
Supported Features
- Binary, integer, and continuous variables
- Quadratic objectives
- Quadratic constraints
- Full dimod CQM compatibility
Limitations
- Requires dimod package
- Higher-order terms not supported
Best Practices
Choose the Right Format
# Linear programming → LP
if model.objective.degree() <= 1:
translator = LpTranslator()
lp = translator.from_lm(model)
# Unconstrained binary quadratic → QUBO
elif (model.objective.degree() <= 2 and
len(model.constraints) == 0 and
all(v.vtype == Vtype.BINARY for v in model.variables())):
translator = QuboTranslator()
qubo = translator.from_lm(model)
# Constrained quadratic → CQM
elif model.objective.degree() <= 2 and len(model.constraints) > 0:
translator = CqmTranslator()
cqm = translator.from_lm(model)
Validate After Translation
# Export and re-import to validate
translator = LpTranslator()
lp_string = translator.from_lm(model)
reimported = translator.to_lm(lp_string)
# Check consistency
assert model.num_variables() == reimported.num_variables()
assert model.num_constraints() == reimported.num_constraints()
Handle Errors
from luna_model.errors import TranslationError
try:
translator = QuboTranslator()
qubo = translator.from_lm(model)
except TranslationError as e:
print(f"Translation failed: {e}")
print("Model may have unsupported features")
See Also
- Solution Translators - Converting solver results
- API: Translators - API reference
- Transformations - Model transformations