⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 solve.c

📁 linux下的源码分类器SVM
💻 C
📖 第 1 页 / 共 3 页
字号:
      }      if(lp->solution[i] > upbo[i] * lp->scale[i] + CHECK_EPS) {	fprintf(stderr,		"Error: variable %d (%s) has a solution (%g) larger than its upper bound (%g)\n",		i - lp->rows, lp->col_name[i - lp->rows],		(double)lp->solution[i], (double)upbo[i] * lp->scale[i]);	/* abort(); */      }    }  else /* columns not scaled */    for(i = lp->rows + 1; i <= lp->sum; i++) {      if(lp->solution[i] < lowbo[i] - CHECK_EPS) {	fprintf(stderr,		"Error: variable %d (%s) has a solution (%g) smaller than its lower bound (%g)\n",		i - lp->rows, lp->col_name[i - lp->rows],		(double)lp->solution[i], (double)lowbo[i]);	/* abort(); */      }      if(lp->solution[i] > upbo[i] + CHECK_EPS) {	fprintf(stderr,		"Error: variable %d (%s) has a solution (%g) larger than its upper bound (%g)\n",		i - lp->rows, lp->col_name[i - lp->rows],		(double)lp->solution[i], (double)upbo[i]);	/* abort(); */      }    }} /* check_solution */static int milpsolve(lprec *lp,		     REAL   *upbo,		     REAL   *lowbo,		     short  *sbasis,		     short  *slower,		     int    *sbas,		     int     recursive){  int i, j, failure, notint, is_worse;  REAL theta, tmpreal;  if(Break_bb)    return(BREAK_BB);  Level++;  lp->total_nodes++;  if(Level > lp->max_level)    lp->max_level = Level;  debug_print(lp, "starting solve");  /* make fresh copies of upbo, lowbo, rh as solving changes them */  memcpy(lp->upbo,  upbo,    (lp->sum + 1)  * sizeof(REAL));  memcpy(lp->lowbo, lowbo,   (lp->sum + 1)  * sizeof(REAL));  memcpy(lp->rh,    lp->orig_rh, (lp->rows + 1) * sizeof(REAL));  /* make shure we do not do memcpy(lp->basis, lp->basis ...) ! */  if(recursive) {    memcpy(lp->basis, sbasis,  (lp->sum + 1)  * sizeof(short));    memcpy(lp->lower, slower,  (lp->sum + 1)  * sizeof(short));    memcpy(lp->bas,   sbas,    (lp->rows + 1) * sizeof(int));  }  if(lp->anti_degen) { /* randomly disturb bounds */    for(i = 1; i <= lp->columns; i++) {      tmpreal = (REAL) (rand() % 100 * 0.00001);      if(tmpreal > lp->epsb)	lp->lowbo[i + lp->rows] -= tmpreal;      tmpreal = (REAL) (rand() % 100 * 0.00001);      if(tmpreal > lp->epsb)	lp->upbo[i + lp->rows] += tmpreal;    }    lp->eta_valid = FALSE;  }  if(!lp->eta_valid) {    /* transform to all lower bounds to zero */    for(i = 1; i <= lp->columns; i++)      if((theta = lp->lowbo[lp->rows + i]) != 0) {	if(lp->upbo[lp->rows + i] < lp->infinite)	  lp->upbo[lp->rows + i] -= theta;	for(j = lp->col_end[i - 1]; j < lp->col_end[i]; j++)	  lp->rh[lp->mat[j].row_nr] -= theta * lp->mat[j].value;      }    invert(lp);    lp->eta_valid = TRUE;  }  failure = solvelp(lp);  if(lp->anti_degen && (failure == OPTIMAL)) {    /* restore to original problem, solve again starting from the basis found       for the disturbed problem */    /* restore original problem */    memcpy(lp->upbo,  upbo,        (lp->sum + 1)  * sizeof(REAL));    memcpy(lp->lowbo, lowbo,       (lp->sum + 1)  * sizeof(REAL));    memcpy(lp->rh,    lp->orig_rh, (lp->rows + 1) * sizeof(REAL));    /* transform to all lower bounds zero */    for(i = 1; i <= lp->columns; i++)      if((theta = lp->lowbo[lp->rows + i]) != 0) {	if(lp->upbo[lp->rows + i] < lp->infinite)	  lp->upbo[lp->rows + i] -= theta;	for(j = lp->col_end[i - 1]; j < lp->col_end[i]; j++)	  lp->rh[lp->mat[j].row_nr] -= theta * lp->mat[j].value;      }    invert(lp);    lp->eta_valid = TRUE;    failure = solvelp(lp); /* and solve again */  }  if(failure != OPTIMAL)    debug_print(lp, "this problem has no solution, it is %s",		(failure == UNBOUNDED) ? "unbounded" : "infeasible");  if(failure == INFEASIBLE && lp->verbose)    fprintf(stderr, "level %d INF\n", Level);  if(failure == OPTIMAL) { /* there is a good solution */    construct_solution(lp);    /* because of reports of solution > upbo */    /* check_solution(lp, upbo, lowbo); get too many hits ?? */    debug_print(lp, "a solution was found");    debug_print_solution(lp);    /* if this solution is worse than the best sofar, this branch must die */    /* if we can only have integer OF values, we might consider requiring to       be at least 1 better than the best sofar, MB */    if(lp->maximise)      is_worse = lp->solution[0] <= lp->best_solution[0];    else /* minimising! */      is_worse = lp->solution[0] >= lp->best_solution[0];    if(is_worse) {      if(lp->verbose)	fprintf(stderr, "level %d OPT NOB value %g bound %g\n",		Level, (double)lp->solution[0],		(double)lp->best_solution[0]);       debug_print(lp, "but it was worse than the best sofar, discarded");      Level--;      return(MILP_FAIL);    }    /* check if solution contains enough ints */    if(lp->bb_rule == FIRST_NI) {      for(notint = 0, i = lp->rows + 1;	  i <= lp->sum && notint == 0;	  i++) {	if(lp->must_be_int[i] && !is_int(lp, i)) {	  if(lowbo[i] == upbo[i]) { /* this var is already fixed */	    fprintf(stderr,		    "Warning: integer var %d is already fixed at %d, but has non-integer value %g\n",		    i - lp->rows, (int)lowbo[i],		    (double)lp->solution[i]);	    fprintf(stderr, "Perhaps the -e option should be used\n");	  }	  else	    notint = i;	}      }    }    if(lp->bb_rule == RAND_NI) {      int nr_not_int, select_not_int;      nr_not_int = 0;            for(i = lp->rows + 1; i <= lp->sum; i++)	if(lp->must_be_int[i] && !is_int(lp, i))	  nr_not_int++;      if(nr_not_int == 0)	notint = 0;      else {	select_not_int = (rand() % nr_not_int) + 1;	i = lp->rows + 1;	while(select_not_int > 0) {	  if(lp->must_be_int[i] && !is_int(lp, i))	    select_not_int--;	  i++;	}	notint = i - 1;      }    }    if(lp->verbose) {      if(notint)	fprintf(stderr, "level %d OPT     value %g\n", Level,		(double)lp->solution[0]);      else	fprintf(stderr, "level %d OPT INT value %g\n", Level,		(double)lp->solution[0]);    }    if(notint) { /* there is at least one value not yet int */      /* set up two new problems */      REAL   *new_upbo, *new_lowbo;      REAL   new_bound;      short  *new_lower,*new_basis;      int    *new_bas;      int     resone, restwo;      /* allocate room for them */      MALLOC(new_upbo,  lp->sum + 1);      MALLOC(new_lowbo, lp->sum + 1);      MALLOC(new_lower, lp->sum + 1);      MALLOC(new_basis, lp->sum + 1);      MALLOC(new_bas,   lp->rows + 1);      memcpy(new_upbo,  upbo,      (lp->sum + 1)  * sizeof(REAL));      memcpy(new_lowbo, lowbo,     (lp->sum + 1)  * sizeof(REAL));      memcpy(new_lower, lp->lower, (lp->sum + 1)  * sizeof(short));      memcpy(new_basis, lp->basis, (lp->sum + 1)  * sizeof(short));      memcpy(new_bas,   lp->bas,   (lp->rows + 1) * sizeof(int));         if(lp->names_used)	debug_print(lp, "not enough ints. Selecting var %s, val: %g",		    lp->col_name[notint - lp->rows],		    (double)lp->solution[notint]);      else	debug_print(lp,		    "not enough ints. Selecting Var [%d], val: %g",		    notint, (double)lp->solution[notint]);      debug_print(lp, "current bounds:\n");      debug_print_bounds(lp, upbo, lowbo);      if(lp->floor_first) {	new_bound = ceil(lp->solution[notint]) - 1;	/* this bound might conflict */	if(new_bound < lowbo[notint]) {	  debug_print(lp,		      "New upper bound value %g conflicts with old lower bound %g\n",		      (double)new_bound, (double)lowbo[notint]);	  resone = MILP_FAIL;	}	else { /* bound feasible */	  check_if_less(new_bound, upbo[notint], lp->solution[notint]);	  new_upbo[notint] = new_bound;	  debug_print(lp, "starting first subproblem with bounds:");	  debug_print_bounds(lp, new_upbo, lowbo);	  lp->eta_valid = FALSE;	  resone = milpsolve(lp, new_upbo, lowbo, new_basis, new_lower,			     new_bas, TRUE);	  lp->eta_valid = FALSE;	}	new_bound += 1;	if(new_bound > upbo[notint]) {	  debug_print(lp,		      "New lower bound value %g conflicts with old upper bound %g\n",		      (double)new_bound, (double)upbo[notint]);	  restwo = MILP_FAIL;	}	else { /* bound feasible */	  check_if_less(lowbo[notint], new_bound, lp->solution[notint]);	  new_lowbo[notint] = new_bound;	  debug_print(lp, "starting second subproblem with bounds:");	  debug_print_bounds(lp, upbo, new_lowbo);	  lp->eta_valid = FALSE;	  restwo = milpsolve(lp, upbo, new_lowbo, new_basis, new_lower,			     new_bas, TRUE);	  lp->eta_valid = FALSE;	}      }      else { /* take ceiling first */	new_bound = ceil(lp->solution[notint]);	/* this bound might conflict */	if(new_bound > upbo[notint]) {	  debug_print(lp,		      "New lower bound value %g conflicts with old upper bound %g\n",		      (double)new_bound, (double)upbo[notint]);	  resone = MILP_FAIL;	}	else { /* bound feasible */	  check_if_less(lowbo[notint], new_bound, lp->solution[notint]);	  new_lowbo[notint] = new_bound;	  debug_print(lp, "starting first subproblem with bounds:");	  debug_print_bounds(lp, upbo, new_lowbo);	  lp->eta_valid = FALSE;	  resone = milpsolve(lp, upbo, new_lowbo, new_basis, new_lower,			     new_bas, TRUE);	  lp->eta_valid = FALSE;	}	new_bound -= 1;	if(new_bound < lowbo[notint]) {	  debug_print(lp,		      "New upper bound value %g conflicts with old lower bound %g\n",		      (double)new_bound, (double)lowbo[notint]);	  restwo = MILP_FAIL;	}	else { /* bound feasible */	  check_if_less(new_bound, upbo[notint], lp->solution[notint]);	  new_upbo[notint] = new_bound;	  debug_print(lp, "starting second subproblem with bounds:");	  debug_print_bounds(lp, new_upbo, lowbo);	  lp->eta_valid = FALSE;	  restwo = milpsolve(lp, new_upbo, lowbo, new_basis, new_lower,			     new_bas, TRUE);	  lp->eta_valid = FALSE;	}      }      if(resone && restwo) /* both failed and must have been infeasible */	failure = INFEASIBLE;      else	failure = OPTIMAL;      free(new_upbo);      free(new_lowbo);      free(new_basis);      free(new_lower);      free(new_bas);    }    else { /* all required values are int */      debug_print(lp, "--> valid solution found");            if(lp->maximise)	is_worse = lp->solution[0] < lp->best_solution[0];      else	is_worse = lp->solution[0] > lp->best_solution[0];      if(!is_worse) { /* Current solution better */	if(lp->debug || (lp->verbose && !lp->print_sol))	  fprintf(stderr,		  "*** new best solution: old: %g, new: %g ***\n",		  (double)lp->best_solution[0], (double)lp->solution[0]);	memcpy(lp->best_solution, lp->solution, (lp->sum + 1) * sizeof(REAL));	calculate_duals(lp);	if(lp->print_sol)	  print_solution(lp); 	if(lp->break_at_int) {	  if(lp->maximise && (lp->best_solution[0] > lp->break_value))	    Break_bb = TRUE;	  if(!lp->maximise && (lp->best_solution[0] < lp->break_value))	    Break_bb = TRUE;	}      }    }  }  Level--;  /* failure can have the values OPTIMAL, UNBOUNDED and INFEASIBLE. */  return(failure);} /* milpsolve */int solve(lprec *lp){  int result, i;  lp->total_iter  = 0;  lp->max_level   = 1;  lp->total_nodes = 0;  if(isvalid(lp)) {    if(lp->maximise && lp->obj_bound == lp->infinite)      lp->best_solution[0] = -lp->infinite;    else if(!lp->maximise && lp->obj_bound == -lp->infinite)      lp->best_solution[0] = lp->infinite;    else      lp->best_solution[0] = lp->obj_bound;    Level = 0;    if(!lp->basis_valid) {      for(i = 0; i <= lp->rows; i++) {	lp->basis[i] = TRUE;	lp->bas[i]   = i;      }      for(i = lp->rows + 1; i <= lp->sum; i++)	lp->basis[i] = FALSE;      for(i = 0; i <= lp->sum; i++)	lp->lower[i] = TRUE;      lp->basis_valid = TRUE;    }    lp->eta_valid = FALSE;    Break_bb      = FALSE;    result        = milpsolve(lp, lp->orig_upbo, lp->orig_lowbo, lp->basis,			      lp->lower, lp->bas, FALSE);     return(result);  }  /* if we get here, isvalid(lp) failed. I suggest we return FAILURE */  fprintf(stderr, "Error, the current LP seems to be invalid\n");  return(FAILURE);} /* solve */int lag_solve(lprec *lp, REAL start_bound, int num_iter, short verbose){  int i, j, result, citer;  short status, OrigFeas, AnyFeas, same_basis;  REAL *OrigObj, *ModObj, *SubGrad, *BestFeasSol;  REAL Zub, Zlb, Ztmp, pie;  REAL rhsmod, Step, SqrsumSubGrad;  int   *old_bas;  short *old_lower;  /* allocate mem */    MALLOC(OrigObj, lp->columns + 1);  CALLOC(ModObj, lp->columns + 1);  CALLOC(SubGrad, lp->nr_lagrange);  CALLOC(BestFeasSol, lp->sum + 1);  MALLOCCPY(old_bas, lp->bas, lp->rows + 1);  MALLOCCPY(old_lower, lp->lower, lp->sum + 1);  get_row(lp, 0, OrigObj);   pie = 2;    if(lp->maximise) {    Zub = DEF_INFINITE;    Zlb = start_bound;  }  else {    Zlb = -DEF_INFINITE;    Zub = start_bound;  }  status   = RUNNING;   Step     = 1;  OrigFeas = FALSE;  AnyFeas  = FALSE;  citer    = 0;  for(i = 0 ; i < lp->nr_lagrange; i++)    lp->lambda[i] = 0;  while(status == RUNNING) {    citer++;    for(i = 1; i <= lp->columns; i++) {      ModObj[i] = OrigObj[i];      for(j = 0; j < lp->nr_lagrange; j++) {	if(lp->maximise)	  ModObj[i] -= lp->lambda[j] * lp->lag_row[j][i]; 	else  	  ModObj[i] += lp->lambda[j] * lp->lag_row[j][i];      }    }    for(i = 1; i <= lp->columns; i++) {        set_mat(lp, 0, i, ModObj[i]);    }    rhsmod = 0;    for(i = 0; i < lp->nr_lagrange; i++)      if(lp->maximise)	rhsmod += lp->lambda[i] * lp->lag_rhs[i];      else	rhsmod -= lp->lambda[i] * lp->lag_rhs[i];     if(verbose) {      fprintf(stderr, "Zub: %10g Zlb: %10g Step: %10g pie: %10g Feas %d\n",	      (double)Zub, (double)Zlb, (double)Step, (double)pie, OrigFeas);      for(i = 0; i < lp->nr_lagrange; i++)	fprintf(stderr, "%3d SubGrad %10g lambda %10g\n", i,		(double)SubGrad[i], (double)lp->lambda[i]);    }    if(verbose && lp->sum < 20)      print_lp(lp);    result = solve(lp);    if(verbose && lp->sum < 20) {       print_solution(lp);    }    same_basis = TRUE;    i = 1;    while(same_basis && i < lp->rows) {      same_basis = (old_bas[i] == lp->bas[i]);      i++;    }    i = 1;    while(same_basis && i < lp->sum) {      same_basis=(old_lower[i] == lp->lower[i]);      i++;    }    if(!same_basis) {      memcpy(old_lower, lp->lower, (lp->sum+1) * sizeof(short));      memcpy(old_bas, lp->bas, (lp->rows+1) * sizeof(int));      pie *= 0.95;    }    if(verbose)      fprintf(stderr, "result: %d  same basis: %d\n", result, same_basis);          if(result == UNBOUNDED) {      for(i = 1; i <= lp->columns; i++)	fprintf(stderr, "%g ", (double)ModObj[i]);      exit(EXIT_FAILURE);    }    if(result == FAILURE)      status = FAILURE;    if(result == INFEASIBLE)      status = INFEASIBLE;          SqrsumSubGrad = 0;    for(i = 0; i < lp->nr_lagrange; i++) {      SubGrad[i]= -lp->lag_rhs[i];      for(j = 1; j <= lp->columns; j++)	SubGrad[i] += lp->best_solution[lp->rows + j] * lp->lag_row[i][j];      SqrsumSubGrad += SubGrad[i] * SubGrad[i];    }    OrigFeas = TRUE;    for(i = 0; i < lp->nr_lagrange; i++)      if(lp->lag_con_type[i]) {	if(my_abs(SubGrad[i]) > lp->epsb)	  OrigFeas = FALSE;      }      else if(SubGrad[i] > lp->epsb)	OrigFeas = FALSE;    if(OrigFeas) {      AnyFeas = TRUE;      Ztmp = 0;      for(i = 1; i <= lp->columns; i++)	Ztmp += lp->best_solution[lp->rows + i] * OrigObj[i];      if((lp->maximise) && (Ztmp > Zlb)) {	Zlb = Ztmp;	for(i = 1; i <= lp->sum; i++)	  BestFeasSol[i] = lp->best_solution[i];	BestFeasSol[0] = Zlb;	if(verbose)	  fprintf(stderr, "Best feasible solution: %g\n", (double)Zlb);      }      else if(Ztmp < Zub) {	Zub = Ztmp;	for(i = 1; i <= lp->sum; i++)	  BestFeasSol[i] = lp->best_solution[i];	BestFeasSol[0] = Zub;	if(verbose)	  fprintf(stderr, "Best feasible solution: %g\n", (double)Zub);      }        }          if(lp->maximise)      Zub = my_min(Zub, rhsmod + lp->best_solution[0]);    else      Zlb = my_max(Zlb, rhsmod + lp->best_solution[0]);    if(my_abs(Zub-Zlb)<0.001) {        status = OPTIMAL;    }    Step = pie * ((1.05*Zub) - Zlb) / SqrsumSubGrad;       for(i = 0; i < lp->nr_lagrange; i++) {      lp->lambda[i] += Step * SubGrad[i];      if(!lp->lag_con_type[i] && lp->lambda[i] < 0)	lp->lambda[i] = 0;    }     if(citer == num_iter && status==RUNNING) {      if(AnyFeas)	status = FEAS_FOUND;      else	status = NO_FEAS_FOUND;    }  }  for(i = 0; i <= lp->sum; i++)    lp->best_solution[i] = BestFeasSol[i];   for(i = 1; i <= lp->columns; i++)    set_mat(lp, 0, i, OrigObj[i]);  if(lp->maximise)    lp->lag_bound = Zub;  else    lp->lag_bound = Zlb;  free(BestFeasSol);  free(SubGrad);  free(OrigObj);  free(ModObj);  free(old_bas);  free(old_lower);    return(status);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -