2.0.4 • Published 1 year ago

munkres v2.0.4

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Munkres

A lightweight and efficient implementation of the Munkres (Hungarian) algorithm for optimal assignment.

Version JSR Maintenance License codecov npm bundle size

Features

  1. Flexible

    • Use number or bigint matrices.
    • Use square (NxN) or rectangular (MxN) matrices.
    • Works with any MatrixLike input. Use arrays, typed arrays, custom objects, etc.
  2. Fast (benchmarks)

    • O(M2N) when M <= N

    • O(MN2) when M > N

  3. Efficient

    • O(M + N) memory
  4. Robust

    • Supports -Infinity and Infinity values.
    • Helper methods provided for creating and modifying matrices.

Getting Started

Install

NPM:

npm install munkres

Yarn:

yarn add munkres

JSR:

jsr add @munkres/munkres

Usage

With a cost matrix:

import munkres from "munkres";

// Create a cost matrix. Cell [y, x] is the cost
// of assigning the y-th worker to the x-th job.
const costMatrix = [
  [1, 2, 3],
  [2, 4, 6],
  [3, 6, 9],
];

// Find a set of optimal assignments pairs (y, x).
const assignments = munkres(costMatrix);

console.log(assignments);
// Output: [[0, 2], [1, 1], [2, 0]]

With a profit matrix:

import { munkres, copyMatrix, invertMatrix } from "munkres";

// Create a profit matrix. Cell [y, x] is the
// profit of assigning the y-th worker to the x-th job.
const profitMatrix = [
  [9, 8, 7],
  [8, 6, 4],
  [7, 4, 1],
];

// Covert the profit matrix into a cost matrix.
const costMatrix = copyMatrix(profitMatrix);
invertMatrix(costMatrix);

// Find a set of optimal assignments pairs (y, x).
const assignments = munkres(costMatrix);

console.log(assignments);
// Output: [[0, 2], [1, 1], [2, 0]]

API

  • munkres(costMatrix)

    Executes the Munkres algorithm on the given cost matrix and returns a set of optimal assignment pairs. Even if there are multiple optimal assignment sets, only one is returned.

Types

  • Matrix<T>: A generic 2D matrix (i.e. T[][]).

  • MatrixLike<T>: A generic read-only 2D matrix.

    • Can be made from any ArrayLike objects (i.e. any indexable object with a numeric length property). This allows for more flexibility, such as matrices made with typed arrays or objects.
  • Pair<A, B = A>: A generic pair (i.e. [A, B]).

Helpers

  1. copyMatrix(matrix): Creates a copy of the given matrix.

  2. createMatrix(workers, jobs, callbackFn): Generates a matrix based on the given workers, jobs, and callback function.

  3. genMatrix(numRows, numCols, callbackFn): Generates a matrix based on the given dimensions and a callback function.

  4. getMatrixMax(matrix): Finds the maximum value in a given matrix.

  5. getMatrixMin(matrix): Finds the minimum value in a given matrix.

  6. invertMatrix(matrix, bigVal?): Inverts the values in the given matrix. Useful for converting between minimizing and maximizing problems. If bigVal is not given, the matrix's max value is used instead.

  7. negateMatrix(matrix): Negates all values in the given matrix. Useful for converting between minimizing and maximizing problems.

Community and Support

Contributions are welcome!

  • Questions / Dicussions: Please contact us via GitHub discussions.

  • Bug Reports: Please use the GitHub issue tracker to report any bugs. Include a detailed description and any relevant code snippets or logs.

  • Feature Requests: Please submit feature requests as issues, clearly describing the feature and its potential benefits.

  • Pull Requests: Please ensure your code adheres to the existing style of the project and include any necessary tests and documentation.

For more information, check out the contributor's guide.

Build

  1. Clone the project from github
git clone git@github.com:havelessbemore/munkres.git
cd munkres
  1. Install dependencies
npm install
  1. Build the project
npm run build

This will output ECMAScript (.mjs) and CommonJS (.js) modules in the dist/ directory.

Format

To run the code linter:

npm run lint

To automatically fix linting issues, run:

npm run format

Test

To run tests:

npm test

To run tests with a coverage report:

npm run test:coverage

A coverage report is generated at ./coverage/index.html.

Benchmarks

Run benchmarks in your browser.

To run locally:

npm run bench

CI / CD

Benchmarks are integrated into our CI/CD pipeline and automatically run with each commit to the main branch. This helps monitor the performance impacts of development, preventing regressions and verifying changes maintain performance standards.

View historical results.

Specs:

  • Package version: latest
  • Runtime: NodeJS v20
  • Benchmarking Tool: tinybench v2.6.0
  • OS: ubuntu-latest

Results

Below are the latest results from running locally.

Specs:

  • Package version: v2.0.2
  • Runtime: NodeJS v20.12.2
  • Benchmarking Tool: tinybench v2.6.0
  • Machine:
    • Model: MacBook Air
    • Chip: Apple M2
    • Memory: 8 GB
    • OS: MacOS Sonoma

number[][]

DimensionsMin (ms)Max (ms)Avg (ms)Samples
2x200.924750.000143,611,437
4x40.000130.386830.000411,227,622
8x80.000620.20050.00134372,763
16x160.0020.263460.00487102,720
32x320.0090.064620.0187426,678
64x640.044830.282790.078376,381
128x1280.2280.520580.343381,457
256x2561.077252.375671.59139315
512x5125.864429.185467.7134765
1024x102431.8208345.47138.1296150
2048x2048165.45792245.93154205.515450
4096x4096905.255921,384.788081,129.7862950
8192x81925,062.635337,561.391296,152.1196450

bigint[][]

DimensionsMin (ms)Max (ms)Avg (ms)Samples
2x20.000041.455670.000182,763,520
4x40.000290.617920.00058860,516
8x80.001210.638290.00246203,435
16x160.00450.6390.0099450,320
32x320.020210.662210.0429911,633
64x640.115751.002830.195142,563
128x1280.539881.926540.9169546
256x2563.324926.380884.51322112
512x51215.7537546.9474625.2709150
1024x1024107.30771171.37271129.8146450
2048x2048546.04767850.22892689.9589350
4096x40962,835.292294,583.966883,697.8520550
8192x819218,069.7982924,171.8826721,107.4719210

Made with ❤️ by Michael Rojas

2.0.3

1 year ago

2.0.4

1 year ago

2.0.2

1 year ago

2.0.1

1 year ago

2.0.0

1 year ago

1.2.4

1 year ago

1.2.3

1 year ago

1.2.0

1 year ago

1.2.2

1 year ago

1.2.1

1 year ago

1.1.0

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago

0.0.3

1 year ago

0.0.5

1 year ago

0.0.4

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago