12 std::vector<int>& assignment,
TMethod Method)
14 assignment.resize(nOfRows, -1);
39 const distMatrix_t& distMatrixIn,
size_t nOfRows,
size_t nOfColumns)
45 size_t nOfElements = nOfRows * nOfColumns;
49 track_t* distMatrixEnd = distMatrix + nOfElements;
51 for (
size_t row = 0; row < nOfElements; row++)
53 track_t value = distMatrixIn[row];
55 distMatrix[row] = value;
59 bool* coveredColumns = (
bool*)calloc(nOfColumns,
sizeof(
bool));
60 bool* coveredRows = (
bool*)calloc(nOfRows,
sizeof(
bool));
61 bool* starMatrix = (
bool*)calloc(nOfElements,
sizeof(
bool));
62 bool* primeMatrix = (
bool*)calloc(nOfElements,
sizeof(
bool));
63 bool* newStarMatrix = (
bool*)calloc(nOfElements,
sizeof(
bool));
66 if (nOfRows <= nOfColumns)
68 for (
size_t row = 0; row < nOfRows; row++)
71 track_t* distMatrixTemp = distMatrix + row;
72 track_t minValue = *distMatrixTemp;
73 distMatrixTemp += nOfRows;
74 while (distMatrixTemp < distMatrixEnd)
76 track_t value = *distMatrixTemp;
81 distMatrixTemp += nOfRows;
84 distMatrixTemp = distMatrix + row;
85 while (distMatrixTemp < distMatrixEnd)
87 *distMatrixTemp -= minValue;
88 distMatrixTemp += nOfRows;
92 for (
size_t row = 0; row < nOfRows; row++)
94 for (
size_t col = 0; col < nOfColumns; col++)
96 if (distMatrix[row + nOfRows * col] == 0)
98 if (!coveredColumns[col])
100 starMatrix[row + nOfRows * col] =
true;
101 coveredColumns[col] =
true;
110 for (
size_t col = 0; col < nOfColumns; col++)
113 track_t* distMatrixTemp = distMatrix + nOfRows * col;
114 track_t* columnEnd = distMatrixTemp + nOfRows;
115 track_t minValue = *distMatrixTemp++;
116 while (distMatrixTemp < columnEnd)
118 track_t value = *distMatrixTemp++;
119 if (value < minValue)
125 distMatrixTemp = distMatrix + nOfRows * col;
126 while (distMatrixTemp < columnEnd)
128 *distMatrixTemp++ -= minValue;
132 for (
size_t col = 0; col < nOfColumns; col++)
134 for (
size_t row = 0; row < nOfRows; row++)
136 if (distMatrix[row + nOfRows * col] == 0)
138 if (!coveredRows[row])
140 starMatrix[row + nOfRows * col] =
true;
141 coveredColumns[col] =
true;
142 coveredRows[row] =
true;
149 for (
size_t row = 0; row < nOfRows; row++)
151 coveredRows[row] =
false;
155 step2b(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows,
156 nOfColumns, (nOfRows <= nOfColumns) ? nOfRows : nOfColumns);
161 free(coveredColumns);
174 for (
size_t row = 0; row < nOfRows; row++)
176 for (
size_t col = 0; col < nOfColumns; col++)
178 if (starMatrix[row + nOfRows * col])
180 assignment[row] =
static_cast<int>(col);
192 for (
size_t row = 0; row < nOfRows; row++)
194 const int col = assignment[row];
197 cost += distMatrixIn[row + nOfRows * col];
206 bool* newStarMatrix,
bool* primeMatrix,
bool* coveredColumns,
bool* coveredRows,
207 size_t nOfRows,
size_t nOfColumns,
size_t minDim)
209 bool* starMatrixTemp, *columnEnd;
211 for (
size_t col = 0; col < nOfColumns; col++)
213 starMatrixTemp = starMatrix + nOfRows * col;
214 columnEnd = starMatrixTemp + nOfRows;
215 while (starMatrixTemp < columnEnd)
217 if (*starMatrixTemp++)
219 coveredColumns[col] =
true;
225 step2b(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows,
233 bool* newStarMatrix,
bool* primeMatrix,
bool* coveredColumns,
bool* coveredRows,
234 size_t nOfRows,
size_t nOfColumns,
size_t minDim)
237 size_t nOfCoveredColumns = 0;
238 for (
size_t col = 0; col < nOfColumns; col++)
240 if (coveredColumns[col])
245 if (nOfCoveredColumns == minDim)
253 step3(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows,
262 bool* newStarMatrix,
bool* primeMatrix,
bool* coveredColumns,
bool* coveredRows,
263 size_t nOfRows,
size_t nOfColumns,
size_t minDim)
265 bool zerosFound =
true;
269 for (
size_t col = 0; col < nOfColumns; col++)
271 if (!coveredColumns[col])
273 for (
size_t row = 0; row < nOfRows; row++)
275 if ((!coveredRows[row]) && (distMatrix[row + nOfRows * col] == 0))
278 primeMatrix[row + nOfRows * col] =
true;
281 for (; starCol < nOfColumns; starCol++)
283 if (starMatrix[row + nOfRows * starCol])
288 if (starCol == nOfColumns)
291 step4(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows,
292 nOfRows, nOfColumns, minDim, row, col);
297 coveredRows[row] =
true;
298 coveredColumns[starCol] =
false;
308 step5(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows,
316 bool* newStarMatrix,
bool* primeMatrix,
bool* coveredColumns,
bool* coveredRows,
317 size_t nOfRows,
size_t nOfColumns,
size_t minDim,
size_t row,
size_t col)
319 const size_t nOfElements = nOfRows * nOfColumns;
321 for (
size_t n = 0; n < nOfElements; n++)
323 newStarMatrix[n] = starMatrix[n];
326 newStarMatrix[row + nOfRows * col] =
true;
328 size_t starCol = col;
330 for (; starRow < nOfRows; starRow++)
332 if (starMatrix[starRow + nOfRows * starCol])
337 while (starRow < nOfRows)
340 newStarMatrix[starRow + nOfRows * starCol] =
false;
342 size_t primeRow = starRow;
344 for (; primeCol < nOfColumns; primeCol++)
346 if (primeMatrix[primeRow + nOfRows * primeCol])
352 newStarMatrix[primeRow + nOfRows * primeCol] =
true;
355 for (starRow = 0; starRow < nOfRows; starRow++)
357 if (starMatrix[starRow + nOfRows * starCol])
365 for (
size_t n = 0; n < nOfElements; n++)
367 primeMatrix[n] =
false;
368 starMatrix[n] = newStarMatrix[n];
370 for (
size_t n = 0; n < nOfRows; n++)
372 coveredRows[n] =
false;
375 step2a(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows,
383 bool* newStarMatrix,
bool* primeMatrix,
bool* coveredColumns,
bool* coveredRows,
384 size_t nOfRows,
size_t nOfColumns,
size_t minDim)
387 float h = std::numeric_limits<track_t>::max();
388 for (
size_t row = 0; row < nOfRows; row++)
390 if (!coveredRows[row])
392 for (
size_t col = 0; col < nOfColumns; col++)
394 if (!coveredColumns[col])
396 const float value = distMatrix[row + nOfRows * col];
406 for (
size_t row = 0; row < nOfRows; row++)
408 if (coveredRows[row])
410 for (
size_t col = 0; col < nOfColumns; col++)
412 distMatrix[row + nOfRows * col] += h;
417 for (
size_t col = 0; col < nOfColumns; col++)
419 if (!coveredColumns[col])
421 for (
size_t row = 0; row < nOfRows; row++)
423 distMatrix[row + nOfRows * col] -= h;
428 step3(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows,
436 const distMatrix_t& distMatrixIn,
size_t nOfRows,
size_t nOfColumns)
439 const size_t nOfElements = nOfRows * nOfColumns;
440 float* distMatrix = (
float*)malloc(nOfElements *
sizeof(
float));
441 for (
size_t n = 0; n < nOfElements; n++)
443 distMatrix[n] = distMatrixIn[n];
450 float minValue = std::numeric_limits<track_t>::max();
453 for (
size_t row = 0; row < nOfRows; row++)
455 for (
size_t col = 0; col < nOfColumns; col++)
457 const float value = distMatrix[row + nOfRows * col];
458 if (value != std::numeric_limits<track_t>::max() && (value < minValue))
467 if (minValue != std::numeric_limits<track_t>::max())
469 assignment[tmpRow] =
static_cast<int>(tmpCol);
471 for (
size_t n = 0; n < nOfRows; n++)
473 distMatrix[n + nOfRows * tmpCol] = std::numeric_limits<track_t>::max();
475 for (
size_t n = 0; n < nOfColumns; n++)
477 distMatrix[tmpRow + nOfRows * n] = std::numeric_limits<track_t>::max();
492 const distMatrix_t& distMatrixIn,
size_t nOfRows,
size_t nOfColumns)
495 const size_t nOfElements = nOfRows * nOfColumns;
496 float* distMatrix = (
float*)malloc(nOfElements *
sizeof(
float));
497 for (
size_t n = 0; n < nOfElements; n++)
499 distMatrix[n] = distMatrixIn[n];
503 int* nOfValidObservations = (
int*)calloc(nOfRows,
sizeof(
int));
504 int* nOfValidTracks = (
int*)calloc(nOfColumns,
sizeof(
int));
507 bool infiniteValueFound =
false;
508 bool finiteValueFound =
false;
509 for (
size_t row = 0; row < nOfRows; row++)
511 for (
size_t col = 0; col < nOfColumns; col++)
513 if (distMatrix[row + nOfRows * col] != std::numeric_limits<track_t>::max())
515 nOfValidTracks[col] += 1;
516 nOfValidObservations[row] += 1;
517 finiteValueFound =
true;
521 infiniteValueFound =
true;
526 if (infiniteValueFound)
528 if (!finiteValueFound)
530 free(nOfValidTracks);
531 free(nOfValidObservations);
535 bool repeatSteps =
true;
542 for (
size_t col = 0; col < nOfColumns; col++)
544 bool singleValidationFound =
false;
545 for (
size_t row = 0; row < nOfRows; row++)
547 if (distMatrix[row + nOfRows * col] != std::numeric_limits<track_t>::max() &&
548 (nOfValidObservations[row] == 1))
550 singleValidationFound =
true;
554 if (singleValidationFound)
556 for (
size_t row = 0; row < nOfRows; row++)
557 if ((nOfValidObservations[row] > 1) &&
558 distMatrix[row + nOfRows * col] != std::numeric_limits<track_t>::max())
560 distMatrix[row + nOfRows * col] = std::numeric_limits<track_t>::max();
561 nOfValidObservations[row] -= 1;
562 nOfValidTracks[col] -= 1;
572 for (
size_t row = 0; row < nOfRows; row++)
574 bool singleValidationFound =
false;
575 for (
size_t col = 0; col < nOfColumns; col++)
577 if (distMatrix[row + nOfRows * col] != std::numeric_limits<track_t>::max() && (nOfValidTracks[col] == 1))
579 singleValidationFound =
true;
584 if (singleValidationFound)
586 for (
size_t col = 0; col < nOfColumns; col++)
588 if ((nOfValidTracks[col] > 1) && distMatrix[row + nOfRows * col] != std::numeric_limits<track_t>::max())
590 distMatrix[row + nOfRows * col] = std::numeric_limits<track_t>::max();
591 nOfValidObservations[row] -= 1;
592 nOfValidTracks[col] -= 1;
603 for (
size_t row = 0; row < nOfRows; row++)
605 if (nOfValidObservations[row] > 1)
607 bool allSinglyValidated =
true;
608 float minValue = std::numeric_limits<track_t>::max();
610 for (
size_t col = 0; col < nOfColumns; col++)
612 const float value = distMatrix[row + nOfRows * col];
613 if (value != std::numeric_limits<track_t>::max())
615 if (nOfValidTracks[col] > 1)
617 allSinglyValidated =
false;
620 else if ((nOfValidTracks[col] == 1) && (value < minValue))
628 if (allSinglyValidated)
630 assignment[row] =
static_cast<int>(tmpCol);
632 for (
size_t n = 0; n < nOfRows; n++)
634 distMatrix[n + nOfRows * tmpCol] = std::numeric_limits<track_t>::max();
636 for (
size_t n = 0; n < nOfColumns; n++)
638 distMatrix[row + nOfRows * n] = std::numeric_limits<track_t>::max();
646 for (
size_t col = 0; col < nOfColumns; col++)
648 if (nOfValidTracks[col] > 1)
650 bool allSinglyValidated =
true;
651 float minValue = std::numeric_limits<track_t>::max();
653 for (
size_t row = 0; row < nOfRows; row++)
655 const float value = distMatrix[row + nOfRows * col];
656 if (value != std::numeric_limits<track_t>::max())
658 if (nOfValidObservations[row] > 1)
660 allSinglyValidated =
false;
663 else if ((nOfValidObservations[row] == 1) && (value < minValue))
671 if (allSinglyValidated)
673 assignment[tmpRow] =
static_cast<int>(col);
675 for (
size_t n = 0; n < nOfRows; n++)
677 distMatrix[n + nOfRows * col] = std::numeric_limits<track_t>::max();
679 for (
size_t n = 0; n < nOfColumns; n++)
681 distMatrix[tmpRow + nOfRows * n] = std::numeric_limits<track_t>::max();
692 float minValue = std::numeric_limits<track_t>::max();
695 for (
size_t row = 0; row < nOfRows; row++)
697 for (
size_t col = 0; col < nOfColumns; col++)
699 const float value = distMatrix[row + nOfRows * col];
700 if (value != std::numeric_limits<track_t>::max() && (value < minValue))
709 if (minValue != std::numeric_limits<track_t>::max())
711 assignment[tmpRow] =
static_cast<int>(tmpCol);
713 for (
size_t n = 0; n < nOfRows; n++)
715 distMatrix[n + nOfRows * tmpCol] = std::numeric_limits<track_t>::max();
717 for (
size_t n = 0; n < nOfColumns; n++)
719 distMatrix[tmpRow + nOfRows * n] = std::numeric_limits<track_t>::max();
729 free(nOfValidObservations);
730 free(nOfValidTracks);
~AssignmentProblemSolver()
void assignmentsuboptimal1(assignments_t &assignment, track_t &cost, const distMatrix_t &distMatrixIn, size_t nOfRows, size_t nOfColumns)
void assignmentoptimal(assignments_t &assignment, track_t &cost, const distMatrix_t &distMatrixIn, size_t nOfRows, size_t nOfColumns)
void buildassignmentvector(assignments_t &assignment, bool *starMatrix, size_t nOfRows, size_t nOfColumns)
void step2a(assignments_t &assignment, track_t *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, size_t nOfRows, size_t nOfColumns, size_t minDim)
void computeassignmentcost(const assignments_t &assignment, track_t &cost, const distMatrix_t &distMatrixIn, size_t nOfRows)
AssignmentProblemSolver()
std::vector< track_t > distMatrix_t
void assignmentsuboptimal2(assignments_t &assignment, track_t &cost, const distMatrix_t &distMatrixIn, size_t nOfRows, size_t nOfColumns)
void step2b(assignments_t &assignment, track_t *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, size_t nOfRows, size_t nOfColumns, size_t minDim)
void step3(assignments_t &assignment, track_t *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, size_t nOfRows, size_t nOfColumns, size_t minDim)
void step4(assignments_t &assignment, track_t *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, size_t nOfRows, size_t nOfColumns, size_t minDim, size_t row, size_t col)
std::vector< int > assignments_t
void step5(assignments_t &assignment, track_t *distMatrix, bool *starMatrix, bool *newStarMatrix, bool *primeMatrix, bool *coveredColumns, bool *coveredRows, size_t nOfRows, size_t nOfColumns, size_t minDim)
track_t Solve(const distMatrix_t &distMatrixIn, size_t nOfRows, size_t nOfColumns, assignments_t &assignment, TMethod Method=optimal)