Sensor Placement Example
Sensor Placement finds the optimal positioning of sensors on a network to maximize coverage while respecting cost and count constraints. Applications include environmental monitoring, security, and infrastructure inspection.
import getpass
import os
import numpy as np
from dotenv import load_dotenv
from luna_quantum.algorithms import SCIP
from luna_usecases.sensor_placement import (
SensorPlacementCollection,
SensorPlacementData,
SensorPlacementFormulation,
SensorPlacementInstance,
)
load_dotenv()
if "LUNA_API_KEY" not in os.environ:
os.environ["LUNA_API_KEY"] = getpass.getpass("Enter your Luna API key: ")
Create Data
Define a 5-node network with placement costs and select 2 sensor locations using from_adjacency_matrix().
adj = np.array(
[
[0, 1, 1.5, 0, 0],
[1, 0, 1, 1.5, 0],
[1.5, 1, 0, 0, 1],
[0, 1.5, 0, 0, 1],
[0, 0, 1, 1, 0],
],
dtype=float,
)
data = SensorPlacementData.from_adjacency_matrix(
adjacency_matrix=adj,
node_names=["A", "B", "C", "D", "E"],
costs=[1.0, 2.0, 1.5, 3.0, 2.5],
n_sensors=2,
)
print(data.to_string())
Plot Data
Visualize the network graph with nodes and weighted edges.
Create Formulation
Maximize coverage by selecting sensor locations within the allowed count.
Sensor Placement Formulation:
Nodes: 5
Edges: 6
Sensors to place: 2
Decision Variables:
x[i] in {0,1} for i = 0, ..., 4
x[i] = 1 if a sensor is placed at node i
Total: 5 binary variables
Objective:
maximize sum_{{(i,j) edges}} w[i,j] * (x[i] + x[j] - x[i] * x[j]) - sum_i costs[i] * x[i]
Constraints:
1. Exact sensor count (1 constraint):
sum_i x[i] == 2
Create Instance
Combine data and formulation into a solvable instance.
Data:Sensor Placement Data:
Nodes: 5
Edges: 6
Sensors to place: 2
Costs: [1. 2. 1.5 3. 2.5]
Formulation:Sensor Placement Formulation:
Nodes: 5
Edges: 6
Sensors to place: 2
Decision Variables:
x[i] in {0,1} for i = 0, ..., 4
x[i] = 1 if a sensor is placed at node i
Total: 5 binary variables
Objective:
maximize sum_{{(i,j) edges}} w[i,j] * (x[i] + x[j] - x[i] * x[j]) - sum_i costs[i] * x[i]
Constraints:
1. Exact sensor count (1 constraint):
sum_i x[i] == 2
Formulate Model
Translate the instance into a mathematical optimization model.
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:52 INFO Sleeping for 5.0 seconds. Waiting and checking a function in a loop.
Plot Solution
Visualize the optimal solution.
Collections
Generate a benchmark collection of random instances for batch processing.
collection = SensorPlacementCollection.from_random(min_size=5, max_size=7, n_sensors=2, seed=42)
model = collection.instances[0].formulate()
print(model)
Model: sensor_placement<sensor_placement>
Maximize
-2.2704291542953743 * x_0 * x_1 - 4.068156349659279 * x_0 * x_2
- 1.0165342455067852 * x_0 * x_4 - 1.7415147268556663 * x_2 * x_3
- 2.5005040519741306 * x_3 * x_4 + 4.405119749461439 * x_0
+ 1.2004291542953742 * x_1 + 4.969671076514945 * x_2 + 3.152018778829797 * x_3
+ 0.9070382974809159 * x_4
Subject To
n_sensors: x_0 + x_1 + x_2 + x_3 + x_4 == 2
Binary
x_0 x_1 x_2 x_3 x_4