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

📄 glpapi06.c

📁 著名的大规模线性规划求解器源码GLPK.C语言版本,可以修剪.内有详细帮助文档.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* glpapi06.c (simplex method routines) *//************************************************************************  This code is part of GLPK (GNU Linear Programming Kit).**  Copyright (C) 2000,01,02,03,04,05,06,07,08,2009 Andrew Makhorin,*  Department for Applied Informatics, Moscow Aviation Institute,*  Moscow, Russia. All rights reserved. E-mail: <mao@mai2.rcnet.ru>.**  GLPK is free software: you can redistribute it and/or modify it*  under the terms of the GNU General Public License as published by*  the Free Software Foundation, either version 3 of the License, or*  (at your option) any later version.**  GLPK is distributed in the hope that it will be useful, but WITHOUT*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY*  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public*  License for more details.**  You should have received a copy of the GNU General Public License*  along with GLPK. If not, see <http://www.gnu.org/licenses/>.***********************************************************************/#include "glpapi.h"#include "glplpp.h"#include "glpspx.h"/************************************************************************  NAME**  glp_simplex - solve LP problem with the simplex method**  SYNOPSIS**  int glp_simplex(glp_prob *lp, const glp_smcp *parm);**  DESCRIPTION**  The routine glp_simplex is a driver to the LP solver based on the*  simplex method. This routine retrieves problem data from the*  specified problem object, calls the solver to solve the problem*  instance, and stores results of computations back into the problem*  object.**  The simplex solver has a set of control parameters. Values of the*  control parameters can be passed in a structure glp_smcp, which the*  parameter parm points to.**  The parameter parm can be specified as NULL, in which case the LP*  solver uses default settings.**  RETURNS**  0  The LP problem instance has been successfully solved. This code*     does not necessarily mean that the solver has found optimal*     solution. It only means that the solution process was successful.**  GLP_EBADB*     Unable to start the search, because the initial basis specified*     in the problem object is invalid--the number of basic (auxiliary*     and structural) variables is not the same as the number of rows in*     the problem object.**  GLP_ESING*     Unable to start the search, because the basis matrix correspodning*     to the initial basis is singular within the working precision.**  GLP_ECOND*     Unable to start the search, because the basis matrix correspodning*     to the initial basis is ill-conditioned, i.e. its condition number*     is too large.**  GLP_EBOUND*     Unable to start the search, because some double-bounded variables*     have incorrect bounds.**  GLP_EFAIL*     The search was prematurely terminated due to the solver failure.**  GLP_EOBJLL*     The search was prematurely terminated, because the objective*     function being maximized has reached its lower limit and continues*     decreasing (dual simplex only).**  GLP_EOBJUL*     The search was prematurely terminated, because the objective*     function being minimized has reached its upper limit and continues*     increasing (dual simplex only).**  GLP_EITLIM*     The search was prematurely terminated, because the simplex*     iteration limit has been exceeded.**  GLP_ETMLIM*     The search was prematurely terminated, because the time limit has*     been exceeded.**  GLP_ENOPFS*     The LP problem instance has no primal feasible solution (only if*     the LP presolver is used).**  GLP_ENODFS*     The LP problem instance has no dual feasible solution (only if the*     LP presolver is used). */static void trivial1(glp_prob *lp, const glp_smcp *parm){     /* solve trivial LP problem which has no rows */      int j;      double dir;      xassert(lp->m == 0);      switch (lp->dir)      {  case GLP_MIN: dir = +1.0; break;         case GLP_MAX: dir = -1.0; break;         default:      xassert(lp != lp);      }      lp->pbs_stat = lp->dbs_stat = GLP_FEAS;      lp->obj_val = lp->c0;      lp->some = 0;      for (j = 1; j <= lp->n; j++)      {  GLPCOL *col = lp->col[j];         col->dual = col->coef;         switch (col->type)         {  case GLP_FR:               if (dir * col->dual < -1e-7)                  lp->dbs_stat = GLP_NOFEAS;               if (dir * col->dual > +1e-7)                  lp->dbs_stat = GLP_NOFEAS;               col->stat = GLP_NF;               col->prim = 0.0;               break;            case GLP_LO:               if (dir * col->dual < -1e-7)                  lp->dbs_stat = GLP_NOFEAS;lo:            col->stat = GLP_NL;               col->prim = col->lb;               break;            case GLP_UP:               if (dir * col->dual > +1e-7)                  lp->dbs_stat = GLP_NOFEAS;up:            col->stat = GLP_NU;               col->prim = col->ub;               break;            case GLP_DB:               if (dir * col->dual < 0.0) goto up;               if (dir * col->dual > 0.0) goto lo;               if (fabs(col->lb) <= fabs(col->ub))                  goto lo;               else                  goto up;            case GLP_FX:               col->stat = GLP_NS;               col->prim = col->lb;               break;            default:               xassert(lp != lp);         }         lp->obj_val += col->coef * col->prim;         if (lp->dbs_stat == GLP_NOFEAS && lp->some == 0)            lp->some = j;      }      if (parm->msg_lev >= GLP_MSG_ON && parm->out_dly == 0)      {  xprintf("~%6d:   objval = %17.9e   infeas = %17.9e\n",            lp->it_cnt, lp->obj_val, 0.0);         if (parm->msg_lev >= GLP_MSG_ALL)         {  if (lp->dbs_stat == GLP_FEAS)               xprintf("OPTIMAL SOLUTION FOUND\n");            else               xprintf("PROBLEM HAS UNBOUNDED SOLUTION\n");         }      }      return;}static void trivial2(glp_prob *lp, const glp_smcp *parm){     /* solve trivial LP problem which has no columns */      int i;      xassert(lp->n == 0);      lp->pbs_stat = lp->dbs_stat = GLP_FEAS;      lp->obj_val = lp->c0;      lp->some = 0;      for (i = 1; i <= lp->m; i++)      {  GLPROW *row = lp->row[i];         row->stat = GLP_BS;         row->prim = row->dual = 0.0;         switch (row->type)         {  case GLP_FR:               break;            case GLP_LO:               if (row->lb > +1e-8)                  lp->pbs_stat = GLP_NOFEAS;               break;            case GLP_UP:               if (row->ub < -1e-8)                  lp->pbs_stat = GLP_NOFEAS;               break;            case GLP_DB:            case GLP_FX:               if (row->lb > +1e-8)                  lp->pbs_stat = GLP_NOFEAS;               if (row->ub < -1e-8)                  lp->pbs_stat = GLP_NOFEAS;               break;            default:               xassert(lp != lp);         }      }      if (parm->msg_lev >= GLP_MSG_ON && parm->out_dly == 0)      {  xprintf("~%6d:   objval = %17.9e   infeas = %17.9e\n",            lp->it_cnt, lp->obj_val);         if (parm->msg_lev >= GLP_MSG_ALL)         {  if (lp->pbs_stat == GLP_FEAS)               xprintf("OPTIMAL SOLUTION FOUND\n");            else               xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n");         }      }      return;}#if 1 /* 18/VIII-2008 */static int simplex1(glp_prob *lp, const glp_smcp *parm){     /* base driver which does not use LP presolver */      int ret;      if (!glp_bf_exists(lp))      {  ret = glp_factorize(lp);         switch (ret)         {  case 0:               break;            case GLP_EBADB:               if (parm->msg_lev >= GLP_MSG_ERR)                  xprintf("glp_simplex: initial basis is invalid\n");               goto done;            case GLP_ESING:               if (parm->msg_lev >= GLP_MSG_ERR)                  xprintf("glp_simplex: initial basis is singular\n");               goto done;            case GLP_ECOND:               if (parm->msg_lev >= GLP_MSG_ERR)                  xprintf("glp_simplex: initial basis is ill-conditione"                     "d\n");               goto done;            default:               xassert(ret != ret);         }      }      switch (parm->meth)      {  case GLP_PRIMAL:            ret = spx_primal(lp, parm);            break;         case GLP_DUALP:            {  glp_smcp parm1 = *parm;#if 0               parm1.msg_lev = GLP_MSG_DBG;               parm1.out_frq = 1;               parm1.out_dly = 0;#endif               ret = spx_dual(lp, &parm1);#if 1               if (ret == GLP_EFAIL && lp->valid)                  ret = spx_primal(lp, parm);#endif            }            break;         case GLP_DUAL:            ret = spx_dual(lp, parm);            break;         default:            xassert(parm != parm);      }done: return ret;}#endifstatic int simplex2(glp_prob *orig, const glp_smcp *parm){     /* extended driver which uses LP presolver */      LPP *lpp;      glp_prob *prob;      glp_bfcp bfcp;      int orig_m, orig_n, orig_nnz, ret;      orig_m = glp_get_num_rows(orig);      orig_n = glp_get_num_cols(orig);      orig_nnz = glp_get_num_nz(orig);      if (parm->msg_lev >= GLP_MSG_ALL)      {  xprintf("glp_simplex: original LP has %d row%s, %d column%s, %"            "d non-zero%s\n",            orig_m, orig_m == 1 ? "" : "s",            orig_n, orig_n == 1 ? "" : "s",            orig_nnz, orig_nnz == 1 ? "" : "s");      }      /* the problem must have at least one row and one column */      xassert(orig_m > 0 && orig_n > 0);      /* create LP presolver workspace */      lpp = lpp_create_wksp();      /* load the original problem into LP presolver workspace */      lpp_load_orig(lpp, orig);      /* perform LP presolve analysis */      ret = lpp_presolve(lpp);      switch (ret)      {  case 0:            /* presolving has been successfully completed */            break;         case 1:            /* the original problem is primal infeasible */            if (parm->msg_lev >= GLP_MSG_ALL)               xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n");            lpp_delete_wksp(lpp);            return GLP_ENOPFS;         case 2:            /* the original problem is dual infeasible */            if (parm->msg_lev >= GLP_MSG_ALL)               xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n");            lpp_delete_wksp(lpp);            return GLP_ENODFS;         default:            xassert(ret != ret);      }      /* if the resultant problem is empty, it has an empty solution,         which is optimal */      if (lpp->row_ptr == NULL || lpp->col_ptr == NULL)      {  xassert(lpp->row_ptr == NULL);         xassert(lpp->col_ptr == NULL);         if (parm->msg_lev >= GLP_MSG_ALL)         {  xprintf("Objective value = %.10g\n",               lpp->orig_dir == LPX_MIN ? + lpp->c0 : - lpp->c0);            xprintf("OPTIMAL SOLUTION FOUND BY LP PRESOLVER\n");         }         /* allocate recovered solution segment */         lpp_alloc_sol(lpp);         goto post;      }      /* build resultant LP problem object */      prob = lpp_build_prob(lpp);      if (parm->msg_lev >= GLP_MSG_ALL)      {  int m = glp_get_num_rows(prob);         int n = glp_get_num_cols(prob);         int nnz = glp_get_num_nz(prob);         xprintf("glp_simplex: presolved LP has %d row%s, %d column%s, "            "%d non-zero%s\n", m, m == 1 ? "" : "s",            n, n == 1 ? "" : "s", nnz, nnz == 1 ? "" : "s");      }      /* inherit basis factorization control parameters */      glp_get_bfcp(orig, &bfcp);      glp_set_bfcp(prob, &bfcp);      /* scale the resultant problem */      {  LIBENV *env = lib_link_env();         int term_out = env->term_out;         if (!term_out || parm->msg_lev < GLP_MSG_ALL)            env->term_out = GLP_OFF;         else            env->term_out = GLP_ON;         glp_scale_prob(prob, GLP_SF_AUTO);         env->term_out = term_out;      }      /* build advanced initial basis */      {  LIBENV *env = lib_link_env();         int term_out = env->term_out;         if (!term_out || parm->msg_lev < GLP_MSG_ALL)            env->term_out = GLP_OFF;         else            env->term_out = GLP_ON;         lpx_adv_basis(prob);         env->term_out = term_out;      }      /* try to solve the resultant problem */      prob->it_cnt = orig->it_cnt;      ret = simplex1(prob, parm);      orig->it_cnt = prob->it_cnt;      /* check if the optimal solution has been found */      if (glp_get_status(prob) != GLP_OPT)      {  if (parm->msg_lev >= GLP_MSG_ERR)            xprintf("glp_simplex: cannot recover undefined or non-optim"               "al solution\n");         if (ret == 0)         {  if (glp_get_prim_stat(prob) == GLP_NOFEAS)               ret = GLP_ENOPFS;            else if (glp_get_dual_stat(prob) == GLP_NOFEAS)               ret = GLP_ENODFS;         }         glp_delete_prob(prob);         lpp_delete_wksp(lpp);         return ret;      }      /* allocate recovered solution segment */      lpp_alloc_sol(lpp);      /* load basic solution of the resultant problem into LP presolver         workspace */      lpp_load_sol(lpp, prob);      /* the resultant problem object is no longer needed */      glp_delete_prob(prob);post: /* perform LP postsolve processing */      lpp_postsolve(lpp);      /* unload recovered basic solution and store it into the original         problem object */      lpp_unload_sol(lpp, orig);      /* delete LP presolver workspace */      lpp_delete_wksp(lpp);      /* the original problem has been successfully solved */      return 0;}int glp_simplex(glp_prob *lp, const glp_smcp *parm){     glp_smcp _parm;      int i, j, ret;      if (parm == NULL)         parm = &_parm, glp_init_smcp((glp_smcp *)parm);      /* check control parameters */      if (!(parm->msg_lev == GLP_MSG_OFF ||            parm->msg_lev == GLP_MSG_ERR ||            parm->msg_lev == GLP_MSG_ON  ||            parm->msg_lev == GLP_MSG_ALL))         xerror("glp_simplex: msg_lev = %d; invalid parameter\n",            parm->msg_lev);      if (!(parm->meth == GLP_PRIMAL ||            parm->meth == GLP_DUALP  ||            parm->meth == GLP_DUAL))         xerror("glp_simplex: meth = %d; invalid parameter\n",            parm->meth);      if (!(parm->pricing == GLP_PT_STD ||

⌨️ 快捷键说明

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