#include #include #include #include #include #include namespace icl{ typedef SimpleMatrix imat; typedef std::vector vec; //#define BEGIN_METHOD(X) counter_##X++; MethodTimer __timer(&timer_##X) void clearCovers(vec &rowCover, vec &colCover){ // {{{ open for (unsigned int i=0; i int hg_step1(int step, SimpleMatrix &cost){ // {{{ open //What STEP 1 does: //For each row of the cost matrix, find the smallest element //and subtract it from from every other element in its row. real minval; for(int i=0; i int hg_step2(int step, SimpleMatrix &cost, imat &mask, vec &rowCover, vec &colCover){ // {{{ open //What STEP 2 does: //Marks uncovered zeros as starred and covers their row and column. for (int i=0; i=mask.w()){//Should be cost.length but ok, because mask has same dimensions. step=7; }else { step=4; } return step; } // }}} /* orig:: working, but slow !!! template int hg_step4(int step, SimpleMatrix &cost, imat &mask, vec &rowCover, vec &colCover, vec &zero_RC){ BEGIN_METHOD(hg_step4); // {{{ open //What STEP 4 does: //Find an uncovered zero in cost and prime it (if none go to step 6). Check for star in same row: //if yes, cover the row and uncover the star's column. Repeat until no uncovered zeros are left //and go to step 6. If not, save location of primed zero and go to step 5. vec row_col(2); //Holds row and col of uncovered zero. bool done = false; while (!done){ row_col = findUncoveredZero(row_col, cost, rowCover, colCover); if (row_col[0] == -1){ done = true; step = 6; }else{ mask[row_col[0]][row_col[1]] = 2; //Prime the found uncovered zero. bool starInRow = false; for (int j=0; j void findZeroPositions(std::vector &dst, SimpleMatrix &cost){ // {{{ open for(int i=0;i vec findUncoveredZero(vec &row_col, SimpleMatrix &cost, vec &rowCover, vec &colCover){ // {{{ open for(int i=0;i= cost.w()){ done = true; } }//end outer while return row_col; ****************************/ } // }}} /* Best function, 5x faster then original, and twice as fast as ***Fast */ vec findUncoveredZeroLite(vec &row_col, const std::vector &indices, vec &rowCover, vec &colCover){ // {{{ open // x = col; for(unsigned int i=0;i int hg_step4(int step, SimpleMatrix &cost, imat &mask, vec &rowCover, vec &colCover, vec &zero_RC){ // {{{ open //What STEP 4 does: //Find an uncovered zero in cost and prime it (if none go to step 6). Check for star in same row: //if yes, cover the row and uncover the star's column. Repeat until no uncovered zeros are left //and go to step 6. If not, save location of primed zero and go to step 5. vec row_col(2); //Holds row and col of uncovered zero. bool done = false; std::vector zeroPositions; findZeroPositions(zeroPositions, cost); if(!zeroPositions.size()){ step = 6; return step; } while (!done){ findUncoveredZeroLite(row_col, zeroPositions, rowCover, colCover); if (row_col[0] == -1){ done = true; step = 6; }else{ mask[row_col[0]][row_col[1]] = 2; //Prime the found uncovered zero. bool starInRow = false; for (int j=0; j vecPath; vecPath.push_back(Point(zero_RC[0],zero_RC[1])); //path[count][0] = zero_RC[0];//Row of last prime. //path[count][1] = zero_RC[1];//Column of last prime. bool done = false; while (!done){ // int r = findStarInCol(mask,path[count][1]); int r = findStarInCol(mask,vecPath[count].y); if (r>=0){ count++; vecPath.push_back(Point(r,vecPath[count-1].y)); // path[count][0] = r; //Row of starred zero. // path[count][1] = path[count-1][1];//Column of starred zero. }else{ done = true; } if(!done){ //int c = findPrimeInRow(mask, path[count][0]); int c = findPrimeInRow(mask, vecPath[count].x); count++; vecPath.push_back(Point(vecPath[count-1].x,c)); // path[count][0] = path [count-1][0]; //Row of primed zero. // path[count][1] = c; //Col of primed zero. } }//end while imat path((int)vecPath.size(),2); for(unsigned int i=0;i int hg_step6(int step, SimpleMatrix &cost, vec &rowCover, vec &colCover, real maxCost){ // {{{ open //What STEP 6 does: //Find smallest uncovered value in cost: a. Add it to every element of covered rows //b. Subtract it from every element of uncovered columns. Go to step 4. real minval = findSmallest(cost, rowCover, colCover, maxCost); for (unsigned int i=0; i real findSmallest(SimpleMatrix &cost, vec &rowCover, vec &colCover, real maxCost){ // {{{ open real minval = maxCost; //There cannot be a larger cost than this. for (int i=0; i cost[i][j])){ minval = cost[i][j]; } } } return minval; } // }}} template vec HungarianAlgorithm::apply(const SimpleMatrix &m, bool isCostMatrix){ // {{{ open mat cost; if(isCostMatrix){ cost = m.deepCopy(); }else{ real maxWeight = cost.max(); for(int i=0;i void HungarianAlgorithm::visualizeAssignment(const SimpleMatrix &cost, const vec &a){ // {{{ open mat v(cost.w(),cost.h()); for(unsigned int i=0;i; template class HungarianAlgorithm; template class HungarianAlgorithm; }