Getting started¶
A Steiner tree problem asks for a minimum-cost subgraph that connects a given set of terminal nodes, optionally passing through other nodes.
In SteinerPy you build a NetworkX graph, list the terminals you want connected, and call SteinerProblem:
import networkx as nx
from steinerpy import SteinerProblem
# Create a graph
G = nx.Graph()
G.add_edge("A", "B", weight=1)
G.add_edge("B", "C", weight=2)
G.add_edge("C", "D", weight=1)
# Define terminal groups
terminal_groups = [["A", "D"]]
# Solve with HiGHS (default)
problem = SteinerProblem(G, terminal_groups)
solution = problem.get_solution()
print(f"Optimal cost: {solution.objective}")
print(f"Selected edges: {solution.selected_edges}")
The returned Solution reports the objective value, the selected edges, the runtime, and — importantly — a proven optimality gap: solution.gap == 0.0 means the solution is provably optimal.
Trees and forests¶
terminal_groups is a list of terminal lists.
One list gives a Steiner tree (all terminals in the group are connected); multiple lists give a Steiner forest (each group is connected within itself, but different groups need not be connected to each other):
# Steiner forest: connect A–B and, independently, C–D
solution = SteinerProblem(G, [["A", "B"], ["C", "D"]]).get_solution()
This convention carries over to every problem variant in the package — see Problem variants.
Next steps¶
Problem variants — the full catalogue of supported problem variants.
Solver backends — choosing between HiGHS and Gurobi.
Performance features — opt-in accelerators for harder instances.
Example of solving a Steiner Tree/Forest Problem using HighsPy — a worked notebook covering the main features.