├── Hungarian.cpp ├── Hungarian.h ├── LICENSE ├── README.txt ├── license.txt ├── makefile └── testMain.cpp /Hungarian.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Hungarian.cpp: Implementation file for Class HungarianAlgorithm. 3 | // 4 | // This is a C++ wrapper with slight modification of a hungarian algorithm implementation by Markus Buehren. 5 | // The original implementation is a few mex-functions for use in MATLAB, found here: 6 | // http://www.mathworks.com/matlabcentral/fileexchange/6543-functions-for-the-rectangular-assignment-problem 7 | // 8 | // Both this code and the orignal code are published under the BSD license. 9 | // by Cong Ma, 2016 10 | // 11 | 12 | #include 13 | #include // for DBL_MAX 14 | #include // for fabs() 15 | #include "Hungarian.h" 16 | 17 | 18 | HungarianAlgorithm::HungarianAlgorithm(){} 19 | HungarianAlgorithm::~HungarianAlgorithm(){} 20 | 21 | 22 | //********************************************************// 23 | // A single function wrapper for solving assignment problem. 24 | //********************************************************// 25 | double HungarianAlgorithm::Solve(vector >& DistMatrix, vector& Assignment) 26 | { 27 | unsigned int nRows = DistMatrix.size(); 28 | unsigned int nCols = DistMatrix[0].size(); 29 | 30 | double *distMatrixIn = new double[nRows * nCols]; 31 | int *assignment = new int[nRows]; 32 | double cost = 0.0; 33 | 34 | // Fill in the distMatrixIn. Mind the index is "i + nRows * j". 35 | // Here the cost matrix of size MxN is defined as a double precision array of N*M elements. 36 | // In the solving functions matrices are seen to be saved MATLAB-internally in row-order. 37 | // (i.e. the matrix [1 2; 3 4] will be stored as a vector [1 3 2 4], NOT [1 2 3 4]). 38 | for (unsigned int i = 0; i < nRows; i++) 39 | for (unsigned int j = 0; j < nCols; j++) 40 | distMatrixIn[i + nRows * j] = DistMatrix[i][j]; 41 | 42 | // call solving function 43 | assignmentoptimal(assignment, &cost, distMatrixIn, nRows, nCols); 44 | 45 | Assignment.clear(); 46 | for (unsigned int r = 0; r < nRows; r++) 47 | Assignment.push_back(assignment[r]); 48 | 49 | delete[] distMatrixIn; 50 | delete[] assignment; 51 | return cost; 52 | } 53 | 54 | 55 | //********************************************************// 56 | // Solve optimal solution for assignment problem using Munkres algorithm, also known as Hungarian Algorithm. 57 | //********************************************************// 58 | void HungarianAlgorithm::assignmentoptimal(int *assignment, double *cost, double *distMatrixIn, int nOfRows, int nOfColumns) 59 | { 60 | double *distMatrix, *distMatrixTemp, *distMatrixEnd, *columnEnd, value, minValue; 61 | bool *coveredColumns, *coveredRows, *starMatrix, *newStarMatrix, *primeMatrix; 62 | int nOfElements, minDim, row, col; 63 | 64 | /* initialization */ 65 | *cost = 0; 66 | for (row = 0; row nOfColumns) */ 131 | { 132 | minDim = nOfColumns; 133 | 134 | for (col = 0; col= 0) 214 | *cost += distMatrix[row + nOfRows*col]; 215 | } 216 | } 217 | 218 | /********************************************************/ 219 | void HungarianAlgorithm::step2a(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim) 220 | { 221 | bool *starMatrixTemp, *columnEnd; 222 | int col; 223 | 224 | /* cover every column containing a starred zero */ 225 | for (col = 0; col 16 | #include 17 | 18 | using namespace std; 19 | 20 | 21 | class HungarianAlgorithm 22 | { 23 | public: 24 | HungarianAlgorithm(); 25 | ~HungarianAlgorithm(); 26 | double Solve(vector >& DistMatrix, vector& Assignment); 27 | 28 | private: 29 | void assignmentoptimal(int *assignment, double *cost, double *distMatrix, int nOfRows, int nOfColumns); 30 | void buildassignmentvector(int *assignment, bool *starMatrix, int nOfRows, int nOfColumns); 31 | void computeassignmentcost(int *assignment, double *cost, double *distMatrix, int nOfRows); 32 | void step2a(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); 33 | void step2b(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); 34 | void step3(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); 35 | void step4(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim, int row, int col); 36 | void step5(int *assignment, double *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, int nOfRows, int nOfColumns, int minDim); 37 | }; 38 | 39 | 40 | #endif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, mcximing 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | 2 | Hungarian algorithm, also known as Munkres algorithm or Kuhn-Munkres algorithm, is a method for solving the assignment problem, for example assigning workers to jobs, which goal is to compute the optimal assignment that minimizes the total cost, and the like. 3 | 4 | This is a C++ wrapper with slight modification of a hungarian algorithm implementation by Markus Buehren. 5 | The original code is a few mex-functions for use in MATLAB, found here: 6 | http://www.mathworks.com/matlabcentral/fileexchange/6543-functions-for-the-rectangular-assignment-problem 7 | 8 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Markus Buehren 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | CFLAGS = -std=c++11 3 | 4 | test: main.o hung.o 5 | $(CC) -o test main.o hung.o 6 | 7 | hung.o: Hungarian.cpp Hungarian.h 8 | $(CC) -c Hungarian.cpp -o hung.o 9 | 10 | main.o: testMain.cpp Hungarian.h 11 | $(CC) $(CFLAGS) -c testMain.cpp -o main.o 12 | 13 | clean: 14 | -rm main.o hung.o 15 | 16 | -------------------------------------------------------------------------------- /testMain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Hungarian.h" 3 | 4 | 5 | int main(void) 6 | { 7 | // please use "-std=c++11" for this initialization of vector. 8 | vector< vector > costMatrix = { { 10, 19, 8, 15, 0 }, 9 | { 10, 18, 7, 17, 0 }, 10 | { 13, 16, 9, 14, 0 }, 11 | { 12, 19, 8, 18, 0 } }; 12 | 13 | HungarianAlgorithm HungAlgo; 14 | vector assignment; 15 | 16 | double cost = HungAlgo.Solve(costMatrix, assignment); 17 | 18 | for (unsigned int x = 0; x < costMatrix.size(); x++) 19 | std::cout << x << "," << assignment[x] << "\t"; 20 | 21 | std::cout << "\ncost: " << cost << std::endl; 22 | 23 | return 0; 24 | } 25 | --------------------------------------------------------------------------------