int user_find_cuts(void *user, int varnum, int iter_num, int level, int index, double objval, int *indices, double *values, double ub, double etol, int *num_cuts, int *alloc_cuts, cut_data ***cuts) { vrp_cg_problem *vrp = (vrp_cg_problem *)user; int vertnum = vrp->vertnum; network *n; vertex *verts = NULL; int *compdemands = NULL, *compnodes = NULL, *compnodes_copy = NULL; int *compmembers = NULL, comp_num = 0; /*__BEGIN_EXPERIMENTAL_SECTION__*/ int *compdemands_copy = NULL; double *compcuts_copy = NULL, *compdensity = NULL, density; /*___END_EXPERIMENTAL_SECTION___*/ double node_cut, max_node_cut, *compcuts = NULL; int rcnt, cur_bins = 0, k; char **coef_list; int i, max_node; double cur_slack = 0.0; int capacity = vrp->capacity; int cut_size = (vertnum >> DELETE_POWER) + 1; cut_data *new_cut = NULL; elist *cur_edge = NULL; int which_connected_routine = vrp->par.which_connected_routine; int *ref = vrp->ref; double *cut_val = vrp->cut_val; char *in_set = vrp->in_set; char *cut_list = vrp->cut_list; elist *cur_edge1 = NULL, *cur_edge2 = NULL; /*__BEGIN_EXPERIMENTAL_SECTION__*/ #ifdef COMPILE_OUR_DECOMP edge *edge_pt; #endif /*___END_EXPERIMENTAL_SECTION___*/ int node1 = 0, node2 = 0; int *demand = vrp->demand; int *new_demand = vrp->new_demand; int total_demand = demand[0]; int num_routes = vrp->numroutes, num_trials; int triangle_cuts = 0; char *coef; if (iter_num == 1) SRANDOM(1); /*__BEGIN_EXPERIMENTAL_SECTION__*/ #if 0 CCutil_sprand(1, &rand_state); #endif /*___END_EXPERIMENTAL_SECTION___*/ /*__BEGIN_EXPERIMENTAL_SECTION__*/ #if 0 if (vrp->dg_id && vrp->par.verbosity > 3){ sprintf(name, "support graph"); display_support_graph(vrp->dg_id, (p->cur_sol.xindex == 0 && p->cur_sol.xiter_num == 1) ? TRUE: FALSE, name, varnum, xind, xval, etol, CTOI_WAIT_FOR_CLICK_AND_REPORT); } #endif /*___END_EXPERIMENTAL_SECTION___*/ /* This creates a fractional graph representing the LP solution */ n = createnet(indices, values, varnum, etol, vrp->edges, demand, vertnum); if (n->is_integral){ /* if the network is integral, check for connectivity */ check_connectivity(n, etol, capacity, num_routes, cuts, num_cuts, alloc_cuts); free_net(n); return(USER_SUCCESS); } #ifdef DO_TSP_CUTS if (vrp->par.which_tsp_cuts && vrp->par.tsp_prob){ tsp_cuts(n, vrp->par.verbosity, vrp->par.tsp_prob, vrp->par.which_tsp_cuts, cuts, num_cuts, alloc_cuts); free_net(n); return(USER_SUCCESS); } #endif /*__BEGIN_EXPERIMENTAL_SECTION__*/ if (!vrp->par.always_do_mincut){/*user_par.always_do_mincut indicates whether we should just always do the min_cut routine or whether we should also try this routine*/ /*___END_EXPERIMENTAL_SECTION___*/ /*UNCOMMENT FOR PRODUCTION CODE*/ #if 0 { #endif verts = n->verts; if (which_connected_routine == BOTH) which_connected_routine = CONNECTED; new_cut = (cut_data *) calloc(1, sizeof(cut_data)); new_cut->size = cut_size; compnodes_copy = (int *) malloc((vertnum + 1) * sizeof(int)); compmembers = (int *) malloc((vertnum + 1) * sizeof(int)); /*__BEGIN_EXPERIMENTAL_SECTION__*/ compdemands_copy = (int *) calloc(vertnum + 1, sizeof(int)); compcuts_copy = (double *) calloc(vertnum + 1, sizeof(double)); #ifdef COMPILE_OUR_DECOMP compdensity = vrp->par.do_our_decomp ? (double *) calloc(vertnum+1, sizeof(double)) : NULL; #endif /*___END_EXPERIMENTAL_SECTION___*/ do{ compnodes = (int *) calloc(vertnum + 1, sizeof(int)); compdemands = (int *) calloc(vertnum + 1, sizeof(int)); compcuts = (double *) calloc(vertnum + 1, sizeof(double)); /*------------------------------------------------------------------*\ * Get the connected components of the solution graph without the * depot and see if the number of components is more than one \*------------------------------------------------------------------*/ rcnt = (which_connected_routine == BICONNECTED ? biconnected(n, compnodes, compdemands, compcuts) : connected(n, compnodes, compdemands, compmembers, /*__BEGIN_EXPERIMENTAL_SECTION__*/ compcuts, compdensity)); /*___END_EXPERIMENTAL_SECTION___*/ /*UNCOMMENT FOR PRODUCTION CODE*/ #if 0 compcuts, NULL)); #endif /* copy the arrays as they will be needed later */ if (!which_connected_routine && /*__BEGIN_EXPERIMENTAL_SECTION__*/ (vrp->par.do_greedy || vrp->par.do_our_decomp)){ /*___END_EXPERIMENTAL_SECTION___*/ /*UNCOMMENT FOR PRODUCTION CODE*/ #if 0 vrp->par.do_greedy){ #endif compnodes_copy = (int *) memcpy((char *)compnodes_copy, (char*)compnodes, (vertnum+1)*sizeof(int)); /*__BEGIN_EXPERIMENTAL_SECTION__*/ compdemands_copy = (int *) memcpy((char *)compdemands_copy, (char *)compdemands, (vertnum+1)*ISIZE); compcuts_copy = (double *) memcpy((char *)compcuts_copy, (char *)compcuts, (vertnum+1)*DSIZE); /*___END_EXPERIMENTAL_SECTION___*/ n->compnodes = compnodes_copy; comp_num = rcnt; } if (rcnt > 1){ /*---------------------------------------------------------------*\ * If the number of components is more then one, then check each * component to see if it violates a capacity constraint \*---------------------------------------------------------------*/ coef_list = (char **) calloc(rcnt, sizeof(char *)); coef_list[0] = (char *) calloc(rcnt*cut_size, sizeof(char)); for(i = 1; i<rcnt; i++) coef_list[i] = coef_list[0]+i*cut_size; for(i = 1; i < vertnum; i++) (coef_list[(verts[i].comp)-1][i >> DELETE_POWER]) |= (1 << (i & DELETE_AND)); for (i = 0; i < rcnt; i++){ if (compnodes[i+1] < 2) continue; /*check ith component to see if it violates a constraint*/ if (vrp->par.which_connected_routine == BOTH && which_connected_routine == BICONNECTED && compcuts[i+1]==0) continue; if (compcuts[i+1] < 2*BINS(compdemands[i+1], capacity)-etol){ /*the constraint is violated so impose it*/ new_cut->coef = (char *) (coef_list[i]); new_cut->type = (compnodes[i+1] < vertnum/2 ? SUBTOUR_ELIM_SIDE:SUBTOUR_ELIM_ACROSS); new_cut->rhs = (new_cut->type == SUBTOUR_ELIM_SIDE ? RHS(compnodes[i+1],compdemands[i+1], capacity): 2*BINS(compdemands[i+1], capacity)); cg_send_cut(new_cut, num_cuts, alloc_cuts, cuts); } else{/*if the constraint is not violated, then try generating a violated constraint by deleting customers that don't change the number of trucks required by the customers in the component but decrease the value of the cut*/ cur_bins = BINS(compdemands[i+1], capacity);/*the current number of trucks required*/ /*current slack in the constraint*/ cur_slack = (compcuts[i+1] - 2*cur_bins); while (compnodes[i+1]){/*while there are still nodes in the component*/ for (max_node = 0, max_node_cut = 0, k = 1; k < vertnum; k++){ if (verts[k].comp == i+1){ if (BINS(compdemands[i+1]-verts[k].demand, capacity) == cur_bins){ /*if the number of trucks doesn't decrease upon deleting this customer*/ for (node_cut = 0, cur_edge = verts[k].first; cur_edge; cur_edge = cur_edge->next_edge){ node_cut += (cur_edge->other_end ? -cur_edge->data->weight : cur_edge->data->weight); } if (node_cut > max_node_cut){/*check whether the value of the cut decrease is the best seen so far*/ max_node = k; max_node_cut = node_cut; } } } } if (!max_node){ break; } /*delete the customer that exhibited the greatest decrease in cut value*/ compnodes[i+1]--; compdemands[i+1] -= verts[max_node].demand; compcuts[i+1] -= max_node_cut; cur_slack -= max_node_cut; verts[max_node].comp = 0; coef_list[i][max_node >> DELETE_POWER] ^= (1 << (max_node & DELETE_AND)); if (cur_slack < 0){/*if the cut is now violated, impose it*/ new_cut->coef = (char *) (coef_list[i]); new_cut->type = (compnodes[i+1] < vertnum/2 ? SUBTOUR_ELIM_SIDE:SUBTOUR_ELIM_ACROSS); new_cut->size = cut_size; new_cut->rhs = (new_cut->type == SUBTOUR_ELIM_SIDE ? RHS(compnodes[i+1], compdemands[i+1], capacity): 2*cur_bins); cg_send_cut(new_cut, num_cuts, alloc_cuts, cuts); break; } } } } FREE(coef_list[0]); FREE(coef_list); } which_connected_routine++; FREE(compnodes); FREE(compdemands); FREE(compcuts); }while((!(*num_cuts) && vrp->par.which_connected_routine == BOTH)
MRI_IMAGE *mri_aff2d_rgb( MRI_IMAGE *im, int flag , float axx, float axy, float ayx, float ayy ) { float bxx,bxy,byx,byy , xbase,ybase , xx,yy , fx,fy ; float f_j00r,f_jp1r , f_j00g,f_jp1g , f_j00b,f_jp1b , wt_00,wt_p1 ; int jj , nx,ny , ix,jy ; MRI_IMAGE *newImg ; byte *far , *nar ; register int ii ; ENTRY("mri_aff2d_rgb") ; if( im == NULL || !MRI_IS_2D(im) || im->kind != MRI_rgb ){ fprintf(stderr,"*** mri_aff2d_rgb only works on 2D RGB images!\n"); RETURN( NULL ); } if( flag == 0 ){ invert2d( axx,axy,ayx,ayy , &bxx,&bxy,&byx,&byy ) ; } else { bxx = axx ; bxy = axy ; byx = ayx ; byy = ayy ; } if( (bxx == 0.0 && bxy == 0.0) || (byx == 0.0 && byy == 0.0) ){ fprintf(stderr,"*** mri_aff2d_byte: input matrix is singular!\n") ; RETURN( NULL ); } nx = im->nx ; ny = im->ny ; xbase = 0.5*nx*(1.0-bxx) - 0.5*ny*bxy ; ybase = 0.5*ny*(1.0-byy) - 0.5*nx*byx ; far = MRI_RGB_PTR(im) ; /* input image data */ newImg = mri_new( nx , nx , MRI_rgb ) ; /* output image */ nar = MRI_RGB_PTR(newImg) ; /* output image data */ /*** loop over output points and warp to them ***/ for( jj=0 ; jj < nx ; jj++ ){ xx = xbase-bxx + bxy * jj ; yy = ybase-byx + byy * jj ; for( ii=0 ; ii < nx ; ii++ ){ xx += bxx ; /* get x,y in original image */ yy += byx ; ix = (xx >= 0.0) ? ((int) xx) : ((int) xx)-1 ; /* floor */ jy = (yy >= 0.0) ? ((int) yy) : ((int) yy)-1 ; fx = xx-ix ; wt_00 = 1.0 - fx ; wt_p1 = fx ; if( ix >= 0 && ix < nx-1 && jy >= 0 && jy < ny-1 ){ byte *fy00 , *fyp1 ; fy00 = far + 3*(ix+jy*nx) ; fyp1 = fy00 + 3*nx ; f_j00r = wt_00 * fy00[0] + wt_p1 * fy00[3] ; f_j00g = wt_00 * fy00[1] + wt_p1 * fy00[4] ; f_j00b = wt_00 * fy00[2] + wt_p1 * fy00[5] ; f_jp1r = wt_00 * fyp1[0] + wt_p1 * fyp1[3] ; f_jp1g = wt_00 * fyp1[1] + wt_p1 * fyp1[4] ; f_jp1b = wt_00 * fyp1[2] + wt_p1 * fyp1[5] ; } else { f_j00r = wt_00 * RINS(ix,jy ) + wt_p1 * RINS(ix+1,jy ) ; f_j00g = wt_00 * GINS(ix,jy ) + wt_p1 * GINS(ix+1,jy ) ; f_j00b = wt_00 * BINS(ix,jy ) + wt_p1 * BINS(ix+1,jy ) ; f_jp1r = wt_00 * RINS(ix,jy+1) + wt_p1 * RINS(ix+1,jy+1) ; f_jp1g = wt_00 * GINS(ix,jy+1) + wt_p1 * GINS(ix+1,jy+1) ; f_jp1b = wt_00 * BINS(ix,jy+1) + wt_p1 * BINS(ix+1,jy+1) ; } fy = yy-jy ; nar[3*ii+ 3*jj*nx ] = (1.0-fy) * f_j00r + fy * f_jp1r ; nar[3*ii+(3*jj*nx+1)] = (1.0-fy) * f_j00g + fy * f_jp1g ; nar[3*ii+(3*jj*nx+2)] = (1.0-fy) * f_j00b + fy * f_jp1b ; } } MRI_COPY_AUX(newImg,im) ; RETURN( newImg ); }