Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions docs/paper/reductions.typ
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"GraphPartitioning": [Graph Partitioning],
"HamiltonianPath": [Hamiltonian Path],
"IsomorphicSpanningTree": [Isomorphic Spanning Tree],
"KthBestSpanningTree": [Kth Best Spanning Tree],
"KColoring": [$k$-Coloring],
"MinimumDominatingSet": [Minimum Dominating Set],
"MaximumMatching": [Maximum Matching],
Expand Down Expand Up @@ -631,6 +632,41 @@ Graph Partitioning is a core NP-hard problem arising in VLSI design, parallel co
]
]
}
#{
let x = load-model-example("KthBestSpanningTree")
let edges = x.instance.graph.inner.edges.map(e => (e.at(0), e.at(1)))
let m = edges.len()
let sol = x.optimal.at(0).config
let tree1 = sol.enumerate().filter(((i, v)) => i < m and v == 1).map(((i, _)) => edges.at(i))
let blue = graph-colors.at(0)
let gray = luma(190)
[
#problem-def("KthBestSpanningTree")[
Given an undirected graph $G = (V, E)$ with edge weights $w: E -> ZZ_(gt.eq 0)$, a positive integer $k$, and a bound $B in ZZ_(gt.eq 0)$, determine whether there exist $k$ distinct spanning trees $T_1, dots, T_k subset.eq E$ such that $sum_(e in T_i) w(e) lt.eq B$ for every $i$.
][
Kth Best Spanning Tree is catalogued as ND9 in Garey and Johnson @garey1979 and is marked there with an asterisk because the general problem is NP-hard but not known to lie in NP. For any fixed value of $k$, Lawler's $k$-best enumeration framework gives a polynomial-time algorithm when combined with minimum-spanning-tree subroutines @lawler1972. For output-sensitive enumeration, Eppstein gave an algorithm that lists the $k$ smallest spanning trees of a weighted graph in $O(m log beta(m, n) + k^2)$ time @eppstein1992.

Variables: $k |E|$ binary values grouped into $k$ consecutive edge-selection blocks. Entry $x_(i, e) = 1$ means edge $e$ belongs to the $i$-th candidate tree. A configuration is satisfying exactly when each block selects a spanning tree, every selected tree has total weight at most $B$, and the $k$ blocks encode pairwise distinct edge sets.

*Example.* Consider the 5-vertex graph with weighted edges ${(0,1): 2, (0,2): 3, (1,2): 1, (1,3): 4, (2,3): 2, (2,4): 5, (3,4): 3, (0,4): 6}$. With $k = 3$ and $B = 12$, the spanning trees $T_1 = {(0,1), (1,2), (2,3), (3,4)}$, $T_2 = {(0,1), (1,2), (1,3), (3,4)}$, and $T_3 = {(0,2), (1,2), (2,3), (3,4)}$ have weights $8$, $10$, and $9$, respectively. They are all distinct and all satisfy the bound, so this instance is a YES-instance.

#figure({
canvas(length: 1cm, {
let pos = ((0.0, 1.2), (1.1, 2.0), (2.3, 1.2), (1.8, 0.0), (0.3, 0.0))
for (u, v) in edges {
let in-tree1 = tree1.any(e => (e.at(0) == u and e.at(1) == v) or (e.at(0) == v and e.at(1) == u))
g-edge(pos.at(u), pos.at(v), stroke: if in-tree1 { 2pt + blue } else { 1pt + gray })
}
for (idx, p) in pos.enumerate() {
g-node(p, name: "v" + str(idx), fill: white, label: $v_#idx$)
}
})
},
caption: [Kth Best Spanning Tree example graph. Blue edges show $T_1 = {(0,1), (1,2), (2,3), (3,4)}$, one of the three bounded spanning trees used to certify the YES-instance for $k = 3$ and $B = 12$.],
) <fig:kth-best-spanning-tree>
]
]
}
#{
let x = load-model-example("KColoring")
let nv = graph-num-vertices(x.instance)
Expand Down
22 changes: 22 additions & 0 deletions docs/paper/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -650,3 +650,25 @@ @article{papadimitriou1982
year = {1982},
doi = {10.1145/322307.322309}
}

@article{lawler1972,
author = {Eugene L. Lawler},
title = {A Procedure for Computing the $K$ Best Solutions to Discrete Optimization Problems and Its Application to the Shortest Path Problem},
journal = {Management Science},
volume = {18},
number = {7},
pages = {401--405},
year = {1972},
doi = {10.1287/mnsc.18.7.401}
}

@article{eppstein1992,
author = {David Eppstein},
title = {Finding the $k$ Smallest Spanning Trees},
journal = {BIT},
volume = {32},
number = {2},
pages = {237--248},
year = {1992},
doi = {10.1007/BF01994880}
}
1 change: 1 addition & 0 deletions docs/src/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ pred create MIS --graph 0-1,1-2,2-3 --weights 2,1,3,1 -o problem.json
pred create SAT --num-vars 3 --clauses "1,2;-1,3" -o sat.json
pred create QUBO --matrix "1,0.5;0.5,2" -o qubo.json
pred create KColoring --k 3 --graph 0-1,1-2,2-0 -o kcol.json
pred create KthBestSpanningTree --graph 0-1,0-2,1-2 --edge-weights 2,3,1 --k 1 --bound 3 -o kth.json
pred create SpinGlass --graph 0-1,1-2 -o sg.json
pred create MaxCut --graph 0-1,1-2,2-0 -o maxcut.json
pred create Factoring --target 15 --bits-m 4 --bits-n 4 -o factoring.json
Expand Down
26 changes: 26 additions & 0 deletions docs/src/reductions/problem_schemas.json
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,32 @@
}
]
},
{
"name": "KthBestSpanningTree",
"description": "Do there exist k distinct spanning trees with total weight at most B?",
"fields": [
{
"name": "graph",
"type_name": "SimpleGraph",
"description": "The underlying graph G=(V,E)"
},
{
"name": "weights",
"type_name": "Vec<W>",
"description": "Edge weights w(e) for each edge in E"
},
{
"name": "k",
"type_name": "usize",
"description": "Number of distinct spanning trees required"
},
{
"name": "bound",
"type_name": "W::Sum",
"description": "Upper bound B on each spanning tree weight"
}
]
},
{
"name": "LongestCommonSubsequence",
"description": "Find the longest string that is a subsequence of every input string",
Expand Down
Loading
Loading