maximum-matching
Version:
Implementation of Blossom's Algorithm for Maximum Matching
49 lines (48 loc) • 1.88 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Blossom = void 0;
const mod_1 = require("../../utils/mod");
const BlossomPathDirection_1 = require("./BlossomPathDirection");
class Blossom {
constructor({ root, cycle }) {
this.ensureOddCycle(cycle);
this.ensureIsInCycle(root, cycle);
this.root = root;
this.cycle = cycle;
}
has(node) {
return this.cycle.includes(node);
}
path(from, to, { direction = BlossomPathDirection_1.BlossomPathDirection.CLOCK_WISE } = {}) {
this.ensureIsInBlossom(from);
this.ensureIsInBlossom(to);
const startIndex = this.cycle.findIndex((node) => node === from);
const indexInc = direction === BlossomPathDirection_1.BlossomPathDirection.CLOCK_WISE ? 1 : -1;
const path = [];
for (let i = startIndex; path[path.length - 1] !== to; i = (0, mod_1.mod)(i + indexInc, this.cycle.length))
path.push(this.cycle[i]);
return path;
}
evenPath(from, to) {
const clockWisePath = this.path(from, to, {
direction: BlossomPathDirection_1.BlossomPathDirection.CLOCK_WISE,
});
const clockWisePathLength = clockWisePath.length - 1;
if (clockWisePathLength % 2 === 0)
return clockWisePath;
return this.path(from, to, { direction: BlossomPathDirection_1.BlossomPathDirection.COUNTER_CLOCK_WISE });
}
ensureOddCycle(cycle) {
if (cycle.length % 2 === 0)
throw new Error(`Blossom cycle is not odd`);
}
ensureIsInCycle(node, cycle) {
if (!cycle.includes(node))
throw new Error(`${node} was not found in cycle`);
}
ensureIsInBlossom(node) {
if (!this.has(node))
throw new Error(`${node} was not found in the Blossom`);
}
}
exports.Blossom = Blossom;