Exemple #1
0
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;
}
Exemple #6
0
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;
}
Exemple #7
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();
    }
Exemple #8
0
 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);
         }
     }
 }
Exemple #9
0
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;
					}
				}
			}
		}




}
Exemple #10
0
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;
}
Exemple #11
0
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;
				}
			}
		}

		
		
}
Exemple #12
0
// 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;
}
Exemple #13
0
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;
}
Exemple #14
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;
}
Exemple #16
0
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;
}
Exemple #18
0
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);

			}
		}

	}
}