glpipp01.c

来自「著名的大规模线性规划求解器源码GLPK.C语言版本,可以修剪.内有详细帮助文档.」· C语言 代码 · 共 806 行 · 第 1/2 页

C
806
字号
         else            col->q_prev->q_next = col->q_next;         if (col->q_next == NULL)            ;         else            col->q_next->q_prev = col->q_prev;      }      return;}/*------------------------------------------------------------------------ ipp_append_tqe - append new transformation queue entry.---- *Synopsis*---- #include "glpipp.h"-- void *ipp_append_tqe(IPP *ipp, int type, int size);---- *Description*---- The routine ipp_append_tqe appends a new transformation queue entry-- to the list.---- The parameter type is the entry type.---- The parameter size is the size of a specific part, in bytes.---- *Returns*---- The routine returns a pointer to a specific part, which is allocated-- and attached to the entry. */void *ipp_append_tqe(IPP *ipp, int type, int size){     IPPTQE *tqe;      tqe = dmp_get_atomv(ipp->tqe_pool, sizeof(IPPTQE));      tqe->type = type;      tqe->info = dmp_get_atomv(ipp->tqe_pool, size);      tqe->next = ipp->tqe_list;      ipp->tqe_list = tqe;      return tqe->info;}/*------------------------------------------------------------------------ ipp_load_orig - load original problem into MIP presolver workspace.---- SYNOPSIS---- #include "glpipp.h"-- void ipp_load_orig(IPP *ipp, LPX *orig);---- DESCRIPTION---- The routine ipp_load_orig loads an original MIP problem, which the-- parameter orig points to, into the MIP presolver workspace.---- On exit from the routine the tranformed problem in the workspace is-- identical to the original problem. */void ipp_load_orig(IPP *ipp, LPX *orig){     IPPROW **row;      IPPCOL *col;      int i, j, k, type, len, *ind;      double lb, ub, *val;      /* save some information about the original problem */      ipp->orig_m = lpx_get_num_rows(orig);      ipp->orig_n = lpx_get_num_cols(orig);      ipp->orig_nnz = lpx_get_num_nz(orig);      ipp->orig_dir = lpx_get_obj_dir(orig);      /* allocate working arrays */      row = xcalloc(1+ipp->orig_m, sizeof(IPPROW *));      ind = xcalloc(1+ipp->orig_m, sizeof(int));      val = xcalloc(1+ipp->orig_m, sizeof(double));      /* copy rows of the original problem into the workspace */      for (i = 1; i <= ipp->orig_m; i++)      {  type = lpx_get_row_type(orig, i);         if (type == LPX_FR || type == LPX_UP)            lb = -DBL_MAX;         else            lb = lpx_get_row_lb(orig, i);         if (type == LPX_FR || type == LPX_LO)            ub = +DBL_MAX;         else            ub = lpx_get_row_ub(orig, i);         row[i] = ipp_add_row(ipp, lb, ub);      }      /* copy columns of the original problem into the workspace; each         column created in the workspace is assigned a reference number         which is its ordinal number in the original problem */      for (j = 1; j <= ipp->orig_n; j++)      {  type = lpx_get_col_type(orig, j);         if (type == LPX_FR || type == LPX_UP)            lb = -DBL_MAX;         else            lb = lpx_get_col_lb(orig, j);         if (type == LPX_FR || type == LPX_LO)            ub = +DBL_MAX;         else            ub = lpx_get_col_ub(orig, j);         col = ipp_add_col(ipp, lpx_get_col_kind(orig, j) == LPX_IV,            lb, ub, lpx_get_obj_coef(orig, j));         len = lpx_get_mat_col(orig, j, ind, val);         for (k = 1; k <= len; k++)            ipp_add_aij(ipp, row[ind[k]], col, val[k]);      }      /* copy the constant term of the original objective function */      ipp->c0 = lpx_get_obj_coef(orig, 0);      /* if the original problem is maximization, change the sign of         the objective function, because the transformed problem to be         processed by the presolver must be minimization */      if (ipp->orig_dir == LPX_MAX)      {  for (col = ipp->col_ptr; col != NULL; col = col->next)            col->c = - col->c;         ipp->c0 = - ipp->c0;      }      /* free working arrays */      xfree(row);      xfree(ind);      xfree(val);      return;}/*------------------------------------------------------------------------ ipp_tight_bnds - tight current column bounds using implied bounds.---- SYNOPSIS---- #include "glpipp.h"-- int ipp_tight_bnds(IPP *ipp, IPPCOL *col, double lb, double ub);---- DESCRIPTION---- The routines ipp_tight_bnds replaces current bounds of the column,-- which the parameter col points to:----    l <= x <= u,                                                   (1)---- by new bounds:----    max(l, l') <= x <= min(u, u'),                                 (2)---- where l' and u' are specified implied bounds of the column.---- RETURNS---- 0 - bounds remain unchanged-- 1 - bounds have been changed-- 2 - new bounds are primal infeasible */int ipp_tight_bnds(IPP *ipp, IPPCOL *col, double lb, double ub){     int ret = 0;      double eps;      xassert(ipp == ipp);      /* if the column is integral, round implied bounds */      if (col->i_flag)      {  eps = 1e-5 * (1.0 + fabs(lb));         if (fabs(lb - floor(lb + 0.5)) <= eps)            lb = floor(lb + 0.5);         else            lb = ceil(lb);         eps = 1e-5 * (1.0 + fabs(ub));         if (fabs(ub - floor(ub + 0.5)) <= eps)            ub = floor(ub + 0.5);         else            ub = floor(ub);      }      /* check for primal infeasibility */      if (col->lb != -DBL_MAX)      {  eps = 1e-5 * (1.0 + fabs(col->lb));         if (ub < col->lb - eps)         {  ret = 2;            goto done;         }      }      if (col->ub != +DBL_MAX)      {  eps = 1e-5 * (1.0 + fabs(col->ub));         if (lb > col->ub + eps)         {  ret = 2;            goto done;         }      }#if 1      if (col->i_flag && lb > ub + 0.5)      {  /* this may happen due to rounding implied bounds */         ret = 2;         goto done;      }#endif      /* replace current bounds by implied ones, if necessary */      if (lb != -DBL_MAX)      {  eps = 1e-7 * (1.0 + fabs(lb));         if (col->lb < lb - eps)         {  col->lb = lb;            ret = 1;         }      }      if (ub != +DBL_MAX)      {  eps = 1e-7 * (1.0 + fabs(ub));         if (col->ub > ub + eps)         {  col->ub = ub;            ret = 1;         }      }      /* if new bounds of the column are close to each other, the         column can be fixed */      if (ret == 1 && col->lb != -DBL_MAX && col->ub != +DBL_MAX)      {  eps = 1e-7 * (1.0 + fabs(col->lb));         if (col->lb >= col->ub - eps)         {  if (fabs(col->lb) <= fabs(col->ub))               col->ub = col->lb;            else               col->lb = col->ub;         }      }done: xassert(col->lb <= col->ub);      return ret;}/*------------------------------------------------------------------------ ipp_build_prob - build resultant problem.---- SYNOPSIS---- #include "glpipp.h"-- LPX *ipp_build_prob(IPP *ipp);---- DESCRIPTION---- The routine ipp_build_prob converts the resultant MIP problem from-- an internal format, in which the problem is stored in the workspace,-- to the standard problem object.---- RETURNS---- The routine returns a pointer to the problem object. */LPX *ipp_build_prob(IPP *ipp){     LPX *prob;      IPPROW *row;      IPPCOL *col;      IPPAIJ *aij;      int i, j, type, len, *ind;      double *val;      /* create problem object */      prob = lpx_create_prob();#if 0      lpx_set_class(prob, LPX_MIP);#endif      /* the resultant problem should have the same optimization sense         as the original problem */      lpx_set_obj_dir(prob, ipp->orig_dir);      /* set the constant term of the objective function */      lpx_set_obj_coef(prob, 0,         ipp->orig_dir == LPX_MIN ? + ipp->c0 : - ipp->c0);      /* copy rows of the resultant problem */      for (row = ipp->row_ptr; row != NULL; row = row->next)      {  i = lpx_add_rows(prob, 1);         if (row->lb == -DBL_MAX && row->ub == +DBL_MAX)            type = LPX_FR;         else if (row->ub == +DBL_MAX)            type = LPX_LO;         else if (row->lb == -DBL_MAX)            type = LPX_UP;         else if (row->lb != row->ub)            type = LPX_DB;         else            type = LPX_FX;         lpx_set_row_bnds(prob, i, type, row->lb, row->ub);         row->temp = i;      }      /* copy columns of the resultant problem */      ind = xcalloc(1+lpx_get_num_rows(prob), sizeof(int));      val = xcalloc(1+lpx_get_num_rows(prob), sizeof(double));      for (col = ipp->col_ptr; col != NULL; col = col->next)      {  j = lpx_add_cols(prob, 1);         if (col->i_flag) lpx_set_col_kind(prob, j, LPX_IV);         if (col->lb == -DBL_MAX && col->ub == +DBL_MAX)            type = LPX_FR;         else if (col->ub == +DBL_MAX)            type = LPX_LO;         else if (col->lb == -DBL_MAX)            type = LPX_UP;         else if (col->lb != col->ub)            type = LPX_DB;         else            type = LPX_FX;         lpx_set_col_bnds(prob, j, type, col->lb, col->ub);         lpx_set_obj_coef(prob, j,            ipp->orig_dir == LPX_MIN ? + col->c : - col->c);         /* copy constraint coefficients */         len = 0;         for (aij = col->ptr; aij != NULL; aij = aij->c_next)         {  len++;            ind[len] = aij->row->temp;            val[len] = aij->val;         }         lpx_set_mat_col(prob, j, len, ind, val);      }      xfree(ind);      xfree(val);      return prob;}/*------------------------------------------------------------------------ ipp_load_sol - load solution into MIP presolver workspace.---- SYNOPSIS---- #include "glpipp.h"-- void ipp_load_sol(IPP *ipp, LPX *prob);---- DESCRIPTION---- The routine ipp_load_sol loads an integer solution of the resultant-- MIP problem into the MIP presolver workspace. */void ipp_load_sol(IPP *ipp, LPX *prob){     IPPCOL *col;      int j;      xassert(lpx_mip_status(prob) != LPX_I_UNDEF);      ipp->col_stat = xcalloc(1+ipp->ncols, sizeof(int));      ipp->col_mipx = xcalloc(1+ipp->ncols, sizeof(double));      for (j = 1; j <= ipp->ncols; j++) ipp->col_stat[j] = 0;      /* columns in the problem object follow in the same order as in         the column list (see ipp_build_prob) */      j = 0;      for (col = ipp->col_ptr; col != NULL; col = col->next)      {  j++;         ipp->col_stat[col->j] = 1;         ipp->col_mipx[col->j] = lpx_mip_col_val(prob, j);      }      return;}/*------------------------------------------------------------------------ ipp_unload_sol - unload solution from MIP presolver workspace.---- SYNOPSIS---- #include "glpipp.h"-- void ipp_unload_sol(IPP *ipp, LPX *orig, int i_stat);---- DESCRIPTION---- The routine ipp_unload_sol unloads a recovered solution from the-- MIP presolver workspace into the original problem object, which the-- parameter orig points to. */void ipp_unload_sol(IPP *ipp, LPX *orig, int i_stat){     int i, j, k, len, *ind;      double temp, *row_mipx, *val;      xassert(ipp->orig_m == lpx_get_num_rows(orig));      xassert(ipp->orig_n == lpx_get_num_cols(orig));      xassert(ipp->orig_dir == lpx_get_obj_dir(orig));      /* all columns must be computed/recovered */      xassert(ipp->orig_n <= ipp->ncols);      for (j = 1; j <= ipp->ncols; j++) xassert(ipp->col_stat[j]);      /* compute values of auxiliary variables using known values of         structural variables (columns) */      row_mipx = xcalloc(1+ipp->orig_m, sizeof(double));      ind = xcalloc(1+ipp->orig_n, sizeof(int));      val = xcalloc(1+ipp->orig_n, sizeof(double));      for (i = 1; i <= ipp->orig_m; i++)      {  len = lpx_get_mat_row(orig, i, ind, val);         temp = 0.0;         for (k = 1; k <= len; k++)            temp += val[k] * ipp->col_mipx[ind[k]];         row_mipx[i] = temp;      }      xfree(ind);      xfree(val);      /* store solution components into the original problem object */      lpx_put_mip_soln(orig, i_stat, row_mipx, ipp->col_mipx);      xfree(row_mipx);      return;}/*------------------------------------------------------------------------ ipp_delete_wksp - delete MIP presolver workspace.---- SYNOPSIS---- #include "glpipp.h"-- void ipp_delete_wksp(IPP *ipp);---- DESCRIPTION---- The routine ipp_delete_wksp deletes a MIP presolver workspace, which-- the parameter ipp points to, freeing all the memory allocated to this-- object. */void ipp_delete_wksp(IPP *ipp){     if (ipp->row_pool != NULL) dmp_delete_pool(ipp->row_pool);      if (ipp->col_pool != NULL) dmp_delete_pool(ipp->col_pool);      if (ipp->aij_pool != NULL) dmp_delete_pool(ipp->aij_pool);      if (ipp->tqe_pool != NULL) dmp_delete_pool(ipp->tqe_pool);      if (ipp->col_stat != NULL) xfree(ipp->col_stat);      if (ipp->col_mipx != NULL) xfree(ipp->col_mipx);      xfree(ipp);      return;}/* eof */

⌨️ 快捷键说明

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