In the NP-hard *Degree-Constrained Bottleneck Spanning Tree (DBST)*, we are given a complete graph $G=(V,E)$ with distance/weight function $w: E \rightarrow \mathbb{N}^+_0$.
The set $V$ can be a set of point on the plane, and $w(v,w)$ the euclidean distance between $v\in V$ and $w\in V$.
Additionally, we have a degree constraint $d\geq 2$.
The objective is to find a tree $T$ in $G$ in which no vertex has a degree greater the degree constraint, i.e., $\forall v\in V: deg_T(v)\leq d$, and the weight of the longest edge is minimized.
## Modelling the Problem with CP-SAT
### Selection of Variables for the Model
The most trivial variable selection would be to choose a boolean variable for every edge, that represents if the edge is in the solution.
Unfortunately, with this representation it is difficult to efficiently contrain the edge set to be a tree.
...
...
@@ -16,39 +25,49 @@ In the beginning, a lot may seem unelegant or random.
* Bottleneck variable $y\in \{0,1,\ldots,\max_{\{v,w\}in E}(d(v,w))\}$ that represent the weight of the most expensive used edge/arc.
* Depth variables $d_v \in \{0, 1, \ldots, |V|-1\}$ for every vertex $v\in V$ representing how deep the vertex is in the arborescence.
## Objective Function
See `__make_vars` in the code.
### Objective Function
The objective function is in this case trivial as we created the auxiliary variable $y$.
As long as we ensure that $y$ actually gets assigned the value of the most expensive selected edge, we just have to specify
$$\min y$
to obtain the feasible solution with the smallest possible $y$-value.
## Constraints
### Constraints
We have specified what a solution looks like and how to measure its quality.
Next, we have to make sure it actually obeys the rules as otherwise we just get the trivial zero solution that is of perfect zero-weight, but unfortunately not a feasible solution.
Let us start with some simple constraints that don't need much explanation:
* Only one direction of an edge can be chosen: $\forall \{v,w\}\in E: x_{vw}+x_{wv}\leq 1$
* We need to select $|V|-1$ edges for a tree: $\sum_{\{v,w\}\in E}x_{vw}+x_{wv} = |V|-1$
*
* Only one direction of an edge can be chosen: $\forall \{v,w\}\in E: x_{vw}+x_{wv}\leq 1$ (see `__forbid_bidirectional_edges`)
* We need to select $|V|-1$ edges for a tree: $\sum_{\{v,w\}\in E}x_{vw}+x_{wv} = |V|-1$ (see `__add_depth_constraints``)
* We set a random vertex $v_0$ as root and enforce that every other vertex has a parent.