int main() { int n,m; scanf("%d%d", &n, &m); vector< vector<double> > M; M.resize(n); for(int i=0; i<n; i++) M[i].resize(n, inf); for(int i=0; i<m; i++) { int a,b,c; scanf("%d%d%d", &a, &b, &c); a--; b--; M[a][b] = c; } Munkres matcher; vector< vector<bool> > sol = matcher.solve(M); int res = 0; for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { if( sol[i][j] ) { if( M[i][j]==inf ) { res = -1; break; } else { res += M[i][j]; } } } if( res==-1 ) break; } if( res==-1 ) printf("NIE\n"); else printf("%d\n", res); }
double computeHungarianAssignment2(const std::vector<std::vector<double> >& costs, std::vector<std::vector<bool> >& assignment) { //printf("Running HUNGARIAN assignment\n"); int nrows = costs.size(); int ncols = costs[0].size(); // Initialize matrix Matrix<double> matrix(nrows, ncols); for ( int row = 0 ; row < nrows ; row++ ) { for ( int col = 0 ; col < ncols ; col++ ) { matrix(row,col) = (double) costs[row][col]; } } // Apply Munkres algorithm to matrix. Munkres m; m.solve(matrix); // Copy data double totalCost = 0.0; for ( int row = 0 ; row < nrows ; row++ ) { for ( int col = 0 ; col < ncols ; col++ ) { assignment[row][col] = matrix(row,col) == 0.0; if (assignment[row][col] == true) totalCost += costs[row][col]; } } return totalCost; }
void solve(boost::numeric::ublas::matrix <double> & boost_matrix) { Matrix <double> matrix = convert_boost_matrix_to_munkres_matrix<double>(boost_matrix); Munkres munkres; munkres.solve (matrix); fill_boost_matrix_from_munkres_matrix<double>(boost_matrix, matrix); };
void solve(std::vector <std::vector <double> > &m) { auto matrix = convert_std_2d_vector_to_munkres_matrix<double>(m); Munkres munkres; munkres.solve (matrix); fill_std_2d_vector_from_munkres_matrix<double>(m, matrix); };
std::vector<int> euclidean_permutation( float* target, float* reference, int n_atoms, int n_dims, std::vector<std::vector<int> >& permute_groups) { // the cost matrix A[i,j] of matching target[i] to reference[j] std::vector<double> A(n_atoms * n_atoms, std::numeric_limits<double>::max()); // is atom [i] in a permute group? std::vector<int> in_permute_group(n_atoms, 0); // fill in the cost matrix with the distance between all pairs that are in // the same permute group for (int g = 0; g < (int) permute_groups.size(); g++) { for (int i = 0; i < (int) permute_groups[g].size(); i++) { const int ii = permute_groups[g][i]; in_permute_group[ii] = 1; for (int j = 0; j < (int) permute_groups[g].size(); j++) { const int jj = permute_groups[g][j]; double sq_euclidean_ii_jj = 0; for (int d = 0; d < n_dims; d++) sq_euclidean_ii_jj += square(target[ii*n_dims + d] - reference[jj*n_dims + d]); A[ii*n_atoms + jj] = sq_euclidean_ii_jj; } } } // set the diagonal entries of the cost matrix for elements that are not // in a permute group for (int i = 0; i < n_atoms; i++) { if (!in_permute_group[i]) { double sq_euclidean_i_i = 0; for (int d = 0; d < n_dims; d++) sq_euclidean_i_i += square(target[i*n_dims + d] - reference[i*n_dims + d]); A[i*n_atoms + i] = sq_euclidean_i_i; } } // solve the assignment problem with this cost matrix Munkres munk; std::vector<int> mask(n_atoms * n_atoms); // printf("running solve...\n"); munk.solve(&A[0], &mask[0], n_atoms, n_atoms); // printf("done\n"); std::vector<int> mapping(n_atoms); for (int i = 0; i < n_atoms; i++) { for (int j = 0; j < n_atoms; j++) { if (mask[i*n_atoms + j]) { mapping[i] = j; break; } } } return mapping; }
int main() { int nrows = 5; int ncols = 5; double infinity = std::numeric_limits<double>::infinity(); Matrix<double> matrix_input = Matrix<double>({ {7.0,6.0,3.5,4.6,8.0}, {3.4,6.3,2.5,9.3,1.3}, {9.1,1.7,8.1,3.4,5.6}, {5.4,4.8,4.1,7.4,8.2}, {4.5,7,4.4,2.1,6.2}}); Matrix<double> matrix = Matrix<double>(matrix_input); double t = 9.1; for ( int row = 0 ; row < nrows ; row++ ) { for ( int col = 0 ; col < ncols ; col++ ) { if ( matrix(row,col) > t ) { matrix(row,col) = infinity;//prune weight > t . } } } Munkres<double> m; int state = m.solve(matrix); // return state =0 means successful match; else means failure match. if (state==0) { printf("t=%lf,success!!!!!!!!\n\n\n",t); double sumweight = 0;// the sum of weights of selected edges. for ( int row = 0 ; row < nrows ; row++ ) { for ( int col = 0 ; col < ncols ; col++ ) { if (matrix(row,col) > -0.5) { // if the edge is a match printf("<%d, %d>: %lf\n",row,col,matrix_input(row,col)); sumweight += matrix_input(row,col); } } } printf("The sum weights is: %lf\n", sumweight); } else { printf("t=%lf,failure !!!!!!!!!!!!!!!!!!!1\n\n\nfailure!!!!!!!!!!!!!!!!!!!!!!!!!1\n\n\n",t); } return 0; }
void Tracker::updateTracks() { createDistanceMatrix(); createCostMatrix(); // Solve Global Nearest Neighbor problem: Munkres munkres; cost_matrix_ = munkres.solve(cost_matrix_, false); // rows: targets (tracks), cols: detections updateDetectedTracks(); fillUnassociatedDetections(); updateLostTracks(); createNewTracks(); }
void munkres_Rwrap(int *nrows, int *ncols, double *dist) { Matrix<double> m(*nrows,*ncols); for ( int row = 0 ; row < *nrows ; row++ ) { for ( int col = 0 ; col < *ncols ; col++ ) { m(row,col) = dist[row+col*(*nrows)]; } } // Apply Munkres algorithm to matrix. Munkres h; h.solve(m); for ( int row = 0 ; row < *nrows ; row++ ) { for ( int col = 0 ; col < *ncols ; col++ ) { dist[row+col*(*nrows)] = m(row,col); } } }
void Utility::hungCorrespondOf2Sets (std::vector<Point3D> set1, std::vector<Point3D>set2, std::vector<int>&assignment1,std::vector<int>&assignment2) { int nrows = set1.size(); int ncols = set2.size(); int maxSize = std::max(nrows,ncols); assignment1.resize(maxSize); assignment2.resize(maxSize); for (int i = 0;i<maxSize;i++) { assignment1[i] = -1; assignment2[i] = -1; } Matrix<double> costMatrix(maxSize, maxSize); for (int i = 0;i<nrows;i++) for (int j = 0;j<ncols;j++) costMatrix(i,j) = euclidDistance(set1[i],set2[j]); Munkres myMunkres; myMunkres.solve(costMatrix); // solution is back stored in costMatrix variable, 0 for matches, otherwise -1; // now fill in assignment for (int i = 0;i<maxSize;i++) { for (int j = 0;j<maxSize;j++) { if (costMatrix(i, j) ==0) { if (i<nrows && j<ncols) { assignment1[i] = j; assignment2[j] = i; } } } } }
void MCC::consolidationLSA(vector <pair <int,int> > &best, Matrix <float> & gamma, unsigned int nP, unsigned int nA, unsigned int nB) const { unsigned int i,j,k,l; pair <int,int> tmp; float *scores = new float[nP]; best.reserve(nP); best.assign(nP, tmp); for (i=0; i<nP; i++) { scores[i] = -1; } Matrix<float> matrix(nA, nB); for (i=0; i<nA; i++) { for (j=0; j<nB; j++) { if (gamma(i,j) > 0) matrix(i,j) = 1.0 / gamma(i,j); else matrix(i,j) = 666; } } // Apply Munkres algorithm to matrix. Munkres m; m.solve(matrix); for (i=0; i<nA; i++) { for (j=0; j<nB; j++) { if (matrix(i,j) == 0) { for (k=0; k<nP && scores[k]>=gamma(i,j); k++); if (k < nP) { for (l=nP-1; l>k; l--) { scores[l] = scores[l-1]; best[l].first = best[l-1].first; best[l].second = best[l-1].second; } scores[k] = gamma(i,j); best[k].first = i; best[k].second = j; } } } } delete [] scores; }
void Utility::hungCorrespondOf2SetsCostFunctionVersion (int size1, int size2, Matrix<double> costMat , std::vector<int>&assignment1,std::vector<int>&assignment2) { int nrows = size1; int ncols = size2; int maxSize = std::max(nrows,ncols); assignment1.resize(maxSize); assignment2.resize(maxSize); for (int i = 0;i<maxSize;i++) { assignment1[i] = -1; assignment2[i] = -1; } assignment1.resize(maxSize); assignment2.resize(maxSize); Munkres myMunkres; myMunkres.solve(costMat); // solution is back stored in costMatrix variable, 0 for matches, otherwise -1; // now fill in assignment for (int i = 0;i<nrows;i++) { for (int j = 0;j<ncols;j++) { if (costMat(i, j) ==0) { assignment1[i] = j; assignment2[j] = i; } } } }
// Core function to compare and place trackId into Pool cache void traceObj::pushPool(vector<Rect> obj){ Mat tmpFrame = *srcFrame; // Remove all non-activated pool member for (vector<pointPool>::size_type i=0; i!= pool.size(); i++) { if (pool[i].step > 20) { pool.erase(pool.begin()+i); i--; } } int rows = (int)pool.size(); int cols = (int)obj.size(); Mat_<int> delta_matrix(rows,cols); // iterate through all pool member // to calculate delta_matrix for (vector<pointPool>::size_type i = 0; i!= pool.size(); i++) { Point2f objPos; float objr; unsigned int newDist;//, smallDist = 50; // kalman prediction setup Mat prediction = pool[i].kfc.predict(); Point2i predictPt; if(pool[i].predicPos[5].x == 0) predictPt = pool[i].pos[0]; else predictPt = Point(prediction.at<float>(0),prediction.at<float>(1)); // Push predicted point to pool cache for (int k = 9; k > 0; k--) pool[i].predicPos[k] = pool[i].predicPos[k-1]; pool[i].predicPos[0] = predictPt; // iterate through all new trace objs to find most fit pool member for (vector<Rect>::size_type m = 0; m!= obj.size(); m++){ objPos.x = obj[m].x + obj[m].width/2; objPos.y = obj[m].y + obj[m].height/2; objr = obj[m].width; newDist = calcDist(predictPt, objPos); delta_matrix((unsigned int)i,(unsigned int)m) = newDist; } } // Solve Hungarian assignment Munkres m; m.diag(true); m.solve(delta_matrix); for( int i=0; i!=rows; i++){ Mat estimated; Point2i stablizedPt; Mat_<float> measurement(3,1); Point2i objPos; unsigned int objr; bool assigned = false; // iterate through current columne to find proper assignment for (int j=0; j<cols; j++) { // skip not assigned if(delta_matrix(i,j) != 0) continue; // if graphics compare match, start pushing to pool //if (matComp(tmpFrame(obj[j]).clone(), pool[i].trackId) > 0.7) { // Shift the pool position for (int k = 9; k > 0; k--) { pool[i].pos[k] = pool[i].pos[k-1]; pool[i].stablizedPos[k] = pool[i].stablizedPos[k-1]; pool[i].predicPos[k] = pool[i].predicPos[k-1]; pool[i].radius[k] = pool[i].radius[k-1]; //pool[i].rec[k] = pool[i].rec[k-1]; } objPos.x = obj[j].x + obj[j].width/2; objPos.y = obj[j].y + obj[j].height/2; objr = obj[j].width; // evaluate kalman prediction // measurement(0) = objPos.x; measurement(1) = objPos.y; measurement(2) = objr; estimated = pool[i].kfc.correct(measurement); stablizedPt = Point(estimated.at<float>(0),estimated.at<float>(1)); pool[i].pos[0] = objPos; pool[i].stablizedPos[0] = stablizedPt; pool[i].radius[0] = (int)estimated.at<float>(2); //pool[i].rec[0] = obj[j]; // pool[i].avgDist = pool[i].avgDist*.75 + smallDist *.25; if(pool[i].step >1) pool[i].step --; // important to set step to 1 for success trace // copy the newly traced img to trackId //pool[i].trackId = tmpFrame(obj[j]).clone(); // Remove from trace obj list to avoid duplicatation // obj.erase(obj.begin() + j); // break the trace obj iteration, continue to next pool member assigned = true; break; // finish assignment, end the iteration } // If no proper assignment found // Copy last status to current status if(!assigned){ for (int k = 9; k > 0; k--) { pool[i].pos[k] = pool[i].pos[k-1]; pool[i].stablizedPos[k] = pool[i].stablizedPos[k-1]; pool[i].radius[k] = pool[i].radius[k-1]; //pool[i].rec[k] = pool[i].rec[k-1]; } // If coresponding detected position is missing, // Set estimated Position to current Position Point2i predictPt = pool[i].predicPos[0]; if(predictPt.x != 0){ measurement(0) = predictPt.x; measurement(1) = predictPt.y; measurement(2) = pool[i].radius[0]; pool[i].pos[0] = predictPt; }else{ measurement(0) = pool[i].pos[0].x; measurement(1) = pool[i].pos[0].y; measurement(2) = pool[i].radius[0]; // pool[i].pos[0] remain untouched } estimated = pool[i].kfc.correct(measurement); stablizedPt = Point(estimated.at<float>(0),estimated.at<float>(1)); pool[i].stablizedPos[0] = stablizedPt; pool[i].predicPos[0] = predictPt; pool[i].radius[0] = estimated.at<float>(2); // if no proper trace obj found, pool member go unstable pool[i].step++; } } // iterate through columns to find un-assigned tracker // and assign to new pool member for (int j=0; j<cols; j++) { bool tag = true; for (int i=0; i<rows; i++) { if(delta_matrix(i,j) == 0) tag = false; } if (tag) { // insert new tracker to pool // and do pool member initializing // for (vector<Rect>::iterator r=obj.begin(); r!=obj.end(); r++) { pointPool newPool; Point2i objPos; unsigned int objr; objPos.x = r->x + r->width/2; objPos.y = r->y + r->height/2; objr = r->width; newPool.pos[0] = objPos; newPool.stablizedPos[0] = objPos; newPool.predicPos[0] = objPos; newPool.radius[0] = objr; //newPool.rec[0] = *r; newPool.step = 15; // activate step and set to unstable //newPool.trackId = tmpFrame(*r).clone(); // copy the traced img to trackId // Initialize the Kalman filter for position prediction // newPool.kfc.init(6, 3, 0); // Setup transitionMatrix to // 1, 0, 1, 0 // 0, 1, 0, 1 // 0, 0, 1, 0 // 0, 0, 0, 1 // very weird, don't understand .... newPool.kfc.transitionMatrix = *(Mat_<float>(6,6) << 1,0,0,3,0,0, 0,1,0,0,3,0, 0,0,1,0,0,1, 0,0,0,1,0,0, 0,0,0,0,1,0, 0,0,0,0,0,1); newPool.kfc.statePost.at<float>(0) = objPos.x; newPool.kfc.statePost.at<float>(1) = objPos.y; newPool.kfc.statePost.at<float>(2) = objr; newPool.kfc.statePost.at<float>(3) = 0; newPool.kfc.statePost.at<float>(4) = 0; newPool.kfc.statePost.at<float>(5) = 0; newPool.kfc.statePre.at<float>(0) = objPos.x; newPool.kfc.statePre.at<float>(1) = objPos.y; newPool.kfc.statePre.at<float>(2) = objr; newPool.kfc.statePre.at<float>(3) = 0; newPool.kfc.statePre.at<float>(4) = 0; newPool.kfc.statePre.at<float>(5) = 0; setIdentity(newPool.kfc.measurementMatrix); setIdentity(newPool.kfc.processNoiseCov, Scalar::all(1e-2)); setIdentity(newPool.kfc.measurementNoiseCov, Scalar::all(1e-1)); setIdentity(newPool.kfc.errorCovPost, Scalar::all(0.1)); // add to pool pool.push_back(newPool); } } } return; }
int main(int argc, char *argv[]) { int nrows = 501; int ncols = 501; if ( argc == 3 ) { nrows = atoi(argv[1]); ncols = atoi(argv[2]); } matrix<double> wmatrix(nrows, ncols); //srandom(time(NULL)); // Seed random number generator. // Initialize matrix with random values. for ( int row = 0 ; row < nrows ; row++ ) { for ( int col = 0 ; col < ncols ; col++ ) { wmatrix(row,col) = std::abs(row+col-7);//(double)random(); } } //wmatrix = trans(wmatrix); // Display begin matrix state. for ( int row = 0 ; row < nrows ; row++ ) { for ( int col = 0 ; col < ncols ; col++ ) { std::cout.width(2); std::cout << wmatrix(row,col) << ","; } std::cout << std::endl; } std::cout << std::endl; // Apply Munkres algorithm to matrix. matrix<double> oldw = wmatrix; Munkres<> m; m.solve(wmatrix); // Display solved matrix. for ( int row = 0 ; row < nrows ; row++ ) { for ( int col = 0 ; col < ncols ; col++ ) { std::cout.width(2); std::cout << wmatrix(row,col) << ","; } std::cout << std::endl; } std::cout << std::endl; double s = 0; for ( int row = 0 ; row < nrows ; row++ ) { for ( int col = 0 ; col < ncols ; col++ ) { if ( wmatrix(row,col) == 0 ) s += oldw(row, col); } } std::cout <<"s="<<s<< std::endl; for ( int row = 0 ; row < nrows ; row++ ) { int rowcount = 0; for ( int col = 0 ; col < ncols ; col++ ) { if ( wmatrix(row,col) == 0 ) rowcount++; } if ( rowcount != 1 ) std::cerr << "Row " << row << " has " << rowcount << " columns that have been matched." << std::endl; } for ( int col = 0 ; col < ncols ; col++ ) { int colcount = 0; for ( int row = 0 ; row < nrows ; row++ ) { if ( wmatrix(row,col) == 0 ) colcount++; } if ( colcount != 1 ) std::cerr << "Column " << col << " has " << colcount << " rows that have been matched." << std::endl; } return 0; }
int main(){ cin.tie(0); ios::sync_with_stdio(false); string line; for(;getline(cin,line);){ vector<pair<int,int> > customers_int; vector<int> products_int; { vector<string>a=split(line,";"); if(a[0]=="" || a[1]==""){puts("0.00");continue;} vector<string>customers=split(a[0],","); for(auto it=customers.begin();it!=customers.end();++it){ int total=0,vowels=0; for(int i=0;i<it->size();i++){ int c=it->at(i); if(('A'<=c&&c<='Z')||('a'<=c&&c<='z'))total++; if(strchr("AaEeIiOoUuYy",c))vowels++; } customers_int.push_back(make_pair(total,vowels)); } vector<string>products=split(a[1],","); for(auto it=products.begin();it!=products.end();++it){ int total=0;//,vowels=0; for(int i=0;i<it->size();i++){ int c=it->at(i); if(('A'<=c&&c<='Z')||('a'<=c&&c<='z'))total++; //if(strchr("AaEeIiOoUuYy",c))vowels++; } products_int.push_back(total); } } int ma=max(customers_int.size(),products_int.size()); vector<vector<int> > v(ma); #if MODE==1 vector<vector<int> > v2(ma); vector<vector<int> > as(ma); #elif MODE==2 Matrix<double> mat(ma,ma); #endif for(int i=0;i<ma;i++){ v[i].resize(ma); #if MODE==1 v2[i].resize(ma); as[i].resize(ma); #endif if(i<customers_int.size()){ for(int j=0;j<products_int.size();j++){ int mul=gcd(customers_int[i].first,products_int[j])>1 ? 3 : 2; int val=-mul*( products_int[j]%2==0 ? customers_int[i].second*3 : (customers_int[i].first-customers_int[i].second)*2 ); v[i][j]=val; #if MODE==1 v2[i][j]=val; #elif MODE==2 mat(i,j)=val; #endif } } } #if MODE==1 runMunkers(v,as,ma,false); #elif MODE==2 Munkres m; m.solve(mat); #endif double ret=0; for(int i=0;i<customers_int.size();i++){ for(int j=0;j<products_int.size();j++){ #if MODE==1 if(as[i][j]==1)ret+=-v2[i][j]/4.0; #elif MODE==2 if(mat(i,j)==0)ret+=-v[i][j]/4.0; #endif } } printf("%.2f\n",ret); } }
RealType wasserstein_distance(const Diagram& dgm1, const Diagram& dgm2, int p) { typedef RealType Distance; typedef typename Diagram::Point Point; typedef Linfty<Point, Point> Norm; unsigned size = dgm1.size() + dgm2.size(); Norm norm; // Setup the matrix Matrix<Distance> m(size,size); for (unsigned i = 0; i < dgm1.size(); ++i) for (unsigned j = 0; j < dgm2.size(); ++j) { const Point& p1 = *(dgm1.begin() + i); const Point& p2 = *(dgm2.begin() + j); m(i,j) = pow(norm(p1, p2), p); m(j + dgm1.size(), i + dgm2.size()) = 0; } for (unsigned i = 0; i < dgm1.size(); ++i) for (unsigned j = dgm2.size(); j < size; ++j) { const Point& p1 = *(dgm1.begin() + i); m(i,j) = pow(norm.diagonal(p1), p); } for (unsigned j = 0; j < dgm2.size(); ++j) for (unsigned i = dgm1.size(); i < size; ++i) { const Point& p2 = *(dgm2.begin() + j); m(i,j) = pow(norm.diagonal(p2), p); } // Compute weighted matching Munkres munkres; munkres.solve(m); // Assume everything is assigned (i.e., that we have a perfect matching) Distance sum = 0; for (unsigned i = 0; i < size; i++) for (unsigned j = 0; j < size; j++) if (m(i,j) == 0) { //std::cout << i << ": " << j << '\n'; //sum += m[i][j]; if (i >= dgm1.size()) { if (j >= dgm2.size()) sum += 0; else { const Point& p2 = *(dgm2.begin() + j); sum += pow(norm.diagonal(p2), p); } } else { if (j >= dgm2.size()) { const Point& p1 = *(dgm1.begin() + i); sum += pow(norm.diagonal(p1), p); } else { const Point& p1 = *(dgm1.begin() + i); const Point& p2 = *(dgm2.begin() + j); sum += pow(norm(p1, p2), p); } } break; } return sum; }
void perf_eval(matrix<float> const& results, matrix<float> const& gt, vector<std::vector<std::pair<int, int> > > & corres, perf_t& perf) { using namespace boost::lambda; vector<int> rtt; vector<int> rnn; extract_nntt(results, rtt, rnn); vector<int> gtt; vector<int> gnn; extract_nntt(gt, gtt, gnn); int T = std::max(*std::max_element(rtt.begin(), rtt.end()), *std::max_element(gtt.begin(), gtt.end()))+1; corres = vector<std::vector<std::pair<int, int> > >(T); for(int tt=0; tt<T; ++tt) { std::vector<int> gbbid, rbbid; for(int ii=0; ii<gtt.size(); ++ii) { if(tt==gtt(ii)) gbbid.push_back(ii); } for(int ii=0; ii<rtt.size(); ++ii) { if(tt==rtt(ii)) rbbid.push_back(ii); } //prepare valid pairs matrix<bool> conn = scalar_matrix<bool>(gbbid.size(), rbbid.size(), false); std::vector<std::pair<int, int> > cand; std::vector<std::pair<int, int> > cand_kkll; for(int kk=0; kk<gbbid.size(); ++kk) { int ii = gbbid[kk]; matrix_row<matrix<float> const> grow(gt, ii); vector<float> r11 = project(grow, range(2, 6)); vector<float> r12 = project(grow, range(6, 10)); float ar11 = (r11(2)-r11(0))*(r11(3)-r11(1)); float ar12 = (r12(2)-r12(0))*(r12(3)-r12(1)); for(int ll=0; ll<rbbid.size(); ++ll) { int jj = rbbid[ll]; matrix_row<matrix<float> const> rrow(results, jj); vector<float> r21 = project(rrow, range(2, 6)); vector<float> r22 = project(rrow, range(6, 10)); float ar21 = (r21(2)-r21(0))*(r21(3)-r21(1)); float ar22 = (r22(2)-r22(0))*(r22(3)-r22(1)); float inar1 = rectint(r11, r21)/std::sqrt(ar11*ar21+1.0f); float inar2 = rectint(r12, r22)/std::sqrt(ar12*ar22+1.0f); if(inar1>=0.4f && inar2>=0.4f) { conn(kk, ll) = true; cand.push_back(std::make_pair<int, int>(ii, jj)); cand_kkll.push_back(std::make_pair<int, int>(kk, ll)); } } } //propagate prev corres if(tt>0) { for(int pp=0; pp<corres(tt-1).size(); ++pp) { int l1 = gnn[corres(tt-1)[pp].first]; int l2 = rnn[corres(tt-1)[pp].second]; for(int qq=0; qq<cand.size(); ++qq) { int l1q = gnn[cand[qq].first]; int l2q = rnn[cand[qq].second]; if(l1 == l1q && l2 == l2q) { corres(tt).push_back(cand[qq]); matrix_row<matrix<bool> > connrow(conn, cand_kkll[qq].first); std::for_each(connrow.begin(), connrow.end(), _1=false); matrix_column<matrix<bool> > conncol(conn, cand_kkll[qq].second); std::for_each(conncol.begin(), conncol.end(), _1=false); } } } } std::vector<int> gbbid_remained, rbbid_remained; std::vector<int> kk_remained, ll_remained; for(int kk=0; kk<conn.size1(); ++kk) { int ii = gbbid[kk]; matrix_row<matrix<bool> > connrow(conn, kk); if(connrow.end() != std::find(connrow.begin(), connrow.end(), true) ) { gbbid_remained.push_back(ii); kk_remained.push_back(kk); } } for(int ll=0; ll<conn.size2(); ++ll) { int jj = rbbid[ll]; matrix_column<matrix<bool> > conncol(conn, ll); if(conncol.end() != std::find(conncol.begin(), conncol.end(), true) ) { rbbid_remained.push_back(jj); ll_remained.push_back(ll); } } matrix<bool> conn_remained(kk_remained.size(), ll_remained.size()); for(int ss=0; ss<conn_remained.size1(); ++ss) { int kk = kk_remained[ss]; for(int zz=0; zz<conn_remained.size2(); ++zz) { int ll = ll_remained[zz]; conn_remained(ss, zz) = conn(kk, ll); } } matrix<float> gt_remained(gbbid_remained.size(), gt.size2()); matrix<float> rst_remained(rbbid_remained.size(), results.size2()); for(int ss=0; ss<gt_remained.size1(); ++ss) { int ii = gbbid_remained[ss]; matrix_row<matrix<float> > gtr_row(gt_remained, ss); gtr_row = row(gt, ii); } for(int zz=0; zz<rst_remained.size1(); ++zz) { int jj = rbbid_remained[zz]; matrix_row<matrix<float> > rstr_row(rst_remained, zz); rstr_row = row(results, jj); } matrix<float> dist; make_distance_matrix(dist, conn_remained, gt_remained, rst_remained); // Apply Munkres algorithm to matrix. //matrix<double> oldw = dist; Munkres<> m; real_timer_t timer; m.solve(dist); //std::cout<<"Munkres algorithm elasped time: "<<timer.elapsed()/1000.0f<<std::endl; for(int ss=0; ss<gbbid_remained.size(); ++ss) { int ii = gbbid_remained[ss]; for(int zz=0; zz<rbbid_remained.size(); ++zz) { int jj = rbbid_remained[zz]; if(dist(ss, zz)>=0) corres(tt).push_back(std::make_pair<int, int>(ii, jj)); } } #if 0 std::cout<<"tt="<<tt<<std::endl; for(int cc=0; cc<corres(tt).size(); ++cc) { std::cout<<"("<<gnn[corres(tt)[cc].first]<<", " <<rnn[corres(tt)[cc].second]<<")"<<std::endl; } #endif } vector<int> gcount=scalar_vector<int>(gt.size1(), 0); vector<int> rcount=scalar_vector<int>(results.size1(), 0); for(int tt=0; tt<corres.size(); ++tt) { for(int cc=0; cc<corres(tt).size(); ++cc) { gcount[corres(tt)[cc].first] ++; rcount[corres(tt)[cc].second] ++; } } int miss = std::count(gcount.begin(), gcount.end(), 0); int fa = std::count(rcount.begin(), rcount.end(), 0); int mismatch = 0; for(int tt=1; tt<corres.size(); ++tt) { for(int pp=0; pp<corres(tt-1).size(); ++pp) { for(int qq=0; qq<corres(tt).size(); ++qq) { if(gnn[corres(tt-1)[pp].first] == gnn[corres(tt)[qq].first] && rnn[corres(tt-1)[pp].second] != rnn[corres(tt)[qq].second]) { mismatch ++; } if(gnn[corres(tt-1)[pp].first] != gnn[corres(tt)[qq].first] && rnn[corres(tt-1)[pp].second] == rnn[corres(tt)[qq].second]) { mismatch ++; } } } } perf.miss = miss; perf.fa = fa; perf.idswitch = mismatch; perf.miss_rate = static_cast<float>(miss)/gt.size1(); perf.fa_rate = static_cast<float>(fa)/results.size1(); std::cout<<"miss="<<miss<<"/"<<gt.size1() <<", \tfa="<<fa<<"/"<<results.size1() <<", \tmismatch="<<mismatch<<std::endl; }
void TrakerManager::doHungarianAlg(const vector<Rect>& detections) { cout << "H---------BEGIN" << endl; _controller.waitList.update(); list<EnsembleTracker*> expert_class; list<EnsembleTracker*> novice_class; vector<Rect> detection_left; for (list<EnsembleTracker*>::iterator it = _tracker_list.begin(); it != _tracker_list.end(); it++) { if ((*it)->getIsNovice()) { novice_class.push_back((*it)); cout << "Novice " << (*it)->getID() << endl; } else { expert_class.push_back((*it)); cout << "Expert " << (*it)->getID() << endl; } (*it)->hasDetection = false; } //deal with experts int hp_size = (int)expert_class.size(); int dt_size = (int)detections.size(); if (dt_size*hp_size>0) { Matrix<double> matrix(dt_size, hp_size + dt_size); vector<bool> indicator; for (int i = 0; i<dt_size; i++) { Rect detect_win_GTsize = scaleWin(detections[i], BODYSIZE_TO_DETECTION_RATIO); Rect shrinkWin = scaleWin(detections[i], TRACKING_TO_DETECTION_RATIO); list<EnsembleTracker*>::iterator j_tl = expert_class.begin(); for (int j = 0; j<hp_size + dt_size; j++) { if (j<hp_size) { Rect currentWin = (*j_tl)->getResult(); double currentWin_cx = currentWin.x + 0.5*currentWin.width + 0.5; double currentWin_cy = currentWin.y + 0.5*currentWin.height + 0.5; double detectWin_cx = detections[i].x + 0.5*detections[i].width + 0.5; double detectWin_cy = detections[i].y + 0.5*detections[i].height + 0.5; double d = sqrt(pow(currentWin_cx - detectWin_cx, 2.0) + pow(currentWin_cy - detectWin_cy, 2.0)); double ratio = (double)(*j_tl)->getBodysizeResult().width / detect_win_GTsize.width; if (d<(*j_tl)->getAssRadius() /*&& ratio<1.2 && ratio>0.8*/) { double dis_to_last = (*j_tl)->getDisToLast(shrinkWin); /* ad hoc consistence enhancing rule, making association better*/ if (dis_to_last / (((double)(*j_tl)->getSuspensionCount() + 1) / (FRAME_RATE * 10 / 7) + 0.5)<((*j_tl)->getBodysizeResult().width*1.5)) { matrix(i, j) = d;//*h; cout << "Expert " << (*j_tl)->getID() << " distance = " << d << endl;; } else { matrix(i, j) = INFINITY; cout << "Expert " << (*j_tl)->getID() << " Goes to infinity" << endl; } } else { matrix(i, j) = INFINITY; cout << "Expert " << (*j_tl)->getID() << " Goes to infinity (" << d << ")" << endl; } j_tl++; } else matrix(i, j) = 100000;// dummy } } Munkres m; m.solve(matrix); for (int i = 0; i<dt_size; i++) { bool flag = false; list<EnsembleTracker*>::iterator j_tl = expert_class.begin(); Rect shrinkWin = scaleWin(detections[i], TRACKING_TO_DETECTION_RATIO); for (int j = 0; j<hp_size; j++) { if (matrix(i, j) == 0)//matched { cout << "Detection associates with expert" << " " << (*j_tl)->getID() << endl;; (*j_tl)->hasDetection = true; (*j_tl)->detectionInThisFrame = detections[i]; (*j_tl)->addAppTemplate(_frame_set, shrinkWin);//will change result_temp if demoted flag = true; if ((*j_tl)->getIsNovice())//release the suspension (*j_tl)->promote(); while ((*j_tl)->getTemplateNum()>MAX_TEMPLATE_SIZE) (*j_tl)->deletePoorestTemplate(); break; } j_tl++; } if (!flag) detection_left.push_back(detections[i]); } } else detection_left = detections; //deal with novice class dt_size = (int)detection_left.size(); hp_size = (int)novice_class.size(); if (dt_size*hp_size>0) { Matrix<double> matrix(dt_size, hp_size + dt_size); for (int i = 0; i<dt_size; i++) { Rect detect_win_GTsize = scaleWin(detection_left[i], BODYSIZE_TO_DETECTION_RATIO); Rect shrinkWin = scaleWin(detection_left[i], TRACKING_TO_DETECTION_RATIO); list<EnsembleTracker*>::iterator j_tl = novice_class.begin(); for (int j = 0; j<hp_size + dt_size; j++) { if (j<hp_size) { Rect currentWin = (*j_tl)->getResult(); double currentWin_cx = currentWin.x + 0.5*currentWin.width + 0.5; double currentWin_cy = currentWin.y + 0.5*currentWin.height + 0.5; double detectWin_cx = detection_left[i].x + 0.5*detection_left[i].width + 0.5; double detectWin_cy = detection_left[i].y + 0.5*detection_left[i].height + 0.5; double d = sqrt(pow(currentWin_cx - detectWin_cx, 2.0) + pow(currentWin_cy - detectWin_cy, 2.0)); double ratio = (double)(*j_tl)->getBodysizeResult().width / detect_win_GTsize.width; if (d<(*j_tl)->getAssRadius()/* && ratio<1.2 && ratio>0.8*/) { double dis_to_last = (*j_tl)->getDisToLast(shrinkWin); // ad hoc consistence enhancing rule, making association better if (dis_to_last / (((double)(*j_tl)->getSuspensionCount() + 1) / (FRAME_RATE * 10 / 7) + 0.5) < ((*j_tl)->getBodysizeResult().width) * 2) { matrix(i, j) = d;//************could be changed cout << "Novice " << (*j_tl)->getID() << " distance = " << d << endl;; } else { matrix(i, j) = INFINITY; cout << "Novice " << (*j_tl)->getID() << " goes to inifinity" << endl; } } else matrix(i, j) = INFINITY; j_tl++; } else matrix(i, j) = 100000; // dummy } } Munkres m; m.solve(matrix); for (int i = 0; i<dt_size; i++) { bool flag = false; list<EnsembleTracker*>::iterator j_tl = novice_class.begin(); Rect shrinkWin = scaleWin(detection_left[i], TRACKING_TO_DETECTION_RATIO); for (int j = 0; j<hp_size; j++) { if (matrix(i, j) == 0)//matched { (*j_tl)->hasDetection = true; (*j_tl)->detectionInThisFrame = detection_left[i]; cout << "Detection associates with novice" << " " << (*j_tl)->getID() << endl;; (*j_tl)->addAppTemplate(_frame_set, shrinkWin);//will change result_temp if demoted flag = true; if ((*j_tl)->getIsNovice())//release the suspension (*j_tl)->promote(); while ((*j_tl)->getTemplateNum()>MAX_TEMPLATE_SIZE) (*j_tl)->deletePoorestTemplate(); break; } j_tl++; } if (!flag) _controller.waitList.feed(scaleWin(detection_left[i], BODYSIZE_TO_DETECTION_RATIO), 1.0); } } //starting position else if (dt_size > 0) { for (int i = 0; i < dt_size; i++) { cout << "Detection feed to waitlist" << endl; _controller.waitList.feed(scaleWin(detection_left[i], BODYSIZE_TO_DETECTION_RATIO), 1.0); } } cout << "H---------END" << endl; }
void assignResource(DataForAI& data) { //updateResource(data); std::vector<Point>::iterator iter=nS.begin(); sort(nS.begin(),nS.end(),nearToTank); short m=nS.size(),n=5; short k=m<n?m:n; Point me; me.row=data.tank[data.myID].row; me.col=data.tank[data.myID].col; Matrix<double> kmMatrix(k,k); //printf("initialize the matrix\n"); //initialize the matrix //initKmMatrix(kmMatrix); int i=0; for(iter=nS.begin();i<k;i++,iter++)//soure id { for(int j=0;j<k;j++)//tank id { kmMatrix(i,j)=1/double(estAstarDistance(me,*iter,data)); } //i++; } //printf("apply the munkres matching \n"); //apply the munkres matching Munkres km; km.solve(kmMatrix); //printf(" Display solved matrix\n"); #ifdef DISP_KMRESULT // Display solved matrix. if(data.round==1) { for ( int row = 0 ; row < k ; row++ ) { for ( int col = 0 ; col < k ; col++ ) { std::cout.width(2); std::cout << kmMatrix(row,col) << ","; } std::cout << std::endl; } } #endif //std::vector<Point>::iterator iter=nS.begin(); for (int r=0;r<k;r++) { for (int c=0;c<k;c++) { if(kmMatrix(r,c)==0) { nearestS[r]=*(iter+c); //if(data.round==1) printf("nS(%d,%d) assigned to tank%d\n",(*(iter+c)).row,(*(iter+c)).col,r); } } } }