/** Function called on CT start to setup resource management * */ int setup_resource_management(vps_handler *h, envid_t veid, vps_res *res) { int ret; if ((ret = check_ub(&res->ub))) return ret; if ((ret = set_ublimit(h, veid, &res->ub))) return ret; return 0; }
int col_gen_before_branch(lp_prob *p, int *new_vars) { our_col_set *new_cols; int dual_feas; check_ub(p); if (! p->has_ub || (p->colgen_strategy & BEFORE_BRANCH__DO_NOT_GENERATE_COLS) || (p->lp_data->nf_status & NF_CHECK_NOTHING)) return(DO_BRANCH); PRINT(p->par.verbosity, 2, ("Generating cols before branching.\n")); p->comp_times.strong_branching += used_time(&p->tt); new_cols = price_all_vars(p); p->comp_times.pricing += used_time(&p->tt); /*price_all_vars sorts by user_ind. We need things sorted by colind */ colind_sort_extra(p); *new_vars = new_cols->num_vars + new_cols->rel_ub + new_cols->rel_lb; dual_feas = new_cols->dual_feas; free_col_set(&new_cols); check_ub(p); if (dual_feas == NOT_TDF){ return(DO_NOT_BRANCH); }else{ if (p->ub - p->par.granularity < p->lp_data->objval || p->lp_data->termcode == LP_D_OBJLIM || p->lp_data->termcode == LP_OPT_FEASIBLE){ /* If total dual feas and high cost or feasibility ==> fathomable */ PRINT(p->par.verbosity, 1, ("Managed to fathom the node.\n")); send_node_desc(p, p->lp_data->termcode == LP_OPT_FEASIBLE ? FEASIBLE_PRUNED : OVER_UB_PRUNED); p->comp_times.communication += used_time(&p->tt); return(DO_NOT_BRANCH__FATHOMED); }else{ return(DO_BRANCH); /* if we got here, then DO_BRANCH */ } } return(DO_BRANCH); /* fake return */ }
int repricing(lp_prob *p) { LPdata *lp_data = p->lp_data; node_times *comp_times = &p->comp_times; int iterd, termcode; int num_errors = 0; our_col_set *new_cols = NULL; int dual_feas, new_vars, cuts, no_more_cuts_count; int cut_term = 0; check_ub(p); p->iter_num = 0; /*------------------------------------------------------------------------*\ * The main loop -- continue solving relaxations until TDF \*------------------------------------------------------------------------*/ while (TRUE){ p->iter_num++; PRINT(p->par.verbosity, 2, ("\n\n**** Starting iteration %i ****\n\n", p->iter_num)); termcode = dual_simplex(lp_data, &iterd); /* Get relevant data */ get_dj_pi(lp_data); get_slacks(lp_data); /* display the current solution */ if (p->mip->obj_sense == SYM_MAXIMIZE){ PRINT(p->par.verbosity, 2, ("The LP value is: %.3f [%i,%i]\n\n", -lp_data->objval + p->mip->obj_offset, termcode, iterd)); }else{ PRINT(p->par.verbosity, 2, ("The LP value is: %.3f [%i,%i]\n\n", lp_data->objval+ p->mip->obj_offset, termcode, iterd)); } comp_times->lp += used_time(&p->tt); switch (termcode){ case LP_D_ITLIM: /* impossible, since itlim is set to infinity */ case LP_D_INFEASIBLE: /* this is impossible (?) as of now */ case LP_ABANDONED: printf("######## Unexpected termcode: %i \n", termcode); if (p->par.try_to_recover_from_error && (++num_errors == 1)){ /* Try to resolve it from scratch */ printf("######## Trying to recover by resolving from scratch...\n", termcode); continue; }else{ char name[50] = ""; printf("######## Recovery failed. %s%s", "LP solver is having numerical difficulties :(.\n", "######## Dumping current LP to MPS file and exiting.\n\n"); sprintf(name, "matrix.%i.%i.mps", p->bc_index, p->iter_num); write_mps(lp_data, name); return(ERROR__NUMERICAL_INSTABILITY); } case LP_D_UNBOUNDED: /* the primal problem is infeasible */ case LP_D_OBJLIM: case LP_OPTIMAL: if (termcode == LP_D_UNBOUNDED){ PRINT(p->par.verbosity, 1, ("Feasibility lost -- ")); }else if ((p->has_ub && lp_data->objval > p->ub - p->par.granularity) || termcode == LP_D_OBJLIM){ PRINT(p->par.verbosity, 1, ("Terminating due to high cost -- ")); }else{ /* optimal and not too high cost */ break; } comp_times->lp += used_time(&p->tt); if (fathom(p, (termcode != LP_D_UNBOUNDED))){ comp_times->communication += used_time(&p->tt); return(FUNCTION_TERMINATED_NORMALLY); }else{ comp_times->communication += used_time(&p->tt); continue; } } /* If come to here, the termcode must have been OPTIMAL and the * cost cannot be too high. */ /* is_feasible_u() fills up lp_data->x, too!! */ if (is_feasible_u(p, FALSE) == IP_FEASIBLE){ if (p->par.verbosity > 2){ printf ("Now displaying the feasible solution ...\n"); display_lp_solution_u(p, DISP_FEAS_SOLUTION); } cuts = -1; }else{ /*------------------------------------------------------------------*\ * send the current solution to the cut generator, and also to the * cut pool if this is the 1st or cut_pool_check_freq-th iteration. \*------------------------------------------------------------------*/ no_more_cuts_count = 0; if (p->cut_pool && ((p->iter_num-1) % p->par.cut_pool_check_freq == 0) ){ no_more_cuts_count += send_lp_solution_u(p, p->cut_pool); } if (p->cut_gen){ no_more_cuts_count += send_lp_solution_u(p, p->cut_gen); } if (p->par.verbosity > 4){ printf ("Now displaying the relaxed solution ...\n"); display_lp_solution_u(p, DISP_RELAXED_SOLUTION); } comp_times->lp += used_time(&p->tt); tighten_bounds(p); comp_times->fixing += used_time(&p->tt); cuts = 0; if (p->cut_gen || p->cut_pool){ cuts = check_row_effectiveness(p); } /*------------------------------------------------------------------*\ * receive the cuts from the cut generator and the cut pool \*------------------------------------------------------------------*/ if ((cut_term = receive_cuts(p, TRUE, no_more_cuts_count)) >= 0){ cuts += cut_term; }else{ return(ERROR__USER); } } comp_times->lp += used_time(&p->tt); if (cuts < 0){ /* i.e. feasible solution is found */ if (fathom(p, TRUE)){ comp_times->communication += used_time(&p->tt); return(FUNCTION_TERMINATED_NORMALLY); }else{ comp_times->communication += used_time(&p->tt); check_ub(p); continue; } } if (cuts == 0){ PRINT(p->par.verbosity, 2, ("\nIn iteration %i ... no cuts were added.\n", p->iter_num)); }else{ /* Go back to top */ PRINT(p->par.verbosity, 2, ("\nIn iteration %i ... %i violated cuts were added.\n", p->iter_num, cuts)); continue; } comp_times->lp += used_time(&p->tt); /* So no cuts were found. Price out everything */ new_cols = price_all_vars(p); new_vars = new_cols->num_vars + new_cols->rel_ub + new_cols->rel_lb; dual_feas = new_cols->dual_feas; free_col_set(&new_cols); comp_times->pricing += used_time(&p->tt); if (dual_feas != NOT_TDF) break; /* Don't have total dual feasibility. The non-dual-feasible vars * have already been added. Go back and resolve. */ PRINT(p->par.verbosity, 2, ("%i variables added in price-out.\n", new_vars)); } /* Now we know that we have TDF, just send back the node */ comp_times->lp += used_time(&p->tt); send_node_desc(p, REPRICED_NODE); comp_times->communication += used_time(&p->tt); return(FUNCTION_TERMINATED_NORMALLY); }
int fathom(lp_prob *p, int primal_feasible) { LPdata *lp_data = p->lp_data; our_col_set *new_cols = NULL; int new_vars; int colgen = p->colgen_strategy & COLGEN__FATHOM; int termcode = p->lp_data->termcode; if (p->lp_data->nf_status == NF_CHECK_NOTHING){ PRINT(p->par.verbosity, 1, ("fathoming node (no more cols to check)\n\n")); send_node_desc(p, primal_feasible ? (termcode == LP_OPT_FEASIBLE ? FEASIBLE_PRUNED: OVER_UB_PRUNED) : INFEASIBLE_PRUNED); return(TRUE); } if (p->colgen_strategy & COLGEN_REPRICING) colgen = FATHOM__GENERATE_COLS__RESOLVE; switch (colgen){ case FATHOM__DO_NOT_GENERATE_COLS__DISCARD: PRINT(p->par.verbosity, 1, ("Pruning node\n\n")); send_node_desc(p, termcode == LP_OPT_FEASIBLE ? FEASIBLE_PRUNED : DISCARDED_NODE); return(TRUE); case FATHOM__DO_NOT_GENERATE_COLS__SEND: PRINT(p->par.verbosity, 1, ("Sending node for pricing\n\n")); send_node_desc(p, primal_feasible ? OVER_UB_HOLD_FOR_NEXT_PHASE : INFEASIBLE_HOLD_FOR_NEXT_PHASE); return(TRUE); case FATHOM__GENERATE_COLS__RESOLVE: check_ub(p); /* Note that in case of COLGEN_REPRICING we must have UB. */ if (! p->has_ub){ PRINT(p->par.verbosity, 1, ("\nCan't generate cols before sending (no UB)\n")); send_node_desc(p, primal_feasible ? OVER_UB_HOLD_FOR_NEXT_PHASE : INFEASIBLE_HOLD_FOR_NEXT_PHASE); return(TRUE); } PRINT(p->par.verbosity, 1, ("\nGenerating columns before fathoming/resolving\n")); new_cols = price_all_vars(p); p->comp_times.pricing += used_time(&p->tt); new_vars = new_cols->num_vars + new_cols->rel_ub + new_cols->rel_lb; if (new_cols->dual_feas == NOT_TDF){ /* Don't have total dual feasibility. The non-dual-feasible vars * have already been added. Go back and resolve. */ PRINT(p->par.verbosity, 2, ("%i variables added in price-out.\n", new_vars)); free_col_set(&new_cols); return(FALSE); } /* Now we know that we have total dual feasibility */ if ((p->has_ub && lp_data->objval > p->ub - p->par.granularity) || termcode == LP_D_OBJLIM || termcode == LP_OPT_FEASIBLE){ /* fathomable */ if (termcode == LP_D_OBJLIM || (p->has_ub && lp_data->objval > p->ub - p->par.granularity)){ PRINT(p->par.verbosity, 1, ("Fathoming node (discovered tdf & high cost)\n\n")); }else{ PRINT(p->par.verbosity, 1, ("Fathoming node (discovered tdf & feasible)\n\n")); } send_node_desc(p, termcode == LP_OPT_FEASIBLE ? FEASIBLE_PRUNED : OVER_UB_PRUNED); free_col_set(&new_cols); return(TRUE); } /* If we ever arrive here then we must have tdf and the function * was called with a primal infeasible LP. * * Again, note that in case of COLGEN_REPRICING, since we do that * only in the root node, the lp relaxation MUST be primal feasible, * * If TDF_HAS_ALL, then whatever can be used to restore * primal feasibility is already in the matrix so don't bother * to figure out restorability, just return and resolve the problem * (if new_vars == 0 then even returning is unnecessary, the node * can be fathomed, nothing can restore feasibility). */ if (new_cols->dual_feas == TDF_HAS_ALL){ if (new_vars == 0){ PRINT(p->par.verbosity, 1, ("fathoming node (no more cols to check)\n\n")); send_node_desc(p, INFEASIBLE_PRUNED); free_col_set(&new_cols); return(TRUE); }else{ free_col_set(&new_cols); return(FALSE); } } /* Sigh. There were too many variables not fixable even though we have * proved tdf. new_cols contains a good many of the non-fixables, use * new_cols to start with in restore_lp_feasibility(). */ if (! restore_lp_feasibility(p, new_cols)){ PRINT(p->par.verbosity, 1, ("Fathoming node (discovered tdf & not restorable inf.)\n\n")); send_node_desc(p, INFEASIBLE_PRUNED); free_col_set(&new_cols); return(TRUE); } /* So primal feasibility is restorable. Exactly one column has been * added (released or a new variable) to destroy the proof of * infeasibility */ free_col_set(&new_cols); p->comp_times.pricing += used_time(&p->tt); return(FALSE); } return(TRUE); /* fake return */ }
int fathom_branch(lp_prob *p) { LPdata *lp_data = p->lp_data; node_times *comp_times = &p->comp_times; char first_in_loop = TRUE; int iterd, termcode, i; int cuts, no_more_cuts_count; int num_errors = 0; int cut_term = 0; check_ub(p); p->iter_num = p->node_iter_num = 0; /*------------------------------------------------------------------------*\ * The main loop -- continue solving relaxations until no new cuts * are found \*------------------------------------------------------------------------*/ while (TRUE){ if (p->par.branch_on_cuts && p->slack_cut_num > 0){ switch (p->par.discard_slack_cuts){ case DISCARD_SLACKS_WHEN_STARTING_NEW_NODE: if (p->iter_num != 0) break; case DISCARD_SLACKS_BEFORE_NEW_ITERATION: free_cuts(p->slack_cuts, p->slack_cut_num); p->slack_cut_num = 0; break; } } p->iter_num++; p->node_iter_num++; PRINT(p->par.verbosity, 2, ("\n\n**** Starting iteration %i ****\n\n", p->iter_num)); termcode = dual_simplex(lp_data, &iterd); /* Get relevant data */ get_dj_pi(lp_data); get_slacks(lp_data); get_x(lp_data); /* display the current solution */ if (p->mip->obj_sense == SYM_MAXIMIZE){ PRINT(p->par.verbosity, 2, ("The LP value is: %.3f [%i,%i]\n\n", -lp_data->objval + p->mip->obj_offset, termcode, iterd)); }else{ PRINT(p->par.verbosity, 2, ("The LP value is: %.3f [%i,%i]\n\n", lp_data->objval+ p->mip->obj_offset, termcode, iterd)); } switch (termcode){ case LP_D_ITLIM: /* impossible, since itlim is set to infinity */ case LP_D_INFEASIBLE: /* this is impossible (?) as of now */ case LP_ABANDONED: printf("######## Unexpected termcode: %i \n", termcode); if (p->par.try_to_recover_from_error && (++num_errors == 1)){ /* Try to resolve it from scratch */ printf("######## Trying to recover by resolving from scratch...\n", termcode); continue; }else{ char name[50] = ""; printf("######## Recovery failed. %s%s", "LP solver is having numerical difficulties :(.\n", "######## Dumping current LP to MPS file and exiting.\n\n"); sprintf(name, "matrix.%i.%i.mps", p->bc_index, p->iter_num); write_mps(lp_data, name); return(ERROR__NUMERICAL_INSTABILITY); } case LP_D_UNBOUNDED: /* the primal problem is infeasible */ case LP_D_OBJLIM: case LP_OPTIMAL: if (num_errors == 1){ printf("######## Recovery succeeded! Continuing with node...\n\n"); num_errors = 0; } if (termcode == LP_D_UNBOUNDED){ PRINT(p->par.verbosity, 1, ("Feasibility lost -- ")); #if 0 char name[50] = ""; sprintf(name, "matrix.%i.%i.mps", p->bc_index, p->iter_num); write_mps(lp_data, name); #endif }else if ((p->has_ub && lp_data->objval > p->ub - p->par.granularity) || termcode == LP_D_OBJLIM){ PRINT(p->par.verbosity, 1, ("Terminating due to high cost -- ")); }else{ /* optimal and not too high cost */ break; } comp_times->lp += used_time(&p->tt); if (fathom(p, (termcode != LP_D_UNBOUNDED))){ comp_times->communication += used_time(&p->tt); return(FUNCTION_TERMINATED_NORMALLY); }else{ first_in_loop = FALSE; comp_times->communication += used_time(&p->tt); continue; } } /* If come to here, the termcode must have been OPTIMAL and the * cost cannot be too high. */ /* is_feasible_u() fills up lp_data->x, too!! */ if (is_feasible_u(p, FALSE) == IP_FEASIBLE){ cuts = -1; }else{ /*------------------------------------------------------------------*\ * send the current solution to the cut generator, and also to the * cut pool if we are either * - at the beginning of a chain (but not in the root in the * first phase) * - or this is the cut_pool_check_freq-th iteration. \*------------------------------------------------------------------*/ cuts = 0; no_more_cuts_count = 0; if (p->cut_pool && ((first_in_loop && (p->bc_level>0 || p->phase==1)) || (p->iter_num % p->par.cut_pool_check_freq == 0)) ){ no_more_cuts_count += send_lp_solution_u(p, p->cut_pool); } if (p->cut_gen){ no_more_cuts_count += send_lp_solution_u(p, p->cut_gen); } if (p->par.verbosity > 4){ printf ("Now displaying the relaxed solution ...\n"); display_lp_solution_u(p, DISP_RELAXED_SOLUTION); } comp_times->lp += used_time(&p->tt); tighten_bounds(p); comp_times->fixing += used_time(&p->tt); if (!first_in_loop){ cuts = check_row_effectiveness(p); } /*------------------------------------------------------------------*\ * receive the cuts from the cut generator and the cut pool \*------------------------------------------------------------------*/ if ((cut_term = receive_cuts(p, first_in_loop, no_more_cuts_count)) >=0 ){ cuts += cut_term; }else{ return(ERROR__USER); } } comp_times->lp += used_time(&p->tt); if (cuts < 0){ /* i.e. feasible solution is found */ if (fathom(p, TRUE)){ return(FUNCTION_TERMINATED_NORMALLY); }else{ first_in_loop = FALSE; check_ub(p); continue; } } PRINT(p->par.verbosity, 2, ("\nIn iteration %i, before calling branch()\n", p->iter_num)); if (cuts == 0){ PRINT(p->par.verbosity, 2, ("... no cuts were added.\n")); if (p->par.verbosity > 4){ printf("Now displaying final relaxed solution...\n\n"); display_lp_solution_u(p, DISP_FINAL_RELAXED_SOLUTION); } }else{ PRINT(p->par.verbosity, 2, ("... %i violated cuts were added\n", cuts)); } comp_times->lp += used_time(&p->tt); switch (cuts = branch(p, cuts)){ case NEW_NODE: #ifndef ROOT_NODEONLY if (p->par.verbosity > 0){ printf("*************************************************\n"); printf("* Now processing NODE %i LEVEL %i\n", p->bc_index, p->bc_level); printf("*************************************************\n\n"); p->node_iter_num = 0; } break; #endif case FATHOMED_NODE: comp_times->strong_branching += used_time(&p->tt); return(FUNCTION_TERMINATED_NORMALLY); case ERROR__NO_BRANCHING_CANDIDATE: /* Something went wrong */ return(ERROR__NO_BRANCHING_CANDIDATE); default: /* the return value is the number of cuts added */ if (p->par.verbosity > 2){ printf("Continue with this node."); if (cuts > 0) printf(" %i cuts added alltogether in iteration %i", cuts, p->iter_num); printf("\n\n"); } break; } comp_times->strong_branching += used_time(&p->tt); check_ub(p); first_in_loop = FALSE; } comp_times->lp += used_time(&p->tt); return(FUNCTION_TERMINATED_NORMALLY); }
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); }
int vps_start_custom(vps_handler *h, envid_t veid, vps_param *param, skipFlags skip, struct mod_action *mod, env_create_FN fn, void *data) { int wait_p[2]; int old_wait_p[2]; int err_p[2]; int ret, err; char buf[64]; char *dist_name; struct sigaction act; vps_res *res = ¶m->res; dist_actions actions; memset(&actions, 0, sizeof(actions)); if (check_var(res->fs.root, "VE_ROOT is not set")) return VZ_VE_ROOT_NOTSET; if (vps_is_run(h, veid)) { logger(-1, 0, "Container is already running"); return VZ_VE_RUNNING; } if ((ret = check_ub(&res->ub))) return ret; dist_name = get_dist_name(&res->tmpl); ret = read_dist_actions(dist_name, DIST_DIR, &actions); free(dist_name); if (ret) return ret; logger(0, 0, "Starting container ..."); if (vps_is_mounted(res->fs.root)) { /* if CT is mounted -- umount first, to cleanup mount state */ vps_umount(h, veid, res->fs.root, skip); } if (!vps_is_mounted(res->fs.root)) { /* increase quota to perform setup */ quota_inc(&res->dq, 100); if ((ret = vps_mount(h, veid, &res->fs, &res->dq, skip))) return ret; quota_inc(&res->dq, -100); } /* Fedora 14/15 hacks */ if (fix_ve_devconsole(res->fs.root) != 0) return VZ_FS_BAD_TMPL; if (fix_ve_systemd(res->fs.root) != 0) return VZ_FS_BAD_TMPL; if (pipe(wait_p) < 0) { logger(-1, errno, "Can not create pipe"); return VZ_RESOURCE_ERROR; } /* old_wait_p is needed for backward compatibility with older kernels, * while for recent ones (that support CPT_SET_LOCKFD2) we use wait_p. * * If old_wait_p is closed without writing any data, it's "OK to go" * signal, and if data are received from old_wait_p it's "no go" * signal". Note that such thing doesn't work if vzctl segfaults, * because in this case the descriptor will be closed without * sending data. */ if (pipe(old_wait_p) < 0) { logger(-1, errno, "Can not create pipe"); return VZ_RESOURCE_ERROR; } if (pipe(err_p) < 0) { close(wait_p[0]); close(wait_p[1]); logger(-1, errno, "Can not create pipe"); return VZ_RESOURCE_ERROR; } sigemptyset(&act.sa_mask); act.sa_handler = SIG_IGN; act.sa_flags = 0; sigaction(SIGPIPE, &act, NULL); fix_numiptent(&res->ub); fix_cpu(&res->cpu); ret = vz_env_create(h, veid, res, wait_p, old_wait_p, err_p, fn, data); if (ret) goto err; if ((ret = vps_setup_res(h, veid, &actions, &res->fs, param, STATE_STARTING, skip, mod))) { goto err; } if (!(skip & SKIP_ACTION_SCRIPT)) { snprintf(buf, sizeof(buf), VPS_CONF_DIR "%d.%s", veid, START_PREFIX); if (stat_file(buf)) { if (vps_exec_script(h, veid, res->fs.root, NULL, NULL, buf, NULL, 0)) { ret = VZ_ACTIONSCRIPT_ERROR; goto err; } } } /* Tell the child that it's time to start /sbin/init */ err = 0; if (write(wait_p[1], &err, sizeof(err)) != sizeof(err)) logger(-1, errno, "Unable to write to waitfd to start init"); close(wait_p[1]); close(old_wait_p[1]); err: free_dist_actions(&actions); if (ret) { /* Kill environment */ logger(-1, 0, "Container start failed (try to check kernel " "messages, e.g. \"dmesg | tail\")"); /* Close wait fd without writing anything to it * to signal the child that we have failed to configure * the environment, so it should not start /sbin/init */ close(wait_p[1]); write(old_wait_p[1], &err, sizeof(err)); close(old_wait_p[1]); } else { if (!read(err_p[0], &ret, sizeof(ret))) { if (res->misc.wait == YES) { logger(0, 0, "Container start in progress" ", waiting ..."); err = vps_execFn(h, veid, res->fs.root, wait_on_fifo, NULL, 0); if (err) { logger(0, 0, "Container wait failed%s", err == VZ_EXEC_TIMEOUT ? \ " - timeout expired" : ""); ret = VZ_WAIT_FAILED; } else { logger(0, 0, "Container started" " successfully"); } } else { logger(0, 0, "Container start in progress..."); } } else { if (ret == VZ_FS_BAD_TMPL) logger(-1, 0, "Unable to start init, probably" " incorrect template"); logger(-1, 0, "Container start failed"); } } if (ret) { if (vps_is_run(h, veid)) env_stop(h, veid, res->fs.root, M_KILL); /* restore original quota values */ vps_set_quota(veid, &res->dq); if (vps_is_mounted(res->fs.root)) vps_umount(h, veid, res->fs.root, skip); } close(wait_p[0]); close(wait_p[1]); close(err_p[0]); close(err_p[1]); return ret; }