[1] | 1 | /* glpspx02.c (dual simplex method) */ |
---|
| 2 | |
---|
| 3 | /*********************************************************************** |
---|
| 4 | * This code is part of GLPK (GNU Linear Programming Kit). |
---|
| 5 | * |
---|
| 6 | * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, |
---|
| 7 | * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, |
---|
| 8 | * Moscow Aviation Institute, Moscow, Russia. All rights reserved. |
---|
| 9 | * E-mail: <mao@gnu.org>. |
---|
| 10 | * |
---|
| 11 | * GLPK is free software: you can redistribute it and/or modify it |
---|
| 12 | * under the terms of the GNU General Public License as published by |
---|
| 13 | * the Free Software Foundation, either version 3 of the License, or |
---|
| 14 | * (at your option) any later version. |
---|
| 15 | * |
---|
| 16 | * GLPK is distributed in the hope that it will be useful, but WITHOUT |
---|
| 17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
---|
| 18 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
---|
| 19 | * License for more details. |
---|
| 20 | * |
---|
| 21 | * You should have received a copy of the GNU General Public License |
---|
| 22 | * along with GLPK. If not, see <http://www.gnu.org/licenses/>. |
---|
| 23 | ***********************************************************************/ |
---|
| 24 | |
---|
| 25 | #include "glpspx.h" |
---|
| 26 | |
---|
| 27 | #define GLP_DEBUG 1 |
---|
| 28 | |
---|
| 29 | #if 0 |
---|
| 30 | #define GLP_LONG_STEP 1 |
---|
| 31 | #endif |
---|
| 32 | |
---|
| 33 | struct csa |
---|
| 34 | { /* common storage area */ |
---|
| 35 | /*--------------------------------------------------------------*/ |
---|
| 36 | /* LP data */ |
---|
| 37 | int m; |
---|
| 38 | /* number of rows (auxiliary variables), m > 0 */ |
---|
| 39 | int n; |
---|
| 40 | /* number of columns (structural variables), n > 0 */ |
---|
| 41 | char *type; /* char type[1+m+n]; */ |
---|
| 42 | /* type[0] is not used; |
---|
| 43 | type[k], 1 <= k <= m+n, is the type of variable x[k]: |
---|
| 44 | GLP_FR - free variable |
---|
| 45 | GLP_LO - variable with lower bound |
---|
| 46 | GLP_UP - variable with upper bound |
---|
| 47 | GLP_DB - double-bounded variable |
---|
| 48 | GLP_FX - fixed variable */ |
---|
| 49 | double *lb; /* double lb[1+m+n]; */ |
---|
| 50 | /* lb[0] is not used; |
---|
| 51 | lb[k], 1 <= k <= m+n, is an lower bound of variable x[k]; |
---|
| 52 | if x[k] has no lower bound, lb[k] is zero */ |
---|
| 53 | double *ub; /* double ub[1+m+n]; */ |
---|
| 54 | /* ub[0] is not used; |
---|
| 55 | ub[k], 1 <= k <= m+n, is an upper bound of variable x[k]; |
---|
| 56 | if x[k] has no upper bound, ub[k] is zero; |
---|
| 57 | if x[k] is of fixed type, ub[k] is the same as lb[k] */ |
---|
| 58 | double *coef; /* double coef[1+m+n]; */ |
---|
| 59 | /* coef[0] is not used; |
---|
| 60 | coef[k], 1 <= k <= m+n, is an objective coefficient at |
---|
| 61 | variable x[k] */ |
---|
| 62 | /*--------------------------------------------------------------*/ |
---|
| 63 | /* original bounds of variables */ |
---|
| 64 | char *orig_type; /* char orig_type[1+m+n]; */ |
---|
| 65 | double *orig_lb; /* double orig_lb[1+m+n]; */ |
---|
| 66 | double *orig_ub; /* double orig_ub[1+m+n]; */ |
---|
| 67 | /*--------------------------------------------------------------*/ |
---|
| 68 | /* original objective function */ |
---|
| 69 | double *obj; /* double obj[1+n]; */ |
---|
| 70 | /* obj[0] is a constant term of the original objective function; |
---|
| 71 | obj[j], 1 <= j <= n, is an original objective coefficient at |
---|
| 72 | structural variable x[m+j] */ |
---|
| 73 | double zeta; |
---|
| 74 | /* factor used to scale original objective coefficients; its |
---|
| 75 | sign defines original optimization direction: zeta > 0 means |
---|
| 76 | minimization, zeta < 0 means maximization */ |
---|
| 77 | /*--------------------------------------------------------------*/ |
---|
| 78 | /* constraint matrix A; it has m rows and n columns and is stored |
---|
| 79 | by columns */ |
---|
| 80 | int *A_ptr; /* int A_ptr[1+n+1]; */ |
---|
| 81 | /* A_ptr[0] is not used; |
---|
| 82 | A_ptr[j], 1 <= j <= n, is starting position of j-th column in |
---|
| 83 | arrays A_ind and A_val; note that A_ptr[1] is always 1; |
---|
| 84 | A_ptr[n+1] indicates the position after the last element in |
---|
| 85 | arrays A_ind and A_val */ |
---|
| 86 | int *A_ind; /* int A_ind[A_ptr[n+1]]; */ |
---|
| 87 | /* row indices */ |
---|
| 88 | double *A_val; /* double A_val[A_ptr[n+1]]; */ |
---|
| 89 | /* non-zero element values */ |
---|
| 90 | #if 1 /* 06/IV-2009 */ |
---|
| 91 | /* constraint matrix A stored by rows */ |
---|
| 92 | int *AT_ptr; /* int AT_ptr[1+m+1]; |
---|
| 93 | /* AT_ptr[0] is not used; |
---|
| 94 | AT_ptr[i], 1 <= i <= m, is starting position of i-th row in |
---|
| 95 | arrays AT_ind and AT_val; note that AT_ptr[1] is always 1; |
---|
| 96 | AT_ptr[m+1] indicates the position after the last element in |
---|
| 97 | arrays AT_ind and AT_val */ |
---|
| 98 | int *AT_ind; /* int AT_ind[AT_ptr[m+1]]; */ |
---|
| 99 | /* column indices */ |
---|
| 100 | double *AT_val; /* double AT_val[AT_ptr[m+1]]; */ |
---|
| 101 | /* non-zero element values */ |
---|
| 102 | #endif |
---|
| 103 | /*--------------------------------------------------------------*/ |
---|
| 104 | /* basis header */ |
---|
| 105 | int *head; /* int head[1+m+n]; */ |
---|
| 106 | /* head[0] is not used; |
---|
| 107 | head[i], 1 <= i <= m, is the ordinal number of basic variable |
---|
| 108 | xB[i]; head[i] = k means that xB[i] = x[k] and i-th column of |
---|
| 109 | matrix B is k-th column of matrix (I|-A); |
---|
| 110 | head[m+j], 1 <= j <= n, is the ordinal number of non-basic |
---|
| 111 | variable xN[j]; head[m+j] = k means that xN[j] = x[k] and j-th |
---|
| 112 | column of matrix N is k-th column of matrix (I|-A) */ |
---|
| 113 | #if 1 /* 06/IV-2009 */ |
---|
| 114 | int *bind; /* int bind[1+m+n]; */ |
---|
| 115 | /* bind[0] is not used; |
---|
| 116 | bind[k], 1 <= k <= m+n, is the position of k-th column of the |
---|
| 117 | matrix (I|-A) in the matrix (B|N); that is, bind[k] = k' means |
---|
| 118 | that head[k'] = k */ |
---|
| 119 | #endif |
---|
| 120 | char *stat; /* char stat[1+n]; */ |
---|
| 121 | /* stat[0] is not used; |
---|
| 122 | stat[j], 1 <= j <= n, is the status of non-basic variable |
---|
| 123 | xN[j], which defines its active bound: |
---|
| 124 | GLP_NL - lower bound is active |
---|
| 125 | GLP_NU - upper bound is active |
---|
| 126 | GLP_NF - free variable |
---|
| 127 | GLP_NS - fixed variable */ |
---|
| 128 | /*--------------------------------------------------------------*/ |
---|
| 129 | /* matrix B is the basis matrix; it is composed from columns of |
---|
| 130 | the augmented constraint matrix (I|-A) corresponding to basic |
---|
| 131 | variables and stored in a factorized (invertable) form */ |
---|
| 132 | int valid; |
---|
| 133 | /* factorization is valid only if this flag is set */ |
---|
| 134 | BFD *bfd; /* BFD bfd[1:m,1:m]; */ |
---|
| 135 | /* factorized (invertable) form of the basis matrix */ |
---|
| 136 | #if 0 /* 06/IV-2009 */ |
---|
| 137 | /*--------------------------------------------------------------*/ |
---|
| 138 | /* matrix N is a matrix composed from columns of the augmented |
---|
| 139 | constraint matrix (I|-A) corresponding to non-basic variables |
---|
| 140 | except fixed ones; it is stored by rows and changes every time |
---|
| 141 | the basis changes */ |
---|
| 142 | int *N_ptr; /* int N_ptr[1+m+1]; */ |
---|
| 143 | /* N_ptr[0] is not used; |
---|
| 144 | N_ptr[i], 1 <= i <= m, is starting position of i-th row in |
---|
| 145 | arrays N_ind and N_val; note that N_ptr[1] is always 1; |
---|
| 146 | N_ptr[m+1] indicates the position after the last element in |
---|
| 147 | arrays N_ind and N_val */ |
---|
| 148 | int *N_len; /* int N_len[1+m]; */ |
---|
| 149 | /* N_len[0] is not used; |
---|
| 150 | N_len[i], 1 <= i <= m, is length of i-th row (0 to n) */ |
---|
| 151 | int *N_ind; /* int N_ind[N_ptr[m+1]]; */ |
---|
| 152 | /* column indices */ |
---|
| 153 | double *N_val; /* double N_val[N_ptr[m+1]]; */ |
---|
| 154 | /* non-zero element values */ |
---|
| 155 | #endif |
---|
| 156 | /*--------------------------------------------------------------*/ |
---|
| 157 | /* working parameters */ |
---|
| 158 | int phase; |
---|
| 159 | /* search phase: |
---|
| 160 | 0 - not determined yet |
---|
| 161 | 1 - search for dual feasible solution |
---|
| 162 | 2 - search for optimal solution */ |
---|
| 163 | glp_long tm_beg; |
---|
| 164 | /* time value at the beginning of the search */ |
---|
| 165 | int it_beg; |
---|
| 166 | /* simplex iteration count at the beginning of the search */ |
---|
| 167 | int it_cnt; |
---|
| 168 | /* simplex iteration count; it increases by one every time the |
---|
| 169 | basis changes */ |
---|
| 170 | int it_dpy; |
---|
| 171 | /* simplex iteration count at the most recent display output */ |
---|
| 172 | /*--------------------------------------------------------------*/ |
---|
| 173 | /* basic solution components */ |
---|
| 174 | double *bbar; /* double bbar[1+m]; */ |
---|
| 175 | /* bbar[0] is not used on phase I; on phase II it is the current |
---|
| 176 | value of the original objective function; |
---|
| 177 | bbar[i], 1 <= i <= m, is primal value of basic variable xB[i] |
---|
| 178 | (if xB[i] is free, its primal value is not updated) */ |
---|
| 179 | double *cbar; /* double cbar[1+n]; */ |
---|
| 180 | /* cbar[0] is not used; |
---|
| 181 | cbar[j], 1 <= j <= n, is reduced cost of non-basic variable |
---|
| 182 | xN[j] (if xN[j] is fixed, its reduced cost is not updated) */ |
---|
| 183 | /*--------------------------------------------------------------*/ |
---|
| 184 | /* the following pricing technique options may be used: |
---|
| 185 | GLP_PT_STD - standard ("textbook") pricing; |
---|
| 186 | GLP_PT_PSE - projected steepest edge; |
---|
| 187 | GLP_PT_DVX - Devex pricing (not implemented yet); |
---|
| 188 | in case of GLP_PT_STD the reference space is not used, and all |
---|
| 189 | steepest edge coefficients are set to 1 */ |
---|
| 190 | int refct; |
---|
| 191 | /* this count is set to an initial value when the reference space |
---|
| 192 | is defined and decreases by one every time the basis changes; |
---|
| 193 | once this count reaches zero, the reference space is redefined |
---|
| 194 | again */ |
---|
| 195 | char *refsp; /* char refsp[1+m+n]; */ |
---|
| 196 | /* refsp[0] is not used; |
---|
| 197 | refsp[k], 1 <= k <= m+n, is the flag which means that variable |
---|
| 198 | x[k] belongs to the current reference space */ |
---|
| 199 | double *gamma; /* double gamma[1+m]; */ |
---|
| 200 | /* gamma[0] is not used; |
---|
| 201 | gamma[i], 1 <= i <= n, is the steepest edge coefficient for |
---|
| 202 | basic variable xB[i]; if xB[i] is free, gamma[i] is not used |
---|
| 203 | and just set to 1 */ |
---|
| 204 | /*--------------------------------------------------------------*/ |
---|
| 205 | /* basic variable xB[p] chosen to leave the basis */ |
---|
| 206 | int p; |
---|
| 207 | /* index of the basic variable xB[p] chosen, 1 <= p <= m; |
---|
| 208 | if the set of eligible basic variables is empty (i.e. if the |
---|
| 209 | current basic solution is primal feasible within a tolerance) |
---|
| 210 | and thus no variable has been chosen, p is set to 0 */ |
---|
| 211 | double delta; |
---|
| 212 | /* change of xB[p] in the adjacent basis; |
---|
| 213 | delta > 0 means that xB[p] violates its lower bound and will |
---|
| 214 | increase to achieve it in the adjacent basis; |
---|
| 215 | delta < 0 means that xB[p] violates its upper bound and will |
---|
| 216 | decrease to achieve it in the adjacent basis */ |
---|
| 217 | /*--------------------------------------------------------------*/ |
---|
| 218 | /* pivot row of the simplex table corresponding to basic variable |
---|
| 219 | xB[p] chosen is the following vector: |
---|
| 220 | T' * e[p] = - N' * inv(B') * e[p] = - N' * rho, |
---|
| 221 | where B' is a matrix transposed to the current basis matrix, |
---|
| 222 | N' is a matrix, whose rows are columns of the matrix (I|-A) |
---|
| 223 | corresponding to non-basic non-fixed variables */ |
---|
| 224 | int trow_nnz; |
---|
| 225 | /* number of non-zero components, 0 <= nnz <= n */ |
---|
| 226 | int *trow_ind; /* int trow_ind[1+n]; */ |
---|
| 227 | /* trow_ind[0] is not used; |
---|
| 228 | trow_ind[t], 1 <= t <= nnz, is an index of non-zero component, |
---|
| 229 | i.e. trow_ind[t] = j means that trow_vec[j] != 0 */ |
---|
| 230 | double *trow_vec; /* int trow_vec[1+n]; */ |
---|
| 231 | /* trow_vec[0] is not used; |
---|
| 232 | trow_vec[j], 1 <= j <= n, is a numeric value of j-th component |
---|
| 233 | of the row */ |
---|
| 234 | double trow_max; |
---|
| 235 | /* infinity (maximum) norm of the row (max |trow_vec[j]|) */ |
---|
| 236 | int trow_num; |
---|
| 237 | /* number of significant non-zero components, which means that: |
---|
| 238 | |trow_vec[j]| >= eps for j in trow_ind[1,...,num], |
---|
| 239 | |tcol_vec[j]| < eps for j in trow_ind[num+1,...,nnz], |
---|
| 240 | where eps is a pivot tolerance */ |
---|
| 241 | /*--------------------------------------------------------------*/ |
---|
| 242 | #ifdef GLP_LONG_STEP /* 07/IV-2009 */ |
---|
| 243 | int nbps; |
---|
| 244 | /* number of breakpoints, 0 <= nbps <= n */ |
---|
| 245 | struct bkpt |
---|
| 246 | { int j; |
---|
| 247 | /* index of non-basic variable xN[j], 1 <= j <= n */ |
---|
| 248 | double t; |
---|
| 249 | /* value of dual ray parameter at breakpoint, t >= 0 */ |
---|
| 250 | double dz; |
---|
| 251 | /* dz = zeta(t = t[k]) - zeta(t = 0) */ |
---|
| 252 | } *bkpt; /* struct bkpt bkpt[1+n]; */ |
---|
| 253 | /* bkpt[0] is not used; |
---|
| 254 | bkpt[k], 1 <= k <= nbps, is k-th breakpoint of the dual |
---|
| 255 | objective */ |
---|
| 256 | #endif |
---|
| 257 | /*--------------------------------------------------------------*/ |
---|
| 258 | /* non-basic variable xN[q] chosen to enter the basis */ |
---|
| 259 | int q; |
---|
| 260 | /* index of the non-basic variable xN[q] chosen, 1 <= q <= n; |
---|
| 261 | if no variable has been chosen, q is set to 0 */ |
---|
| 262 | double new_dq; |
---|
| 263 | /* reduced cost of xN[q] in the adjacent basis (it is the change |
---|
| 264 | of lambdaB[p]) */ |
---|
| 265 | /*--------------------------------------------------------------*/ |
---|
| 266 | /* pivot column of the simplex table corresponding to non-basic |
---|
| 267 | variable xN[q] chosen is the following vector: |
---|
| 268 | T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], |
---|
| 269 | where B is the current basis matrix, N[q] is a column of the |
---|
| 270 | matrix (I|-A) corresponding to xN[q] */ |
---|
| 271 | int tcol_nnz; |
---|
| 272 | /* number of non-zero components, 0 <= nnz <= m */ |
---|
| 273 | int *tcol_ind; /* int tcol_ind[1+m]; */ |
---|
| 274 | /* tcol_ind[0] is not used; |
---|
| 275 | tcol_ind[t], 1 <= t <= nnz, is an index of non-zero component, |
---|
| 276 | i.e. tcol_ind[t] = i means that tcol_vec[i] != 0 */ |
---|
| 277 | double *tcol_vec; /* double tcol_vec[1+m]; */ |
---|
| 278 | /* tcol_vec[0] is not used; |
---|
| 279 | tcol_vec[i], 1 <= i <= m, is a numeric value of i-th component |
---|
| 280 | of the column */ |
---|
| 281 | /*--------------------------------------------------------------*/ |
---|
| 282 | /* working arrays */ |
---|
| 283 | double *work1; /* double work1[1+m]; */ |
---|
| 284 | double *work2; /* double work2[1+m]; */ |
---|
| 285 | double *work3; /* double work3[1+m]; */ |
---|
| 286 | double *work4; /* double work4[1+m]; */ |
---|
| 287 | }; |
---|
| 288 | |
---|
| 289 | static const double kappa = 0.10; |
---|
| 290 | |
---|
| 291 | /*********************************************************************** |
---|
| 292 | * alloc_csa - allocate common storage area |
---|
| 293 | * |
---|
| 294 | * This routine allocates all arrays in the common storage area (CSA) |
---|
| 295 | * and returns a pointer to the CSA. */ |
---|
| 296 | |
---|
| 297 | static struct csa *alloc_csa(glp_prob *lp) |
---|
| 298 | { struct csa *csa; |
---|
| 299 | int m = lp->m; |
---|
| 300 | int n = lp->n; |
---|
| 301 | int nnz = lp->nnz; |
---|
| 302 | csa = xmalloc(sizeof(struct csa)); |
---|
| 303 | xassert(m > 0 && n > 0); |
---|
| 304 | csa->m = m; |
---|
| 305 | csa->n = n; |
---|
| 306 | csa->type = xcalloc(1+m+n, sizeof(char)); |
---|
| 307 | csa->lb = xcalloc(1+m+n, sizeof(double)); |
---|
| 308 | csa->ub = xcalloc(1+m+n, sizeof(double)); |
---|
| 309 | csa->coef = xcalloc(1+m+n, sizeof(double)); |
---|
| 310 | csa->orig_type = xcalloc(1+m+n, sizeof(char)); |
---|
| 311 | csa->orig_lb = xcalloc(1+m+n, sizeof(double)); |
---|
| 312 | csa->orig_ub = xcalloc(1+m+n, sizeof(double)); |
---|
| 313 | csa->obj = xcalloc(1+n, sizeof(double)); |
---|
| 314 | csa->A_ptr = xcalloc(1+n+1, sizeof(int)); |
---|
| 315 | csa->A_ind = xcalloc(1+nnz, sizeof(int)); |
---|
| 316 | csa->A_val = xcalloc(1+nnz, sizeof(double)); |
---|
| 317 | #if 1 /* 06/IV-2009 */ |
---|
| 318 | csa->AT_ptr = xcalloc(1+m+1, sizeof(int)); |
---|
| 319 | csa->AT_ind = xcalloc(1+nnz, sizeof(int)); |
---|
| 320 | csa->AT_val = xcalloc(1+nnz, sizeof(double)); |
---|
| 321 | #endif |
---|
| 322 | csa->head = xcalloc(1+m+n, sizeof(int)); |
---|
| 323 | #if 1 /* 06/IV-2009 */ |
---|
| 324 | csa->bind = xcalloc(1+m+n, sizeof(int)); |
---|
| 325 | #endif |
---|
| 326 | csa->stat = xcalloc(1+n, sizeof(char)); |
---|
| 327 | #if 0 /* 06/IV-2009 */ |
---|
| 328 | csa->N_ptr = xcalloc(1+m+1, sizeof(int)); |
---|
| 329 | csa->N_len = xcalloc(1+m, sizeof(int)); |
---|
| 330 | csa->N_ind = NULL; /* will be allocated later */ |
---|
| 331 | csa->N_val = NULL; /* will be allocated later */ |
---|
| 332 | #endif |
---|
| 333 | csa->bbar = xcalloc(1+m, sizeof(double)); |
---|
| 334 | csa->cbar = xcalloc(1+n, sizeof(double)); |
---|
| 335 | csa->refsp = xcalloc(1+m+n, sizeof(char)); |
---|
| 336 | csa->gamma = xcalloc(1+m, sizeof(double)); |
---|
| 337 | csa->trow_ind = xcalloc(1+n, sizeof(int)); |
---|
| 338 | csa->trow_vec = xcalloc(1+n, sizeof(double)); |
---|
| 339 | #ifdef GLP_LONG_STEP /* 07/IV-2009 */ |
---|
| 340 | csa->bkpt = xcalloc(1+n, sizeof(struct bkpt)); |
---|
| 341 | #endif |
---|
| 342 | csa->tcol_ind = xcalloc(1+m, sizeof(int)); |
---|
| 343 | csa->tcol_vec = xcalloc(1+m, sizeof(double)); |
---|
| 344 | csa->work1 = xcalloc(1+m, sizeof(double)); |
---|
| 345 | csa->work2 = xcalloc(1+m, sizeof(double)); |
---|
| 346 | csa->work3 = xcalloc(1+m, sizeof(double)); |
---|
| 347 | csa->work4 = xcalloc(1+m, sizeof(double)); |
---|
| 348 | return csa; |
---|
| 349 | } |
---|
| 350 | |
---|
| 351 | /*********************************************************************** |
---|
| 352 | * init_csa - initialize common storage area |
---|
| 353 | * |
---|
| 354 | * This routine initializes all data structures in the common storage |
---|
| 355 | * area (CSA). */ |
---|
| 356 | |
---|
| 357 | static void init_csa(struct csa *csa, glp_prob *lp) |
---|
| 358 | { int m = csa->m; |
---|
| 359 | int n = csa->n; |
---|
| 360 | char *type = csa->type; |
---|
| 361 | double *lb = csa->lb; |
---|
| 362 | double *ub = csa->ub; |
---|
| 363 | double *coef = csa->coef; |
---|
| 364 | char *orig_type = csa->orig_type; |
---|
| 365 | double *orig_lb = csa->orig_lb; |
---|
| 366 | double *orig_ub = csa->orig_ub; |
---|
| 367 | double *obj = csa->obj; |
---|
| 368 | int *A_ptr = csa->A_ptr; |
---|
| 369 | int *A_ind = csa->A_ind; |
---|
| 370 | double *A_val = csa->A_val; |
---|
| 371 | #if 1 /* 06/IV-2009 */ |
---|
| 372 | int *AT_ptr = csa->AT_ptr; |
---|
| 373 | int *AT_ind = csa->AT_ind; |
---|
| 374 | double *AT_val = csa->AT_val; |
---|
| 375 | #endif |
---|
| 376 | int *head = csa->head; |
---|
| 377 | #if 1 /* 06/IV-2009 */ |
---|
| 378 | int *bind = csa->bind; |
---|
| 379 | #endif |
---|
| 380 | char *stat = csa->stat; |
---|
| 381 | char *refsp = csa->refsp; |
---|
| 382 | double *gamma = csa->gamma; |
---|
| 383 | int i, j, k, loc; |
---|
| 384 | double cmax; |
---|
| 385 | /* auxiliary variables */ |
---|
| 386 | for (i = 1; i <= m; i++) |
---|
| 387 | { GLPROW *row = lp->row[i]; |
---|
| 388 | type[i] = (char)row->type; |
---|
| 389 | lb[i] = row->lb * row->rii; |
---|
| 390 | ub[i] = row->ub * row->rii; |
---|
| 391 | coef[i] = 0.0; |
---|
| 392 | } |
---|
| 393 | /* structural variables */ |
---|
| 394 | for (j = 1; j <= n; j++) |
---|
| 395 | { GLPCOL *col = lp->col[j]; |
---|
| 396 | type[m+j] = (char)col->type; |
---|
| 397 | lb[m+j] = col->lb / col->sjj; |
---|
| 398 | ub[m+j] = col->ub / col->sjj; |
---|
| 399 | coef[m+j] = col->coef * col->sjj; |
---|
| 400 | } |
---|
| 401 | /* original bounds of variables */ |
---|
| 402 | memcpy(&orig_type[1], &type[1], (m+n) * sizeof(char)); |
---|
| 403 | memcpy(&orig_lb[1], &lb[1], (m+n) * sizeof(double)); |
---|
| 404 | memcpy(&orig_ub[1], &ub[1], (m+n) * sizeof(double)); |
---|
| 405 | /* original objective function */ |
---|
| 406 | obj[0] = lp->c0; |
---|
| 407 | memcpy(&obj[1], &coef[m+1], n * sizeof(double)); |
---|
| 408 | /* factor used to scale original objective coefficients */ |
---|
| 409 | cmax = 0.0; |
---|
| 410 | for (j = 1; j <= n; j++) |
---|
| 411 | if (cmax < fabs(obj[j])) cmax = fabs(obj[j]); |
---|
| 412 | if (cmax == 0.0) cmax = 1.0; |
---|
| 413 | switch (lp->dir) |
---|
| 414 | { case GLP_MIN: |
---|
| 415 | csa->zeta = + 1.0 / cmax; |
---|
| 416 | break; |
---|
| 417 | case GLP_MAX: |
---|
| 418 | csa->zeta = - 1.0 / cmax; |
---|
| 419 | break; |
---|
| 420 | default: |
---|
| 421 | xassert(lp != lp); |
---|
| 422 | } |
---|
| 423 | #if 1 |
---|
| 424 | if (fabs(csa->zeta) < 1.0) csa->zeta *= 1000.0; |
---|
| 425 | #endif |
---|
| 426 | /* scale working objective coefficients */ |
---|
| 427 | for (j = 1; j <= n; j++) coef[m+j] *= csa->zeta; |
---|
| 428 | /* matrix A (by columns) */ |
---|
| 429 | loc = 1; |
---|
| 430 | for (j = 1; j <= n; j++) |
---|
| 431 | { GLPAIJ *aij; |
---|
| 432 | A_ptr[j] = loc; |
---|
| 433 | for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next) |
---|
| 434 | { A_ind[loc] = aij->row->i; |
---|
| 435 | A_val[loc] = aij->row->rii * aij->val * aij->col->sjj; |
---|
| 436 | loc++; |
---|
| 437 | } |
---|
| 438 | } |
---|
| 439 | A_ptr[n+1] = loc; |
---|
| 440 | xassert(loc-1 == lp->nnz); |
---|
| 441 | #if 1 /* 06/IV-2009 */ |
---|
| 442 | /* matrix A (by rows) */ |
---|
| 443 | loc = 1; |
---|
| 444 | for (i = 1; i <= m; i++) |
---|
| 445 | { GLPAIJ *aij; |
---|
| 446 | AT_ptr[i] = loc; |
---|
| 447 | for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next) |
---|
| 448 | { AT_ind[loc] = aij->col->j; |
---|
| 449 | AT_val[loc] = aij->row->rii * aij->val * aij->col->sjj; |
---|
| 450 | loc++; |
---|
| 451 | } |
---|
| 452 | } |
---|
| 453 | AT_ptr[m+1] = loc; |
---|
| 454 | xassert(loc-1 == lp->nnz); |
---|
| 455 | #endif |
---|
| 456 | /* basis header */ |
---|
| 457 | xassert(lp->valid); |
---|
| 458 | memcpy(&head[1], &lp->head[1], m * sizeof(int)); |
---|
| 459 | k = 0; |
---|
| 460 | for (i = 1; i <= m; i++) |
---|
| 461 | { GLPROW *row = lp->row[i]; |
---|
| 462 | if (row->stat != GLP_BS) |
---|
| 463 | { k++; |
---|
| 464 | xassert(k <= n); |
---|
| 465 | head[m+k] = i; |
---|
| 466 | stat[k] = (char)row->stat; |
---|
| 467 | } |
---|
| 468 | } |
---|
| 469 | for (j = 1; j <= n; j++) |
---|
| 470 | { GLPCOL *col = lp->col[j]; |
---|
| 471 | if (col->stat != GLP_BS) |
---|
| 472 | { k++; |
---|
| 473 | xassert(k <= n); |
---|
| 474 | head[m+k] = m + j; |
---|
| 475 | stat[k] = (char)col->stat; |
---|
| 476 | } |
---|
| 477 | } |
---|
| 478 | xassert(k == n); |
---|
| 479 | #if 1 /* 06/IV-2009 */ |
---|
| 480 | for (k = 1; k <= m+n; k++) |
---|
| 481 | bind[head[k]] = k; |
---|
| 482 | #endif |
---|
| 483 | /* factorization of matrix B */ |
---|
| 484 | csa->valid = 1, lp->valid = 0; |
---|
| 485 | csa->bfd = lp->bfd, lp->bfd = NULL; |
---|
| 486 | #if 0 /* 06/IV-2009 */ |
---|
| 487 | /* matrix N (by rows) */ |
---|
| 488 | alloc_N(csa); |
---|
| 489 | build_N(csa); |
---|
| 490 | #endif |
---|
| 491 | /* working parameters */ |
---|
| 492 | csa->phase = 0; |
---|
| 493 | csa->tm_beg = xtime(); |
---|
| 494 | csa->it_beg = csa->it_cnt = lp->it_cnt; |
---|
| 495 | csa->it_dpy = -1; |
---|
| 496 | /* reference space and steepest edge coefficients */ |
---|
| 497 | csa->refct = 0; |
---|
| 498 | memset(&refsp[1], 0, (m+n) * sizeof(char)); |
---|
| 499 | for (i = 1; i <= m; i++) gamma[i] = 1.0; |
---|
| 500 | return; |
---|
| 501 | } |
---|
| 502 | |
---|
| 503 | #if 1 /* copied from primal */ |
---|
| 504 | /*********************************************************************** |
---|
| 505 | * invert_B - compute factorization of the basis matrix |
---|
| 506 | * |
---|
| 507 | * This routine computes factorization of the current basis matrix B. |
---|
| 508 | * |
---|
| 509 | * If the operation is successful, the routine returns zero, otherwise |
---|
| 510 | * non-zero. */ |
---|
| 511 | |
---|
| 512 | static int inv_col(void *info, int i, int ind[], double val[]) |
---|
| 513 | { /* this auxiliary routine returns row indices and numeric values |
---|
| 514 | of non-zero elements of i-th column of the basis matrix */ |
---|
| 515 | struct csa *csa = info; |
---|
| 516 | int m = csa->m; |
---|
| 517 | #ifdef GLP_DEBUG |
---|
| 518 | int n = csa->n; |
---|
| 519 | #endif |
---|
| 520 | int *A_ptr = csa->A_ptr; |
---|
| 521 | int *A_ind = csa->A_ind; |
---|
| 522 | double *A_val = csa->A_val; |
---|
| 523 | int *head = csa->head; |
---|
| 524 | int k, len, ptr, t; |
---|
| 525 | #ifdef GLP_DEBUG |
---|
| 526 | xassert(1 <= i && i <= m); |
---|
| 527 | #endif |
---|
| 528 | k = head[i]; /* B[i] is k-th column of (I|-A) */ |
---|
| 529 | #ifdef GLP_DEBUG |
---|
| 530 | xassert(1 <= k && k <= m+n); |
---|
| 531 | #endif |
---|
| 532 | if (k <= m) |
---|
| 533 | { /* B[i] is k-th column of submatrix I */ |
---|
| 534 | len = 1; |
---|
| 535 | ind[1] = k; |
---|
| 536 | val[1] = 1.0; |
---|
| 537 | } |
---|
| 538 | else |
---|
| 539 | { /* B[i] is (k-m)-th column of submatrix (-A) */ |
---|
| 540 | ptr = A_ptr[k-m]; |
---|
| 541 | len = A_ptr[k-m+1] - ptr; |
---|
| 542 | memcpy(&ind[1], &A_ind[ptr], len * sizeof(int)); |
---|
| 543 | memcpy(&val[1], &A_val[ptr], len * sizeof(double)); |
---|
| 544 | for (t = 1; t <= len; t++) val[t] = - val[t]; |
---|
| 545 | } |
---|
| 546 | return len; |
---|
| 547 | } |
---|
| 548 | |
---|
| 549 | static int invert_B(struct csa *csa) |
---|
| 550 | { int ret; |
---|
| 551 | ret = bfd_factorize(csa->bfd, csa->m, NULL, inv_col, csa); |
---|
| 552 | csa->valid = (ret == 0); |
---|
| 553 | return ret; |
---|
| 554 | } |
---|
| 555 | #endif |
---|
| 556 | |
---|
| 557 | #if 1 /* copied from primal */ |
---|
| 558 | /*********************************************************************** |
---|
| 559 | * update_B - update factorization of the basis matrix |
---|
| 560 | * |
---|
| 561 | * This routine replaces i-th column of the basis matrix B by k-th |
---|
| 562 | * column of the augmented constraint matrix (I|-A) and then updates |
---|
| 563 | * the factorization of B. |
---|
| 564 | * |
---|
| 565 | * If the factorization has been successfully updated, the routine |
---|
| 566 | * returns zero, otherwise non-zero. */ |
---|
| 567 | |
---|
| 568 | static int update_B(struct csa *csa, int i, int k) |
---|
| 569 | { int m = csa->m; |
---|
| 570 | #ifdef GLP_DEBUG |
---|
| 571 | int n = csa->n; |
---|
| 572 | #endif |
---|
| 573 | int ret; |
---|
| 574 | #ifdef GLP_DEBUG |
---|
| 575 | xassert(1 <= i && i <= m); |
---|
| 576 | xassert(1 <= k && k <= m+n); |
---|
| 577 | #endif |
---|
| 578 | if (k <= m) |
---|
| 579 | { /* new i-th column of B is k-th column of I */ |
---|
| 580 | int ind[1+1]; |
---|
| 581 | double val[1+1]; |
---|
| 582 | ind[1] = k; |
---|
| 583 | val[1] = 1.0; |
---|
| 584 | xassert(csa->valid); |
---|
| 585 | ret = bfd_update_it(csa->bfd, i, 0, 1, ind, val); |
---|
| 586 | } |
---|
| 587 | else |
---|
| 588 | { /* new i-th column of B is (k-m)-th column of (-A) */ |
---|
| 589 | int *A_ptr = csa->A_ptr; |
---|
| 590 | int *A_ind = csa->A_ind; |
---|
| 591 | double *A_val = csa->A_val; |
---|
| 592 | double *val = csa->work1; |
---|
| 593 | int beg, end, ptr, len; |
---|
| 594 | beg = A_ptr[k-m]; |
---|
| 595 | end = A_ptr[k-m+1]; |
---|
| 596 | len = 0; |
---|
| 597 | for (ptr = beg; ptr < end; ptr++) |
---|
| 598 | val[++len] = - A_val[ptr]; |
---|
| 599 | xassert(csa->valid); |
---|
| 600 | ret = bfd_update_it(csa->bfd, i, 0, len, &A_ind[beg-1], val); |
---|
| 601 | } |
---|
| 602 | csa->valid = (ret == 0); |
---|
| 603 | return ret; |
---|
| 604 | } |
---|
| 605 | #endif |
---|
| 606 | |
---|
| 607 | #if 1 /* copied from primal */ |
---|
| 608 | /*********************************************************************** |
---|
| 609 | * error_ftran - compute residual vector r = h - B * x |
---|
| 610 | * |
---|
| 611 | * This routine computes the residual vector r = h - B * x, where B is |
---|
| 612 | * the current basis matrix, h is the vector of right-hand sides, x is |
---|
| 613 | * the solution vector. */ |
---|
| 614 | |
---|
| 615 | static void error_ftran(struct csa *csa, double h[], double x[], |
---|
| 616 | double r[]) |
---|
| 617 | { int m = csa->m; |
---|
| 618 | #ifdef GLP_DEBUG |
---|
| 619 | int n = csa->n; |
---|
| 620 | #endif |
---|
| 621 | int *A_ptr = csa->A_ptr; |
---|
| 622 | int *A_ind = csa->A_ind; |
---|
| 623 | double *A_val = csa->A_val; |
---|
| 624 | int *head = csa->head; |
---|
| 625 | int i, k, beg, end, ptr; |
---|
| 626 | double temp; |
---|
| 627 | /* compute the residual vector: |
---|
| 628 | r = h - B * x = h - B[1] * x[1] - ... - B[m] * x[m], |
---|
| 629 | where B[1], ..., B[m] are columns of matrix B */ |
---|
| 630 | memcpy(&r[1], &h[1], m * sizeof(double)); |
---|
| 631 | for (i = 1; i <= m; i++) |
---|
| 632 | { temp = x[i]; |
---|
| 633 | if (temp == 0.0) continue; |
---|
| 634 | k = head[i]; /* B[i] is k-th column of (I|-A) */ |
---|
| 635 | #ifdef GLP_DEBUG |
---|
| 636 | xassert(1 <= k && k <= m+n); |
---|
| 637 | #endif |
---|
| 638 | if (k <= m) |
---|
| 639 | { /* B[i] is k-th column of submatrix I */ |
---|
| 640 | r[k] -= temp; |
---|
| 641 | } |
---|
| 642 | else |
---|
| 643 | { /* B[i] is (k-m)-th column of submatrix (-A) */ |
---|
| 644 | beg = A_ptr[k-m]; |
---|
| 645 | end = A_ptr[k-m+1]; |
---|
| 646 | for (ptr = beg; ptr < end; ptr++) |
---|
| 647 | r[A_ind[ptr]] += A_val[ptr] * temp; |
---|
| 648 | } |
---|
| 649 | } |
---|
| 650 | return; |
---|
| 651 | } |
---|
| 652 | #endif |
---|
| 653 | |
---|
| 654 | #if 1 /* copied from primal */ |
---|
| 655 | /*********************************************************************** |
---|
| 656 | * refine_ftran - refine solution of B * x = h |
---|
| 657 | * |
---|
| 658 | * This routine performs one iteration to refine the solution of |
---|
| 659 | * the system B * x = h, where B is the current basis matrix, h is the |
---|
| 660 | * vector of right-hand sides, x is the solution vector. */ |
---|
| 661 | |
---|
| 662 | static void refine_ftran(struct csa *csa, double h[], double x[]) |
---|
| 663 | { int m = csa->m; |
---|
| 664 | double *r = csa->work1; |
---|
| 665 | double *d = csa->work1; |
---|
| 666 | int i; |
---|
| 667 | /* compute the residual vector r = h - B * x */ |
---|
| 668 | error_ftran(csa, h, x, r); |
---|
| 669 | /* compute the correction vector d = inv(B) * r */ |
---|
| 670 | xassert(csa->valid); |
---|
| 671 | bfd_ftran(csa->bfd, d); |
---|
| 672 | /* refine the solution vector (new x) = (old x) + d */ |
---|
| 673 | for (i = 1; i <= m; i++) x[i] += d[i]; |
---|
| 674 | return; |
---|
| 675 | } |
---|
| 676 | #endif |
---|
| 677 | |
---|
| 678 | #if 1 /* copied from primal */ |
---|
| 679 | /*********************************************************************** |
---|
| 680 | * error_btran - compute residual vector r = h - B'* x |
---|
| 681 | * |
---|
| 682 | * This routine computes the residual vector r = h - B'* x, where B' |
---|
| 683 | * is a matrix transposed to the current basis matrix, h is the vector |
---|
| 684 | * of right-hand sides, x is the solution vector. */ |
---|
| 685 | |
---|
| 686 | static void error_btran(struct csa *csa, double h[], double x[], |
---|
| 687 | double r[]) |
---|
| 688 | { int m = csa->m; |
---|
| 689 | #ifdef GLP_DEBUG |
---|
| 690 | int n = csa->n; |
---|
| 691 | #endif |
---|
| 692 | int *A_ptr = csa->A_ptr; |
---|
| 693 | int *A_ind = csa->A_ind; |
---|
| 694 | double *A_val = csa->A_val; |
---|
| 695 | int *head = csa->head; |
---|
| 696 | int i, k, beg, end, ptr; |
---|
| 697 | double temp; |
---|
| 698 | /* compute the residual vector r = b - B'* x */ |
---|
| 699 | for (i = 1; i <= m; i++) |
---|
| 700 | { /* r[i] := b[i] - (i-th column of B)'* x */ |
---|
| 701 | k = head[i]; /* B[i] is k-th column of (I|-A) */ |
---|
| 702 | #ifdef GLP_DEBUG |
---|
| 703 | xassert(1 <= k && k <= m+n); |
---|
| 704 | #endif |
---|
| 705 | temp = h[i]; |
---|
| 706 | if (k <= m) |
---|
| 707 | { /* B[i] is k-th column of submatrix I */ |
---|
| 708 | temp -= x[k]; |
---|
| 709 | } |
---|
| 710 | else |
---|
| 711 | { /* B[i] is (k-m)-th column of submatrix (-A) */ |
---|
| 712 | beg = A_ptr[k-m]; |
---|
| 713 | end = A_ptr[k-m+1]; |
---|
| 714 | for (ptr = beg; ptr < end; ptr++) |
---|
| 715 | temp += A_val[ptr] * x[A_ind[ptr]]; |
---|
| 716 | } |
---|
| 717 | r[i] = temp; |
---|
| 718 | } |
---|
| 719 | return; |
---|
| 720 | } |
---|
| 721 | #endif |
---|
| 722 | |
---|
| 723 | #if 1 /* copied from primal */ |
---|
| 724 | /*********************************************************************** |
---|
| 725 | * refine_btran - refine solution of B'* x = h |
---|
| 726 | * |
---|
| 727 | * This routine performs one iteration to refine the solution of the |
---|
| 728 | * system B'* x = h, where B' is a matrix transposed to the current |
---|
| 729 | * basis matrix, h is the vector of right-hand sides, x is the solution |
---|
| 730 | * vector. */ |
---|
| 731 | |
---|
| 732 | static void refine_btran(struct csa *csa, double h[], double x[]) |
---|
| 733 | { int m = csa->m; |
---|
| 734 | double *r = csa->work1; |
---|
| 735 | double *d = csa->work1; |
---|
| 736 | int i; |
---|
| 737 | /* compute the residual vector r = h - B'* x */ |
---|
| 738 | error_btran(csa, h, x, r); |
---|
| 739 | /* compute the correction vector d = inv(B') * r */ |
---|
| 740 | xassert(csa->valid); |
---|
| 741 | bfd_btran(csa->bfd, d); |
---|
| 742 | /* refine the solution vector (new x) = (old x) + d */ |
---|
| 743 | for (i = 1; i <= m; i++) x[i] += d[i]; |
---|
| 744 | return; |
---|
| 745 | } |
---|
| 746 | #endif |
---|
| 747 | |
---|
| 748 | #if 1 /* copied from primal */ |
---|
| 749 | /*********************************************************************** |
---|
| 750 | * get_xN - determine current value of non-basic variable xN[j] |
---|
| 751 | * |
---|
| 752 | * This routine returns the current value of non-basic variable xN[j], |
---|
| 753 | * which is a value of its active bound. */ |
---|
| 754 | |
---|
| 755 | static double get_xN(struct csa *csa, int j) |
---|
| 756 | { int m = csa->m; |
---|
| 757 | #ifdef GLP_DEBUG |
---|
| 758 | int n = csa->n; |
---|
| 759 | #endif |
---|
| 760 | double *lb = csa->lb; |
---|
| 761 | double *ub = csa->ub; |
---|
| 762 | int *head = csa->head; |
---|
| 763 | char *stat = csa->stat; |
---|
| 764 | int k; |
---|
| 765 | double xN; |
---|
| 766 | #ifdef GLP_DEBUG |
---|
| 767 | xassert(1 <= j && j <= n); |
---|
| 768 | #endif |
---|
| 769 | k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 770 | #ifdef GLP_DEBUG |
---|
| 771 | xassert(1 <= k && k <= m+n); |
---|
| 772 | #endif |
---|
| 773 | switch (stat[j]) |
---|
| 774 | { case GLP_NL: |
---|
| 775 | /* x[k] is on its lower bound */ |
---|
| 776 | xN = lb[k]; break; |
---|
| 777 | case GLP_NU: |
---|
| 778 | /* x[k] is on its upper bound */ |
---|
| 779 | xN = ub[k]; break; |
---|
| 780 | case GLP_NF: |
---|
| 781 | /* x[k] is free non-basic variable */ |
---|
| 782 | xN = 0.0; break; |
---|
| 783 | case GLP_NS: |
---|
| 784 | /* x[k] is fixed non-basic variable */ |
---|
| 785 | xN = lb[k]; break; |
---|
| 786 | default: |
---|
| 787 | xassert(stat != stat); |
---|
| 788 | } |
---|
| 789 | return xN; |
---|
| 790 | } |
---|
| 791 | #endif |
---|
| 792 | |
---|
| 793 | #if 1 /* copied from primal */ |
---|
| 794 | /*********************************************************************** |
---|
| 795 | * eval_beta - compute primal values of basic variables |
---|
| 796 | * |
---|
| 797 | * This routine computes current primal values of all basic variables: |
---|
| 798 | * |
---|
| 799 | * beta = - inv(B) * N * xN, |
---|
| 800 | * |
---|
| 801 | * where B is the current basis matrix, N is a matrix built of columns |
---|
| 802 | * of matrix (I|-A) corresponding to non-basic variables, and xN is the |
---|
| 803 | * vector of current values of non-basic variables. */ |
---|
| 804 | |
---|
| 805 | static void eval_beta(struct csa *csa, double beta[]) |
---|
| 806 | { int m = csa->m; |
---|
| 807 | int n = csa->n; |
---|
| 808 | int *A_ptr = csa->A_ptr; |
---|
| 809 | int *A_ind = csa->A_ind; |
---|
| 810 | double *A_val = csa->A_val; |
---|
| 811 | int *head = csa->head; |
---|
| 812 | double *h = csa->work2; |
---|
| 813 | int i, j, k, beg, end, ptr; |
---|
| 814 | double xN; |
---|
| 815 | /* compute the right-hand side vector: |
---|
| 816 | h := - N * xN = - N[1] * xN[1] - ... - N[n] * xN[n], |
---|
| 817 | where N[1], ..., N[n] are columns of matrix N */ |
---|
| 818 | for (i = 1; i <= m; i++) |
---|
| 819 | h[i] = 0.0; |
---|
| 820 | for (j = 1; j <= n; j++) |
---|
| 821 | { k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 822 | #ifdef GLP_DEBUG |
---|
| 823 | xassert(1 <= k && k <= m+n); |
---|
| 824 | #endif |
---|
| 825 | /* determine current value of xN[j] */ |
---|
| 826 | xN = get_xN(csa, j); |
---|
| 827 | if (xN == 0.0) continue; |
---|
| 828 | if (k <= m) |
---|
| 829 | { /* N[j] is k-th column of submatrix I */ |
---|
| 830 | h[k] -= xN; |
---|
| 831 | } |
---|
| 832 | else |
---|
| 833 | { /* N[j] is (k-m)-th column of submatrix (-A) */ |
---|
| 834 | beg = A_ptr[k-m]; |
---|
| 835 | end = A_ptr[k-m+1]; |
---|
| 836 | for (ptr = beg; ptr < end; ptr++) |
---|
| 837 | h[A_ind[ptr]] += xN * A_val[ptr]; |
---|
| 838 | } |
---|
| 839 | } |
---|
| 840 | /* solve system B * beta = h */ |
---|
| 841 | memcpy(&beta[1], &h[1], m * sizeof(double)); |
---|
| 842 | xassert(csa->valid); |
---|
| 843 | bfd_ftran(csa->bfd, beta); |
---|
| 844 | /* and refine the solution */ |
---|
| 845 | refine_ftran(csa, h, beta); |
---|
| 846 | return; |
---|
| 847 | } |
---|
| 848 | #endif |
---|
| 849 | |
---|
| 850 | #if 1 /* copied from primal */ |
---|
| 851 | /*********************************************************************** |
---|
| 852 | * eval_pi - compute vector of simplex multipliers |
---|
| 853 | * |
---|
| 854 | * This routine computes the vector of current simplex multipliers: |
---|
| 855 | * |
---|
| 856 | * pi = inv(B') * cB, |
---|
| 857 | * |
---|
| 858 | * where B' is a matrix transposed to the current basis matrix, cB is |
---|
| 859 | * a subvector of objective coefficients at basic variables. */ |
---|
| 860 | |
---|
| 861 | static void eval_pi(struct csa *csa, double pi[]) |
---|
| 862 | { int m = csa->m; |
---|
| 863 | double *c = csa->coef; |
---|
| 864 | int *head = csa->head; |
---|
| 865 | double *cB = csa->work2; |
---|
| 866 | int i; |
---|
| 867 | /* construct the right-hand side vector cB */ |
---|
| 868 | for (i = 1; i <= m; i++) |
---|
| 869 | cB[i] = c[head[i]]; |
---|
| 870 | /* solve system B'* pi = cB */ |
---|
| 871 | memcpy(&pi[1], &cB[1], m * sizeof(double)); |
---|
| 872 | xassert(csa->valid); |
---|
| 873 | bfd_btran(csa->bfd, pi); |
---|
| 874 | /* and refine the solution */ |
---|
| 875 | refine_btran(csa, cB, pi); |
---|
| 876 | return; |
---|
| 877 | } |
---|
| 878 | #endif |
---|
| 879 | |
---|
| 880 | #if 1 /* copied from primal */ |
---|
| 881 | /*********************************************************************** |
---|
| 882 | * eval_cost - compute reduced cost of non-basic variable xN[j] |
---|
| 883 | * |
---|
| 884 | * This routine computes the current reduced cost of non-basic variable |
---|
| 885 | * xN[j]: |
---|
| 886 | * |
---|
| 887 | * d[j] = cN[j] - N'[j] * pi, |
---|
| 888 | * |
---|
| 889 | * where cN[j] is the objective coefficient at variable xN[j], N[j] is |
---|
| 890 | * a column of the augmented constraint matrix (I|-A) corresponding to |
---|
| 891 | * xN[j], pi is the vector of simplex multipliers. */ |
---|
| 892 | |
---|
| 893 | static double eval_cost(struct csa *csa, double pi[], int j) |
---|
| 894 | { int m = csa->m; |
---|
| 895 | #ifdef GLP_DEBUG |
---|
| 896 | int n = csa->n; |
---|
| 897 | #endif |
---|
| 898 | double *coef = csa->coef; |
---|
| 899 | int *head = csa->head; |
---|
| 900 | int k; |
---|
| 901 | double dj; |
---|
| 902 | #ifdef GLP_DEBUG |
---|
| 903 | xassert(1 <= j && j <= n); |
---|
| 904 | #endif |
---|
| 905 | k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 906 | #ifdef GLP_DEBUG |
---|
| 907 | xassert(1 <= k && k <= m+n); |
---|
| 908 | #endif |
---|
| 909 | dj = coef[k]; |
---|
| 910 | if (k <= m) |
---|
| 911 | { /* N[j] is k-th column of submatrix I */ |
---|
| 912 | dj -= pi[k]; |
---|
| 913 | } |
---|
| 914 | else |
---|
| 915 | { /* N[j] is (k-m)-th column of submatrix (-A) */ |
---|
| 916 | int *A_ptr = csa->A_ptr; |
---|
| 917 | int *A_ind = csa->A_ind; |
---|
| 918 | double *A_val = csa->A_val; |
---|
| 919 | int beg, end, ptr; |
---|
| 920 | beg = A_ptr[k-m]; |
---|
| 921 | end = A_ptr[k-m+1]; |
---|
| 922 | for (ptr = beg; ptr < end; ptr++) |
---|
| 923 | dj += A_val[ptr] * pi[A_ind[ptr]]; |
---|
| 924 | } |
---|
| 925 | return dj; |
---|
| 926 | } |
---|
| 927 | #endif |
---|
| 928 | |
---|
| 929 | #if 1 /* copied from primal */ |
---|
| 930 | /*********************************************************************** |
---|
| 931 | * eval_bbar - compute and store primal values of basic variables |
---|
| 932 | * |
---|
| 933 | * This routine computes primal values of all basic variables and then |
---|
| 934 | * stores them in the solution array. */ |
---|
| 935 | |
---|
| 936 | static void eval_bbar(struct csa *csa) |
---|
| 937 | { eval_beta(csa, csa->bbar); |
---|
| 938 | return; |
---|
| 939 | } |
---|
| 940 | #endif |
---|
| 941 | |
---|
| 942 | #if 1 /* copied from primal */ |
---|
| 943 | /*********************************************************************** |
---|
| 944 | * eval_cbar - compute and store reduced costs of non-basic variables |
---|
| 945 | * |
---|
| 946 | * This routine computes reduced costs of all non-basic variables and |
---|
| 947 | * then stores them in the solution array. */ |
---|
| 948 | |
---|
| 949 | static void eval_cbar(struct csa *csa) |
---|
| 950 | { |
---|
| 951 | #ifdef GLP_DEBUG |
---|
| 952 | int m = csa->m; |
---|
| 953 | #endif |
---|
| 954 | int n = csa->n; |
---|
| 955 | #ifdef GLP_DEBUG |
---|
| 956 | int *head = csa->head; |
---|
| 957 | #endif |
---|
| 958 | double *cbar = csa->cbar; |
---|
| 959 | double *pi = csa->work3; |
---|
| 960 | int j; |
---|
| 961 | #ifdef GLP_DEBUG |
---|
| 962 | int k; |
---|
| 963 | #endif |
---|
| 964 | /* compute simplex multipliers */ |
---|
| 965 | eval_pi(csa, pi); |
---|
| 966 | /* compute and store reduced costs */ |
---|
| 967 | for (j = 1; j <= n; j++) |
---|
| 968 | { |
---|
| 969 | #ifdef GLP_DEBUG |
---|
| 970 | k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 971 | xassert(1 <= k && k <= m+n); |
---|
| 972 | #endif |
---|
| 973 | cbar[j] = eval_cost(csa, pi, j); |
---|
| 974 | } |
---|
| 975 | return; |
---|
| 976 | } |
---|
| 977 | #endif |
---|
| 978 | |
---|
| 979 | /*********************************************************************** |
---|
| 980 | * reset_refsp - reset the reference space |
---|
| 981 | * |
---|
| 982 | * This routine resets (redefines) the reference space used in the |
---|
| 983 | * projected steepest edge pricing algorithm. */ |
---|
| 984 | |
---|
| 985 | static void reset_refsp(struct csa *csa) |
---|
| 986 | { int m = csa->m; |
---|
| 987 | int n = csa->n; |
---|
| 988 | int *head = csa->head; |
---|
| 989 | char *refsp = csa->refsp; |
---|
| 990 | double *gamma = csa->gamma; |
---|
| 991 | int i, k; |
---|
| 992 | xassert(csa->refct == 0); |
---|
| 993 | csa->refct = 1000; |
---|
| 994 | memset(&refsp[1], 0, (m+n) * sizeof(char)); |
---|
| 995 | for (i = 1; i <= m; i++) |
---|
| 996 | { k = head[i]; /* x[k] = xB[i] */ |
---|
| 997 | refsp[k] = 1; |
---|
| 998 | gamma[i] = 1.0; |
---|
| 999 | } |
---|
| 1000 | return; |
---|
| 1001 | } |
---|
| 1002 | |
---|
| 1003 | /*********************************************************************** |
---|
| 1004 | * eval_gamma - compute steepest edge coefficients |
---|
| 1005 | * |
---|
| 1006 | * This routine computes the vector of steepest edge coefficients for |
---|
| 1007 | * all basic variables (except free ones) using its direct definition: |
---|
| 1008 | * |
---|
| 1009 | * gamma[i] = eta[i] + sum alfa[i,j]^2, i = 1,...,m, |
---|
| 1010 | * j in C |
---|
| 1011 | * |
---|
| 1012 | * where eta[i] = 1 means that xB[i] is in the current reference space, |
---|
| 1013 | * and 0 otherwise; C is a set of non-basic non-fixed variables xN[j], |
---|
| 1014 | * which are in the current reference space; alfa[i,j] are elements of |
---|
| 1015 | * the current simplex table. |
---|
| 1016 | * |
---|
| 1017 | * NOTE: The routine is intended only for debugginig purposes. */ |
---|
| 1018 | |
---|
| 1019 | static void eval_gamma(struct csa *csa, double gamma[]) |
---|
| 1020 | { int m = csa->m; |
---|
| 1021 | int n = csa->n; |
---|
| 1022 | char *type = csa->type; |
---|
| 1023 | int *head = csa->head; |
---|
| 1024 | char *refsp = csa->refsp; |
---|
| 1025 | double *alfa = csa->work3; |
---|
| 1026 | double *h = csa->work3; |
---|
| 1027 | int i, j, k; |
---|
| 1028 | /* gamma[i] := eta[i] (or 1, if xB[i] is free) */ |
---|
| 1029 | for (i = 1; i <= m; i++) |
---|
| 1030 | { k = head[i]; /* x[k] = xB[i] */ |
---|
| 1031 | #ifdef GLP_DEBUG |
---|
| 1032 | xassert(1 <= k && k <= m+n); |
---|
| 1033 | #endif |
---|
| 1034 | if (type[k] == GLP_FR) |
---|
| 1035 | gamma[i] = 1.0; |
---|
| 1036 | else |
---|
| 1037 | gamma[i] = (refsp[k] ? 1.0 : 0.0); |
---|
| 1038 | } |
---|
| 1039 | /* compute columns of the current simplex table */ |
---|
| 1040 | for (j = 1; j <= n; j++) |
---|
| 1041 | { k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 1042 | #ifdef GLP_DEBUG |
---|
| 1043 | xassert(1 <= k && k <= m+n); |
---|
| 1044 | #endif |
---|
| 1045 | /* skip column, if xN[j] is not in C */ |
---|
| 1046 | if (!refsp[k]) continue; |
---|
| 1047 | #ifdef GLP_DEBUG |
---|
| 1048 | /* set C must not contain fixed variables */ |
---|
| 1049 | xassert(type[k] != GLP_FX); |
---|
| 1050 | #endif |
---|
| 1051 | /* construct the right-hand side vector h = - N[j] */ |
---|
| 1052 | for (i = 1; i <= m; i++) |
---|
| 1053 | h[i] = 0.0; |
---|
| 1054 | if (k <= m) |
---|
| 1055 | { /* N[j] is k-th column of submatrix I */ |
---|
| 1056 | h[k] = -1.0; |
---|
| 1057 | } |
---|
| 1058 | else |
---|
| 1059 | { /* N[j] is (k-m)-th column of submatrix (-A) */ |
---|
| 1060 | int *A_ptr = csa->A_ptr; |
---|
| 1061 | int *A_ind = csa->A_ind; |
---|
| 1062 | double *A_val = csa->A_val; |
---|
| 1063 | int beg, end, ptr; |
---|
| 1064 | beg = A_ptr[k-m]; |
---|
| 1065 | end = A_ptr[k-m+1]; |
---|
| 1066 | for (ptr = beg; ptr < end; ptr++) |
---|
| 1067 | h[A_ind[ptr]] = A_val[ptr]; |
---|
| 1068 | } |
---|
| 1069 | /* solve system B * alfa = h */ |
---|
| 1070 | xassert(csa->valid); |
---|
| 1071 | bfd_ftran(csa->bfd, alfa); |
---|
| 1072 | /* gamma[i] := gamma[i] + alfa[i,j]^2 */ |
---|
| 1073 | for (i = 1; i <= m; i++) |
---|
| 1074 | { k = head[i]; /* x[k] = xB[i] */ |
---|
| 1075 | if (type[k] != GLP_FR) |
---|
| 1076 | gamma[i] += alfa[i] * alfa[i]; |
---|
| 1077 | } |
---|
| 1078 | } |
---|
| 1079 | return; |
---|
| 1080 | } |
---|
| 1081 | |
---|
| 1082 | /*********************************************************************** |
---|
| 1083 | * chuzr - choose basic variable (row of the simplex table) |
---|
| 1084 | * |
---|
| 1085 | * This routine chooses basic variable xB[p] having largest weighted |
---|
| 1086 | * bound violation: |
---|
| 1087 | * |
---|
| 1088 | * |r[p]| / sqrt(gamma[p]) = max |r[i]| / sqrt(gamma[i]), |
---|
| 1089 | * i in I |
---|
| 1090 | * |
---|
| 1091 | * / lB[i] - beta[i], if beta[i] < lB[i] |
---|
| 1092 | * | |
---|
| 1093 | * r[i] = < 0, if lB[i] <= beta[i] <= uB[i] |
---|
| 1094 | * | |
---|
| 1095 | * \ uB[i] - beta[i], if beta[i] > uB[i] |
---|
| 1096 | * |
---|
| 1097 | * where beta[i] is primal value of xB[i] in the current basis, lB[i] |
---|
| 1098 | * and uB[i] are lower and upper bounds of xB[i], I is a subset of |
---|
| 1099 | * eligible basic variables, which significantly violates their bounds, |
---|
| 1100 | * gamma[i] is the steepest edge coefficient. |
---|
| 1101 | * |
---|
| 1102 | * If |r[i]| is less than a specified tolerance, xB[i] is not included |
---|
| 1103 | * in I and therefore ignored. |
---|
| 1104 | * |
---|
| 1105 | * If I is empty and no variable has been chosen, p is set to 0. */ |
---|
| 1106 | |
---|
| 1107 | static void chuzr(struct csa *csa, double tol_bnd) |
---|
| 1108 | { int m = csa->m; |
---|
| 1109 | #ifdef GLP_DEBUG |
---|
| 1110 | int n = csa->n; |
---|
| 1111 | #endif |
---|
| 1112 | char *type = csa->type; |
---|
| 1113 | double *lb = csa->lb; |
---|
| 1114 | double *ub = csa->ub; |
---|
| 1115 | int *head = csa->head; |
---|
| 1116 | double *bbar = csa->bbar; |
---|
| 1117 | double *gamma = csa->gamma; |
---|
| 1118 | int i, k, p; |
---|
| 1119 | double delta, best, eps, ri, temp; |
---|
| 1120 | /* nothing is chosen so far */ |
---|
| 1121 | p = 0, delta = 0.0, best = 0.0; |
---|
| 1122 | /* look through the list of basic variables */ |
---|
| 1123 | for (i = 1; i <= m; i++) |
---|
| 1124 | { k = head[i]; /* x[k] = xB[i] */ |
---|
| 1125 | #ifdef GLP_DEBUG |
---|
| 1126 | xassert(1 <= k && k <= m+n); |
---|
| 1127 | #endif |
---|
| 1128 | /* determine bound violation ri[i] */ |
---|
| 1129 | ri = 0.0; |
---|
| 1130 | if (type[k] == GLP_LO || type[k] == GLP_DB || |
---|
| 1131 | type[k] == GLP_FX) |
---|
| 1132 | { /* xB[i] has lower bound */ |
---|
| 1133 | eps = tol_bnd * (1.0 + kappa * fabs(lb[k])); |
---|
| 1134 | if (bbar[i] < lb[k] - eps) |
---|
| 1135 | { /* and significantly violates it */ |
---|
| 1136 | ri = lb[k] - bbar[i]; |
---|
| 1137 | } |
---|
| 1138 | } |
---|
| 1139 | if (type[k] == GLP_UP || type[k] == GLP_DB || |
---|
| 1140 | type[k] == GLP_FX) |
---|
| 1141 | { /* xB[i] has upper bound */ |
---|
| 1142 | eps = tol_bnd * (1.0 + kappa * fabs(ub[k])); |
---|
| 1143 | if (bbar[i] > ub[k] + eps) |
---|
| 1144 | { /* and significantly violates it */ |
---|
| 1145 | ri = ub[k] - bbar[i]; |
---|
| 1146 | } |
---|
| 1147 | } |
---|
| 1148 | /* if xB[i] is not eligible, skip it */ |
---|
| 1149 | if (ri == 0.0) continue; |
---|
| 1150 | /* xB[i] is eligible basic variable; choose one with largest |
---|
| 1151 | weighted bound violation */ |
---|
| 1152 | #ifdef GLP_DEBUG |
---|
| 1153 | xassert(gamma[i] >= 0.0); |
---|
| 1154 | #endif |
---|
| 1155 | temp = gamma[i]; |
---|
| 1156 | if (temp < DBL_EPSILON) temp = DBL_EPSILON; |
---|
| 1157 | temp = (ri * ri) / temp; |
---|
| 1158 | if (best < temp) |
---|
| 1159 | p = i, delta = ri, best = temp; |
---|
| 1160 | } |
---|
| 1161 | /* store the index of basic variable xB[p] chosen and its change |
---|
| 1162 | in the adjacent basis */ |
---|
| 1163 | csa->p = p; |
---|
| 1164 | csa->delta = delta; |
---|
| 1165 | return; |
---|
| 1166 | } |
---|
| 1167 | |
---|
| 1168 | #if 1 /* copied from primal */ |
---|
| 1169 | /*********************************************************************** |
---|
| 1170 | * eval_rho - compute pivot row of the inverse |
---|
| 1171 | * |
---|
| 1172 | * This routine computes the pivot (p-th) row of the inverse inv(B), |
---|
| 1173 | * which corresponds to basic variable xB[p] chosen: |
---|
| 1174 | * |
---|
| 1175 | * rho = inv(B') * e[p], |
---|
| 1176 | * |
---|
| 1177 | * where B' is a matrix transposed to the current basis matrix, e[p] |
---|
| 1178 | * is unity vector. */ |
---|
| 1179 | |
---|
| 1180 | static void eval_rho(struct csa *csa, double rho[]) |
---|
| 1181 | { int m = csa->m; |
---|
| 1182 | int p = csa->p; |
---|
| 1183 | double *e = rho; |
---|
| 1184 | int i; |
---|
| 1185 | #ifdef GLP_DEBUG |
---|
| 1186 | xassert(1 <= p && p <= m); |
---|
| 1187 | #endif |
---|
| 1188 | /* construct the right-hand side vector e[p] */ |
---|
| 1189 | for (i = 1; i <= m; i++) |
---|
| 1190 | e[i] = 0.0; |
---|
| 1191 | e[p] = 1.0; |
---|
| 1192 | /* solve system B'* rho = e[p] */ |
---|
| 1193 | xassert(csa->valid); |
---|
| 1194 | bfd_btran(csa->bfd, rho); |
---|
| 1195 | return; |
---|
| 1196 | } |
---|
| 1197 | #endif |
---|
| 1198 | |
---|
| 1199 | #if 1 /* copied from primal */ |
---|
| 1200 | /*********************************************************************** |
---|
| 1201 | * refine_rho - refine pivot row of the inverse |
---|
| 1202 | * |
---|
| 1203 | * This routine refines the pivot row of the inverse inv(B) assuming |
---|
| 1204 | * that it was previously computed by the routine eval_rho. */ |
---|
| 1205 | |
---|
| 1206 | static void refine_rho(struct csa *csa, double rho[]) |
---|
| 1207 | { int m = csa->m; |
---|
| 1208 | int p = csa->p; |
---|
| 1209 | double *e = csa->work3; |
---|
| 1210 | int i; |
---|
| 1211 | #ifdef GLP_DEBUG |
---|
| 1212 | xassert(1 <= p && p <= m); |
---|
| 1213 | #endif |
---|
| 1214 | /* construct the right-hand side vector e[p] */ |
---|
| 1215 | for (i = 1; i <= m; i++) |
---|
| 1216 | e[i] = 0.0; |
---|
| 1217 | e[p] = 1.0; |
---|
| 1218 | /* refine solution of B'* rho = e[p] */ |
---|
| 1219 | refine_btran(csa, e, rho); |
---|
| 1220 | return; |
---|
| 1221 | } |
---|
| 1222 | #endif |
---|
| 1223 | |
---|
| 1224 | #if 1 /* 06/IV-2009 */ |
---|
| 1225 | /*********************************************************************** |
---|
| 1226 | * eval_trow - compute pivot row of the simplex table |
---|
| 1227 | * |
---|
| 1228 | * This routine computes the pivot row of the simplex table, which |
---|
| 1229 | * corresponds to basic variable xB[p] chosen. |
---|
| 1230 | * |
---|
| 1231 | * The pivot row is the following vector: |
---|
| 1232 | * |
---|
| 1233 | * trow = T'* e[p] = - N'* inv(B') * e[p] = - N' * rho, |
---|
| 1234 | * |
---|
| 1235 | * where rho is the pivot row of the inverse inv(B) previously computed |
---|
| 1236 | * by the routine eval_rho. |
---|
| 1237 | * |
---|
| 1238 | * Note that elements of the pivot row corresponding to fixed non-basic |
---|
| 1239 | * variables are not computed. |
---|
| 1240 | * |
---|
| 1241 | * NOTES |
---|
| 1242 | * |
---|
| 1243 | * Computing pivot row of the simplex table is one of the most time |
---|
| 1244 | * consuming operations, and for some instances it may take more than |
---|
| 1245 | * 50% of the total solution time. |
---|
| 1246 | * |
---|
| 1247 | * In the current implementation there are two routines to compute the |
---|
| 1248 | * pivot row. The routine eval_trow1 computes elements of the pivot row |
---|
| 1249 | * as inner products of columns of the matrix N and the vector rho; it |
---|
| 1250 | * is used when the vector rho is relatively dense. The routine |
---|
| 1251 | * eval_trow2 computes the pivot row as a linear combination of rows of |
---|
| 1252 | * the matrix N; it is used when the vector rho is relatively sparse. */ |
---|
| 1253 | |
---|
| 1254 | static void eval_trow1(struct csa *csa, double rho[]) |
---|
| 1255 | { int m = csa->m; |
---|
| 1256 | int n = csa->n; |
---|
| 1257 | int *A_ptr = csa->A_ptr; |
---|
| 1258 | int *A_ind = csa->A_ind; |
---|
| 1259 | double *A_val = csa->A_val; |
---|
| 1260 | int *head = csa->head; |
---|
| 1261 | char *stat = csa->stat; |
---|
| 1262 | int *trow_ind = csa->trow_ind; |
---|
| 1263 | double *trow_vec = csa->trow_vec; |
---|
| 1264 | int j, k, beg, end, ptr, nnz; |
---|
| 1265 | double temp; |
---|
| 1266 | /* compute the pivot row as inner products of columns of the |
---|
| 1267 | matrix N and vector rho: trow[j] = - rho * N[j] */ |
---|
| 1268 | nnz = 0; |
---|
| 1269 | for (j = 1; j <= n; j++) |
---|
| 1270 | { if (stat[j] == GLP_NS) |
---|
| 1271 | { /* xN[j] is fixed */ |
---|
| 1272 | trow_vec[j] = 0.0; |
---|
| 1273 | continue; |
---|
| 1274 | } |
---|
| 1275 | k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 1276 | if (k <= m) |
---|
| 1277 | { /* N[j] is k-th column of submatrix I */ |
---|
| 1278 | temp = - rho[k]; |
---|
| 1279 | } |
---|
| 1280 | else |
---|
| 1281 | { /* N[j] is (k-m)-th column of submatrix (-A) */ |
---|
| 1282 | beg = A_ptr[k-m], end = A_ptr[k-m+1]; |
---|
| 1283 | temp = 0.0; |
---|
| 1284 | for (ptr = beg; ptr < end; ptr++) |
---|
| 1285 | temp += rho[A_ind[ptr]] * A_val[ptr]; |
---|
| 1286 | } |
---|
| 1287 | if (temp != 0.0) |
---|
| 1288 | trow_ind[++nnz] = j; |
---|
| 1289 | trow_vec[j] = temp; |
---|
| 1290 | } |
---|
| 1291 | csa->trow_nnz = nnz; |
---|
| 1292 | return; |
---|
| 1293 | } |
---|
| 1294 | |
---|
| 1295 | static void eval_trow2(struct csa *csa, double rho[]) |
---|
| 1296 | { int m = csa->m; |
---|
| 1297 | int n = csa->n; |
---|
| 1298 | int *AT_ptr = csa->AT_ptr; |
---|
| 1299 | int *AT_ind = csa->AT_ind; |
---|
| 1300 | double *AT_val = csa->AT_val; |
---|
| 1301 | int *bind = csa->bind; |
---|
| 1302 | char *stat = csa->stat; |
---|
| 1303 | int *trow_ind = csa->trow_ind; |
---|
| 1304 | double *trow_vec = csa->trow_vec; |
---|
| 1305 | int i, j, beg, end, ptr, nnz; |
---|
| 1306 | double temp; |
---|
| 1307 | /* clear the pivot row */ |
---|
| 1308 | for (j = 1; j <= n; j++) |
---|
| 1309 | trow_vec[j] = 0.0; |
---|
| 1310 | /* compute the pivot row as a linear combination of rows of the |
---|
| 1311 | matrix N: trow = - rho[1] * N'[1] - ... - rho[m] * N'[m] */ |
---|
| 1312 | for (i = 1; i <= m; i++) |
---|
| 1313 | { temp = rho[i]; |
---|
| 1314 | if (temp == 0.0) continue; |
---|
| 1315 | /* trow := trow - rho[i] * N'[i] */ |
---|
| 1316 | j = bind[i] - m; /* x[i] = xN[j] */ |
---|
| 1317 | if (j >= 1 && stat[j] != GLP_NS) |
---|
| 1318 | trow_vec[j] -= temp; |
---|
| 1319 | beg = AT_ptr[i], end = AT_ptr[i+1]; |
---|
| 1320 | for (ptr = beg; ptr < end; ptr++) |
---|
| 1321 | { j = bind[m + AT_ind[ptr]] - m; /* x[k] = xN[j] */ |
---|
| 1322 | if (j >= 1 && stat[j] != GLP_NS) |
---|
| 1323 | trow_vec[j] += temp * AT_val[ptr]; |
---|
| 1324 | } |
---|
| 1325 | } |
---|
| 1326 | /* construct sparse pattern of the pivot row */ |
---|
| 1327 | nnz = 0; |
---|
| 1328 | for (j = 1; j <= n; j++) |
---|
| 1329 | { if (trow_vec[j] != 0.0) |
---|
| 1330 | trow_ind[++nnz] = j; |
---|
| 1331 | } |
---|
| 1332 | csa->trow_nnz = nnz; |
---|
| 1333 | return; |
---|
| 1334 | } |
---|
| 1335 | |
---|
| 1336 | static void eval_trow(struct csa *csa, double rho[]) |
---|
| 1337 | { int m = csa->m; |
---|
| 1338 | int i, nnz; |
---|
| 1339 | double dens; |
---|
| 1340 | /* determine the density of the vector rho */ |
---|
| 1341 | nnz = 0; |
---|
| 1342 | for (i = 1; i <= m; i++) |
---|
| 1343 | if (rho[i] != 0.0) nnz++; |
---|
| 1344 | dens = (double)nnz / (double)m; |
---|
| 1345 | if (dens >= 0.20) |
---|
| 1346 | { /* rho is relatively dense */ |
---|
| 1347 | eval_trow1(csa, rho); |
---|
| 1348 | } |
---|
| 1349 | else |
---|
| 1350 | { /* rho is relatively sparse */ |
---|
| 1351 | eval_trow2(csa, rho); |
---|
| 1352 | } |
---|
| 1353 | return; |
---|
| 1354 | } |
---|
| 1355 | #endif |
---|
| 1356 | |
---|
| 1357 | /*********************************************************************** |
---|
| 1358 | * sort_trow - sort pivot row of the simplex table |
---|
| 1359 | * |
---|
| 1360 | * This routine reorders the list of non-zero elements of the pivot |
---|
| 1361 | * row to put significant elements, whose magnitude is not less than |
---|
| 1362 | * a specified tolerance, in front of the list, and stores the number |
---|
| 1363 | * of significant elements in trow_num. */ |
---|
| 1364 | |
---|
| 1365 | static void sort_trow(struct csa *csa, double tol_piv) |
---|
| 1366 | { |
---|
| 1367 | #ifdef GLP_DEBUG |
---|
| 1368 | int n = csa->n; |
---|
| 1369 | char *stat = csa->stat; |
---|
| 1370 | #endif |
---|
| 1371 | int nnz = csa->trow_nnz; |
---|
| 1372 | int *trow_ind = csa->trow_ind; |
---|
| 1373 | double *trow_vec = csa->trow_vec; |
---|
| 1374 | int j, num, pos; |
---|
| 1375 | double big, eps, temp; |
---|
| 1376 | /* compute infinity (maximum) norm of the row */ |
---|
| 1377 | big = 0.0; |
---|
| 1378 | for (pos = 1; pos <= nnz; pos++) |
---|
| 1379 | { |
---|
| 1380 | #ifdef GLP_DEBUG |
---|
| 1381 | j = trow_ind[pos]; |
---|
| 1382 | xassert(1 <= j && j <= n); |
---|
| 1383 | xassert(stat[j] != GLP_NS); |
---|
| 1384 | #endif |
---|
| 1385 | temp = fabs(trow_vec[trow_ind[pos]]); |
---|
| 1386 | if (big < temp) big = temp; |
---|
| 1387 | } |
---|
| 1388 | csa->trow_max = big; |
---|
| 1389 | /* determine absolute pivot tolerance */ |
---|
| 1390 | eps = tol_piv * (1.0 + 0.01 * big); |
---|
| 1391 | /* move significant row components to the front of the list */ |
---|
| 1392 | for (num = 0; num < nnz; ) |
---|
| 1393 | { j = trow_ind[nnz]; |
---|
| 1394 | if (fabs(trow_vec[j]) < eps) |
---|
| 1395 | nnz--; |
---|
| 1396 | else |
---|
| 1397 | { num++; |
---|
| 1398 | trow_ind[nnz] = trow_ind[num]; |
---|
| 1399 | trow_ind[num] = j; |
---|
| 1400 | } |
---|
| 1401 | } |
---|
| 1402 | csa->trow_num = num; |
---|
| 1403 | return; |
---|
| 1404 | } |
---|
| 1405 | |
---|
| 1406 | #ifdef GLP_LONG_STEP /* 07/IV-2009 */ |
---|
| 1407 | static int ls_func(const void *p1_, const void *p2_) |
---|
| 1408 | { const struct bkpt *p1 = p1_, *p2 = p2_; |
---|
| 1409 | if (p1->t < p2->t) return -1; |
---|
| 1410 | if (p1->t > p2->t) return +1; |
---|
| 1411 | return 0; |
---|
| 1412 | } |
---|
| 1413 | |
---|
| 1414 | static int ls_func1(const void *p1_, const void *p2_) |
---|
| 1415 | { const struct bkpt *p1 = p1_, *p2 = p2_; |
---|
| 1416 | if (p1->dz < p2->dz) return -1; |
---|
| 1417 | if (p1->dz > p2->dz) return +1; |
---|
| 1418 | return 0; |
---|
| 1419 | } |
---|
| 1420 | |
---|
| 1421 | static void long_step(struct csa *csa) |
---|
| 1422 | { int m = csa->m; |
---|
| 1423 | #ifdef GLP_DEBUG |
---|
| 1424 | int n = csa->n; |
---|
| 1425 | #endif |
---|
| 1426 | char *type = csa->type; |
---|
| 1427 | double *lb = csa->lb; |
---|
| 1428 | double *ub = csa->ub; |
---|
| 1429 | int *head = csa->head; |
---|
| 1430 | char *stat = csa->stat; |
---|
| 1431 | double *cbar = csa->cbar; |
---|
| 1432 | double delta = csa->delta; |
---|
| 1433 | int *trow_ind = csa->trow_ind; |
---|
| 1434 | double *trow_vec = csa->trow_vec; |
---|
| 1435 | int trow_num = csa->trow_num; |
---|
| 1436 | struct bkpt *bkpt = csa->bkpt; |
---|
| 1437 | int j, k, kk, nbps, pos; |
---|
| 1438 | double alfa, s, slope, dzmax; |
---|
| 1439 | /* delta > 0 means that xB[p] violates its lower bound, so to |
---|
| 1440 | increase the dual objective lambdaB[p] must increase; |
---|
| 1441 | delta < 0 means that xB[p] violates its upper bound, so to |
---|
| 1442 | increase the dual objective lambdaB[p] must decrease */ |
---|
| 1443 | /* s := sign(delta) */ |
---|
| 1444 | s = (delta > 0.0 ? +1.0 : -1.0); |
---|
| 1445 | /* determine breakpoints of the dual objective */ |
---|
| 1446 | nbps = 0; |
---|
| 1447 | for (pos = 1; pos <= trow_num; pos++) |
---|
| 1448 | { j = trow_ind[pos]; |
---|
| 1449 | #ifdef GLP_DEBUG |
---|
| 1450 | xassert(1 <= j && j <= n); |
---|
| 1451 | xassert(stat[j] != GLP_NS); |
---|
| 1452 | #endif |
---|
| 1453 | /* if there is free non-basic variable, switch to the standard |
---|
| 1454 | ratio test */ |
---|
| 1455 | if (stat[j] == GLP_NF) |
---|
| 1456 | { nbps = 0; |
---|
| 1457 | goto done; |
---|
| 1458 | } |
---|
| 1459 | /* lambdaN[j] = ... - alfa * t - ..., where t = s * lambdaB[i] |
---|
| 1460 | is the dual ray parameter, t >= 0 */ |
---|
| 1461 | alfa = s * trow_vec[j]; |
---|
| 1462 | #ifdef GLP_DEBUG |
---|
| 1463 | xassert(alfa != 0.0); |
---|
| 1464 | xassert(stat[j] == GLP_NL || stat[j] == GLP_NU); |
---|
| 1465 | #endif |
---|
| 1466 | if (alfa > 0.0 && stat[j] == GLP_NL || |
---|
| 1467 | alfa < 0.0 && stat[j] == GLP_NU) |
---|
| 1468 | { /* either lambdaN[j] >= 0 (if stat = GLP_NL) and decreases |
---|
| 1469 | or lambdaN[j] <= 0 (if stat = GLP_NU) and increases; in |
---|
| 1470 | both cases we have a breakpoint */ |
---|
| 1471 | nbps++; |
---|
| 1472 | #ifdef GLP_DEBUG |
---|
| 1473 | xassert(nbps <= n); |
---|
| 1474 | #endif |
---|
| 1475 | bkpt[nbps].j = j; |
---|
| 1476 | bkpt[nbps].t = cbar[j] / alfa; |
---|
| 1477 | /* |
---|
| 1478 | if (stat[j] == GLP_NL && cbar[j] < 0.0 || |
---|
| 1479 | stat[j] == GLP_NU && cbar[j] > 0.0) |
---|
| 1480 | xprintf("%d %g\n", stat[j], cbar[j]); |
---|
| 1481 | */ |
---|
| 1482 | /* if t is negative, replace it by exact zero (see comments |
---|
| 1483 | in the routine chuzc) */ |
---|
| 1484 | if (bkpt[nbps].t < 0.0) bkpt[nbps].t = 0.0; |
---|
| 1485 | } |
---|
| 1486 | } |
---|
| 1487 | /* if there are less than two breakpoints, switch to the standard |
---|
| 1488 | ratio test */ |
---|
| 1489 | if (nbps < 2) |
---|
| 1490 | { nbps = 0; |
---|
| 1491 | goto done; |
---|
| 1492 | } |
---|
| 1493 | /* sort breakpoints by ascending the dual ray parameter, t */ |
---|
| 1494 | qsort(&bkpt[1], nbps, sizeof(struct bkpt), ls_func); |
---|
| 1495 | /* determine last breakpoint, at which the dual objective still |
---|
| 1496 | greater than at t = 0 */ |
---|
| 1497 | dzmax = 0.0; |
---|
| 1498 | slope = fabs(delta); /* initial slope */ |
---|
| 1499 | for (kk = 1; kk <= nbps; kk++) |
---|
| 1500 | { if (kk == 1) |
---|
| 1501 | bkpt[kk].dz = |
---|
| 1502 | 0.0 + slope * (bkpt[kk].t - 0.0); |
---|
| 1503 | else |
---|
| 1504 | bkpt[kk].dz = |
---|
| 1505 | bkpt[kk-1].dz + slope * (bkpt[kk].t - bkpt[kk-1].t); |
---|
| 1506 | if (dzmax < bkpt[kk].dz) |
---|
| 1507 | dzmax = bkpt[kk].dz; |
---|
| 1508 | else if (bkpt[kk].dz < 0.05 * (1.0 + dzmax)) |
---|
| 1509 | { nbps = kk - 1; |
---|
| 1510 | break; |
---|
| 1511 | } |
---|
| 1512 | j = bkpt[kk].j; |
---|
| 1513 | k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 1514 | if (type[k] == GLP_DB) |
---|
| 1515 | slope -= fabs(trow_vec[j]) * (ub[k] - lb[k]); |
---|
| 1516 | else |
---|
| 1517 | { nbps = kk; |
---|
| 1518 | break; |
---|
| 1519 | } |
---|
| 1520 | } |
---|
| 1521 | /* if there are less than two breakpoints, switch to the standard |
---|
| 1522 | ratio test */ |
---|
| 1523 | if (nbps < 2) |
---|
| 1524 | { nbps = 0; |
---|
| 1525 | goto done; |
---|
| 1526 | } |
---|
| 1527 | /* sort breakpoints by ascending the dual change, dz */ |
---|
| 1528 | qsort(&bkpt[1], nbps, sizeof(struct bkpt), ls_func1); |
---|
| 1529 | /* |
---|
| 1530 | for (kk = 1; kk <= nbps; kk++) |
---|
| 1531 | xprintf("%d; t = %g; dz = %g\n", kk, bkpt[kk].t, bkpt[kk].dz); |
---|
| 1532 | */ |
---|
| 1533 | done: csa->nbps = nbps; |
---|
| 1534 | return; |
---|
| 1535 | } |
---|
| 1536 | #endif |
---|
| 1537 | |
---|
| 1538 | /*********************************************************************** |
---|
| 1539 | * chuzc - choose non-basic variable (column of the simplex table) |
---|
| 1540 | * |
---|
| 1541 | * This routine chooses non-basic variable xN[q], which being entered |
---|
| 1542 | * in the basis keeps dual feasibility of the basic solution. |
---|
| 1543 | * |
---|
| 1544 | * The parameter rtol is a relative tolerance used to relax zero bounds |
---|
| 1545 | * of reduced costs of non-basic variables. If rtol = 0, the routine |
---|
| 1546 | * implements the standard ratio test. Otherwise, if rtol > 0, the |
---|
| 1547 | * routine implements Harris' two-pass ratio test. In the latter case |
---|
| 1548 | * rtol should be about three times less than a tolerance used to check |
---|
| 1549 | * dual feasibility. */ |
---|
| 1550 | |
---|
| 1551 | static void chuzc(struct csa *csa, double rtol) |
---|
| 1552 | { |
---|
| 1553 | #ifdef GLP_DEBUG |
---|
| 1554 | int m = csa->m; |
---|
| 1555 | int n = csa->n; |
---|
| 1556 | #endif |
---|
| 1557 | char *stat = csa->stat; |
---|
| 1558 | double *cbar = csa->cbar; |
---|
| 1559 | #ifdef GLP_DEBUG |
---|
| 1560 | int p = csa->p; |
---|
| 1561 | #endif |
---|
| 1562 | double delta = csa->delta; |
---|
| 1563 | int *trow_ind = csa->trow_ind; |
---|
| 1564 | double *trow_vec = csa->trow_vec; |
---|
| 1565 | int trow_num = csa->trow_num; |
---|
| 1566 | int j, pos, q; |
---|
| 1567 | double alfa, big, s, t, teta, tmax; |
---|
| 1568 | #ifdef GLP_DEBUG |
---|
| 1569 | xassert(1 <= p && p <= m); |
---|
| 1570 | #endif |
---|
| 1571 | /* delta > 0 means that xB[p] violates its lower bound and goes |
---|
| 1572 | to it in the adjacent basis, so lambdaB[p] is increasing from |
---|
| 1573 | its lower zero bound; |
---|
| 1574 | delta < 0 means that xB[p] violates its upper bound and goes |
---|
| 1575 | to it in the adjacent basis, so lambdaB[p] is decreasing from |
---|
| 1576 | its upper zero bound */ |
---|
| 1577 | #ifdef GLP_DEBUG |
---|
| 1578 | xassert(delta != 0.0); |
---|
| 1579 | #endif |
---|
| 1580 | /* s := sign(delta) */ |
---|
| 1581 | s = (delta > 0.0 ? +1.0 : -1.0); |
---|
| 1582 | /*** FIRST PASS ***/ |
---|
| 1583 | /* nothing is chosen so far */ |
---|
| 1584 | q = 0, teta = DBL_MAX, big = 0.0; |
---|
| 1585 | /* walk through significant elements of the pivot row */ |
---|
| 1586 | for (pos = 1; pos <= trow_num; pos++) |
---|
| 1587 | { j = trow_ind[pos]; |
---|
| 1588 | #ifdef GLP_DEBUG |
---|
| 1589 | xassert(1 <= j && j <= n); |
---|
| 1590 | #endif |
---|
| 1591 | alfa = s * trow_vec[j]; |
---|
| 1592 | #ifdef GLP_DEBUG |
---|
| 1593 | xassert(alfa != 0.0); |
---|
| 1594 | #endif |
---|
| 1595 | /* lambdaN[j] = ... - alfa * lambdaB[p] - ..., and due to s we |
---|
| 1596 | need to consider only increasing lambdaB[p] */ |
---|
| 1597 | if (alfa > 0.0) |
---|
| 1598 | { /* lambdaN[j] is decreasing */ |
---|
| 1599 | if (stat[j] == GLP_NL || stat[j] == GLP_NF) |
---|
| 1600 | { /* lambdaN[j] has zero lower bound */ |
---|
| 1601 | t = (cbar[j] + rtol) / alfa; |
---|
| 1602 | } |
---|
| 1603 | else |
---|
| 1604 | { /* lambdaN[j] has no lower bound */ |
---|
| 1605 | continue; |
---|
| 1606 | } |
---|
| 1607 | } |
---|
| 1608 | else |
---|
| 1609 | { /* lambdaN[j] is increasing */ |
---|
| 1610 | if (stat[j] == GLP_NU || stat[j] == GLP_NF) |
---|
| 1611 | { /* lambdaN[j] has zero upper bound */ |
---|
| 1612 | t = (cbar[j] - rtol) / alfa; |
---|
| 1613 | } |
---|
| 1614 | else |
---|
| 1615 | { /* lambdaN[j] has no upper bound */ |
---|
| 1616 | continue; |
---|
| 1617 | } |
---|
| 1618 | } |
---|
| 1619 | /* t is a change of lambdaB[p], on which lambdaN[j] reaches |
---|
| 1620 | its zero bound (possibly relaxed); since the basic solution |
---|
| 1621 | is assumed to be dual feasible, t has to be non-negative by |
---|
| 1622 | definition; however, it may happen that lambdaN[j] slightly |
---|
| 1623 | (i.e. within a tolerance) violates its zero bound, that |
---|
| 1624 | leads to negative t; in the latter case, if xN[j] is chosen, |
---|
| 1625 | negative t means that lambdaB[p] changes in wrong direction |
---|
| 1626 | that may cause wrong results on updating reduced costs; |
---|
| 1627 | thus, if t is negative, we should replace it by exact zero |
---|
| 1628 | assuming that lambdaN[j] is exactly on its zero bound, and |
---|
| 1629 | violation appears due to round-off errors */ |
---|
| 1630 | if (t < 0.0) t = 0.0; |
---|
| 1631 | /* apply minimal ratio test */ |
---|
| 1632 | if (teta > t || teta == t && big < fabs(alfa)) |
---|
| 1633 | q = j, teta = t, big = fabs(alfa); |
---|
| 1634 | } |
---|
| 1635 | /* the second pass is skipped in the following cases: */ |
---|
| 1636 | /* if the standard ratio test is used */ |
---|
| 1637 | if (rtol == 0.0) goto done; |
---|
| 1638 | /* if no non-basic variable has been chosen on the first pass */ |
---|
| 1639 | if (q == 0) goto done; |
---|
| 1640 | /* if lambdaN[q] prevents lambdaB[p] from any change */ |
---|
| 1641 | if (teta == 0.0) goto done; |
---|
| 1642 | /*** SECOND PASS ***/ |
---|
| 1643 | /* here tmax is a maximal change of lambdaB[p], on which the |
---|
| 1644 | solution remains dual feasible within a tolerance */ |
---|
| 1645 | #if 0 |
---|
| 1646 | tmax = (1.0 + 10.0 * DBL_EPSILON) * teta; |
---|
| 1647 | #else |
---|
| 1648 | tmax = teta; |
---|
| 1649 | #endif |
---|
| 1650 | /* nothing is chosen so far */ |
---|
| 1651 | q = 0, teta = DBL_MAX, big = 0.0; |
---|
| 1652 | /* walk through significant elements of the pivot row */ |
---|
| 1653 | for (pos = 1; pos <= trow_num; pos++) |
---|
| 1654 | { j = trow_ind[pos]; |
---|
| 1655 | #ifdef GLP_DEBUG |
---|
| 1656 | xassert(1 <= j && j <= n); |
---|
| 1657 | #endif |
---|
| 1658 | alfa = s * trow_vec[j]; |
---|
| 1659 | #ifdef GLP_DEBUG |
---|
| 1660 | xassert(alfa != 0.0); |
---|
| 1661 | #endif |
---|
| 1662 | /* lambdaN[j] = ... - alfa * lambdaB[p] - ..., and due to s we |
---|
| 1663 | need to consider only increasing lambdaB[p] */ |
---|
| 1664 | if (alfa > 0.0) |
---|
| 1665 | { /* lambdaN[j] is decreasing */ |
---|
| 1666 | if (stat[j] == GLP_NL || stat[j] == GLP_NF) |
---|
| 1667 | { /* lambdaN[j] has zero lower bound */ |
---|
| 1668 | t = cbar[j] / alfa; |
---|
| 1669 | } |
---|
| 1670 | else |
---|
| 1671 | { /* lambdaN[j] has no lower bound */ |
---|
| 1672 | continue; |
---|
| 1673 | } |
---|
| 1674 | } |
---|
| 1675 | else |
---|
| 1676 | { /* lambdaN[j] is increasing */ |
---|
| 1677 | if (stat[j] == GLP_NU || stat[j] == GLP_NF) |
---|
| 1678 | { /* lambdaN[j] has zero upper bound */ |
---|
| 1679 | t = cbar[j] / alfa; |
---|
| 1680 | } |
---|
| 1681 | else |
---|
| 1682 | { /* lambdaN[j] has no upper bound */ |
---|
| 1683 | continue; |
---|
| 1684 | } |
---|
| 1685 | } |
---|
| 1686 | /* (see comments for the first pass) */ |
---|
| 1687 | if (t < 0.0) t = 0.0; |
---|
| 1688 | /* t is a change of lambdaB[p], on which lambdaN[j] reaches |
---|
| 1689 | its zero (lower or upper) bound; if t <= tmax, all reduced |
---|
| 1690 | costs can violate their zero bounds only within relaxation |
---|
| 1691 | tolerance rtol, so we can choose non-basic variable having |
---|
| 1692 | largest influence coefficient to avoid possible numerical |
---|
| 1693 | instability */ |
---|
| 1694 | if (t <= tmax && big < fabs(alfa)) |
---|
| 1695 | q = j, teta = t, big = fabs(alfa); |
---|
| 1696 | } |
---|
| 1697 | /* something must be chosen on the second pass */ |
---|
| 1698 | xassert(q != 0); |
---|
| 1699 | done: /* store the index of non-basic variable xN[q] chosen */ |
---|
| 1700 | csa->q = q; |
---|
| 1701 | /* store reduced cost of xN[q] in the adjacent basis */ |
---|
| 1702 | csa->new_dq = s * teta; |
---|
| 1703 | return; |
---|
| 1704 | } |
---|
| 1705 | |
---|
| 1706 | #if 1 /* copied from primal */ |
---|
| 1707 | /*********************************************************************** |
---|
| 1708 | * eval_tcol - compute pivot column of the simplex table |
---|
| 1709 | * |
---|
| 1710 | * This routine computes the pivot column of the simplex table, which |
---|
| 1711 | * corresponds to non-basic variable xN[q] chosen. |
---|
| 1712 | * |
---|
| 1713 | * The pivot column is the following vector: |
---|
| 1714 | * |
---|
| 1715 | * tcol = T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q], |
---|
| 1716 | * |
---|
| 1717 | * where B is the current basis matrix, N[q] is a column of the matrix |
---|
| 1718 | * (I|-A) corresponding to variable xN[q]. */ |
---|
| 1719 | |
---|
| 1720 | static void eval_tcol(struct csa *csa) |
---|
| 1721 | { int m = csa->m; |
---|
| 1722 | #ifdef GLP_DEBUG |
---|
| 1723 | int n = csa->n; |
---|
| 1724 | #endif |
---|
| 1725 | int *head = csa->head; |
---|
| 1726 | int q = csa->q; |
---|
| 1727 | int *tcol_ind = csa->tcol_ind; |
---|
| 1728 | double *tcol_vec = csa->tcol_vec; |
---|
| 1729 | double *h = csa->tcol_vec; |
---|
| 1730 | int i, k, nnz; |
---|
| 1731 | #ifdef GLP_DEBUG |
---|
| 1732 | xassert(1 <= q && q <= n); |
---|
| 1733 | #endif |
---|
| 1734 | k = head[m+q]; /* x[k] = xN[q] */ |
---|
| 1735 | #ifdef GLP_DEBUG |
---|
| 1736 | xassert(1 <= k && k <= m+n); |
---|
| 1737 | #endif |
---|
| 1738 | /* construct the right-hand side vector h = - N[q] */ |
---|
| 1739 | for (i = 1; i <= m; i++) |
---|
| 1740 | h[i] = 0.0; |
---|
| 1741 | if (k <= m) |
---|
| 1742 | { /* N[q] is k-th column of submatrix I */ |
---|
| 1743 | h[k] = -1.0; |
---|
| 1744 | } |
---|
| 1745 | else |
---|
| 1746 | { /* N[q] is (k-m)-th column of submatrix (-A) */ |
---|
| 1747 | int *A_ptr = csa->A_ptr; |
---|
| 1748 | int *A_ind = csa->A_ind; |
---|
| 1749 | double *A_val = csa->A_val; |
---|
| 1750 | int beg, end, ptr; |
---|
| 1751 | beg = A_ptr[k-m]; |
---|
| 1752 | end = A_ptr[k-m+1]; |
---|
| 1753 | for (ptr = beg; ptr < end; ptr++) |
---|
| 1754 | h[A_ind[ptr]] = A_val[ptr]; |
---|
| 1755 | } |
---|
| 1756 | /* solve system B * tcol = h */ |
---|
| 1757 | xassert(csa->valid); |
---|
| 1758 | bfd_ftran(csa->bfd, tcol_vec); |
---|
| 1759 | /* construct sparse pattern of the pivot column */ |
---|
| 1760 | nnz = 0; |
---|
| 1761 | for (i = 1; i <= m; i++) |
---|
| 1762 | { if (tcol_vec[i] != 0.0) |
---|
| 1763 | tcol_ind[++nnz] = i; |
---|
| 1764 | } |
---|
| 1765 | csa->tcol_nnz = nnz; |
---|
| 1766 | return; |
---|
| 1767 | } |
---|
| 1768 | #endif |
---|
| 1769 | |
---|
| 1770 | #if 1 /* copied from primal */ |
---|
| 1771 | /*********************************************************************** |
---|
| 1772 | * refine_tcol - refine pivot column of the simplex table |
---|
| 1773 | * |
---|
| 1774 | * This routine refines the pivot column of the simplex table assuming |
---|
| 1775 | * that it was previously computed by the routine eval_tcol. */ |
---|
| 1776 | |
---|
| 1777 | static void refine_tcol(struct csa *csa) |
---|
| 1778 | { int m = csa->m; |
---|
| 1779 | #ifdef GLP_DEBUG |
---|
| 1780 | int n = csa->n; |
---|
| 1781 | #endif |
---|
| 1782 | int *head = csa->head; |
---|
| 1783 | int q = csa->q; |
---|
| 1784 | int *tcol_ind = csa->tcol_ind; |
---|
| 1785 | double *tcol_vec = csa->tcol_vec; |
---|
| 1786 | double *h = csa->work3; |
---|
| 1787 | int i, k, nnz; |
---|
| 1788 | #ifdef GLP_DEBUG |
---|
| 1789 | xassert(1 <= q && q <= n); |
---|
| 1790 | #endif |
---|
| 1791 | k = head[m+q]; /* x[k] = xN[q] */ |
---|
| 1792 | #ifdef GLP_DEBUG |
---|
| 1793 | xassert(1 <= k && k <= m+n); |
---|
| 1794 | #endif |
---|
| 1795 | /* construct the right-hand side vector h = - N[q] */ |
---|
| 1796 | for (i = 1; i <= m; i++) |
---|
| 1797 | h[i] = 0.0; |
---|
| 1798 | if (k <= m) |
---|
| 1799 | { /* N[q] is k-th column of submatrix I */ |
---|
| 1800 | h[k] = -1.0; |
---|
| 1801 | } |
---|
| 1802 | else |
---|
| 1803 | { /* N[q] is (k-m)-th column of submatrix (-A) */ |
---|
| 1804 | int *A_ptr = csa->A_ptr; |
---|
| 1805 | int *A_ind = csa->A_ind; |
---|
| 1806 | double *A_val = csa->A_val; |
---|
| 1807 | int beg, end, ptr; |
---|
| 1808 | beg = A_ptr[k-m]; |
---|
| 1809 | end = A_ptr[k-m+1]; |
---|
| 1810 | for (ptr = beg; ptr < end; ptr++) |
---|
| 1811 | h[A_ind[ptr]] = A_val[ptr]; |
---|
| 1812 | } |
---|
| 1813 | /* refine solution of B * tcol = h */ |
---|
| 1814 | refine_ftran(csa, h, tcol_vec); |
---|
| 1815 | /* construct sparse pattern of the pivot column */ |
---|
| 1816 | nnz = 0; |
---|
| 1817 | for (i = 1; i <= m; i++) |
---|
| 1818 | { if (tcol_vec[i] != 0.0) |
---|
| 1819 | tcol_ind[++nnz] = i; |
---|
| 1820 | } |
---|
| 1821 | csa->tcol_nnz = nnz; |
---|
| 1822 | return; |
---|
| 1823 | } |
---|
| 1824 | #endif |
---|
| 1825 | |
---|
| 1826 | /*********************************************************************** |
---|
| 1827 | * update_cbar - update reduced costs of non-basic variables |
---|
| 1828 | * |
---|
| 1829 | * This routine updates reduced costs of all (except fixed) non-basic |
---|
| 1830 | * variables for the adjacent basis. */ |
---|
| 1831 | |
---|
| 1832 | static void update_cbar(struct csa *csa) |
---|
| 1833 | { |
---|
| 1834 | #ifdef GLP_DEBUG |
---|
| 1835 | int n = csa->n; |
---|
| 1836 | #endif |
---|
| 1837 | double *cbar = csa->cbar; |
---|
| 1838 | int trow_nnz = csa->trow_nnz; |
---|
| 1839 | int *trow_ind = csa->trow_ind; |
---|
| 1840 | double *trow_vec = csa->trow_vec; |
---|
| 1841 | int q = csa->q; |
---|
| 1842 | double new_dq = csa->new_dq; |
---|
| 1843 | int j, pos; |
---|
| 1844 | #ifdef GLP_DEBUG |
---|
| 1845 | xassert(1 <= q && q <= n); |
---|
| 1846 | #endif |
---|
| 1847 | /* set new reduced cost of xN[q] */ |
---|
| 1848 | cbar[q] = new_dq; |
---|
| 1849 | /* update reduced costs of other non-basic variables */ |
---|
| 1850 | if (new_dq == 0.0) goto done; |
---|
| 1851 | for (pos = 1; pos <= trow_nnz; pos++) |
---|
| 1852 | { j = trow_ind[pos]; |
---|
| 1853 | #ifdef GLP_DEBUG |
---|
| 1854 | xassert(1 <= j && j <= n); |
---|
| 1855 | #endif |
---|
| 1856 | if (j != q) |
---|
| 1857 | cbar[j] -= trow_vec[j] * new_dq; |
---|
| 1858 | } |
---|
| 1859 | done: return; |
---|
| 1860 | } |
---|
| 1861 | |
---|
| 1862 | /*********************************************************************** |
---|
| 1863 | * update_bbar - update values of basic variables |
---|
| 1864 | * |
---|
| 1865 | * This routine updates values of all basic variables for the adjacent |
---|
| 1866 | * basis. */ |
---|
| 1867 | |
---|
| 1868 | static void update_bbar(struct csa *csa) |
---|
| 1869 | { |
---|
| 1870 | #ifdef GLP_DEBUG |
---|
| 1871 | int m = csa->m; |
---|
| 1872 | int n = csa->n; |
---|
| 1873 | #endif |
---|
| 1874 | double *bbar = csa->bbar; |
---|
| 1875 | int p = csa->p; |
---|
| 1876 | double delta = csa->delta; |
---|
| 1877 | int q = csa->q; |
---|
| 1878 | int tcol_nnz = csa->tcol_nnz; |
---|
| 1879 | int *tcol_ind = csa->tcol_ind; |
---|
| 1880 | double *tcol_vec = csa->tcol_vec; |
---|
| 1881 | int i, pos; |
---|
| 1882 | double teta; |
---|
| 1883 | #ifdef GLP_DEBUG |
---|
| 1884 | xassert(1 <= p && p <= m); |
---|
| 1885 | xassert(1 <= q && q <= n); |
---|
| 1886 | #endif |
---|
| 1887 | /* determine the change of xN[q] in the adjacent basis */ |
---|
| 1888 | #ifdef GLP_DEBUG |
---|
| 1889 | xassert(tcol_vec[p] != 0.0); |
---|
| 1890 | #endif |
---|
| 1891 | teta = delta / tcol_vec[p]; |
---|
| 1892 | /* set new primal value of xN[q] */ |
---|
| 1893 | bbar[p] = get_xN(csa, q) + teta; |
---|
| 1894 | /* update primal values of other basic variables */ |
---|
| 1895 | if (teta == 0.0) goto done; |
---|
| 1896 | for (pos = 1; pos <= tcol_nnz; pos++) |
---|
| 1897 | { i = tcol_ind[pos]; |
---|
| 1898 | #ifdef GLP_DEBUG |
---|
| 1899 | xassert(1 <= i && i <= m); |
---|
| 1900 | #endif |
---|
| 1901 | if (i != p) |
---|
| 1902 | bbar[i] += tcol_vec[i] * teta; |
---|
| 1903 | } |
---|
| 1904 | done: return; |
---|
| 1905 | } |
---|
| 1906 | |
---|
| 1907 | /*********************************************************************** |
---|
| 1908 | * update_gamma - update steepest edge coefficients |
---|
| 1909 | * |
---|
| 1910 | * This routine updates steepest-edge coefficients for the adjacent |
---|
| 1911 | * basis. */ |
---|
| 1912 | |
---|
| 1913 | static void update_gamma(struct csa *csa) |
---|
| 1914 | { int m = csa->m; |
---|
| 1915 | #ifdef GLP_DEBUG |
---|
| 1916 | int n = csa->n; |
---|
| 1917 | #endif |
---|
| 1918 | char *type = csa->type; |
---|
| 1919 | int *head = csa->head; |
---|
| 1920 | char *refsp = csa->refsp; |
---|
| 1921 | double *gamma = csa->gamma; |
---|
| 1922 | int p = csa->p; |
---|
| 1923 | int trow_nnz = csa->trow_nnz; |
---|
| 1924 | int *trow_ind = csa->trow_ind; |
---|
| 1925 | double *trow_vec = csa->trow_vec; |
---|
| 1926 | int q = csa->q; |
---|
| 1927 | int tcol_nnz = csa->tcol_nnz; |
---|
| 1928 | int *tcol_ind = csa->tcol_ind; |
---|
| 1929 | double *tcol_vec = csa->tcol_vec; |
---|
| 1930 | double *u = csa->work3; |
---|
| 1931 | int i, j, k,pos; |
---|
| 1932 | double gamma_p, eta_p, pivot, t, t1, t2; |
---|
| 1933 | #ifdef GLP_DEBUG |
---|
| 1934 | xassert(1 <= p && p <= m); |
---|
| 1935 | xassert(1 <= q && q <= n); |
---|
| 1936 | #endif |
---|
| 1937 | /* the basis changes, so decrease the count */ |
---|
| 1938 | xassert(csa->refct > 0); |
---|
| 1939 | csa->refct--; |
---|
| 1940 | /* recompute gamma[p] for the current basis more accurately and |
---|
| 1941 | compute auxiliary vector u */ |
---|
| 1942 | #ifdef GLP_DEBUG |
---|
| 1943 | xassert(type[head[p]] != GLP_FR); |
---|
| 1944 | #endif |
---|
| 1945 | gamma_p = eta_p = (refsp[head[p]] ? 1.0 : 0.0); |
---|
| 1946 | for (i = 1; i <= m; i++) u[i] = 0.0; |
---|
| 1947 | for (pos = 1; pos <= trow_nnz; pos++) |
---|
| 1948 | { j = trow_ind[pos]; |
---|
| 1949 | #ifdef GLP_DEBUG |
---|
| 1950 | xassert(1 <= j && j <= n); |
---|
| 1951 | #endif |
---|
| 1952 | k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 1953 | #ifdef GLP_DEBUG |
---|
| 1954 | xassert(1 <= k && k <= m+n); |
---|
| 1955 | xassert(type[k] != GLP_FX); |
---|
| 1956 | #endif |
---|
| 1957 | if (!refsp[k]) continue; |
---|
| 1958 | t = trow_vec[j]; |
---|
| 1959 | gamma_p += t * t; |
---|
| 1960 | /* u := u + N[j] * delta[j] * trow[j] */ |
---|
| 1961 | if (k <= m) |
---|
| 1962 | { /* N[k] = k-j stolbec submatrix I */ |
---|
| 1963 | u[k] += t; |
---|
| 1964 | } |
---|
| 1965 | else |
---|
| 1966 | { /* N[k] = k-m-k stolbec (-A) */ |
---|
| 1967 | int *A_ptr = csa->A_ptr; |
---|
| 1968 | int *A_ind = csa->A_ind; |
---|
| 1969 | double *A_val = csa->A_val; |
---|
| 1970 | int beg, end, ptr; |
---|
| 1971 | beg = A_ptr[k-m]; |
---|
| 1972 | end = A_ptr[k-m+1]; |
---|
| 1973 | for (ptr = beg; ptr < end; ptr++) |
---|
| 1974 | u[A_ind[ptr]] -= t * A_val[ptr]; |
---|
| 1975 | } |
---|
| 1976 | } |
---|
| 1977 | xassert(csa->valid); |
---|
| 1978 | bfd_ftran(csa->bfd, u); |
---|
| 1979 | /* update gamma[i] for other basic variables (except xB[p] and |
---|
| 1980 | free variables) */ |
---|
| 1981 | pivot = tcol_vec[p]; |
---|
| 1982 | #ifdef GLP_DEBUG |
---|
| 1983 | xassert(pivot != 0.0); |
---|
| 1984 | #endif |
---|
| 1985 | for (pos = 1; pos <= tcol_nnz; pos++) |
---|
| 1986 | { i = tcol_ind[pos]; |
---|
| 1987 | #ifdef GLP_DEBUG |
---|
| 1988 | xassert(1 <= i && i <= m); |
---|
| 1989 | #endif |
---|
| 1990 | k = head[i]; |
---|
| 1991 | #ifdef GLP_DEBUG |
---|
| 1992 | xassert(1 <= k && k <= m+n); |
---|
| 1993 | #endif |
---|
| 1994 | /* skip xB[p] */ |
---|
| 1995 | if (i == p) continue; |
---|
| 1996 | /* skip free basic variable */ |
---|
| 1997 | if (type[head[i]] == GLP_FR) |
---|
| 1998 | { |
---|
| 1999 | #ifdef GLP_DEBUG |
---|
| 2000 | xassert(gamma[i] == 1.0); |
---|
| 2001 | #endif |
---|
| 2002 | continue; |
---|
| 2003 | } |
---|
| 2004 | /* compute gamma[i] for the adjacent basis */ |
---|
| 2005 | t = tcol_vec[i] / pivot; |
---|
| 2006 | t1 = gamma[i] + t * t * gamma_p + 2.0 * t * u[i]; |
---|
| 2007 | t2 = (refsp[k] ? 1.0 : 0.0) + eta_p * t * t; |
---|
| 2008 | gamma[i] = (t1 >= t2 ? t1 : t2); |
---|
| 2009 | /* (though gamma[i] can be exact zero, because the reference |
---|
| 2010 | space does not include non-basic fixed variables) */ |
---|
| 2011 | if (gamma[i] < DBL_EPSILON) gamma[i] = DBL_EPSILON; |
---|
| 2012 | } |
---|
| 2013 | /* compute gamma[p] for the adjacent basis */ |
---|
| 2014 | if (type[head[m+q]] == GLP_FR) |
---|
| 2015 | gamma[p] = 1.0; |
---|
| 2016 | else |
---|
| 2017 | { gamma[p] = gamma_p / (pivot * pivot); |
---|
| 2018 | if (gamma[p] < DBL_EPSILON) gamma[p] = DBL_EPSILON; |
---|
| 2019 | } |
---|
| 2020 | /* if xB[p], which becomes xN[q] in the adjacent basis, is fixed |
---|
| 2021 | and belongs to the reference space, remove it from there, and |
---|
| 2022 | change all gamma's appropriately */ |
---|
| 2023 | k = head[p]; |
---|
| 2024 | if (type[k] == GLP_FX && refsp[k]) |
---|
| 2025 | { refsp[k] = 0; |
---|
| 2026 | for (pos = 1; pos <= tcol_nnz; pos++) |
---|
| 2027 | { i = tcol_ind[pos]; |
---|
| 2028 | if (i == p) |
---|
| 2029 | { if (type[head[m+q]] == GLP_FR) continue; |
---|
| 2030 | t = 1.0 / tcol_vec[p]; |
---|
| 2031 | } |
---|
| 2032 | else |
---|
| 2033 | { if (type[head[i]] == GLP_FR) continue; |
---|
| 2034 | t = tcol_vec[i] / tcol_vec[p]; |
---|
| 2035 | } |
---|
| 2036 | gamma[i] -= t * t; |
---|
| 2037 | if (gamma[i] < DBL_EPSILON) gamma[i] = DBL_EPSILON; |
---|
| 2038 | } |
---|
| 2039 | } |
---|
| 2040 | return; |
---|
| 2041 | } |
---|
| 2042 | |
---|
| 2043 | #if 1 /* copied from primal */ |
---|
| 2044 | /*********************************************************************** |
---|
| 2045 | * err_in_bbar - compute maximal relative error in primal solution |
---|
| 2046 | * |
---|
| 2047 | * This routine returns maximal relative error: |
---|
| 2048 | * |
---|
| 2049 | * max |beta[i] - bbar[i]| / (1 + |beta[i]|), |
---|
| 2050 | * |
---|
| 2051 | * where beta and bbar are, respectively, directly computed and the |
---|
| 2052 | * current (updated) values of basic variables. |
---|
| 2053 | * |
---|
| 2054 | * NOTE: The routine is intended only for debugginig purposes. */ |
---|
| 2055 | |
---|
| 2056 | static double err_in_bbar(struct csa *csa) |
---|
| 2057 | { int m = csa->m; |
---|
| 2058 | double *bbar = csa->bbar; |
---|
| 2059 | int i; |
---|
| 2060 | double e, emax, *beta; |
---|
| 2061 | beta = xcalloc(1+m, sizeof(double)); |
---|
| 2062 | eval_beta(csa, beta); |
---|
| 2063 | emax = 0.0; |
---|
| 2064 | for (i = 1; i <= m; i++) |
---|
| 2065 | { e = fabs(beta[i] - bbar[i]) / (1.0 + fabs(beta[i])); |
---|
| 2066 | if (emax < e) emax = e; |
---|
| 2067 | } |
---|
| 2068 | xfree(beta); |
---|
| 2069 | return emax; |
---|
| 2070 | } |
---|
| 2071 | #endif |
---|
| 2072 | |
---|
| 2073 | #if 1 /* copied from primal */ |
---|
| 2074 | /*********************************************************************** |
---|
| 2075 | * err_in_cbar - compute maximal relative error in dual solution |
---|
| 2076 | * |
---|
| 2077 | * This routine returns maximal relative error: |
---|
| 2078 | * |
---|
| 2079 | * max |cost[j] - cbar[j]| / (1 + |cost[j]|), |
---|
| 2080 | * |
---|
| 2081 | * where cost and cbar are, respectively, directly computed and the |
---|
| 2082 | * current (updated) reduced costs of non-basic non-fixed variables. |
---|
| 2083 | * |
---|
| 2084 | * NOTE: The routine is intended only for debugginig purposes. */ |
---|
| 2085 | |
---|
| 2086 | static double err_in_cbar(struct csa *csa) |
---|
| 2087 | { int m = csa->m; |
---|
| 2088 | int n = csa->n; |
---|
| 2089 | char *stat = csa->stat; |
---|
| 2090 | double *cbar = csa->cbar; |
---|
| 2091 | int j; |
---|
| 2092 | double e, emax, cost, *pi; |
---|
| 2093 | pi = xcalloc(1+m, sizeof(double)); |
---|
| 2094 | eval_pi(csa, pi); |
---|
| 2095 | emax = 0.0; |
---|
| 2096 | for (j = 1; j <= n; j++) |
---|
| 2097 | { if (stat[j] == GLP_NS) continue; |
---|
| 2098 | cost = eval_cost(csa, pi, j); |
---|
| 2099 | e = fabs(cost - cbar[j]) / (1.0 + fabs(cost)); |
---|
| 2100 | if (emax < e) emax = e; |
---|
| 2101 | } |
---|
| 2102 | xfree(pi); |
---|
| 2103 | return emax; |
---|
| 2104 | } |
---|
| 2105 | #endif |
---|
| 2106 | |
---|
| 2107 | /*********************************************************************** |
---|
| 2108 | * err_in_gamma - compute maximal relative error in steepest edge cff. |
---|
| 2109 | * |
---|
| 2110 | * This routine returns maximal relative error: |
---|
| 2111 | * |
---|
| 2112 | * max |gamma'[j] - gamma[j]| / (1 + |gamma'[j]), |
---|
| 2113 | * |
---|
| 2114 | * where gamma'[j] and gamma[j] are, respectively, directly computed |
---|
| 2115 | * and the current (updated) steepest edge coefficients for non-basic |
---|
| 2116 | * non-fixed variable x[j]. |
---|
| 2117 | * |
---|
| 2118 | * NOTE: The routine is intended only for debugginig purposes. */ |
---|
| 2119 | |
---|
| 2120 | static double err_in_gamma(struct csa *csa) |
---|
| 2121 | { int m = csa->m; |
---|
| 2122 | char *type = csa->type; |
---|
| 2123 | int *head = csa->head; |
---|
| 2124 | double *gamma = csa->gamma; |
---|
| 2125 | double *exact = csa->work4; |
---|
| 2126 | int i; |
---|
| 2127 | double e, emax, temp; |
---|
| 2128 | eval_gamma(csa, exact); |
---|
| 2129 | emax = 0.0; |
---|
| 2130 | for (i = 1; i <= m; i++) |
---|
| 2131 | { if (type[head[i]] == GLP_FR) |
---|
| 2132 | { xassert(gamma[i] == 1.0); |
---|
| 2133 | xassert(exact[i] == 1.0); |
---|
| 2134 | continue; |
---|
| 2135 | } |
---|
| 2136 | temp = exact[i]; |
---|
| 2137 | e = fabs(temp - gamma[i]) / (1.0 + fabs(temp)); |
---|
| 2138 | if (emax < e) emax = e; |
---|
| 2139 | } |
---|
| 2140 | return emax; |
---|
| 2141 | } |
---|
| 2142 | |
---|
| 2143 | /*********************************************************************** |
---|
| 2144 | * change_basis - change basis header |
---|
| 2145 | * |
---|
| 2146 | * This routine changes the basis header to make it corresponding to |
---|
| 2147 | * the adjacent basis. */ |
---|
| 2148 | |
---|
| 2149 | static void change_basis(struct csa *csa) |
---|
| 2150 | { int m = csa->m; |
---|
| 2151 | #ifdef GLP_DEBUG |
---|
| 2152 | int n = csa->n; |
---|
| 2153 | #endif |
---|
| 2154 | char *type = csa->type; |
---|
| 2155 | int *head = csa->head; |
---|
| 2156 | #if 1 /* 06/IV-2009 */ |
---|
| 2157 | int *bind = csa->bind; |
---|
| 2158 | #endif |
---|
| 2159 | char *stat = csa->stat; |
---|
| 2160 | int p = csa->p; |
---|
| 2161 | double delta = csa->delta; |
---|
| 2162 | int q = csa->q; |
---|
| 2163 | int k; |
---|
| 2164 | /* xB[p] leaves the basis, xN[q] enters the basis */ |
---|
| 2165 | #ifdef GLP_DEBUG |
---|
| 2166 | xassert(1 <= p && p <= m); |
---|
| 2167 | xassert(1 <= q && q <= n); |
---|
| 2168 | #endif |
---|
| 2169 | /* xB[p] <-> xN[q] */ |
---|
| 2170 | k = head[p], head[p] = head[m+q], head[m+q] = k; |
---|
| 2171 | #if 1 /* 06/IV-2009 */ |
---|
| 2172 | bind[head[p]] = p, bind[head[m+q]] = m + q; |
---|
| 2173 | #endif |
---|
| 2174 | if (type[k] == GLP_FX) |
---|
| 2175 | stat[q] = GLP_NS; |
---|
| 2176 | else if (delta > 0.0) |
---|
| 2177 | { |
---|
| 2178 | #ifdef GLP_DEBUG |
---|
| 2179 | xassert(type[k] == GLP_LO || type[k] == GLP_DB); |
---|
| 2180 | #endif |
---|
| 2181 | stat[q] = GLP_NL; |
---|
| 2182 | } |
---|
| 2183 | else /* delta < 0.0 */ |
---|
| 2184 | { |
---|
| 2185 | #ifdef GLP_DEBUG |
---|
| 2186 | xassert(type[k] == GLP_UP || type[k] == GLP_DB); |
---|
| 2187 | #endif |
---|
| 2188 | stat[q] = GLP_NU; |
---|
| 2189 | } |
---|
| 2190 | return; |
---|
| 2191 | } |
---|
| 2192 | |
---|
| 2193 | /*********************************************************************** |
---|
| 2194 | * check_feas - check dual feasibility of basic solution |
---|
| 2195 | * |
---|
| 2196 | * If the current basic solution is dual feasible within a tolerance, |
---|
| 2197 | * this routine returns zero, otherwise it returns non-zero. */ |
---|
| 2198 | |
---|
| 2199 | static int check_feas(struct csa *csa, double tol_dj) |
---|
| 2200 | { int m = csa->m; |
---|
| 2201 | int n = csa->n; |
---|
| 2202 | char *orig_type = csa->orig_type; |
---|
| 2203 | int *head = csa->head; |
---|
| 2204 | double *cbar = csa->cbar; |
---|
| 2205 | int j, k; |
---|
| 2206 | for (j = 1; j <= n; j++) |
---|
| 2207 | { k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 2208 | #ifdef GLP_DEBUG |
---|
| 2209 | xassert(1 <= k && k <= m+n); |
---|
| 2210 | #endif |
---|
| 2211 | if (cbar[j] < - tol_dj) |
---|
| 2212 | if (orig_type[k] == GLP_LO || orig_type[k] == GLP_FR) |
---|
| 2213 | return 1; |
---|
| 2214 | if (cbar[j] > + tol_dj) |
---|
| 2215 | if (orig_type[k] == GLP_UP || orig_type[k] == GLP_FR) |
---|
| 2216 | return 1; |
---|
| 2217 | } |
---|
| 2218 | return 0; |
---|
| 2219 | } |
---|
| 2220 | |
---|
| 2221 | /*********************************************************************** |
---|
| 2222 | * set_aux_bnds - assign auxiliary bounds to variables |
---|
| 2223 | * |
---|
| 2224 | * This routine assigns auxiliary bounds to variables to construct an |
---|
| 2225 | * LP problem solved on phase I. */ |
---|
| 2226 | |
---|
| 2227 | static void set_aux_bnds(struct csa *csa) |
---|
| 2228 | { int m = csa->m; |
---|
| 2229 | int n = csa->n; |
---|
| 2230 | char *type = csa->type; |
---|
| 2231 | double *lb = csa->lb; |
---|
| 2232 | double *ub = csa->ub; |
---|
| 2233 | char *orig_type = csa->orig_type; |
---|
| 2234 | int *head = csa->head; |
---|
| 2235 | char *stat = csa->stat; |
---|
| 2236 | double *cbar = csa->cbar; |
---|
| 2237 | int j, k; |
---|
| 2238 | for (k = 1; k <= m+n; k++) |
---|
| 2239 | { switch (orig_type[k]) |
---|
| 2240 | { case GLP_FR: |
---|
| 2241 | #if 0 |
---|
| 2242 | type[k] = GLP_DB, lb[k] = -1.0, ub[k] = +1.0; |
---|
| 2243 | #else |
---|
| 2244 | /* to force free variables to enter the basis */ |
---|
| 2245 | type[k] = GLP_DB, lb[k] = -1e3, ub[k] = +1e3; |
---|
| 2246 | #endif |
---|
| 2247 | break; |
---|
| 2248 | case GLP_LO: |
---|
| 2249 | type[k] = GLP_DB, lb[k] = 0.0, ub[k] = +1.0; |
---|
| 2250 | break; |
---|
| 2251 | case GLP_UP: |
---|
| 2252 | type[k] = GLP_DB, lb[k] = -1.0, ub[k] = 0.0; |
---|
| 2253 | break; |
---|
| 2254 | case GLP_DB: |
---|
| 2255 | case GLP_FX: |
---|
| 2256 | type[k] = GLP_FX, lb[k] = ub[k] = 0.0; |
---|
| 2257 | break; |
---|
| 2258 | default: |
---|
| 2259 | xassert(orig_type != orig_type); |
---|
| 2260 | } |
---|
| 2261 | } |
---|
| 2262 | for (j = 1; j <= n; j++) |
---|
| 2263 | { k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 2264 | #ifdef GLP_DEBUG |
---|
| 2265 | xassert(1 <= k && k <= m+n); |
---|
| 2266 | #endif |
---|
| 2267 | if (type[k] == GLP_FX) |
---|
| 2268 | stat[j] = GLP_NS; |
---|
| 2269 | else if (cbar[j] >= 0.0) |
---|
| 2270 | stat[j] = GLP_NL; |
---|
| 2271 | else |
---|
| 2272 | stat[j] = GLP_NU; |
---|
| 2273 | } |
---|
| 2274 | return; |
---|
| 2275 | } |
---|
| 2276 | |
---|
| 2277 | /*********************************************************************** |
---|
| 2278 | * set_orig_bnds - restore original bounds of variables |
---|
| 2279 | * |
---|
| 2280 | * This routine restores original types and bounds of variables and |
---|
| 2281 | * determines statuses of non-basic variables assuming that the current |
---|
| 2282 | * basis is dual feasible. */ |
---|
| 2283 | |
---|
| 2284 | static void set_orig_bnds(struct csa *csa) |
---|
| 2285 | { int m = csa->m; |
---|
| 2286 | int n = csa->n; |
---|
| 2287 | char *type = csa->type; |
---|
| 2288 | double *lb = csa->lb; |
---|
| 2289 | double *ub = csa->ub; |
---|
| 2290 | char *orig_type = csa->orig_type; |
---|
| 2291 | double *orig_lb = csa->orig_lb; |
---|
| 2292 | double *orig_ub = csa->orig_ub; |
---|
| 2293 | int *head = csa->head; |
---|
| 2294 | char *stat = csa->stat; |
---|
| 2295 | double *cbar = csa->cbar; |
---|
| 2296 | int j, k; |
---|
| 2297 | memcpy(&type[1], &orig_type[1], (m+n) * sizeof(char)); |
---|
| 2298 | memcpy(&lb[1], &orig_lb[1], (m+n) * sizeof(double)); |
---|
| 2299 | memcpy(&ub[1], &orig_ub[1], (m+n) * sizeof(double)); |
---|
| 2300 | for (j = 1; j <= n; j++) |
---|
| 2301 | { k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 2302 | #ifdef GLP_DEBUG |
---|
| 2303 | xassert(1 <= k && k <= m+n); |
---|
| 2304 | #endif |
---|
| 2305 | switch (type[k]) |
---|
| 2306 | { case GLP_FR: |
---|
| 2307 | stat[j] = GLP_NF; |
---|
| 2308 | break; |
---|
| 2309 | case GLP_LO: |
---|
| 2310 | stat[j] = GLP_NL; |
---|
| 2311 | break; |
---|
| 2312 | case GLP_UP: |
---|
| 2313 | stat[j] = GLP_NU; |
---|
| 2314 | break; |
---|
| 2315 | case GLP_DB: |
---|
| 2316 | if (cbar[j] >= +DBL_EPSILON) |
---|
| 2317 | stat[j] = GLP_NL; |
---|
| 2318 | else if (cbar[j] <= -DBL_EPSILON) |
---|
| 2319 | stat[j] = GLP_NU; |
---|
| 2320 | else if (fabs(lb[k]) <= fabs(ub[k])) |
---|
| 2321 | stat[j] = GLP_NL; |
---|
| 2322 | else |
---|
| 2323 | stat[j] = GLP_NU; |
---|
| 2324 | break; |
---|
| 2325 | case GLP_FX: |
---|
| 2326 | stat[j] = GLP_NS; |
---|
| 2327 | break; |
---|
| 2328 | default: |
---|
| 2329 | xassert(type != type); |
---|
| 2330 | } |
---|
| 2331 | } |
---|
| 2332 | return; |
---|
| 2333 | } |
---|
| 2334 | |
---|
| 2335 | /*********************************************************************** |
---|
| 2336 | * check_stab - check numerical stability of basic solution |
---|
| 2337 | * |
---|
| 2338 | * If the current basic solution is dual feasible within a tolerance, |
---|
| 2339 | * this routine returns zero, otherwise it returns non-zero. */ |
---|
| 2340 | |
---|
| 2341 | static int check_stab(struct csa *csa, double tol_dj) |
---|
| 2342 | { int n = csa->n; |
---|
| 2343 | char *stat = csa->stat; |
---|
| 2344 | double *cbar = csa->cbar; |
---|
| 2345 | int j; |
---|
| 2346 | for (j = 1; j <= n; j++) |
---|
| 2347 | { if (cbar[j] < - tol_dj) |
---|
| 2348 | if (stat[j] == GLP_NL || stat[j] == GLP_NF) return 1; |
---|
| 2349 | if (cbar[j] > + tol_dj) |
---|
| 2350 | if (stat[j] == GLP_NU || stat[j] == GLP_NF) return 1; |
---|
| 2351 | } |
---|
| 2352 | return 0; |
---|
| 2353 | } |
---|
| 2354 | |
---|
| 2355 | #if 1 /* copied from primal */ |
---|
| 2356 | /*********************************************************************** |
---|
| 2357 | * eval_obj - compute original objective function |
---|
| 2358 | * |
---|
| 2359 | * This routine computes the current value of the original objective |
---|
| 2360 | * function. */ |
---|
| 2361 | |
---|
| 2362 | static double eval_obj(struct csa *csa) |
---|
| 2363 | { int m = csa->m; |
---|
| 2364 | int n = csa->n; |
---|
| 2365 | double *obj = csa->obj; |
---|
| 2366 | int *head = csa->head; |
---|
| 2367 | double *bbar = csa->bbar; |
---|
| 2368 | int i, j, k; |
---|
| 2369 | double sum; |
---|
| 2370 | sum = obj[0]; |
---|
| 2371 | /* walk through the list of basic variables */ |
---|
| 2372 | for (i = 1; i <= m; i++) |
---|
| 2373 | { k = head[i]; /* x[k] = xB[i] */ |
---|
| 2374 | #ifdef GLP_DEBUG |
---|
| 2375 | xassert(1 <= k && k <= m+n); |
---|
| 2376 | #endif |
---|
| 2377 | if (k > m) |
---|
| 2378 | sum += obj[k-m] * bbar[i]; |
---|
| 2379 | } |
---|
| 2380 | /* walk through the list of non-basic variables */ |
---|
| 2381 | for (j = 1; j <= n; j++) |
---|
| 2382 | { k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 2383 | #ifdef GLP_DEBUG |
---|
| 2384 | xassert(1 <= k && k <= m+n); |
---|
| 2385 | #endif |
---|
| 2386 | if (k > m) |
---|
| 2387 | sum += obj[k-m] * get_xN(csa, j); |
---|
| 2388 | } |
---|
| 2389 | return sum; |
---|
| 2390 | } |
---|
| 2391 | #endif |
---|
| 2392 | |
---|
| 2393 | /*********************************************************************** |
---|
| 2394 | * display - display the search progress |
---|
| 2395 | * |
---|
| 2396 | * This routine displays some information about the search progress. */ |
---|
| 2397 | |
---|
| 2398 | static void display(struct csa *csa, const glp_smcp *parm, int spec) |
---|
| 2399 | { int m = csa->m; |
---|
| 2400 | int n = csa->n; |
---|
| 2401 | double *coef = csa->coef; |
---|
| 2402 | char *orig_type = csa->orig_type; |
---|
| 2403 | int *head = csa->head; |
---|
| 2404 | char *stat = csa->stat; |
---|
| 2405 | int phase = csa->phase; |
---|
| 2406 | double *bbar = csa->bbar; |
---|
| 2407 | double *cbar = csa->cbar; |
---|
| 2408 | int i, j, cnt; |
---|
| 2409 | double sum; |
---|
| 2410 | if (parm->msg_lev < GLP_MSG_ON) goto skip; |
---|
| 2411 | if (parm->out_dly > 0 && |
---|
| 2412 | 1000.0 * xdifftime(xtime(), csa->tm_beg) < parm->out_dly) |
---|
| 2413 | goto skip; |
---|
| 2414 | if (csa->it_cnt == csa->it_dpy) goto skip; |
---|
| 2415 | if (!spec && csa->it_cnt % parm->out_frq != 0) goto skip; |
---|
| 2416 | /* compute the sum of dual infeasibilities */ |
---|
| 2417 | sum = 0.0; |
---|
| 2418 | if (phase == 1) |
---|
| 2419 | { for (i = 1; i <= m; i++) |
---|
| 2420 | sum -= coef[head[i]] * bbar[i]; |
---|
| 2421 | for (j = 1; j <= n; j++) |
---|
| 2422 | sum -= coef[head[m+j]] * get_xN(csa, j); |
---|
| 2423 | } |
---|
| 2424 | else |
---|
| 2425 | { for (j = 1; j <= n; j++) |
---|
| 2426 | { if (cbar[j] < 0.0) |
---|
| 2427 | if (stat[j] == GLP_NL || stat[j] == GLP_NF) |
---|
| 2428 | sum -= cbar[j]; |
---|
| 2429 | if (cbar[j] > 0.0) |
---|
| 2430 | if (stat[j] == GLP_NU || stat[j] == GLP_NF) |
---|
| 2431 | sum += cbar[j]; |
---|
| 2432 | } |
---|
| 2433 | } |
---|
| 2434 | /* determine the number of basic fixed variables */ |
---|
| 2435 | cnt = 0; |
---|
| 2436 | for (i = 1; i <= m; i++) |
---|
| 2437 | if (orig_type[head[i]] == GLP_FX) cnt++; |
---|
| 2438 | if (csa->phase == 1) |
---|
| 2439 | xprintf(" %6d: %24s infeas = %10.3e (%d)\n", |
---|
| 2440 | csa->it_cnt, "", sum, cnt); |
---|
| 2441 | else |
---|
| 2442 | xprintf("|%6d: obj = %17.9e infeas = %10.3e (%d)\n", |
---|
| 2443 | csa->it_cnt, eval_obj(csa), sum, cnt); |
---|
| 2444 | csa->it_dpy = csa->it_cnt; |
---|
| 2445 | skip: return; |
---|
| 2446 | } |
---|
| 2447 | |
---|
| 2448 | #if 1 /* copied from primal */ |
---|
| 2449 | /*********************************************************************** |
---|
| 2450 | * store_sol - store basic solution back to the problem object |
---|
| 2451 | * |
---|
| 2452 | * This routine stores basic solution components back to the problem |
---|
| 2453 | * object. */ |
---|
| 2454 | |
---|
| 2455 | static void store_sol(struct csa *csa, glp_prob *lp, int p_stat, |
---|
| 2456 | int d_stat, int ray) |
---|
| 2457 | { int m = csa->m; |
---|
| 2458 | int n = csa->n; |
---|
| 2459 | double zeta = csa->zeta; |
---|
| 2460 | int *head = csa->head; |
---|
| 2461 | char *stat = csa->stat; |
---|
| 2462 | double *bbar = csa->bbar; |
---|
| 2463 | double *cbar = csa->cbar; |
---|
| 2464 | int i, j, k; |
---|
| 2465 | #ifdef GLP_DEBUG |
---|
| 2466 | xassert(lp->m == m); |
---|
| 2467 | xassert(lp->n == n); |
---|
| 2468 | #endif |
---|
| 2469 | /* basis factorization */ |
---|
| 2470 | #ifdef GLP_DEBUG |
---|
| 2471 | xassert(!lp->valid && lp->bfd == NULL); |
---|
| 2472 | xassert(csa->valid && csa->bfd != NULL); |
---|
| 2473 | #endif |
---|
| 2474 | lp->valid = 1, csa->valid = 0; |
---|
| 2475 | lp->bfd = csa->bfd, csa->bfd = NULL; |
---|
| 2476 | memcpy(&lp->head[1], &head[1], m * sizeof(int)); |
---|
| 2477 | /* basic solution status */ |
---|
| 2478 | lp->pbs_stat = p_stat; |
---|
| 2479 | lp->dbs_stat = d_stat; |
---|
| 2480 | /* objective function value */ |
---|
| 2481 | lp->obj_val = eval_obj(csa); |
---|
| 2482 | /* simplex iteration count */ |
---|
| 2483 | lp->it_cnt = csa->it_cnt; |
---|
| 2484 | /* unbounded ray */ |
---|
| 2485 | lp->some = ray; |
---|
| 2486 | /* basic variables */ |
---|
| 2487 | for (i = 1; i <= m; i++) |
---|
| 2488 | { k = head[i]; /* x[k] = xB[i] */ |
---|
| 2489 | #ifdef GLP_DEBUG |
---|
| 2490 | xassert(1 <= k && k <= m+n); |
---|
| 2491 | #endif |
---|
| 2492 | if (k <= m) |
---|
| 2493 | { GLPROW *row = lp->row[k]; |
---|
| 2494 | row->stat = GLP_BS; |
---|
| 2495 | row->bind = i; |
---|
| 2496 | row->prim = bbar[i] / row->rii; |
---|
| 2497 | row->dual = 0.0; |
---|
| 2498 | } |
---|
| 2499 | else |
---|
| 2500 | { GLPCOL *col = lp->col[k-m]; |
---|
| 2501 | col->stat = GLP_BS; |
---|
| 2502 | col->bind = i; |
---|
| 2503 | col->prim = bbar[i] * col->sjj; |
---|
| 2504 | col->dual = 0.0; |
---|
| 2505 | } |
---|
| 2506 | } |
---|
| 2507 | /* non-basic variables */ |
---|
| 2508 | for (j = 1; j <= n; j++) |
---|
| 2509 | { k = head[m+j]; /* x[k] = xN[j] */ |
---|
| 2510 | #ifdef GLP_DEBUG |
---|
| 2511 | xassert(1 <= k && k <= m+n); |
---|
| 2512 | #endif |
---|
| 2513 | if (k <= m) |
---|
| 2514 | { GLPROW *row = lp->row[k]; |
---|
| 2515 | row->stat = stat[j]; |
---|
| 2516 | row->bind = 0; |
---|
| 2517 | #if 0 |
---|
| 2518 | row->prim = get_xN(csa, j) / row->rii; |
---|
| 2519 | #else |
---|
| 2520 | switch (stat[j]) |
---|
| 2521 | { case GLP_NL: |
---|
| 2522 | row->prim = row->lb; break; |
---|
| 2523 | case GLP_NU: |
---|
| 2524 | row->prim = row->ub; break; |
---|
| 2525 | case GLP_NF: |
---|
| 2526 | row->prim = 0.0; break; |
---|
| 2527 | case GLP_NS: |
---|
| 2528 | row->prim = row->lb; break; |
---|
| 2529 | default: |
---|
| 2530 | xassert(stat != stat); |
---|
| 2531 | } |
---|
| 2532 | #endif |
---|
| 2533 | row->dual = (cbar[j] * row->rii) / zeta; |
---|
| 2534 | } |
---|
| 2535 | else |
---|
| 2536 | { GLPCOL *col = lp->col[k-m]; |
---|
| 2537 | col->stat = stat[j]; |
---|
| 2538 | col->bind = 0; |
---|
| 2539 | #if 0 |
---|
| 2540 | col->prim = get_xN(csa, j) * col->sjj; |
---|
| 2541 | #else |
---|
| 2542 | switch (stat[j]) |
---|
| 2543 | { case GLP_NL: |
---|
| 2544 | col->prim = col->lb; break; |
---|
| 2545 | case GLP_NU: |
---|
| 2546 | col->prim = col->ub; break; |
---|
| 2547 | case GLP_NF: |
---|
| 2548 | col->prim = 0.0; break; |
---|
| 2549 | case GLP_NS: |
---|
| 2550 | col->prim = col->lb; break; |
---|
| 2551 | default: |
---|
| 2552 | xassert(stat != stat); |
---|
| 2553 | } |
---|
| 2554 | #endif |
---|
| 2555 | col->dual = (cbar[j] / col->sjj) / zeta; |
---|
| 2556 | } |
---|
| 2557 | } |
---|
| 2558 | return; |
---|
| 2559 | } |
---|
| 2560 | #endif |
---|
| 2561 | |
---|
| 2562 | /*********************************************************************** |
---|
| 2563 | * free_csa - deallocate common storage area |
---|
| 2564 | * |
---|
| 2565 | * This routine frees all the memory allocated to arrays in the common |
---|
| 2566 | * storage area (CSA). */ |
---|
| 2567 | |
---|
| 2568 | static void free_csa(struct csa *csa) |
---|
| 2569 | { xfree(csa->type); |
---|
| 2570 | xfree(csa->lb); |
---|
| 2571 | xfree(csa->ub); |
---|
| 2572 | xfree(csa->coef); |
---|
| 2573 | xfree(csa->orig_type); |
---|
| 2574 | xfree(csa->orig_lb); |
---|
| 2575 | xfree(csa->orig_ub); |
---|
| 2576 | xfree(csa->obj); |
---|
| 2577 | xfree(csa->A_ptr); |
---|
| 2578 | xfree(csa->A_ind); |
---|
| 2579 | xfree(csa->A_val); |
---|
| 2580 | #if 1 /* 06/IV-2009 */ |
---|
| 2581 | xfree(csa->AT_ptr); |
---|
| 2582 | xfree(csa->AT_ind); |
---|
| 2583 | xfree(csa->AT_val); |
---|
| 2584 | #endif |
---|
| 2585 | xfree(csa->head); |
---|
| 2586 | #if 1 /* 06/IV-2009 */ |
---|
| 2587 | xfree(csa->bind); |
---|
| 2588 | #endif |
---|
| 2589 | xfree(csa->stat); |
---|
| 2590 | #if 0 /* 06/IV-2009 */ |
---|
| 2591 | xfree(csa->N_ptr); |
---|
| 2592 | xfree(csa->N_len); |
---|
| 2593 | xfree(csa->N_ind); |
---|
| 2594 | xfree(csa->N_val); |
---|
| 2595 | #endif |
---|
| 2596 | xfree(csa->bbar); |
---|
| 2597 | xfree(csa->cbar); |
---|
| 2598 | xfree(csa->refsp); |
---|
| 2599 | xfree(csa->gamma); |
---|
| 2600 | xfree(csa->trow_ind); |
---|
| 2601 | xfree(csa->trow_vec); |
---|
| 2602 | #ifdef GLP_LONG_STEP /* 07/IV-2009 */ |
---|
| 2603 | xfree(csa->bkpt); |
---|
| 2604 | #endif |
---|
| 2605 | xfree(csa->tcol_ind); |
---|
| 2606 | xfree(csa->tcol_vec); |
---|
| 2607 | xfree(csa->work1); |
---|
| 2608 | xfree(csa->work2); |
---|
| 2609 | xfree(csa->work3); |
---|
| 2610 | xfree(csa->work4); |
---|
| 2611 | xfree(csa); |
---|
| 2612 | return; |
---|
| 2613 | } |
---|
| 2614 | |
---|
| 2615 | /*********************************************************************** |
---|
| 2616 | * spx_dual - core LP solver based on the dual simplex method |
---|
| 2617 | * |
---|
| 2618 | * SYNOPSIS |
---|
| 2619 | * |
---|
| 2620 | * #include "glpspx.h" |
---|
| 2621 | * int spx_dual(glp_prob *lp, const glp_smcp *parm); |
---|
| 2622 | * |
---|
| 2623 | * DESCRIPTION |
---|
| 2624 | * |
---|
| 2625 | * The routine spx_dual is a core LP solver based on the two-phase dual |
---|
| 2626 | * simplex method. |
---|
| 2627 | * |
---|
| 2628 | * RETURNS |
---|
| 2629 | * |
---|
| 2630 | * 0 LP instance has been successfully solved. |
---|
| 2631 | * |
---|
| 2632 | * GLP_EOBJLL |
---|
| 2633 | * Objective lower limit has been reached (maximization). |
---|
| 2634 | * |
---|
| 2635 | * GLP_EOBJUL |
---|
| 2636 | * Objective upper limit has been reached (minimization). |
---|
| 2637 | * |
---|
| 2638 | * GLP_EITLIM |
---|
| 2639 | * Iteration limit has been exhausted. |
---|
| 2640 | * |
---|
| 2641 | * GLP_ETMLIM |
---|
| 2642 | * Time limit has been exhausted. |
---|
| 2643 | * |
---|
| 2644 | * GLP_EFAIL |
---|
| 2645 | * The solver failed to solve LP instance. */ |
---|
| 2646 | |
---|
| 2647 | int spx_dual(glp_prob *lp, const glp_smcp *parm) |
---|
| 2648 | { struct csa *csa; |
---|
| 2649 | int binv_st = 2; |
---|
| 2650 | /* status of basis matrix factorization: |
---|
| 2651 | 0 - invalid; 1 - just computed; 2 - updated */ |
---|
| 2652 | int bbar_st = 0; |
---|
| 2653 | /* status of primal values of basic variables: |
---|
| 2654 | 0 - invalid; 1 - just computed; 2 - updated */ |
---|
| 2655 | int cbar_st = 0; |
---|
| 2656 | /* status of reduced costs of non-basic variables: |
---|
| 2657 | 0 - invalid; 1 - just computed; 2 - updated */ |
---|
| 2658 | int rigorous = 0; |
---|
| 2659 | /* rigorous mode flag; this flag is used to enable iterative |
---|
| 2660 | refinement on computing pivot rows and columns of the simplex |
---|
| 2661 | table */ |
---|
| 2662 | int check = 0; |
---|
| 2663 | int p_stat, d_stat, ret; |
---|
| 2664 | /* allocate and initialize the common storage area */ |
---|
| 2665 | csa = alloc_csa(lp); |
---|
| 2666 | init_csa(csa, lp); |
---|
| 2667 | if (parm->msg_lev >= GLP_MSG_DBG) |
---|
| 2668 | xprintf("Objective scale factor = %g\n", csa->zeta); |
---|
| 2669 | loop: /* main loop starts here */ |
---|
| 2670 | /* compute factorization of the basis matrix */ |
---|
| 2671 | if (binv_st == 0) |
---|
| 2672 | { ret = invert_B(csa); |
---|
| 2673 | if (ret != 0) |
---|
| 2674 | { if (parm->msg_lev >= GLP_MSG_ERR) |
---|
| 2675 | { xprintf("Error: unable to factorize the basis matrix (%d" |
---|
| 2676 | ")\n", ret); |
---|
| 2677 | xprintf("Sorry, basis recovery procedure not implemented" |
---|
| 2678 | " yet\n"); |
---|
| 2679 | } |
---|
| 2680 | xassert(!lp->valid && lp->bfd == NULL); |
---|
| 2681 | lp->bfd = csa->bfd, csa->bfd = NULL; |
---|
| 2682 | lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; |
---|
| 2683 | lp->obj_val = 0.0; |
---|
| 2684 | lp->it_cnt = csa->it_cnt; |
---|
| 2685 | lp->some = 0; |
---|
| 2686 | ret = GLP_EFAIL; |
---|
| 2687 | goto done; |
---|
| 2688 | } |
---|
| 2689 | csa->valid = 1; |
---|
| 2690 | binv_st = 1; /* just computed */ |
---|
| 2691 | /* invalidate basic solution components */ |
---|
| 2692 | bbar_st = cbar_st = 0; |
---|
| 2693 | } |
---|
| 2694 | /* compute reduced costs of non-basic variables */ |
---|
| 2695 | if (cbar_st == 0) |
---|
| 2696 | { eval_cbar(csa); |
---|
| 2697 | cbar_st = 1; /* just computed */ |
---|
| 2698 | /* determine the search phase, if not determined yet */ |
---|
| 2699 | if (csa->phase == 0) |
---|
| 2700 | { if (check_feas(csa, 0.90 * parm->tol_dj) != 0) |
---|
| 2701 | { /* current basic solution is dual infeasible */ |
---|
| 2702 | /* start searching for dual feasible solution */ |
---|
| 2703 | csa->phase = 1; |
---|
| 2704 | set_aux_bnds(csa); |
---|
| 2705 | } |
---|
| 2706 | else |
---|
| 2707 | { /* current basic solution is dual feasible */ |
---|
| 2708 | /* start searching for optimal solution */ |
---|
| 2709 | csa->phase = 2; |
---|
| 2710 | set_orig_bnds(csa); |
---|
| 2711 | } |
---|
| 2712 | xassert(check_stab(csa, parm->tol_dj) == 0); |
---|
| 2713 | /* some non-basic double-bounded variables might become |
---|
| 2714 | fixed (on phase I) or vice versa (on phase II) */ |
---|
| 2715 | #if 0 /* 06/IV-2009 */ |
---|
| 2716 | build_N(csa); |
---|
| 2717 | #endif |
---|
| 2718 | csa->refct = 0; |
---|
| 2719 | /* bounds of non-basic variables have been changed, so |
---|
| 2720 | invalidate primal values */ |
---|
| 2721 | bbar_st = 0; |
---|
| 2722 | } |
---|
| 2723 | /* make sure that the current basic solution remains dual |
---|
| 2724 | feasible */ |
---|
| 2725 | if (check_stab(csa, parm->tol_dj) != 0) |
---|
| 2726 | { if (parm->msg_lev >= GLP_MSG_ERR) |
---|
| 2727 | xprintf("Warning: numerical instability (dual simplex, p" |
---|
| 2728 | "hase %s)\n", csa->phase == 1 ? "I" : "II"); |
---|
| 2729 | #if 1 |
---|
| 2730 | if (parm->meth == GLP_DUALP) |
---|
| 2731 | { store_sol(csa, lp, GLP_UNDEF, GLP_UNDEF, 0); |
---|
| 2732 | ret = GLP_EFAIL; |
---|
| 2733 | goto done; |
---|
| 2734 | } |
---|
| 2735 | #endif |
---|
| 2736 | /* restart the search */ |
---|
| 2737 | csa->phase = 0; |
---|
| 2738 | binv_st = 0; |
---|
| 2739 | rigorous = 5; |
---|
| 2740 | goto loop; |
---|
| 2741 | } |
---|
| 2742 | } |
---|
| 2743 | xassert(csa->phase == 1 || csa->phase == 2); |
---|
| 2744 | /* on phase I we do not need to wait until the current basic |
---|
| 2745 | solution becomes primal feasible; it is sufficient to make |
---|
| 2746 | sure that all reduced costs have correct signs */ |
---|
| 2747 | if (csa->phase == 1 && check_feas(csa, parm->tol_dj) == 0) |
---|
| 2748 | { /* the current basis is dual feasible; switch to phase II */ |
---|
| 2749 | display(csa, parm, 1); |
---|
| 2750 | csa->phase = 2; |
---|
| 2751 | if (cbar_st != 1) |
---|
| 2752 | { eval_cbar(csa); |
---|
| 2753 | cbar_st = 1; |
---|
| 2754 | } |
---|
| 2755 | set_orig_bnds(csa); |
---|
| 2756 | #if 0 /* 06/IV-2009 */ |
---|
| 2757 | build_N(csa); |
---|
| 2758 | #endif |
---|
| 2759 | csa->refct = 0; |
---|
| 2760 | bbar_st = 0; |
---|
| 2761 | } |
---|
| 2762 | /* compute primal values of basic variables */ |
---|
| 2763 | if (bbar_st == 0) |
---|
| 2764 | { eval_bbar(csa); |
---|
| 2765 | if (csa->phase == 2) |
---|
| 2766 | csa->bbar[0] = eval_obj(csa); |
---|
| 2767 | bbar_st = 1; /* just computed */ |
---|
| 2768 | } |
---|
| 2769 | /* redefine the reference space, if required */ |
---|
| 2770 | switch (parm->pricing) |
---|
| 2771 | { case GLP_PT_STD: |
---|
| 2772 | break; |
---|
| 2773 | case GLP_PT_PSE: |
---|
| 2774 | if (csa->refct == 0) reset_refsp(csa); |
---|
| 2775 | break; |
---|
| 2776 | default: |
---|
| 2777 | xassert(parm != parm); |
---|
| 2778 | } |
---|
| 2779 | /* at this point the basis factorization and all basic solution |
---|
| 2780 | components are valid */ |
---|
| 2781 | xassert(binv_st && bbar_st && cbar_st); |
---|
| 2782 | /* check accuracy of current basic solution components (only for |
---|
| 2783 | debugging) */ |
---|
| 2784 | if (check) |
---|
| 2785 | { double e_bbar = err_in_bbar(csa); |
---|
| 2786 | double e_cbar = err_in_cbar(csa); |
---|
| 2787 | double e_gamma = |
---|
| 2788 | (parm->pricing == GLP_PT_PSE ? err_in_gamma(csa) : 0.0); |
---|
| 2789 | xprintf("e_bbar = %10.3e; e_cbar = %10.3e; e_gamma = %10.3e\n", |
---|
| 2790 | e_bbar, e_cbar, e_gamma); |
---|
| 2791 | xassert(e_bbar <= 1e-5 && e_cbar <= 1e-5 && e_gamma <= 1e-3); |
---|
| 2792 | } |
---|
| 2793 | /* if the objective has to be maximized, check if it has reached |
---|
| 2794 | its lower limit */ |
---|
| 2795 | if (csa->phase == 2 && csa->zeta < 0.0 && |
---|
| 2796 | parm->obj_ll > -DBL_MAX && csa->bbar[0] <= parm->obj_ll) |
---|
| 2797 | { if (bbar_st != 1 || cbar_st != 1) |
---|
| 2798 | { if (bbar_st != 1) bbar_st = 0; |
---|
| 2799 | if (cbar_st != 1) cbar_st = 0; |
---|
| 2800 | goto loop; |
---|
| 2801 | } |
---|
| 2802 | display(csa, parm, 1); |
---|
| 2803 | if (parm->msg_lev >= GLP_MSG_ALL) |
---|
| 2804 | xprintf("OBJECTIVE LOWER LIMIT REACHED; SEARCH TERMINATED\n" |
---|
| 2805 | ); |
---|
| 2806 | store_sol(csa, lp, GLP_INFEAS, GLP_FEAS, 0); |
---|
| 2807 | ret = GLP_EOBJLL; |
---|
| 2808 | goto done; |
---|
| 2809 | } |
---|
| 2810 | /* if the objective has to be minimized, check if it has reached |
---|
| 2811 | its upper limit */ |
---|
| 2812 | if (csa->phase == 2 && csa->zeta > 0.0 && |
---|
| 2813 | parm->obj_ul < +DBL_MAX && csa->bbar[0] >= parm->obj_ul) |
---|
| 2814 | { if (bbar_st != 1 || cbar_st != 1) |
---|
| 2815 | { if (bbar_st != 1) bbar_st = 0; |
---|
| 2816 | if (cbar_st != 1) cbar_st = 0; |
---|
| 2817 | goto loop; |
---|
| 2818 | } |
---|
| 2819 | display(csa, parm, 1); |
---|
| 2820 | if (parm->msg_lev >= GLP_MSG_ALL) |
---|
| 2821 | xprintf("OBJECTIVE UPPER LIMIT REACHED; SEARCH TERMINATED\n" |
---|
| 2822 | ); |
---|
| 2823 | store_sol(csa, lp, GLP_INFEAS, GLP_FEAS, 0); |
---|
| 2824 | ret = GLP_EOBJUL; |
---|
| 2825 | goto done; |
---|
| 2826 | } |
---|
| 2827 | /* check if the iteration limit has been exhausted */ |
---|
| 2828 | if (parm->it_lim < INT_MAX && |
---|
| 2829 | csa->it_cnt - csa->it_beg >= parm->it_lim) |
---|
| 2830 | { if (csa->phase == 2 && bbar_st != 1 || cbar_st != 1) |
---|
| 2831 | { if (csa->phase == 2 && bbar_st != 1) bbar_st = 0; |
---|
| 2832 | if (cbar_st != 1) cbar_st = 0; |
---|
| 2833 | goto loop; |
---|
| 2834 | } |
---|
| 2835 | display(csa, parm, 1); |
---|
| 2836 | if (parm->msg_lev >= GLP_MSG_ALL) |
---|
| 2837 | xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n"); |
---|
| 2838 | switch (csa->phase) |
---|
| 2839 | { case 1: |
---|
| 2840 | d_stat = GLP_INFEAS; |
---|
| 2841 | set_orig_bnds(csa); |
---|
| 2842 | eval_bbar(csa); |
---|
| 2843 | break; |
---|
| 2844 | case 2: |
---|
| 2845 | d_stat = GLP_FEAS; |
---|
| 2846 | break; |
---|
| 2847 | default: |
---|
| 2848 | xassert(csa != csa); |
---|
| 2849 | } |
---|
| 2850 | store_sol(csa, lp, GLP_INFEAS, d_stat, 0); |
---|
| 2851 | ret = GLP_EITLIM; |
---|
| 2852 | goto done; |
---|
| 2853 | } |
---|
| 2854 | /* check if the time limit has been exhausted */ |
---|
| 2855 | if (parm->tm_lim < INT_MAX && |
---|
| 2856 | 1000.0 * xdifftime(xtime(), csa->tm_beg) >= parm->tm_lim) |
---|
| 2857 | { if (csa->phase == 2 && bbar_st != 1 || cbar_st != 1) |
---|
| 2858 | { if (csa->phase == 2 && bbar_st != 1) bbar_st = 0; |
---|
| 2859 | if (cbar_st != 1) cbar_st = 0; |
---|
| 2860 | goto loop; |
---|
| 2861 | } |
---|
| 2862 | display(csa, parm, 1); |
---|
| 2863 | if (parm->msg_lev >= GLP_MSG_ALL) |
---|
| 2864 | xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n"); |
---|
| 2865 | switch (csa->phase) |
---|
| 2866 | { case 1: |
---|
| 2867 | d_stat = GLP_INFEAS; |
---|
| 2868 | set_orig_bnds(csa); |
---|
| 2869 | eval_bbar(csa); |
---|
| 2870 | break; |
---|
| 2871 | case 2: |
---|
| 2872 | d_stat = GLP_FEAS; |
---|
| 2873 | break; |
---|
| 2874 | default: |
---|
| 2875 | xassert(csa != csa); |
---|
| 2876 | } |
---|
| 2877 | store_sol(csa, lp, GLP_INFEAS, d_stat, 0); |
---|
| 2878 | ret = GLP_ETMLIM; |
---|
| 2879 | goto done; |
---|
| 2880 | } |
---|
| 2881 | /* display the search progress */ |
---|
| 2882 | display(csa, parm, 0); |
---|
| 2883 | /* choose basic variable xB[p] */ |
---|
| 2884 | chuzr(csa, parm->tol_bnd); |
---|
| 2885 | if (csa->p == 0) |
---|
| 2886 | { if (bbar_st != 1 || cbar_st != 1) |
---|
| 2887 | { if (bbar_st != 1) bbar_st = 0; |
---|
| 2888 | if (cbar_st != 1) cbar_st = 0; |
---|
| 2889 | goto loop; |
---|
| 2890 | } |
---|
| 2891 | display(csa, parm, 1); |
---|
| 2892 | switch (csa->phase) |
---|
| 2893 | { case 1: |
---|
| 2894 | if (parm->msg_lev >= GLP_MSG_ALL) |
---|
| 2895 | xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n"); |
---|
| 2896 | set_orig_bnds(csa); |
---|
| 2897 | eval_bbar(csa); |
---|
| 2898 | p_stat = GLP_INFEAS, d_stat = GLP_NOFEAS; |
---|
| 2899 | break; |
---|
| 2900 | case 2: |
---|
| 2901 | if (parm->msg_lev >= GLP_MSG_ALL) |
---|
| 2902 | xprintf("OPTIMAL SOLUTION FOUND\n"); |
---|
| 2903 | p_stat = d_stat = GLP_FEAS; |
---|
| 2904 | break; |
---|
| 2905 | default: |
---|
| 2906 | xassert(csa != csa); |
---|
| 2907 | } |
---|
| 2908 | store_sol(csa, lp, p_stat, d_stat, 0); |
---|
| 2909 | ret = 0; |
---|
| 2910 | goto done; |
---|
| 2911 | } |
---|
| 2912 | /* compute pivot row of the simplex table */ |
---|
| 2913 | { double *rho = csa->work4; |
---|
| 2914 | eval_rho(csa, rho); |
---|
| 2915 | if (rigorous) refine_rho(csa, rho); |
---|
| 2916 | eval_trow(csa, rho); |
---|
| 2917 | sort_trow(csa, parm->tol_bnd); |
---|
| 2918 | } |
---|
| 2919 | /* unlike primal simplex there is no need to check accuracy of |
---|
| 2920 | the primal value of xB[p] (which might be computed using the |
---|
| 2921 | pivot row), since bbar is a result of FTRAN */ |
---|
| 2922 | #ifdef GLP_LONG_STEP /* 07/IV-2009 */ |
---|
| 2923 | long_step(csa); |
---|
| 2924 | if (csa->nbps > 0) |
---|
| 2925 | { csa->q = csa->bkpt[csa->nbps].j; |
---|
| 2926 | if (csa->delta > 0.0) |
---|
| 2927 | csa->new_dq = + csa->bkpt[csa->nbps].t; |
---|
| 2928 | else |
---|
| 2929 | csa->new_dq = - csa->bkpt[csa->nbps].t; |
---|
| 2930 | } |
---|
| 2931 | else |
---|
| 2932 | #endif |
---|
| 2933 | /* choose non-basic variable xN[q] */ |
---|
| 2934 | switch (parm->r_test) |
---|
| 2935 | { case GLP_RT_STD: |
---|
| 2936 | chuzc(csa, 0.0); |
---|
| 2937 | break; |
---|
| 2938 | case GLP_RT_HAR: |
---|
| 2939 | chuzc(csa, 0.30 * parm->tol_dj); |
---|
| 2940 | break; |
---|
| 2941 | default: |
---|
| 2942 | xassert(parm != parm); |
---|
| 2943 | } |
---|
| 2944 | if (csa->q == 0) |
---|
| 2945 | { if (bbar_st != 1 || cbar_st != 1 || !rigorous) |
---|
| 2946 | { if (bbar_st != 1) bbar_st = 0; |
---|
| 2947 | if (cbar_st != 1) cbar_st = 0; |
---|
| 2948 | rigorous = 1; |
---|
| 2949 | goto loop; |
---|
| 2950 | } |
---|
| 2951 | display(csa, parm, 1); |
---|
| 2952 | switch (csa->phase) |
---|
| 2953 | { case 1: |
---|
| 2954 | if (parm->msg_lev >= GLP_MSG_ERR) |
---|
| 2955 | xprintf("Error: unable to choose basic variable on ph" |
---|
| 2956 | "ase I\n"); |
---|
| 2957 | xassert(!lp->valid && lp->bfd == NULL); |
---|
| 2958 | lp->bfd = csa->bfd, csa->bfd = NULL; |
---|
| 2959 | lp->pbs_stat = lp->dbs_stat = GLP_UNDEF; |
---|
| 2960 | lp->obj_val = 0.0; |
---|
| 2961 | lp->it_cnt = csa->it_cnt; |
---|
| 2962 | lp->some = 0; |
---|
| 2963 | ret = GLP_EFAIL; |
---|
| 2964 | break; |
---|
| 2965 | case 2: |
---|
| 2966 | if (parm->msg_lev >= GLP_MSG_ALL) |
---|
| 2967 | xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n"); |
---|
| 2968 | store_sol(csa, lp, GLP_NOFEAS, GLP_FEAS, |
---|
| 2969 | csa->head[csa->p]); |
---|
| 2970 | ret = 0; |
---|
| 2971 | break; |
---|
| 2972 | default: |
---|
| 2973 | xassert(csa != csa); |
---|
| 2974 | } |
---|
| 2975 | goto done; |
---|
| 2976 | } |
---|
| 2977 | /* check if the pivot element is acceptable */ |
---|
| 2978 | { double piv = csa->trow_vec[csa->q]; |
---|
| 2979 | double eps = 1e-5 * (1.0 + 0.01 * csa->trow_max); |
---|
| 2980 | if (fabs(piv) < eps) |
---|
| 2981 | { if (parm->msg_lev >= GLP_MSG_DBG) |
---|
| 2982 | xprintf("piv = %.12g; eps = %g\n", piv, eps); |
---|
| 2983 | if (!rigorous) |
---|
| 2984 | { rigorous = 5; |
---|
| 2985 | goto loop; |
---|
| 2986 | } |
---|
| 2987 | } |
---|
| 2988 | } |
---|
| 2989 | /* now xN[q] and xB[p] have been chosen anyhow */ |
---|
| 2990 | /* compute pivot column of the simplex table */ |
---|
| 2991 | eval_tcol(csa); |
---|
| 2992 | if (rigorous) refine_tcol(csa); |
---|
| 2993 | /* accuracy check based on the pivot element */ |
---|
| 2994 | { double piv1 = csa->tcol_vec[csa->p]; /* more accurate */ |
---|
| 2995 | double piv2 = csa->trow_vec[csa->q]; /* less accurate */ |
---|
| 2996 | xassert(piv1 != 0.0); |
---|
| 2997 | if (fabs(piv1 - piv2) > 1e-8 * (1.0 + fabs(piv1)) || |
---|
| 2998 | !(piv1 > 0.0 && piv2 > 0.0 || piv1 < 0.0 && piv2 < 0.0)) |
---|
| 2999 | { if (parm->msg_lev >= GLP_MSG_DBG) |
---|
| 3000 | xprintf("piv1 = %.12g; piv2 = %.12g\n", piv1, piv2); |
---|
| 3001 | if (binv_st != 1 || !rigorous) |
---|
| 3002 | { if (binv_st != 1) binv_st = 0; |
---|
| 3003 | rigorous = 5; |
---|
| 3004 | goto loop; |
---|
| 3005 | } |
---|
| 3006 | /* (not a good idea; should be revised later) */ |
---|
| 3007 | if (csa->tcol_vec[csa->p] == 0.0) |
---|
| 3008 | { csa->tcol_nnz++; |
---|
| 3009 | xassert(csa->tcol_nnz <= csa->m); |
---|
| 3010 | csa->tcol_ind[csa->tcol_nnz] = csa->p; |
---|
| 3011 | } |
---|
| 3012 | csa->tcol_vec[csa->p] = piv2; |
---|
| 3013 | } |
---|
| 3014 | } |
---|
| 3015 | /* update primal values of basic variables */ |
---|
| 3016 | #ifdef GLP_LONG_STEP /* 07/IV-2009 */ |
---|
| 3017 | if (csa->nbps > 0) |
---|
| 3018 | { int kk, j, k; |
---|
| 3019 | for (kk = 1; kk < csa->nbps; kk++) |
---|
| 3020 | { if (csa->bkpt[kk].t >= csa->bkpt[csa->nbps].t) continue; |
---|
| 3021 | j = csa->bkpt[kk].j; |
---|
| 3022 | k = csa->head[csa->m + j]; |
---|
| 3023 | xassert(csa->type[k] == GLP_DB); |
---|
| 3024 | if (csa->stat[j] == GLP_NL) |
---|
| 3025 | csa->stat[j] = GLP_NU; |
---|
| 3026 | else |
---|
| 3027 | csa->stat[j] = GLP_NL; |
---|
| 3028 | } |
---|
| 3029 | } |
---|
| 3030 | bbar_st = 0; |
---|
| 3031 | #else |
---|
| 3032 | update_bbar(csa); |
---|
| 3033 | if (csa->phase == 2) |
---|
| 3034 | csa->bbar[0] += (csa->cbar[csa->q] / csa->zeta) * |
---|
| 3035 | (csa->delta / csa->tcol_vec[csa->p]); |
---|
| 3036 | bbar_st = 2; /* updated */ |
---|
| 3037 | #endif |
---|
| 3038 | /* update reduced costs of non-basic variables */ |
---|
| 3039 | update_cbar(csa); |
---|
| 3040 | cbar_st = 2; /* updated */ |
---|
| 3041 | /* update steepest edge coefficients */ |
---|
| 3042 | switch (parm->pricing) |
---|
| 3043 | { case GLP_PT_STD: |
---|
| 3044 | break; |
---|
| 3045 | case GLP_PT_PSE: |
---|
| 3046 | if (csa->refct > 0) update_gamma(csa); |
---|
| 3047 | break; |
---|
| 3048 | default: |
---|
| 3049 | xassert(parm != parm); |
---|
| 3050 | } |
---|
| 3051 | /* update factorization of the basis matrix */ |
---|
| 3052 | ret = update_B(csa, csa->p, csa->head[csa->m+csa->q]); |
---|
| 3053 | if (ret == 0) |
---|
| 3054 | binv_st = 2; /* updated */ |
---|
| 3055 | else |
---|
| 3056 | { csa->valid = 0; |
---|
| 3057 | binv_st = 0; /* invalid */ |
---|
| 3058 | } |
---|
| 3059 | #if 0 /* 06/IV-2009 */ |
---|
| 3060 | /* update matrix N */ |
---|
| 3061 | del_N_col(csa, csa->q, csa->head[csa->m+csa->q]); |
---|
| 3062 | if (csa->type[csa->head[csa->p]] != GLP_FX) |
---|
| 3063 | add_N_col(csa, csa->q, csa->head[csa->p]); |
---|
| 3064 | #endif |
---|
| 3065 | /* change the basis header */ |
---|
| 3066 | change_basis(csa); |
---|
| 3067 | /* iteration complete */ |
---|
| 3068 | csa->it_cnt++; |
---|
| 3069 | if (rigorous > 0) rigorous--; |
---|
| 3070 | goto loop; |
---|
| 3071 | done: /* deallocate the common storage area */ |
---|
| 3072 | free_csa(csa); |
---|
| 3073 | /* return to the calling program */ |
---|
| 3074 | return ret; |
---|
| 3075 | } |
---|
| 3076 | |
---|
| 3077 | /* eof */ |
---|