Пример #1
0
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)
Пример #2
0
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 );
}