UNPKG

maximum-matching

Version:

Implementation of Blossom's Algorithm for Maximum Matching

49 lines (48 loc) 1.88 kB
"use strict"; 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;