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

📄 glpbfd.c

📁 著名的大规模线性规划求解器源码GLPK.C语言版本,可以修剪.内有详细帮助文档.
💻 C
字号:
/* glpbfd.c (LP basis factorization driver) *//************************************************************************  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/>.***********************************************************************/#define _GLPBFD_PRIVATE#include "glpbfd.h"#include "glplib.h"#define xfault xerror/* CAUTION: DO NOT CHANGE THE LIMIT BELOW */#define M_MAX 100000000 /* = 100*10^6 *//* maximal order of the basis matrix *//************************************************************************  NAME**  bfd_create_it - create LP basis factorization**  SYNOPSIS**  #include "glpbfd.h"*  BFD *bfd_create_it(void);**  DESCRIPTION**  The routine bfd_create_it creates a program object, which represents*  a factorization of LP basis.**  RETURNS**  The routine bfd_create_it returns a pointer to the object created. */BFD *bfd_create_it(void){     BFD *bfd;      bfd = xmalloc(sizeof(BFD));      bfd->valid = 0;      bfd->type = BFD_TFT;      bfd->fhv = NULL;      bfd->lpf = NULL;      bfd->lu_size = 0;      bfd->piv_tol = 0.10;      bfd->piv_lim = 4;      bfd->suhl = 1;      bfd->eps_tol = 1e-15;      bfd->max_gro = 1e+10;      bfd->nfs_max = 50;      bfd->upd_tol = 1e-6;      bfd->nrs_max = 50;      bfd->rs_size = 1000;      bfd->upd_lim = -1;      bfd->upd_cnt = 0;      return bfd;}/************************************************************************  NAME**  bfd_factorize - compute LP basis factorization**  SYNOPSIS**  #include "glpbfd.h"*  int bfd_factorize(BFD *bfd, int m, int bh[], int (*col)(void *info,*     int j, int ind[], double val[]), void *info);**  DESCRIPTION**  The routine bfd_factorize computes the factorization of the basis*  matrix B specified by the routine col.**  The parameter bfd specified the basis factorization data structure*  created with the routine bfd_create_it.**  The parameter m specifies the order of B, m > 0.**  The array bh specifies the basis header: bh[j], 1 <= j <= m, is the*  number of j-th column of B in some original matrix. The array bh is*  optional and can be specified as NULL.**  The formal routine col specifies the matrix B to be factorized. To*  obtain j-th column of A the routine bfd_factorize calls the routine*  col with the parameter j (1 <= j <= n). In response the routine col*  should store row indices and numerical values of non-zero elements*  of j-th column of B to locations ind[1,...,len] and val[1,...,len],*  respectively, where len is the number of non-zeros in j-th column*  returned on exit. Neither zero nor duplicate elements are allowed.**  The parameter info is a transit pointer passed to the routine col.**  RETURNS**  0  The factorization has been successfully computed.**  BFD_ESING*     The specified matrix is singular within the working precision.**  BFD_ECOND*     The specified matrix is ill-conditioned.**  For more details see comments to the routine luf_factorize. */int bfd_factorize(BFD *bfd, int m, const int bh[], int (*col)      (void *info, int j, int ind[], double val[]), void *info){     LUF *luf;      int nov, ret;      if (m < 1)         xfault("bfd_factorize: m = %d; invalid parameter\n", m);      if (m > M_MAX)         xfault("bfd_factorize: m = %d; matrix too big\n", m);      /* invalidate the factorization */      bfd->valid = 0;      /* create the factorization, if necessary */      nov = 0;      switch (bfd->type)      {  case BFD_TFT:            if (bfd->lpf != NULL)               lpf_delete_it(bfd->lpf), bfd->lpf = NULL;            if (bfd->fhv == NULL)               bfd->fhv = fhv_create_it(), nov = 1;            break;         case BFD_TBG:         case BFD_TGR:            if (bfd->fhv != NULL)               fhv_delete_it(bfd->fhv), bfd->fhv = NULL;            if (bfd->lpf == NULL)               bfd->lpf = lpf_create_it(), nov = 1;            break;         default:            xfault("bfd_factorize: bfd->type = %d; invalid factorizatio"               "n type\n", bfd->type);      }      /* set control parameters specific to LUF */      if (bfd->fhv != NULL)         luf = bfd->fhv->luf;      else if (bfd->lpf != NULL)         luf = bfd->lpf->luf;      else         xassert(bfd != bfd);      if (nov) luf->new_sva = bfd->lu_size;      luf->piv_tol = bfd->piv_tol;      luf->piv_lim = bfd->piv_lim;      luf->suhl = bfd->suhl;      luf->eps_tol = bfd->eps_tol;      luf->max_gro = bfd->max_gro;      /* set control parameters specific to FHV */      if (bfd->fhv != NULL)      {  if (nov) bfd->fhv->hh_max = bfd->nfs_max;         bfd->fhv->upd_tol = bfd->upd_tol;      }      /* set control parameters specific to LPF */      if (bfd->lpf != NULL)      {  if (nov) bfd->lpf->n_max = bfd->nrs_max;         if (nov) bfd->lpf->v_size = bfd->rs_size;      }      /* try to factorize the basis matrix */      if (bfd->fhv != NULL)      {  switch (fhv_factorize(bfd->fhv, m, col, info))         {  case 0:               break;            case FHV_ESING:               ret = BFD_ESING;               goto done;            case FHV_ECOND:               ret = BFD_ECOND;               goto done;            default:               xassert(bfd != bfd);         }      }      else if (bfd->lpf != NULL)      {  switch (lpf_factorize(bfd->lpf, m, bh, col, info))         {  case 0:               /* set the Schur complement update type */               switch (bfd->type)               {  case BFD_TBG:                     /* Bartels-Golub update */                     bfd->lpf->scf->t_opt = SCF_TBG;                     break;                  case BFD_TGR:                     /* Givens rotation update */                     bfd->lpf->scf->t_opt = SCF_TGR;                     break;                  default:                     xassert(bfd != bfd);               }               break;            case LPF_ESING:               ret = BFD_ESING;               goto done;            case LPF_ECOND:               ret = BFD_ECOND;               goto done;            default:               xassert(bfd != bfd);         }      }      else         xassert(bfd != bfd);      /* the basis matrix has been successfully factorized */      bfd->valid = 1;      bfd->upd_cnt = 0;      ret = 0;done: /* return to the calling program */      return ret;}/************************************************************************  NAME**  bfd_ftran - perform forward transformation (solve system B*x = b)**  SYNOPSIS**  #include "glpbfd.h"*  void bfd_ftran(BFD *bfd, double x[]);**  DESCRIPTION**  The routine bfd_ftran performs forward transformation, i.e. solves*  the system B*x = b, where B is the basis matrix, x is the vector of*  unknowns to be computed, b is the vector of right-hand sides.**  On entry elements of the vector b should be stored in dense format*  in locations x[1], ..., x[m], where m is the number of rows. On exit*  the routine stores elements of the vector x in the same locations. */void bfd_ftran(BFD *bfd, double x[]){     if (!bfd->valid)         xfault("bfd_ftran: the factorization is not valid\n");      if (bfd->fhv != NULL)         fhv_ftran(bfd->fhv, x);      else if (bfd->lpf != NULL)         lpf_ftran(bfd->lpf, x);      else         xassert(bfd != bfd);      return;}/************************************************************************  NAME**  bfd_btran - perform backward transformation (solve system B'*x = b)**  SYNOPSIS**  #include "glpbfd.h"*  void bfd_btran(BFD *bfd, double x[]);**  DESCRIPTION**  The routine bfd_btran performs backward transformation, i.e. solves*  the system B'*x = b, where B' is a matrix transposed to the basis*  matrix B, x is the vector of unknowns to be computed, b is the vector*  of right-hand sides.**  On entry elements of the vector b should be stored in dense format*  in locations x[1], ..., x[m], where m is the number of rows. On exit*  the routine stores elements of the vector x in the same locations. */void bfd_btran(BFD *bfd, double x[]){     if (!bfd->valid)         xfault("bfd_btran: the factorization is not valid\n");      if (bfd->fhv != NULL)         fhv_btran(bfd->fhv, x);      else if (bfd->lpf != NULL)         lpf_btran(bfd->lpf, x);      else         xassert(bfd != bfd);      return;}/************************************************************************  NAME**  bfd_update_it - update LP basis factorization**  SYNOPSIS**  #include "glpbfd.h"*  int bfd_update_it(BFD *bfd, int j, int bh, int len, const int ind[],*     const double val[]);**  DESCRIPTION**  The routine bfd_update_it updates the factorization of the basis*  matrix B after replacing its j-th column by a new vector.**  The parameter j specifies the number of column of B, which has been*  replaced, 1 <= j <= m, where m is the order of B.**  The parameter bh specifies the basis header entry for the new column*  of B, which is the number of the new column in some original matrix.*  This parameter is optional and can be specified as 0.**  Row indices and numerical values of non-zero elements of the new*  column of B should be placed in locations ind[1], ..., ind[len] and*  val[1], ..., val[len], resp., where len is the number of non-zeros*  in the column. Neither zero nor duplicate elements are allowed.**  RETURNS**  0  The factorization has been successfully updated.**  BFD_ESING*     New basis matrix is singular within the working precision.**  BFD_ECHECK*     The factorization is inaccurate.**  BFD_ELIMIT*     Factorization update limit has been reached.**  BFD_EROOM*     Overflow of the sparse vector area.**  In case of non-zero return code the factorization becomes invalid.*  It should not be used until it has been recomputed with the routine*  bfd_factorize. */int bfd_update_it(BFD *bfd, int j, int bh, int len, const int ind[],      const double val[]){     int ret;      if (!bfd->valid)         xfault("bfd_update_it: the factorization is not valid\n");      /* try to update the factorization */      if (bfd->fhv != NULL)      {  switch (fhv_update_it(bfd->fhv, j, len, ind, val))         {  case 0:               break;            case FHV_ESING:               bfd->valid = 0;               ret = BFD_ESING;               goto done;            case FHV_ECHECK:               bfd->valid = 0;               ret = BFD_ECHECK;               goto done;            case FHV_ELIMIT:               bfd->valid = 0;               ret = BFD_ELIMIT;               goto done;            case FHV_EROOM:               bfd->valid = 0;               ret = BFD_EROOM;               goto done;            default:               xassert(bfd != bfd);         }      }      else if (bfd->lpf != NULL)      {  switch (lpf_update_it(bfd->lpf, j, bh, len, ind, val))         {  case 0:               break;            case LPF_ESING:               bfd->valid = 0;               ret = BFD_ESING;               goto done;            case LPF_ELIMIT:               bfd->valid = 0;               ret = BFD_ELIMIT;               goto done;            default:               xassert(bfd != bfd);         }      }      else         xassert(bfd != bfd);      /* the factorization has been successfully updated */      /* increase the update count */      bfd->upd_cnt++;      ret = 0;done: /* return to the calling program */      return ret;}/************************************************************************  NAME**  bfd_delete_it - delete LP basis factorization**  SYNOPSIS**  #include "glpbfd.h"*  void bfd_delete_it(BFD *bfd);**  DESCRIPTION**  The routine bfd_delete_it deletes LP basis factorization specified*  by the parameter fhv and frees all memory allocated to this program*  object. */void bfd_delete_it(BFD *bfd){     if (bfd->fhv != NULL) fhv_delete_it(bfd->fhv);      if (bfd->lpf != NULL) lpf_delete_it(bfd->lpf);      xfree(bfd);      return;}/* eof */

⌨️ 快捷键说明

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