Skip to content

[Model] DegreeConstrainedSpanningTree #896

@isPANN

Description

@isPANN

Motivation

DEGREE-CONSTRAINED SPANNING TREE (ND1) from Garey & Johnson, A2. Given a graph G and a positive integer K, does G have a spanning tree with maximum vertex degree at most K? NP-complete for any fixed K >= 2 (when K = 2, the problem is equivalent to Hamiltonian Path). Applications in network design where hub congestion must be bounded.

Associated rules:

Definition

Name: DegreeConstrainedSpanningTree
Reference: Garey & Johnson, Computers and Intractability, A2 ND1

Mathematical definition:

INSTANCE: Graph G = (V, E), positive integer K <= |V| - 1.
QUESTION: Does G have a spanning tree T = (V, E') with E' subset of E such that every vertex in T has degree at most K?

Variables

  • Count: |E| (one binary variable per edge)
  • Per-variable domain: {0, 1}
  • Meaning: Whether each edge is included in the spanning tree. The selected edges must form a tree spanning all vertices, and every vertex must have degree at most K in the tree.

Schema

Type name: DegreeConstrainedSpanningTree
Variants: graph: SimpleGraph

Field Type Description
graph SimpleGraph The input graph G = (V, E)
max_degree usize The maximum degree bound K

Notes:

  • This is a feasibility (decision) problem: Value = Or.
  • Key getter methods: num_vertices() (= |V|), num_edges() (= |E|), max_degree() (= K).

Complexity

  • Decision complexity: NP-complete for any fixed K >= 2 (Garey & Johnson; transformation from Hamiltonian Path).
  • Best known exact algorithm: For K = 2, equivalent to Hamiltonian Path: O*(1.657^n) randomized time (Bjorklund 2014). For general K >= 3, dynamic programming approaches run in O*(2^n) time.
  • Concrete complexity expression: "2^num_vertices" (for declare_variants!; general case)
  • Special cases:
    • K = 1: trivially NO for |V| >= 3 (a tree on >= 3 vertices must have a vertex of degree >= 2).
    • K = 2: equivalent to Hamiltonian Path.
    • K >= |V| - 1: trivially YES if G is connected (any spanning tree suffices).
  • References:
    • M.R. Garey and D.S. Johnson (1979). Computers and Intractability. W.H. Freeman.
    • A. Bjorklund (2014). "Determinant Sums for Undirected Hamiltonicity." SIAM J. Comput. 43(1), pp. 280-299.

Extra Remark

Full book text:

INSTANCE: Graph G = (V, E), positive integer K <= |V|.
QUESTION: Does G have a spanning tree with maximum degree K or less?

Reference: Transformation from HAMILTONIAN PATH.
Comment: NP-complete for any fixed K >= 2. When K = 2, the problem is equivalent to HAMILTONIAN PATH.

How to solve

  • It can be solved by (existing) bruteforce. (Enumerate all (n-1)-edge subsets of E that form a spanning tree; check the maximum degree constraint.)
  • It can be solved by reducing to integer programming.
  • Other:

Example Instance

Input:
G with V = {0, 1, 2, 3, 4} and 7 edges: {0,1}, {0,2}, {0,3}, {1,2}, {1,4}, {2,3}, {3,4}.

K = 2 (Hamiltonian path):
Spanning tree: 4—1—2—0—3. Edges: {1,4}, {1,2}, {0,2}, {0,3}.
Degrees: v0=2, v1=2, v2=2, v3=1, v4=1. Maximum degree = 2 ≤ K. ✓
Answer: YES.

K = 3:
Spanning tree: edges {0,1}, {0,2}, {0,3}, {1,4}.
Degrees: v0=3, v1=2, v2=1, v3=1, v4=1. Maximum degree = 3 ≤ K. ✓
Answer: YES.

K = 1:
Impossible for |V| = 5 — a tree on 5 vertices has 4 edges, so some vertex must have degree ≥ 2.
Answer: NO.

Python validation script
from collections import defaultdict

def is_spanning_tree(n, edges):
    adj = defaultdict(set)
    for u, v in edges:
        adj[u].add(v); adj[v].add(u)
    visited = set()
    queue = [0]
    while queue:
        node = queue.pop(0)
        if node in visited: continue
        visited.add(node)
        for nb in adj[node]:
            if nb not in visited: queue.append(nb)
    return len(visited) == n and len(edges) == n - 1

def max_degree(n, edges):
    deg = [0] * n
    for u, v in edges:
        deg[u] += 1; deg[v] += 1
    return max(deg)

# K=2: Hamiltonian path 4-1-2-0-3
tree_k2 = [(1,4), (1,2), (0,2), (0,3)]
assert is_spanning_tree(5, tree_k2)
assert max_degree(5, tree_k2) == 2
print("K=2: valid spanning tree, max degree 2")

# K=3
tree_k3 = [(0,1), (0,2), (0,3), (1,4)]
assert is_spanning_tree(5, tree_k3)
assert max_degree(5, tree_k3) == 3
print("K=3: valid spanning tree, max degree 3")

Metadata

Metadata

Assignees

No one assigned

    Labels

    GoodAn issue passed all checks.modelA model problem to be implemented.

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions