Max 3-SAT Example
The Maximum 3-Satisfiability (Max3SAT) problem asks for a truth assignment that satisfies the maximum number of clauses in a 3-CNF formula. It is NP-hard.
import getpass
import os
from dotenv import load_dotenv
from luna_quantum.algorithms import SCIP
from luna_usecases.max3sat import (
Max3satCollection,
Max3satData,
Max3satFormulation,
Max3satInstance,
)
load_dotenv()
if "LUNA_API_KEY" not in os.environ:
os.environ["LUNA_API_KEY"] = getpass.getpass("Enter your Luna API key: ")
Create Data
Generate a random Max3SAT instance with 5 variables and 10 clauses.
Max3sat Data:
name: max3sat
variables: 5
clauses: 10
Clauses list:
0: (~x_4 OR x_0 OR ~x_3)
1: (~x_0 OR ~x_3 OR ~x_2)
2: (x_1 OR x_4 OR ~x_0)
3: (x_2 OR x_3 OR x_4)
4: (~x_4 OR x_2 OR ~x_0)
5: (~x_4 OR x_0 OR ~x_3)
6: (x_3 OR x_4 OR x_2)
7: (~x_1 OR x_0 OR ~x_3)
8: (x_4 OR ~x_1 OR x_3)
9: (x_3 OR ~x_1 OR ~x_0)
Plot Data
Visualize the bipartite variable–clause graph. Solid edges represent positive literals, dashed edges represent negated literals.
Create Formulation
Set up the optimization formulation that encodes clause satisfaction.
Max 3-SAT Formulation:
Variables: 5
Clauses: 10
Decision Variables:
v[i] in {0,1} for i = 0, ..., 4 (truth value of variable i)
s[c] in {0,1} for c = 0, ..., 9 (whether clause c is satisfied)
Total: 15 binary variables
Objective:
maximize sum_c s[c]
Constraints:
1. Clause satisfaction (10 constraints):
s[c] <= expr(l1) + expr(l2) + expr(l3) for all c = 0, ..., 9
where expr(i, True) = v[i], expr(i, False) = 1 - v[i]
Create Instance
Combine data and formulation into a solvable instance.
Data:Max3sat Data:
name: max3sat
variables: 5
clauses: 10
Clauses list:
0: (~x_4 OR x_0 OR ~x_3)
1: (~x_0 OR ~x_3 OR ~x_2)
2: (x_1 OR x_4 OR ~x_0)
3: (x_2 OR x_3 OR x_4)
4: (~x_4 OR x_2 OR ~x_0)
5: (~x_4 OR x_0 OR ~x_3)
6: (x_3 OR x_4 OR x_2)
7: (~x_1 OR x_0 OR ~x_3)
8: (x_4 OR ~x_1 OR x_3)
9: (x_3 OR ~x_1 OR ~x_0)
Formulation:Max 3-SAT Formulation:
Variables: 5
Clauses: 10
Decision Variables:
v[i] in {0,1} for i = 0, ..., 4 (truth value of variable i)
s[c] in {0,1} for c = 0, ..., 9 (whether clause c is satisfied)
Total: 15 binary variables
Objective:
maximize sum_c s[c]
Constraints:
1. Clause satisfaction (10 constraints):
s[c] <= expr(l1) + expr(l2) + expr(l3) for all c = 0, ..., 9
where expr(i, True) = v[i], expr(i, False) = 1 - v[i]
Formulate Model
Translate the instance into a mathematical optimization model.
Model: max3sat<max3sat>
Maximize
s_0 + s_1 + s_2 + s_3 + s_4 + s_5 + s_6 + s_7 + s_8 + s_9
Subject To
clause_0: -v_0 + v_3 + v_4 + s_0 <= 2
clause_1: v_0 + v_2 + v_3 + s_1 <= 3
clause_2: v_0 - v_1 - v_4 + s_2 <= 1
clause_3: -v_2 - v_3 - v_4 + s_3 <= 0
clause_4: v_0 - v_2 + v_4 + s_4 <= 2
clause_5: -v_0 + v_3 + v_4 + s_5 <= 2
clause_6: -v_2 - v_3 - v_4 + s_6 <= 0
clause_7: -v_0 + v_1 + v_3 + s_7 <= 2
clause_8: v_1 - v_3 - v_4 + s_8 <= 1
clause_9: v_0 + v_1 - v_3 + s_9 <= 2
Binary
v_0 v_1 v_2 v_3 v_4 s_0 s_1 s_2 s_3 s_4 s_5 s_6 s_7 s_8 s_9
Solve and Interpret
Solve the model with SCIP and interpret the raw result into a use-case-specific solution.
scip = SCIP()
job = scip.run(model)
sol = job.result()
uc_solution = instance.interpret(sol)
print(uc_solution.to_string())
/Users/maximilianjanetschek/PycharmProjects/luna-usecases/.venv/lib/python3.13/site-packages/rich/live.py:260:
UserWarning: install "ipywidgets" for Jupyter support
warnings.warn('install "ipywidgets" for Jupyter support')
2026-05-29 11:35:07 INFO Sleeping for 5.0 seconds. Waiting and checking a function in a loop.
Max3sat Solution:
Satisfied Clauses: 10
Valid: True
Assignment: {0: False, 1: False, 2: False, 3: True, 4: False}
Satisfied Indices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Plot Solution
Visualize the solution on the bipartite graph. Variable nodes are colored by their assignment (green = True, red = False), clause nodes by satisfaction status.
Collections
Generate a benchmark collection of random instances for batch processing.
collection = Max3satCollection.from_random(
min_size=3,
max_size=5,
num_instances=2,
seed=42,
)
print(f"Collection: {collection.name}")
print(f"Description: {collection.description}")
print(f"Total instances: {len(collection.instances)}")