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);