//Calculates matching cost and show matching results on the window float GraphMatch::matchTwoImages(vector<NodeSig> ns1, vector<NodeSig> ns2, Mat& assignment, Mat& cost) { //Construct [rowsxcols] cost matrix using pairwise //distance between node signature int rows = ns1.size(); int cols = ns2.size(); int** cost_matrix = (int**)calloc(rows,sizeof(int*)); for(int i = 0; i < rows; i++) { cost_matrix[i] = (int*)calloc(cols,sizeof(int)); for(int j = 0; j < cols; j++) cost_matrix[i][j] = GraphMatch::calcN2NDistance(ns1[i], ns2[j])*MULTIPLIER_1000; } hungarian_problem_t p; // initialize the hungarian_problem using the cost matrix hungarian_init(&p, cost_matrix , rows, cols, HUNGARIAN_MODE_MINIMIZE_COST); // solve the assignment problem hungarian_solve(&p); //Convert results to OpenCV format assignment = array2Mat8U(p.assignment,rows,cols); cost = array2Mat32F(cost_matrix,rows,cols); //Divide for correction cost = cost / MULTIPLIER_1000; //free variables hungarian_free(&p); // Calculate match score float matching_cost = 0; //Get non-zero indices which defines the optimal match(assignment) vector<Point> nonzero_locs; findNonZero(assignment,nonzero_locs); //Find optimal match cost for(int i = 0; i < nonzero_locs.size(); i++) { matching_cost = matching_cost + cost.at<float>(nonzero_locs[i].y, nonzero_locs[i].x); } return matching_cost; }
void BipartiteWeightedMatchingBinding::solveBipartiteWeightedMatching(Table &weights, Table &assignments) { hungarian_problem_t p; int rows = weights.size(); assert(rows > 0); int cols = weights[0].size(); assert(cols > 0); // not necessary but good to enforce assert(rows == cols); int** m = vector_to_matrix(weights, rows, cols); /* initialize the hungarian_problem using the cost matrix*/ hungarian_init(&p, m, rows, cols, HUNGARIAN_MODE_MINIMIZE_COST); /* solve the assignement problem */ hungarian_solve(&p); /* fprintf(stderr, "assignment matrix: %d rows and %d columns.\n\n", matrix_size, matrix_size); fprintf(stderr, "cost-matrix:"); hungarian_print_costmatrix(&p); fprintf(stderr, "assignment:"); hungarian_print_assignment(&p); */ for(int i = 0; i < rows; i++) { for(int j = 0; j < cols; j++) { assignments[i][j] = p.assignment[i][j]; } } /* free used memory */ hungarian_free(&p); for(int i = 0; i < rows; i++) { free(m[i]); } free(m); }
int main(int argc, char** argv) { hungarian_t prob; /* int r[4][4] = {{ 363, 626, 376, 46 }, { 802, 993, 784, 953 }, { 673, 23, 823, 207 }, { 380, 451, 520, 646 }}; */ int* r; m = n = 4; parse_args(argc,argv); if(!strlen(input_fname)) r = make_random_r(m,n); else r = make_r_from_ORlib(input_fname,&m,&n); if(!r) { puts("got NULL input"); exit(-1); } hungarian_init(&prob,(int*)r,m,n,HUNGARIAN_MIN); hungarian_print_rating(&prob); hungarian_solve(&prob); hungarian_print_assignment(&prob); printf("\nfeasible? %s\n", (hungarian_check_feasibility(&prob)) ? "yes" : "no"); printf("benefit: %d\n\n", hungarian_benefit(&prob)); hungarian_fini(&prob); free(r); return(0); }
void OAWrapper(double* Rpre, int* m, int* n, int* mod, double* res){ hungarian_problem_t prob; int i, j; double** R = (double**)R_alloc(*m,sizeof(double*)); double maxweight = -999999; for(i = 0; i < *m; i++){ R[i] = (double*)R_alloc(*n,sizeof(double)); for(j = 0; j < *n; j++){ R[i][j] = (Rpre[j* *m + i]); if(R[i][j] > maxweight) maxweight = R[i][j]; } } int mode = (*mod == 1)? HUNGARIAN_MODE_MAXIMIZE_UTIL: HUNGARIAN_MODE_MINIMIZE_COST; int dim = hungarian_init(&prob,R,*m,*n, mode); double cost=hungarian_solve(&prob); if(mode == HUNGARIAN_MODE_MAXIMIZE_UTIL) cost = dim * maxweight - cost; hungarian_free(&prob); res[0] = cost; }
int main(int argc,char** argv) { hungarian_t prob; int i,j,k; i=0,j=0; int m = atoi(argv[1]); int n = atoi(argv[2]); int *r; r = malloc(m*n*sizeof(int)); k=3; for(i=0;i<m;i++) { for(j=0;j<n;j++) { r[i*n+j] = atoi(argv[k]); k++; } } /* int r[4][4] = {{ 363, 626, 376, 46 }, { 802, 993, 784, 953 }, { 673, 23, 823, 207 }, { 380, 451, 520, 646 }}; */ hungarian_init(&prob,(int*)r,m,n,HUNGARIAN_MAX); // hungarian_print_rating(&prob); hungarian_solve(&prob); // hungarian_print_assignment(&prob); // hungarian_check_feasibility(&prob)); printf("%d", hungarian_benefit(&prob)); hungarian_fini(&prob); //free(r); return(0); }
//Calculates matching cost and show matching results on the window float GraphMatch::drawMatches(vector<NodeSig> ns1, vector<NodeSig> ns2, Mat img1, Mat img2) { Mat assignment, cost; //Construct [rowsxcols] cost matrix using pairwise //distance between node signature int rows = ns1.size(); int cols = ns2.size(); int** cost_matrix = (int**)calloc(rows,sizeof(int*)); for(int i = 0; i < rows; i++) { cost_matrix[i] = (int*)calloc(cols,sizeof(int)); for(int j = 0; j < cols; j++) { //Multiplied by constant because hungarian algorithm accept integer defined cost //matrix. We later divide by constant for correction cost_matrix[i][j] = GraphMatch::calcN2NDistance(ns1[i], ns2[j])*MULTIPLIER_1000; } } hungarian_problem_t p; // initialize the hungarian_problem using the cost matrix hungarian_init(&p, cost_matrix , rows, cols, HUNGARIAN_MODE_MINIMIZE_COST); // solve the assignment problem hungarian_solve(&p); //Convert results to OpenCV format assignment = array2Mat8U(p.assignment,rows,cols); cost = array2Mat32F(cost_matrix,rows,cols); //Divide for correction cost = cost / MULTIPLIER_1000; //free variables hungarian_free(&p); // Calculate match score and // show matching results given assignment and cost matrix Mat img_merged; float matching_cost = 0; //Concatenate two images hconcat(img1, img2, img_merged); //Get non-zero indices which defines the optimal match(assignment) vector<Point> nonzero_locs; findNonZero(assignment,nonzero_locs); //Draw optimal match for(int i = 0; i < nonzero_locs.size(); i++) { Point p1 = ns1[nonzero_locs[i].y].center; Point p2 = ns2[nonzero_locs[i].x].center+Point(img1.size().width,0); circle(img_merged,p1,MATCH_CIRCLE_RADIUS,MATCH_LINE_COLOR); circle(img_merged,p2,MATCH_CIRCLE_RADIUS,MATCH_LINE_COLOR); line(img_merged,p1,p2,MATCH_LINE_COLOR,MATCH_LINE_WIDTH); float dist = cost.at<float>(nonzero_locs[i].y, nonzero_locs[i].x); matching_cost = matching_cost + dist; //Draw cost on match image stringstream ss; ss << dist; string cost_str = ss.str(); Point center_pt((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0); //putText(img_merged, cost_str, center_pt, cv::FONT_HERSHEY_SIMPLEX, 1.0, Scalar(255, 0, 0), 1); } //Show matching results image on the window emit showMatchImage(mat2QImage(img_merged)); return matching_cost; }
void gsl_matrix_hungarian(gsl_matrix* gm_C,gsl_matrix* gm_P,gsl_vector* gv_col_inc, gsl_permutation* gp_sol, int _bprev_init, gsl_matrix *gm_C_denied, bool bgreedy) { // mexPrintf("VV\n"); long dim, startdim, enddim, n1,n2; double *C; int i,j; int **m; double *z; hungarian_problem_t p, *q; int matrix_size; double C_min=gsl_matrix_min(gm_C)-1; n1 = gm_C->size1; /* first dimension of the cost matrix */ n2 = gm_C->size2; /* second dimension of the cost matrix */ C = gm_C->data; //greedy solution if (bgreedy) { int ind,ind1,ind2; size_t *C_ind=new size_t[n1*n2]; gsl_heapsort_index(C_ind,C,n1*n2,sizeof(double),compare_doubles); bool* bperm_fix_1=new bool[n1]; bool* bperm_fix_2=new bool[n2]; int inummatch=0; for (i=0;i<n1;i++) {bperm_fix_1[i]=false;bperm_fix_2[i]=false;}; gsl_matrix_set_zero(gm_P); for (long l=0;l<n1*n2;l++) { ind=C_ind[l]; ind1=floor(ind/n1); ind2=ind%n2; if (!bperm_fix_1[ind1] and !bperm_fix_2[ind2]) { bperm_fix_1[ind1]=true; bperm_fix_2[ind2]=true; gm_P->data[ind]=1;inummatch++; }; if (inummatch==n1) break; }; delete[] bperm_fix_1;delete[] bperm_fix_2; //because C is a transpose matrix gsl_matrix_transpose(gm_P); return; }; double C_max=((gsl_matrix_max(gm_C)-C_min>1)?(gsl_matrix_max(gm_C)-C_min):1)*(n1>n2?n1:n2); m = (int**)calloc(n1,sizeof(int*)); // mexPrintf("C[2] = %f \n",C[2]); for (i=0;i<n1;i++) { m[i] = (int*)calloc(n2,sizeof(int)); for (j=0;j<n2;j++) m[i][j] = (int) (C[i+n1*j] - C_min); // mexPrintf("m[%d][%d] = %f %f\n",i,j,m[i][j],C[i+n1*j] - C_min); if (gm_C_denied!=NULL) for (j=0;j<n2;j++){ if (j==30) int dbg=1; bool bden=(gm_C_denied->data[n2*i+j]<1e-10); if (bden) m[i][j] =C_max; else int dbg=1; }; }; //normalization: rows and columns // mexPrintf("C[2] = %f \n",C[2]); double dmin; for (i=0;i<n1;i++) { dmin=m[i][0]; for (j=1;j<n2;j++) dmin= (m[i][j]<dmin)? m[i][j]:dmin; for (j=0;j<n2;j++) m[i][j]-=dmin; }; for (j=0;j<n2;j++) { dmin=m[0][j]; for (i=1;i<n1;i++) dmin= (m[i][j]<dmin)? m[i][j]:dmin; for (i=0;i<n1;i++) m[i][j]-=dmin; }; if ((_bprev_init) &&(gv_col_inc !=NULL)) { //dual solution v substraction for (j=0;j<n2;j++) for (i=0;i<n1;i++) m[i][j]-=gv_col_inc->data[j]; //permutation of m columns int *mt = new int[n2]; for (i=0;i<n1;i++) { for (j=0;j<n2;j++) mt[j]=m[i][j]; for (j=0;j<n2;j++) m[i][j]=mt[gsl_permutation_get(gp_sol,j)]; }; delete[] mt; }; /* initialize the hungarian_problem using the cost matrix*/ matrix_size = hungarian_init(&p, m , n1,n2, HUNGARIAN_MODE_MINIMIZE_COST) ; /* solve the assignement problem */ hungarian_solve(&p); q = &p; //gsl_matrix* gm_P=gsl_matrix_alloc(n1,n2); gsl_permutation* gp_sol_inv=gsl_permutation_alloc(n2); if (gp_sol!=NULL) gsl_permutation_inverse(gp_sol_inv,gp_sol); else gsl_permutation_init(gp_sol_inv); for (i=0;i<n1;i++) for (j=0;j<n2;j++) gsl_matrix_set(gm_P,i,j,q->assignment[i][gp_sol_inv->data[j]]); //initialization by the previous solution if ((_bprev_init) &&(gv_col_inc !=NULL)) for (j=0;j<n2;j++) gv_col_inc->data[j]=q->col_inc[gp_sol_inv->data[j]]; if ((_bprev_init) && (gp_sol!=NULL)) { for (i=0;i<n1;i++) for (j=0;j<n2;j++) if (gsl_matrix_get(gm_P,i,j)==HUNGARIAN_ASSIGNED) gp_sol->data[i]=j; }; /* free used memory */ gsl_permutation_free(gp_sol_inv); hungarian_free(&p); for (i=0;i<n1;i++) free(m[i]); free(m); /* for (int i=0;i<gm_C->size1;i++) { for (int j=0;j<gm_C->size1;j++) { mexPrintf("G[%d][%d] = %f %f \n",i,j,gsl_matrix_get(gm_P,i,j),gsl_matrix_get(gm_C,i,j)); } }*/ // mexPrintf("AAA"); //return gm_P; }