예제 #1
0
파일: gc.c 프로젝트: Seneol/FileSystem
static void logfs_cleanup_list(struct super_block *sb,
		struct candidate_list *list)
{
	struct gc_candidate *cand;

	while (list->count) {
		cand = rb_entry(list->rb_tree.rb_node, struct gc_candidate,
				rb_node);
		remove_from_list(cand);
		free_candidate(sb, cand);
	}
	BUG_ON(list->rb_tree.rb_node);
}
예제 #2
0
파일: lp_free.cpp 프로젝트: Alihina/ogdf
void free_candidate(branch_obj **cand)
{
   int i;

   if (*cand){
      branch_obj *can = *cand;
#ifdef COMPILE_FRAC_BRANCHING
      for (i = can->child_num-1; i >= 0; i--){
	 if (can->frac_num[i]){
	    FREE(can->frac_ind[i]);
	    FREE(can->frac_val[i]);
	 }
      }
#endif
      free_waiting_row(&(can->row));
#ifndef MAX_CHILDREN_NUM
      FREE(can->sense); FREE(can->rhs); FREE(can->range); FREE(can->branch);

      if (can->solutions){
	 for (i = can->child_num-1; i >= 0; i--){
#else
      if (can->solutions){
         for (i = MAX_CHILDREN_NUM - 1; i >= 0; i--){
#endif
	    FREE(can->sol_inds[i]);
	    FREE(can->solutions[i]);
	 }
      }

#ifdef SENSITIVITY_ANALYSIS
#ifndef MAX_CHILDREN_NUM
      if (can->duals){
	 for (i = can->child_num-1; i >= 0; i--){
#else
      if (can->duals){
	 for (i = MAX_CHILDREN_NUM - 1; i >= 0; i--){
#endif
	    FREE(can->duals[i]);
	 }
      }
#endif

      FREE(can->sol_sizes);
      FREE(can->sol_inds);
      FREE(can->solutions);
#ifdef SENSITIVITY_ANALYSIS
      FREE(can->duals);
#endif

      FREE(*cand);
   }
}

/*===========================================================================*/

void free_candidate_completely(branch_obj **cand)
{
   if (*cand){
#ifndef MAX_CHILDREN_NUM
      branch_obj *can = *cand;
#endif
#ifndef MAX_CHILDREN_NUM
      FREE(can->objval);
      FREE(can->termcode);
      FREE(can->feasible);
      FREE(can->iterd);
#  ifdef COMPILE_FRAC_BRANCHING
      FREE(can->frac_num); FREE(can->frac_ind); FREE(can->frac_val);
#  endif
#endif
      free_candidate(cand);
   }
}

/*===========================================================================*/

void free_waiting_row(waiting_row **wrow)
{
   waiting_row *wr = *wrow;
   if (wr){
      FREE(wr->matval);
      FREE(wr->matind);
      free_cut(&wr->cut);
      free(wr);
      *wrow = NULL;
   }
}

/*===========================================================================*/

void free_waiting_rows(waiting_row **rows, int row_num)
{
   int i;
   if (rows)
      for (i=row_num-1; i>=0; i--)
	 free_waiting_row(rows+i);
}

/*===========================================================================*/

void free_waiting_row_array(waiting_row ***rows, int row_num)
{
   free_waiting_rows(*rows, row_num);
   FREE(*rows);
}

/*===========================================================================*/

void free_node_desc(node_desc **desc)
{
   if (*desc){
      node_desc *n = *desc;
      FREE(n->cutind.list);
      FREE(n->uind.list);
      if (n->nf_status == NF_CHECK_AFTER_LAST ||
	  n->nf_status == NF_CHECK_UNTIL_LAST)
	 FREE(n->not_fixed.list);
      if (n->basis.basis_exists){
	 FREE(n->basis.basevars.list);
	 FREE(n->basis.basevars.stat);
	 FREE(n->basis.extravars.list);
	 FREE(n->basis.extravars.stat);
	 FREE(n->basis.baserows.list);
	 FREE(n->basis.baserows.stat);
	 FREE(n->basis.extrarows.list);
	 FREE(n->basis.extrarows.stat);
      }
      if (n->desc_size > 0)
	 FREE(n->desc);
      if (n->bnd_change) {
         FREE(n->bnd_change->index);
         FREE(n->bnd_change->lbub);
         FREE(n->bnd_change->value);
         FREE(n->bnd_change);
      }
      FREE(*desc);
   }
}

/*===========================================================================*/

void free_node_dependent(lp_prob *p)
{
   LPdata *lp_data = p->lp_data;
   int i;

   free_node_desc(&p->desc);
   for (i = p->base.cutnum; i < lp_data->m; i++){
#ifdef COMPILE_IN_LP
      if (lp_data->rows[i].cut->name < 0 ||
	  lp_data->rows[i].cut->branch & CUT_BRANCHED_ON)
#endif
	 free_cut(&lp_data->rows[i].cut);
#ifdef COMPILE_IN_LP
      else
	 lp_data->rows[i].cut = NULL;
#endif
   }
   if (p->par.branch_on_cuts && p->slack_cut_num > 0){
      free_cuts(p->slack_cuts, p->slack_cut_num);
      p->slack_cut_num = 0;
   }
   // necessary to purge waiting rows, otherwise these may get added to the
   // node that is solved next time.
   if (p->waiting_row_num>0) {
      free_waiting_rows(p->waiting_rows, p->waiting_row_num);
      p->waiting_row_num = 0;
      FREE(p->waiting_rows);
   }

   unload_lp_prob(lp_data);
}
예제 #3
0
branch_obj *select_branching_object(lp_prob *p, int *cuts)
{
   LPdata *lp_data = p->lp_data;
   var_desc **vars;
   row_data *rows;
   int m;
#ifndef MAX_CHILDREN_NUM
   int maxnum;
   double *objval, *pobj;
   int *termcode, *pterm, *feasible, *pfeas, *iterd, *piter;
#ifdef COMPILE_FRAC_BRANCHING
   int *frnum, *pfrnum, **frind, **pfrind;
   double **frval, **pfrval;
#endif
#endif
   int i, j, k, branch_var, branch_row;
   double lb, ub, oldobjval;
   cut_data *cut;
   branch_obj *can, *best_can = NULL;
#ifdef COMPILE_FRAC_BRANCHING
   int *xind;
   double *xval;
#endif
   double *pseudo_costs_zero, *pseudo_costs_one;

   /* These are the return values from select_candidates_u() */
   int cand_num = 0, new_vars = 0;
   branch_obj **candidates = NULL;
#ifdef STATISTICS
   int itlim = 0, cnum = 0;
#endif

#if 0
   if (p->bc_level == 0){ 
      lp_data->pseudo_costs_zero = (double *) calloc(lp_data->n, DSIZE);
      lp_data->pseudo_costs_one  = (double *) calloc(lp_data->n, DSIZE);
#if 0
      memcpy((char *)pseudo_costs_one, (char *)lp_data->obj, lp_data->n*DSIZE);
      memcpy((char *)pseudo_costs_zero,(char *)lp_data->obj, lp_data->n*DSIZE);
#endif
   }
   
   pseudo_costs_one  = lp_data->pseudo_costs_one;
   pseudo_costs_zero = lp_data->pseudo_costs_zero;
#endif
   
   /*------------------------------------------------------------------------*\
    * First we call branch_u() to select candidates. It can
    * -- return with DO_BRANCH and a bunch of candidates, or
    * -- return with DO_NOT_BRANCH along with a bunch of violated cuts
    *    in the matrix and/or among the slack_cuts, or
    * -- return with DO_NOT_BRANCH__FATHOMED, i.e., the node can be fathomed.
   \*------------------------------------------------------------------------*/

   j = select_candidates_u(p, cuts, &new_vars, &cand_num, &candidates);
   switch (j){
    case DO_NOT_BRANCH__FATHOMED:
      *cuts = -1;
      return(NULL);

    case DO_NOT_BRANCH:
      if (cand_num)
	 *cuts += add_violated_slacks(p, cand_num, candidates);
#ifdef DO_TESTS
      if (*cuts == 0 && new_vars == 0){
	 printf("Told not to branch, but there are no cuts!\n");
	 exit(-1);
      }
#endif
      /* Free the candidates */
      if (candidates){
	 for (i=0; i<cand_num; i++){
	    free_candidate(candidates + i);
	 }
	 FREE(candidates);
      }
      return(NULL);

    case DO_BRANCH:
      break;
   }

   /* OK, now we have to branch. */

   /* First of all, send everything to the cutpool that hasn't been sent
      before and send the current node description to the TM. */
   p->comp_times.strong_branching += used_time(&p->tt);
#pragma omp critical(cut_pool)
   send_cuts_to_pool(p, -1);
   send_node_desc(p, NODE_BRANCHED_ON);
   p->comp_times.communication += used_time(&p->tt);

   /* Add all the branching cuts */
   if (p->par.branch_on_cuts)
      add_slacks_to_matrix(p, cand_num, candidates);
   m = lp_data->m;
   rows = lp_data->rows;

#ifndef MAX_CHILDREN_NUM
   /* The part below is not needed when we have MAX_CHILDREN_NUM specified */
   /* Count how many objval/termcode/feasible entry we might need
      and allocate space for it */
   for (maxnum = candidates[0]->child_num, j=0, i=1; i<cand_num; i++){
      if (maxnum < candidates[i]->child_num)
	 maxnum = candidates[i]->child_num;
   }

   objval   = (double *) malloc(maxnum * DSIZE);
   termcode = (int *) malloc(maxnum * ISIZE);
   feasible = (int *) malloc(maxnum * ISIZE);
   iterd    = (int *) malloc(maxnum * ISIZE);
#ifdef COMPILE_FRAC_BRANCHING
   frval = (double **) malloc(maxnum * sizeof(double *));
   pfrval = (double **) malloc(maxnum * sizeof(double *));
   frind = (int **) malloc(maxnum * sizeof(int *));
   pfrind = (int **) malloc(maxnum * sizeof(int *));
   frnum = (int *) malloc(maxnum * ISIZE);
   pfrnum = (int *) malloc(maxnum * ISIZE);
#endif
   pobj  = (double *) malloc(maxnum * DSIZE);
   pterm = (int *) malloc(maxnum * ISIZE);
   pfeas = (int *) malloc(maxnum * ISIZE);
   piter = (int *) malloc(maxnum * ISIZE);
#endif

   /* Set the iteration limit */
   if (p->par.max_presolve_iter > 0)
      set_itlim(lp_data, p->par.max_presolve_iter);

   vars = lp_data->vars;

   /* Look at the candidates one-by-one and presolve them. */
   oldobjval = lp_data->objval;
   for (i=0; i<cand_num; i++){

      can = candidates[i];
#ifndef MAX_CHILDREN_NUM
      can->objval = pobj;
      can->termcode = pterm;
      can->feasible = pfeas;
      can->iterd = piter;
#ifdef COMPILE_FRAC_BRANCHING
      can->frac_num = pfrnum;
      can->frac_ind = pfrind;
      can->frac_val = pfrval;
#endif
#endif
#ifdef STATISTICS
      cnum += can->child_num;
#endif

      /* Now depending on the type, adjust ub/lb or rhs/range/sense */
      switch (can->type){
       case CANDIDATE_VARIABLE:
	 branch_var = can->position;
	 if (lp_data->status[branch_var] & PERM_FIXED_TO_LB ||
	     lp_data->status[branch_var] & PERM_FIXED_TO_UB){
	    printf("Error -- candidate is fixed. Discarding.\n\n");
	    continue;
	 }
#if 0
	 if (pseudo_costs_one[can->position] ||
	     pseudo_costs_zero[can->position]){
	    can->objval[1] = oldobjval + (1 - lp_data->x[can->position]) *
	                                 pseudo_costs_one[can->position];
	    can->objval[0] = oldobjval + lp_data->x[can->position] *
	                                 pseudo_costs_zero[can->position];
	    break;
	 }
#endif 
	 lb = vars[branch_var]->lb;
	 ub = vars[branch_var]->ub;
	 for (j = 0; j < can->child_num; j++){
	    switch (can->sense[j]){
	     case 'E':
	       change_lbub(lp_data, branch_var, can->rhs[j], can->rhs[j]);
	       break;
	     case 'R':
	       change_lbub(lp_data, branch_var, can->rhs[j],
			   can->rhs[j] + can->range[j]);
	       break;
	     case 'L':
	       change_lbub(lp_data, branch_var, lb, can->rhs[j]);
	       break;
	     case 'G':
	       change_lbub(lp_data, branch_var, can->rhs[j], ub);
	       break;
	    }
	    check_ub(p);
	    /* The original basis is in lp_data->lpbas */
	    can->termcode[j] = dual_simplex(lp_data, can->iterd+j);
	    can->objval[j] = lp_data->objval;
	    if (can->termcode[j] == LP_OPTIMAL){
	       /* is_feasible_u() fills up lp_data->x, too!! */
	       if (is_feasible_u(p) == IP_FEASIBLE){
		  can->termcode[j] = LP_OPT_FEASIBLE;
		  /*NOTE: This is confusing but not all that citical...*/
		  /*The "feasible" field is only filled out for the
		    purposes of display (in vbctool) to keep track of
		    where in the tree the feasible solutions were
		    found. Since this may not be the actual candidate
		    branched on, we need to pass this info on to whatever
		    candidate does get branched on so the that the fact that
		    a feasible solution was found in presolve can be recorded*/
		  if (best_can)
		     best_can->feasible[j] = TRUE;
		  else
		     can->feasible[j] = TRUE;
	       }
	    }
#ifdef COMPILE_FRAC_BRANCHING
	    else
	       if (can->termcode[j] != LP_ABANDONED)
		  get_x(lp_data);
	    if (can->termcode[j] != LP_ABANDONED){
	       xind = lp_data->tmp.i1; /* n */
	       xval = lp_data->tmp.d; /* n */
	       can->frac_num[j] = collect_fractions(p, lp_data->x, xind, xval);
	       if (can->frac_num[j] > 0){
		  can->frac_ind[j] = (int *) malloc(can->frac_num[j] * ISIZE);
		  can->frac_val[j] = (double *) malloc(can->frac_num[j]*DSIZE);
		  memcpy(can->frac_ind[j], xind, can->frac_num[j] * ISIZE);
		  memcpy(can->frac_val[j], xval, can->frac_num[j] * DSIZE);
	       }
	    }else{
	       can->frac_num[j] = 0;
	    }
#endif
#ifdef STATISTICS
	    if (can->termcode[j] == LP_D_ITLIM)
	       itlim++;
#endif
	 }
	 change_lbub(lp_data, branch_var, lb, ub);
#if 0
	 pseudo_costs_one[can->position] =
	    (can->objval[1] - oldobjval)/lp_data->x[can->position];
	 pseudo_costs_zero[can->position] =
	    (can->objval[0] - oldobjval)/lp_data->x[can->position];
#endif
	 break;

       case CANDIDATE_CUT_IN_MATRIX:
	 branch_row = can->position;
	 for (j = 0; j < can->child_num; j++){
	    change_row(lp_data, branch_row,
		       can->sense[j], can->rhs[j], can->range[j]);
	    check_ub(p);
	    /* The original basis is in lp_data->lpbas */
	    can->termcode[j] = dual_simplex(lp_data, can->iterd+j);
	    can->objval[j] = lp_data->objval;
	    if (can->termcode[j] == LP_OPTIMAL){
	       /* is_feasible_u() fills up lp_data->x, too!! */
	       if (is_feasible_u(p) == IP_FEASIBLE){
		  can->termcode[j] = LP_OPT_FEASIBLE;
		  /*NOTE: This is confusing but not all that citical...*/
		  /*The "feasible" field is only filled out for the
		    purposes of display (in vbctool) to keep track of
		    where in the tree the feasible solutions were
		    found. Since this may not be the actual candidate
		    branched on, we need to pass this info on to whatever
		    candidate does get branched on so the that the fact that
		    a feasible solution was found in presolve can be recorded*/
		  if (best_can)
		     best_can->feasible[j] = TRUE;
		  else
		     can->feasible[j] = TRUE;
	       }
	    }
#ifdef COMPILE_FRAC_BRANCHING
	    else
	       if (can->termcode[j] != LP_ABANDONED)
		  get_x(lp_data);
	    if (can->termcode[j] != LP_ABANDONED){
	       xind = lp_data->tmp.i1; /* n */
	       xval = lp_data->tmp.d; /* n */
	       can->frac_num[j] = collect_fractions(p, lp_data->x, xind, xval);
	       if (can->frac_num[j] > 0){
		  can->frac_ind[j] = (int *) malloc(can->frac_num[j] * ISIZE);
		  can->frac_val[j] = (double *) malloc(can->frac_num[j]*DSIZE);
		  memcpy(can->frac_ind[j], xind, can->frac_num[j] * ISIZE);
		  memcpy(can->frac_val[j], xval, can->frac_num[j] * DSIZE);
	       }
	    }else{
	       can->frac_num[j] = 0;
	    }
#endif
#ifdef STATISTICS
	    if (can->termcode[j] == LP_D_ITLIM)
	       itlim++;
#endif
	 }
	 cut = rows[branch_row].cut;
	 change_row(lp_data, branch_row, cut->sense, cut->rhs, cut->range);
	 free_row_set(lp_data, 1, &branch_row);
	 break;
      }

      switch ((j = compare_candidates_u(p, oldobjval, best_can, can))){
       case FIRST_CANDIDATE_BETTER:
       case FIRST_CANDIDATE_BETTER_AND_BRANCH_ON_IT:
	 free_candidate(candidates + i);
	 break;
       case SECOND_CANDIDATE_BETTER:
       case SECOND_CANDIDATE_BETTER_AND_BRANCH_ON_IT:
#ifndef MAX_CHILDREN_NUM
	 if (best_can == NULL){
	    pobj  = objval;
	    pterm = termcode;
	    pfeas = feasible;
	    piter = iterd;
#ifdef COMPILE_FRAC_BRANCHING
	    pfrnum = frnum;
	    pfrind = frind;
	    pfrval = frval;
#endif
	 }else{
	    pobj  = best_can->objval;
	    pterm = best_can->termcode;
	    pfeas = best_can->feasible;
	    piter = best_can->iterd;
#ifdef COMPILE_FRAC_BRANCHING
	    pfrnum = best_can->frac_num;
	    pfrind = best_can->frac_ind;
	    pfrval = best_can->frac_val;
#endif
	 }
#endif
	 if (best_can){
	    for (k = can->child_num - 1; k >= 0; k--){
	       /* Again, this is only for tracking that there was a feasible
		  solution discovered in presolve for display purposes */
	       if (best_can->feasible[k])
		  can->feasible[k] = TRUE;
	    }
	    free_candidate(&best_can);
	 }
	 best_can = can;
	 candidates[i] = NULL;
	 break;
      }
      if ((j & BRANCH_ON_IT))
	 break;
   }

#ifndef MAX_CHILDREN_NUM
   FREE(pobj); FREE(pterm); FREE(pfeas); FREE(piter);
#  ifdef COMPILE_FRAC_BRANCHING
   FREE(pfrnum); FREE(pfrind); FREE(pfrval);
#  endif
#endif

   if (p->par.max_presolve_iter > 0)
      set_itlim(lp_data, -1);

#ifdef STATISTICS
   PRINT(p->par.verbosity, 5,
	 ("Itlim reached %i times out of %i .\n\n", itlim, cnum));
#endif

   for (i++; i<cand_num; i++){
      /* Free the remaining candidates */
      free_candidate(candidates + i);
   }
   FREE(candidates);

   return(best_can);
}