Skip to content

Getting Started

Welcome to LunaModel! This guide will get you up and running with LunaModel in just a few minutes.

Installation

LunaModel can be installed with:

terminal
uv add luna-model
terminal
pip install luna-model
terminal
poetry add luna-model

Your First Optimization Model

Let's create a simple optimization problem to see LunaModel in action. We'll define a basic problem with two binary variables.

Python
from luna_model import Model, Variable, Sense, Vtype

# Create a model
model = Model(name="MyFirstModel", sense=Sense.MAX)

# Add variables
x = model.add_variable("x", vtype=Vtype.BINARY)
y = model.add_variable("y", vtype=Vtype.BINARY)

# Set the objective function: maximize 3x + 2y
model.objective = 3 * x + 2 * y

# Add a constraint: x + y <= 1
model.constraints += x + y <= 1

# Display the model
print(model)

Printing the model gives us the following output:

Model: MyFirstModel
Maximize
  3 * x + 2 * y
Subject To
  c0: x + y <= 1
Binary
  x y

That's it! You've created your first optimization model with LunaModel.

Core Concepts

LunaModel has four fundamental building blocks:

Variables

Variables represent unknown values that the optimization algorithm will determine.

Python
from luna_model import Variable, Vtype, Bounds, Environment

with Environment():
    # Binary variable (0 or 1)
    x = Variable("x", vtype=Vtype.BINARY)

    # Integer variable with bounds
    y = Variable("y", vtype=Vtype.INTEGER, bounds=Bounds(0, 10))

    # Continuous variable
    z = Variable("z", vtype=Vtype.REAL, bounds=Bounds(-1.5, 1.5))

    # Spin variable (-1 or +1)
    s = Variable("s", vtype=Vtype.SPIN)

Expressions

Expressions are mathematical combinations of variables and constants.

Python
# Create an expression
expr = 5 * x + 3 * y - 2 * z

# Expressions support all standard operations
quadratic = x * y + 2 * x * z
higher_order = x * y * z  # LunaModel supports arbitrary degree!

Constraints

Constraints limit the feasible solutions.

Python
# Inequality constraints
model.constraints += x + y <= 5
model.constraints += 2 * x - y >= 1

# Equality constraints
model.constraints += x + y == 3

Models

Models combine variables, an objective function, and constraints.

Python
from luna_model import Model, Sense

# Create a model
model = Model(name="MyModel", sense=Sense.MIN)

# Add variables
x = model.add_variable("x")
y = model.add_variable("y")

# Set objective (what to optimize)
model.objective = x**2 + y**2

# Add constraints (what must be satisfied)
model.constraints += x + y >= 1

A Complete Example: Knapsack Problem

Let's solve a classic optimization problem - the knapsack problem. We have items with values and weights, and we want to maximize value while staying within a weight limit.

Python
from luna_model import Model, Sense, Vtype
from luna_model.utils import quicksum

# Problem data
n_items = 5
max_weight = 25
weights = [1.5, 10.0, 5.2, 3.5, 8.32]
values = [10.0, 22.0, 3.2, 1.99, 6.25]

# Create the model
model = Model(name="Knapsack", sense=Sense.MAX)

# Create binary variables (1 = take item, 0 = don't take)
items = [
    model.add_variable(f"item_{i}", vtype=Vtype.BINARY)
    for i in range(n_items)
]

# Objective: maximize total value
model.objective = quicksum(values[i] * items[i] for i in range(n_items))

# Constraint: don't exceed weight limit
model.constraints += quicksum(weights[i] * items[i] for i in range(n_items)) <= max_weight

print(model)
print(f"\nObjective degree: {model.objective.degree()}")
print(f"Number of constraints: {len(model.constraints)}")

Working with Solutions

Once you have a solution (e.g. by using LunaSolve), LunaModel provides tools to work with it:

Python
from luna_model import Solution

# Access solution data
print(f"Best solutions: {solution.best()}")
print(f"Is feasible: {solution.feasible}")
print(f"Variable values: {solution.samples}")

# Evaluate a solution against a model
sol = model.evaluate(solution)

Using Translators

LunaModel can translate between different optimization formats:

Python
from pathlib import Path
from luna_model.translator import LpTranslator

lp_filepath = Path("path/to/your/model.lp")
model = LpTranslator.to_lm(lp_filepath)
Python
from luna_model.translator import LpTranslator

lp_filestr = "..."
model = LpTranslator.to_lm(lp_filestr)
Python
from luna_model.translator import QuboTranslator
import numpy as np

qubo = np.array([[-2, 1], [0, -1]])
model = QuboTranslator.to_lm(model)
Python
from luna_model.translator import BqmTranslator
from dimod import BinaryQuadraticModel

bqm = BinaryQuadraticModel({"x": -1, "y": 2}, {("x", "y"): 1}, 0.5, "BINARY")
model = BqmTranslator.to_lm(bqm, name="example")

This translator requires luna-model to be installed with the dimod extra.

Python
from luna_model.translator import CqmTranslator
from dimod import ConstrainedQuadraticModel, Binary, Integer

cqm = ConstrainedQuadraticModel()
x = Binary("x")
y = Integer("y", lower_bound=0, upper_bound=10)
cqm.set_objective(x + 2 * y)
cqm.add_constraint(x + y >= 3, label="min_sum")

model = CqmTranslator.to_lm(cqm, name="example")

This translator requires luna-model to be installed with the dimod extra.

Next Steps

Now that you've learned the basics, explore more:

Quick Reference

Common Imports

Python
from luna_model import (
    Model,           # Create optimization models
    Variable,        # Define variables
    Expression,      # Work with expressions
    Solution,        # Handle solutions
    Sense,           # MIN or MAX
    Vtype,           # Variable types
)
from luna_model.utils import quicksum  # Efficient sum creation

Variable Types

Type Values Use Case
Vtype.BINARY 0 or 1 Yes/no decisions
Vtype.SPIN -1 or +1 todo
Vtype.INTEGER ..., -1, 0, 1, ... Counting, discrete values
Vtype.REAL Real numbers Continuous optimization

Model Sense

Sense Description
Sense.MIN Minimize the objective function
Sense.MAX Maximize the objective function