origins = {
const n = nodes.length,
origins = Array.from({ length }, () => (Math.random() * n) | 0);
yield origins;
const prev0 = origins.slice(),
prev1 = origins.slice();
let last = origins.slice();
for (let t = 0; t < 1000; t++) {
const tree = shortest_tree({ graph, origins }).next().value;
const weights = Uint32Array.from(tree.predecessor).fill(0);
function branch_length(i) {
if (weights[i]) return weights[i];
const j = tree.predecessor[i];
if (j > -1) {
return (weights[i] = branch_length(j) + 1);
}
return 0;
}
for (let j = 0; j < n; j++) {
if (tree.origin[j] == -1) continue;
branch_length(j);
}
for (let k = 0; k < origins.length; k++) {
const i = origins[k];
let best = -1,
value = 0;
for (let j = 0; j < n; j++) {
if (tree.origin[j] === i && weights[j] > value) {
value = weights[j];
best = j;
}
}
if (best > -1) {
while (
tree.predecessor[best] !== -1 &&
tree.predecessor[tree.predecessor[best]] !== -1
)
best = tree.predecessor[best];
if (best !== prev0[k] && best !== prev1[k]) {
prev1[k] = prev0[k];
prev0[k] = origins[k];
origins[k] = best;
}
}
}
if (last.toString() == origins.toString()) break;
last = origins.slice();
yield origins;
}
}