Fix the minimum spanning tree algorithm.

Tinc uses Kruskal's algorithm to calculate a MST. However, this was broken in
commit 6e80da3370. Revert back to the working
algorithm from tinc 1.0.

Thanks to Cheng LI for spotting the problem.
This commit is contained in:
Guus Sliepen 2013-01-17 11:21:18 +01:00
parent 61275547cd
commit 1ddd6111a4

View file

@ -61,7 +61,7 @@
#include "graph.h" #include "graph.h"
/* Implementation of Kruskal's algorithm. /* Implementation of Kruskal's algorithm.
Running time: O(E) Running time: O(EN)
Please note that sorting on weight is already done by add_edge(). Please note that sorting on weight is already done by add_edge().
*/ */
@ -78,11 +78,24 @@ static void mst_kruskal(void) {
for splay_each(node_t, n, node_tree) for splay_each(node_t, n, node_tree)
n->status.visited = false; n->status.visited = false;
/* Add safe edges */ /* Starting point */
for splay_each(edge_t, e, edge_weight_tree) { for splay_each(edge_t, e, edge_weight_tree) {
if(!e->reverse || (e->from->status.visited && e->to->status.visited)) if(e->from->status.reachable) {
e->from->status.visited = true;
break;
}
}
/* Add safe edges */
bool skipped = false;
for splay_each(edge_t, e, edge_weight_tree) {
if(!e->reverse || (e->from->status.visited == e->to->status.visited)) {
skipped = true;
continue; continue;
}
e->from->status.visited = true; e->from->status.visited = true;
e->to->status.visited = true; e->to->status.visited = true;
@ -93,8 +106,12 @@ static void mst_kruskal(void) {
if(e->reverse->connection) if(e->reverse->connection)
e->reverse->connection->status.mst = true; e->reverse->connection->status.mst = true;
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight);
e->to->name, e->weight);
if(skipped) {
skipped = false;
next = edge_weight_tree->head;
}
} }
} }