27 vector<vector<double>> &DistMatrix,
28 vector<int> &Assignment)
30 unsigned int nRows = DistMatrix.size();
31 unsigned int nCols = DistMatrix[0].size();
33 double *distMatrixIn =
new double[nRows * nCols];
34 int *assignment =
new int[nRows];
41 for (
unsigned int i = 0; i < nRows; i++)
42 for (
unsigned int j = 0; j < nCols; j++)
43 distMatrixIn[i + nRows * j] = DistMatrix[i][j];
46 assignmentoptimal(assignment, &cost, distMatrixIn, nRows, nCols);
49 for (
unsigned int r = 0; r < nRows; r++)
50 Assignment.push_back(assignment[r]);
52 delete[] distMatrixIn;
60 void HungarianAlgorithm::assignmentoptimal(
67 double *distMatrix, *distMatrixTemp, *distMatrixEnd, *columnEnd, value, minValue;
68 bool *coveredColumns, *coveredRows, *starMatrix, *newStarMatrix, *primeMatrix;
69 int nOfElements, minDim, row, col;
73 for (row = 0; row < nOfRows; row++)
78 nOfElements = nOfRows * nOfColumns;
79 distMatrix = (
double *)malloc(nOfElements *
sizeof(
double));
80 distMatrixEnd = distMatrix + nOfElements;
82 for (row = 0; row < nOfElements; row++)
84 value = distMatrixIn[row];
86 cerr <<
"All matrix elements have to be non-negative." << endl;
87 distMatrix[row] = value;
91 coveredColumns = (
bool *)calloc(nOfColumns,
sizeof(
bool));
92 coveredRows = (
bool *)calloc(nOfRows,
sizeof(
bool));
93 starMatrix = (
bool *)calloc(nOfElements,
sizeof(
bool));
94 primeMatrix = (
bool *)calloc(nOfElements,
sizeof(
bool));
95 newStarMatrix = (
bool *)calloc(nOfElements,
sizeof(
bool));
98 if (nOfRows <= nOfColumns)
102 for (row = 0; row < nOfRows; row++)
105 distMatrixTemp = distMatrix + row;
106 minValue = *distMatrixTemp;
107 distMatrixTemp += nOfRows;
108 while (distMatrixTemp < distMatrixEnd)
110 value = *distMatrixTemp;
111 if (value < minValue)
113 distMatrixTemp += nOfRows;
117 distMatrixTemp = distMatrix + row;
118 while (distMatrixTemp < distMatrixEnd)
120 *distMatrixTemp -= minValue;
121 distMatrixTemp += nOfRows;
126 for (row = 0; row < nOfRows; row++)
127 for (col = 0; col < nOfColumns; col++)
128 if (fabs(distMatrix[row + nOfRows * col]) < DBL_EPSILON)
129 if (!coveredColumns[col])
131 starMatrix[row + nOfRows * col] =
true;
132 coveredColumns[col] =
true;
140 for (col = 0; col < nOfColumns; col++)
143 distMatrixTemp = distMatrix + nOfRows * col;
144 columnEnd = distMatrixTemp + nOfRows;
146 minValue = *distMatrixTemp++;
147 while (distMatrixTemp < columnEnd)
149 value = *distMatrixTemp++;
150 if (value < minValue)
155 distMatrixTemp = distMatrix + nOfRows * col;
156 while (distMatrixTemp < columnEnd)
157 *distMatrixTemp++ -= minValue;
161 for (col = 0; col < nOfColumns; col++)
162 for (row = 0; row < nOfRows; row++)
163 if (fabs(distMatrix[row + nOfRows * col]) < DBL_EPSILON)
164 if (!coveredRows[row])
166 starMatrix[row + nOfRows * col] =
true;
167 coveredColumns[col] =
true;
168 coveredRows[row] =
true;
171 for (row = 0; row < nOfRows; row++)
172 coveredRows[row] =
false;
176 step2b(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
179 computeassignmentcost(assignment, cost, distMatrixIn, nOfRows);
183 free(coveredColumns);
193 void HungarianAlgorithm::buildassignmentvector(
199 for (
int row = 0; row < nOfRows; row++)
200 for (
int col = 0; col < nOfColumns; col++)
201 if (starMatrix[row + nOfRows * col])
204 assignment[row] = col + 1;
206 assignment[row] = col;
213 void HungarianAlgorithm::computeassignmentcost(
221 for (row = 0; row < nOfRows; row++)
223 col = assignment[row];
225 *cost += distMatrix[row + nOfRows * col];
230 void HungarianAlgorithm::step2a(
236 bool *coveredColumns,
242 bool *starMatrixTemp, *columnEnd;
246 for (col = 0; col < nOfColumns; col++)
248 starMatrixTemp = starMatrix + nOfRows * col;
249 columnEnd = starMatrixTemp + nOfRows;
250 while (starMatrixTemp < columnEnd)
252 if (*starMatrixTemp++)
254 coveredColumns[col] =
true;
261 step2b(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
265 void HungarianAlgorithm::step2b(
271 bool *coveredColumns,
277 int col, nOfCoveredColumns;
280 nOfCoveredColumns = 0;
281 for (col = 0; col < nOfColumns; col++)
282 if (coveredColumns[col])
285 if (nOfCoveredColumns == minDim)
288 buildassignmentvector(assignment, starMatrix, nOfRows, nOfColumns);
293 step3(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
298 void HungarianAlgorithm::step3(
304 bool *coveredColumns,
311 int row, col, starCol;
317 for (col = 0; col < nOfColumns; col++)
318 if (!coveredColumns[col])
319 for (row = 0; row < nOfRows; row++)
320 if ((!coveredRows[row]) && (fabs(distMatrix[row + nOfRows * col]) < DBL_EPSILON))
323 primeMatrix[row + nOfRows * col] =
true;
326 for (starCol = 0; starCol < nOfColumns; starCol++)
327 if (starMatrix[row + nOfRows * starCol])
330 if (starCol == nOfColumns)
333 step4(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim, row, col);
338 coveredRows[row] =
true;
339 coveredColumns[starCol] =
false;
347 step5(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
351 void HungarianAlgorithm::step4(
357 bool *coveredColumns,
365 int n, starRow, starCol, primeRow, primeCol;
366 int nOfElements = nOfRows * nOfColumns;
369 for (n = 0; n < nOfElements; n++)
370 newStarMatrix[n] = starMatrix[n];
373 newStarMatrix[row + nOfRows * col] =
true;
377 for (starRow = 0; starRow < nOfRows; starRow++)
378 if (starMatrix[starRow + nOfRows * starCol])
381 while (starRow < nOfRows)
384 newStarMatrix[starRow + nOfRows * starCol] =
false;
388 for (primeCol = 0; primeCol < nOfColumns; primeCol++)
389 if (primeMatrix[primeRow + nOfRows * primeCol])
393 newStarMatrix[primeRow + nOfRows * primeCol] =
true;
397 for (starRow = 0; starRow < nOfRows; starRow++)
398 if (starMatrix[starRow + nOfRows * starCol])
404 for (n = 0; n < nOfElements; n++)
406 primeMatrix[n] =
false;
407 starMatrix[n] = newStarMatrix[n];
409 for (n = 0; n < nOfRows; n++)
410 coveredRows[n] =
false;
413 step2a(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);
417 void HungarianAlgorithm::step5(
423 bool *coveredColumns,
434 for (row = 0; row < nOfRows; row++)
435 if (!coveredRows[row])
436 for (col = 0; col < nOfColumns; col++)
437 if (!coveredColumns[col])
439 value = distMatrix[row + nOfRows * col];
445 for (row = 0; row < nOfRows; row++)
446 if (coveredRows[row])
447 for (col = 0; col < nOfColumns; col++)
448 distMatrix[row + nOfRows * col] += h;
451 for (col = 0; col < nOfColumns; col++)
452 if (!coveredColumns[col])
453 for (row = 0; row < nOfRows; row++)
454 distMatrix[row + nOfRows * col] -= h;
457 step3(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);