123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826 |
- /* glpios02.c (preprocess current subproblem) */
- /***********************************************************************
- * This code is part of GLPK (GNU Linear Programming Kit).
- *
- * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- * 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
- * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
- * E-mail: <mao@gnu.org>.
- *
- * GLPK is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GLPK is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
- ***********************************************************************/
- #include "glpios.h"
- /***********************************************************************
- * prepare_row_info - prepare row info to determine implied bounds
- *
- * Given a row (linear form)
- *
- * n
- * sum a[j] * x[j] (1)
- * j=1
- *
- * and bounds of columns (variables)
- *
- * l[j] <= x[j] <= u[j] (2)
- *
- * this routine computes f_min, j_min, f_max, j_max needed to determine
- * implied bounds.
- *
- * ALGORITHM
- *
- * Let J+ = {j : a[j] > 0} and J- = {j : a[j] < 0}.
- *
- * Parameters f_min and j_min are computed as follows:
- *
- * 1) if there is no x[k] such that k in J+ and l[k] = -inf or k in J-
- * and u[k] = +inf, then
- *
- * f_min := sum a[j] * l[j] + sum a[j] * u[j]
- * j in J+ j in J-
- * (3)
- * j_min := 0
- *
- * 2) if there is exactly one x[k] such that k in J+ and l[k] = -inf
- * or k in J- and u[k] = +inf, then
- *
- * f_min := sum a[j] * l[j] + sum a[j] * u[j]
- * j in J+\{k} j in J-\{k}
- * (4)
- * j_min := k
- *
- * 3) if there are two or more x[k] such that k in J+ and l[k] = -inf
- * or k in J- and u[k] = +inf, then
- *
- * f_min := -inf
- * (5)
- * j_min := 0
- *
- * Parameters f_max and j_max are computed in a similar way as follows:
- *
- * 1) if there is no x[k] such that k in J+ and u[k] = +inf or k in J-
- * and l[k] = -inf, then
- *
- * f_max := sum a[j] * u[j] + sum a[j] * l[j]
- * j in J+ j in J-
- * (6)
- * j_max := 0
- *
- * 2) if there is exactly one x[k] such that k in J+ and u[k] = +inf
- * or k in J- and l[k] = -inf, then
- *
- * f_max := sum a[j] * u[j] + sum a[j] * l[j]
- * j in J+\{k} j in J-\{k}
- * (7)
- * j_max := k
- *
- * 3) if there are two or more x[k] such that k in J+ and u[k] = +inf
- * or k in J- and l[k] = -inf, then
- *
- * f_max := +inf
- * (8)
- * j_max := 0 */
- struct f_info
- { int j_min, j_max;
- double f_min, f_max;
- };
- static void prepare_row_info(int n, const double a[], const double l[],
- const double u[], struct f_info *f)
- { int j, j_min, j_max;
- double f_min, f_max;
- xassert(n >= 0);
- /* determine f_min and j_min */
- f_min = 0.0, j_min = 0;
- for (j = 1; j <= n; j++)
- { if (a[j] > 0.0)
- { if (l[j] == -DBL_MAX)
- { if (j_min == 0)
- j_min = j;
- else
- { f_min = -DBL_MAX, j_min = 0;
- break;
- }
- }
- else
- f_min += a[j] * l[j];
- }
- else if (a[j] < 0.0)
- { if (u[j] == +DBL_MAX)
- { if (j_min == 0)
- j_min = j;
- else
- { f_min = -DBL_MAX, j_min = 0;
- break;
- }
- }
- else
- f_min += a[j] * u[j];
- }
- else
- xassert(a != a);
- }
- f->f_min = f_min, f->j_min = j_min;
- /* determine f_max and j_max */
- f_max = 0.0, j_max = 0;
- for (j = 1; j <= n; j++)
- { if (a[j] > 0.0)
- { if (u[j] == +DBL_MAX)
- { if (j_max == 0)
- j_max = j;
- else
- { f_max = +DBL_MAX, j_max = 0;
- break;
- }
- }
- else
- f_max += a[j] * u[j];
- }
- else if (a[j] < 0.0)
- { if (l[j] == -DBL_MAX)
- { if (j_max == 0)
- j_max = j;
- else
- { f_max = +DBL_MAX, j_max = 0;
- break;
- }
- }
- else
- f_max += a[j] * l[j];
- }
- else
- xassert(a != a);
- }
- f->f_max = f_max, f->j_max = j_max;
- return;
- }
- /***********************************************************************
- * row_implied_bounds - determine row implied bounds
- *
- * Given a row (linear form)
- *
- * n
- * sum a[j] * x[j]
- * j=1
- *
- * and bounds of columns (variables)
- *
- * l[j] <= x[j] <= u[j]
- *
- * this routine determines implied bounds of the row.
- *
- * ALGORITHM
- *
- * Let J+ = {j : a[j] > 0} and J- = {j : a[j] < 0}.
- *
- * The implied lower bound of the row is computed as follows:
- *
- * L' := sum a[j] * l[j] + sum a[j] * u[j] (9)
- * j in J+ j in J-
- *
- * and as it follows from (3), (4), and (5):
- *
- * L' := if j_min = 0 then f_min else -inf (10)
- *
- * The implied upper bound of the row is computed as follows:
- *
- * U' := sum a[j] * u[j] + sum a[j] * l[j] (11)
- * j in J+ j in J-
- *
- * and as it follows from (6), (7), and (8):
- *
- * U' := if j_max = 0 then f_max else +inf (12)
- *
- * The implied bounds are stored in locations LL and UU. */
- static void row_implied_bounds(const struct f_info *f, double *LL,
- double *UU)
- { *LL = (f->j_min == 0 ? f->f_min : -DBL_MAX);
- *UU = (f->j_max == 0 ? f->f_max : +DBL_MAX);
- return;
- }
- /***********************************************************************
- * col_implied_bounds - determine column implied bounds
- *
- * Given a row (constraint)
- *
- * n
- * L <= sum a[j] * x[j] <= U (13)
- * j=1
- *
- * and bounds of columns (variables)
- *
- * l[j] <= x[j] <= u[j]
- *
- * this routine determines implied bounds of variable x[k].
- *
- * It is assumed that if L != -inf, the lower bound of the row can be
- * active, and if U != +inf, the upper bound of the row can be active.
- *
- * ALGORITHM
- *
- * From (13) it follows that
- *
- * L <= sum a[j] * x[j] + a[k] * x[k] <= U
- * j!=k
- * or
- *
- * L - sum a[j] * x[j] <= a[k] * x[k] <= U - sum a[j] * x[j]
- * j!=k j!=k
- *
- * Thus, if the row lower bound L can be active, implied lower bound of
- * term a[k] * x[k] can be determined as follows:
- *
- * ilb(a[k] * x[k]) = min(L - sum a[j] * x[j]) =
- * j!=k
- * (14)
- * = L - max sum a[j] * x[j]
- * j!=k
- *
- * where, as it follows from (6), (7), and (8)
- *
- * / f_max - a[k] * u[k], j_max = 0, a[k] > 0
- * |
- * | f_max - a[k] * l[k], j_max = 0, a[k] < 0
- * max sum a[j] * x[j] = {
- * j!=k | f_max, j_max = k
- * |
- * \ +inf, j_max != 0
- *
- * and if the upper bound U can be active, implied upper bound of term
- * a[k] * x[k] can be determined as follows:
- *
- * iub(a[k] * x[k]) = max(U - sum a[j] * x[j]) =
- * j!=k
- * (15)
- * = U - min sum a[j] * x[j]
- * j!=k
- *
- * where, as it follows from (3), (4), and (5)
- *
- * / f_min - a[k] * l[k], j_min = 0, a[k] > 0
- * |
- * | f_min - a[k] * u[k], j_min = 0, a[k] < 0
- * min sum a[j] * x[j] = {
- * j!=k | f_min, j_min = k
- * |
- * \ -inf, j_min != 0
- *
- * Since
- *
- * ilb(a[k] * x[k]) <= a[k] * x[k] <= iub(a[k] * x[k])
- *
- * implied lower and upper bounds of x[k] are determined as follows:
- *
- * l'[k] := if a[k] > 0 then ilb / a[k] else ulb / a[k] (16)
- *
- * u'[k] := if a[k] > 0 then ulb / a[k] else ilb / a[k] (17)
- *
- * The implied bounds are stored in locations ll and uu. */
- static void col_implied_bounds(const struct f_info *f, int n,
- const double a[], double L, double U, const double l[],
- const double u[], int k, double *ll, double *uu)
- { double ilb, iub;
- xassert(n >= 0);
- xassert(1 <= k && k <= n);
- /* determine implied lower bound of term a[k] * x[k] (14) */
- if (L == -DBL_MAX || f->f_max == +DBL_MAX)
- ilb = -DBL_MAX;
- else if (f->j_max == 0)
- { if (a[k] > 0.0)
- { xassert(u[k] != +DBL_MAX);
- ilb = L - (f->f_max - a[k] * u[k]);
- }
- else if (a[k] < 0.0)
- { xassert(l[k] != -DBL_MAX);
- ilb = L - (f->f_max - a[k] * l[k]);
- }
- else
- xassert(a != a);
- }
- else if (f->j_max == k)
- ilb = L - f->f_max;
- else
- ilb = -DBL_MAX;
- /* determine implied upper bound of term a[k] * x[k] (15) */
- if (U == +DBL_MAX || f->f_min == -DBL_MAX)
- iub = +DBL_MAX;
- else if (f->j_min == 0)
- { if (a[k] > 0.0)
- { xassert(l[k] != -DBL_MAX);
- iub = U - (f->f_min - a[k] * l[k]);
- }
- else if (a[k] < 0.0)
- { xassert(u[k] != +DBL_MAX);
- iub = U - (f->f_min - a[k] * u[k]);
- }
- else
- xassert(a != a);
- }
- else if (f->j_min == k)
- iub = U - f->f_min;
- else
- iub = +DBL_MAX;
- /* determine implied bounds of x[k] (16) and (17) */
- #if 1
- /* do not use a[k] if it has small magnitude to prevent wrong
- implied bounds; for example, 1e-15 * x1 >= x2 + x3, where
- x1 >= -10, x2, x3 >= 0, would lead to wrong conclusion that
- x1 >= 0 */
- if (fabs(a[k]) < 1e-6)
- *ll = -DBL_MAX, *uu = +DBL_MAX; else
- #endif
- if (a[k] > 0.0)
- { *ll = (ilb == -DBL_MAX ? -DBL_MAX : ilb / a[k]);
- *uu = (iub == +DBL_MAX ? +DBL_MAX : iub / a[k]);
- }
- else if (a[k] < 0.0)
- { *ll = (iub == +DBL_MAX ? -DBL_MAX : iub / a[k]);
- *uu = (ilb == -DBL_MAX ? +DBL_MAX : ilb / a[k]);
- }
- else
- xassert(a != a);
- return;
- }
- /***********************************************************************
- * check_row_bounds - check and relax original row bounds
- *
- * Given a row (constraint)
- *
- * n
- * L <= sum a[j] * x[j] <= U
- * j=1
- *
- * and bounds of columns (variables)
- *
- * l[j] <= x[j] <= u[j]
- *
- * this routine checks the original row bounds L and U for feasibility
- * and redundancy. If the original lower bound L or/and upper bound U
- * cannot be active due to bounds of variables, the routine remove them
- * replacing by -inf or/and +inf, respectively.
- *
- * If no primal infeasibility is detected, the routine returns zero,
- * otherwise non-zero. */
- static int check_row_bounds(const struct f_info *f, double *L_,
- double *U_)
- { int ret = 0;
- double L = *L_, U = *U_, LL, UU;
- /* determine implied bounds of the row */
- row_implied_bounds(f, &LL, &UU);
- /* check if the original lower bound is infeasible */
- if (L != -DBL_MAX)
- { double eps = 1e-3 * (1.0 + fabs(L));
- if (UU < L - eps)
- { ret = 1;
- goto done;
- }
- }
- /* check if the original upper bound is infeasible */
- if (U != +DBL_MAX)
- { double eps = 1e-3 * (1.0 + fabs(U));
- if (LL > U + eps)
- { ret = 1;
- goto done;
- }
- }
- /* check if the original lower bound is redundant */
- if (L != -DBL_MAX)
- { double eps = 1e-12 * (1.0 + fabs(L));
- if (LL > L - eps)
- { /* it cannot be active, so remove it */
- *L_ = -DBL_MAX;
- }
- }
- /* check if the original upper bound is redundant */
- if (U != +DBL_MAX)
- { double eps = 1e-12 * (1.0 + fabs(U));
- if (UU < U + eps)
- { /* it cannot be active, so remove it */
- *U_ = +DBL_MAX;
- }
- }
- done: return ret;
- }
- /***********************************************************************
- * check_col_bounds - check and tighten original column bounds
- *
- * Given a row (constraint)
- *
- * n
- * L <= sum a[j] * x[j] <= U
- * j=1
- *
- * and bounds of columns (variables)
- *
- * l[j] <= x[j] <= u[j]
- *
- * for column (variable) x[j] this routine checks the original column
- * bounds l[j] and u[j] for feasibility and redundancy. If the original
- * lower bound l[j] or/and upper bound u[j] cannot be active due to
- * bounds of the constraint and other variables, the routine tighten
- * them replacing by corresponding implied bounds, if possible.
- *
- * NOTE: It is assumed that if L != -inf, the row lower bound can be
- * active, and if U != +inf, the row upper bound can be active.
- *
- * The flag means that variable x[j] is required to be integer.
- *
- * New actual bounds for x[j] are stored in locations lj and uj.
- *
- * If no primal infeasibility is detected, the routine returns zero,
- * otherwise non-zero. */
- static int check_col_bounds(const struct f_info *f, int n,
- const double a[], double L, double U, const double l[],
- const double u[], int flag, int j, double *_lj, double *_uj)
- { int ret = 0;
- double lj, uj, ll, uu;
- xassert(n >= 0);
- xassert(1 <= j && j <= n);
- lj = l[j], uj = u[j];
- /* determine implied bounds of the column */
- col_implied_bounds(f, n, a, L, U, l, u, j, &ll, &uu);
- /* if x[j] is integral, round its implied bounds */
- if (flag)
- { if (ll != -DBL_MAX)
- ll = (ll - floor(ll) < 1e-3 ? floor(ll) : ceil(ll));
- if (uu != +DBL_MAX)
- uu = (ceil(uu) - uu < 1e-3 ? ceil(uu) : floor(uu));
- }
- /* check if the original lower bound is infeasible */
- if (lj != -DBL_MAX)
- { double eps = 1e-3 * (1.0 + fabs(lj));
- if (uu < lj - eps)
- { ret = 1;
- goto done;
- }
- }
- /* check if the original upper bound is infeasible */
- if (uj != +DBL_MAX)
- { double eps = 1e-3 * (1.0 + fabs(uj));
- if (ll > uj + eps)
- { ret = 1;
- goto done;
- }
- }
- /* check if the original lower bound is redundant */
- if (ll != -DBL_MAX)
- { double eps = 1e-3 * (1.0 + fabs(ll));
- if (lj < ll - eps)
- { /* it cannot be active, so tighten it */
- lj = ll;
- }
- }
- /* check if the original upper bound is redundant */
- if (uu != +DBL_MAX)
- { double eps = 1e-3 * (1.0 + fabs(uu));
- if (uj > uu + eps)
- { /* it cannot be active, so tighten it */
- uj = uu;
- }
- }
- /* due to round-off errors it may happen that lj > uj (although
- lj < uj + eps, since no primal infeasibility is detected), so
- adjuct the new actual bounds to provide lj <= uj */
- if (!(lj == -DBL_MAX || uj == +DBL_MAX))
- { double t1 = fabs(lj), t2 = fabs(uj);
- double eps = 1e-10 * (1.0 + (t1 <= t2 ? t1 : t2));
- if (lj > uj - eps)
- { if (lj == l[j])
- uj = lj;
- else if (uj == u[j])
- lj = uj;
- else if (t1 <= t2)
- uj = lj;
- else
- lj = uj;
- }
- }
- *_lj = lj, *_uj = uj;
- done: return ret;
- }
- /***********************************************************************
- * check_efficiency - check if change in column bounds is efficient
- *
- * Given the original bounds of a column l and u and its new actual
- * bounds l' and u' (possibly tighten by the routine check_col_bounds)
- * this routine checks if the change in the column bounds is efficient
- * enough. If so, the routine returns non-zero, otherwise zero.
- *
- * The flag means that the variable is required to be integer. */
- static int check_efficiency(int flag, double l, double u, double ll,
- double uu)
- { int eff = 0;
- /* check efficiency for lower bound */
- if (l < ll)
- { if (flag || l == -DBL_MAX)
- eff++;
- else
- { double r;
- if (u == +DBL_MAX)
- r = 1.0 + fabs(l);
- else
- r = 1.0 + (u - l);
- if (ll - l >= 0.25 * r)
- eff++;
- }
- }
- /* check efficiency for upper bound */
- if (u > uu)
- { if (flag || u == +DBL_MAX)
- eff++;
- else
- { double r;
- if (l == -DBL_MAX)
- r = 1.0 + fabs(u);
- else
- r = 1.0 + (u - l);
- if (u - uu >= 0.25 * r)
- eff++;
- }
- }
- return eff;
- }
- /***********************************************************************
- * basic_preprocessing - perform basic preprocessing
- *
- * This routine performs basic preprocessing of the specified MIP that
- * includes relaxing some row bounds and tightening some column bounds.
- *
- * On entry the arrays L and U contains original row bounds, and the
- * arrays l and u contains original column bounds:
- *
- * L[0] is the lower bound of the objective row;
- * L[i], i = 1,...,m, is the lower bound of i-th row;
- * U[0] is the upper bound of the objective row;
- * U[i], i = 1,...,m, is the upper bound of i-th row;
- * l[0] is not used;
- * l[j], j = 1,...,n, is the lower bound of j-th column;
- * u[0] is not used;
- * u[j], j = 1,...,n, is the upper bound of j-th column.
- *
- * On exit the arrays L, U, l, and u contain new actual bounds of rows
- * and column in the same locations.
- *
- * The parameters nrs and num specify an initial list of rows to be
- * processed:
- *
- * nrs is the number of rows in the initial list, 0 <= nrs <= m+1;
- * num[0] is not used;
- * num[1,...,nrs] are row numbers (0 means the objective row).
- *
- * The parameter max_pass specifies the maximal number of times that
- * each row can be processed, max_pass > 0.
- *
- * If no primal infeasibility is detected, the routine returns zero,
- * otherwise non-zero. */
- static int basic_preprocessing(glp_prob *mip, double L[], double U[],
- double l[], double u[], int nrs, const int num[], int max_pass)
- { int m = mip->m;
- int n = mip->n;
- struct f_info f;
- int i, j, k, len, size, ret = 0;
- int *ind, *list, *mark, *pass;
- double *val, *lb, *ub;
- xassert(0 <= nrs && nrs <= m+1);
- xassert(max_pass > 0);
- /* allocate working arrays */
- ind = xcalloc(1+n, sizeof(int));
- list = xcalloc(1+m+1, sizeof(int));
- mark = xcalloc(1+m+1, sizeof(int));
- memset(&mark[0], 0, (m+1) * sizeof(int));
- pass = xcalloc(1+m+1, sizeof(int));
- memset(&pass[0], 0, (m+1) * sizeof(int));
- val = xcalloc(1+n, sizeof(double));
- lb = xcalloc(1+n, sizeof(double));
- ub = xcalloc(1+n, sizeof(double));
- /* initialize the list of rows to be processed */
- size = 0;
- for (k = 1; k <= nrs; k++)
- { i = num[k];
- xassert(0 <= i && i <= m);
- /* duplicate row numbers are not allowed */
- xassert(!mark[i]);
- list[++size] = i, mark[i] = 1;
- }
- xassert(size == nrs);
- /* process rows in the list until it becomes empty */
- while (size > 0)
- { /* get a next row from the list */
- i = list[size--], mark[i] = 0;
- /* increase the row processing count */
- pass[i]++;
- /* if the row is free, skip it */
- if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) continue;
- /* obtain coefficients of the row */
- len = 0;
- if (i == 0)
- { for (j = 1; j <= n; j++)
- { GLPCOL *col = mip->col[j];
- if (col->coef != 0.0)
- len++, ind[len] = j, val[len] = col->coef;
- }
- }
- else
- { GLPROW *row = mip->row[i];
- GLPAIJ *aij;
- for (aij = row->ptr; aij != NULL; aij = aij->r_next)
- len++, ind[len] = aij->col->j, val[len] = aij->val;
- }
- /* determine lower and upper bounds of columns corresponding
- to non-zero row coefficients */
- for (k = 1; k <= len; k++)
- j = ind[k], lb[k] = l[j], ub[k] = u[j];
- /* prepare the row info to determine implied bounds */
- prepare_row_info(len, val, lb, ub, &f);
- /* check and relax bounds of the row */
- if (check_row_bounds(&f, &L[i], &U[i]))
- { /* the feasible region is empty */
- ret = 1;
- goto done;
- }
- /* if the row became free, drop it */
- if (L[i] == -DBL_MAX && U[i] == +DBL_MAX) continue;
- /* process columns having non-zero coefficients in the row */
- for (k = 1; k <= len; k++)
- { GLPCOL *col;
- int flag, eff;
- double ll, uu;
- /* take a next column in the row */
- j = ind[k], col = mip->col[j];
- flag = col->kind != GLP_CV;
- /* check and tighten bounds of the column */
- if (check_col_bounds(&f, len, val, L[i], U[i], lb, ub,
- flag, k, &ll, &uu))
- { /* the feasible region is empty */
- ret = 1;
- goto done;
- }
- /* check if change in the column bounds is efficient */
- eff = check_efficiency(flag, l[j], u[j], ll, uu);
- /* set new actual bounds of the column */
- l[j] = ll, u[j] = uu;
- /* if the change is efficient, add all rows affected by the
- corresponding column, to the list */
- if (eff > 0)
- { GLPAIJ *aij;
- for (aij = col->ptr; aij != NULL; aij = aij->c_next)
- { int ii = aij->row->i;
- /* if the row was processed maximal number of times,
- skip it */
- if (pass[ii] >= max_pass) continue;
- /* if the row is free, skip it */
- if (L[ii] == -DBL_MAX && U[ii] == +DBL_MAX) continue;
- /* put the row into the list */
- if (mark[ii] == 0)
- { xassert(size <= m);
- list[++size] = ii, mark[ii] = 1;
- }
- }
- }
- }
- }
- done: /* free working arrays */
- xfree(ind);
- xfree(list);
- xfree(mark);
- xfree(pass);
- xfree(val);
- xfree(lb);
- xfree(ub);
- return ret;
- }
- /***********************************************************************
- * NAME
- *
- * ios_preprocess_node - preprocess current subproblem
- *
- * SYNOPSIS
- *
- * #include "glpios.h"
- * int ios_preprocess_node(glp_tree *tree, int max_pass);
- *
- * DESCRIPTION
- *
- * The routine ios_preprocess_node performs basic preprocessing of the
- * current subproblem.
- *
- * RETURNS
- *
- * If no primal infeasibility is detected, the routine returns zero,
- * otherwise non-zero. */
- int ios_preprocess_node(glp_tree *tree, int max_pass)
- { glp_prob *mip = tree->mip;
- int m = mip->m;
- int n = mip->n;
- int i, j, nrs, *num, ret = 0;
- double *L, *U, *l, *u;
- /* the current subproblem must exist */
- xassert(tree->curr != NULL);
- /* determine original row bounds */
- L = xcalloc(1+m, sizeof(double));
- U = xcalloc(1+m, sizeof(double));
- switch (mip->mip_stat)
- { case GLP_UNDEF:
- L[0] = -DBL_MAX, U[0] = +DBL_MAX;
- break;
- case GLP_FEAS:
- switch (mip->dir)
- { case GLP_MIN:
- L[0] = -DBL_MAX, U[0] = mip->mip_obj - mip->c0;
- break;
- case GLP_MAX:
- L[0] = mip->mip_obj - mip->c0, U[0] = +DBL_MAX;
- break;
- default:
- xassert(mip != mip);
- }
- break;
- default:
- xassert(mip != mip);
- }
- for (i = 1; i <= m; i++)
- { L[i] = glp_get_row_lb(mip, i);
- U[i] = glp_get_row_ub(mip, i);
- }
- /* determine original column bounds */
- l = xcalloc(1+n, sizeof(double));
- u = xcalloc(1+n, sizeof(double));
- for (j = 1; j <= n; j++)
- { l[j] = glp_get_col_lb(mip, j);
- u[j] = glp_get_col_ub(mip, j);
- }
- /* build the initial list of rows to be analyzed */
- nrs = m + 1;
- num = xcalloc(1+nrs, sizeof(int));
- for (i = 1; i <= nrs; i++) num[i] = i - 1;
- /* perform basic preprocessing */
- if (basic_preprocessing(mip , L, U, l, u, nrs, num, max_pass))
- { ret = 1;
- goto done;
- }
- /* set new actual (relaxed) row bounds */
- for (i = 1; i <= m; i++)
- { /* consider only non-active rows to keep dual feasibility */
- if (glp_get_row_stat(mip, i) == GLP_BS)
- { if (L[i] == -DBL_MAX && U[i] == +DBL_MAX)
- glp_set_row_bnds(mip, i, GLP_FR, 0.0, 0.0);
- else if (U[i] == +DBL_MAX)
- glp_set_row_bnds(mip, i, GLP_LO, L[i], 0.0);
- else if (L[i] == -DBL_MAX)
- glp_set_row_bnds(mip, i, GLP_UP, 0.0, U[i]);
- }
- }
- /* set new actual (tightened) column bounds */
- for (j = 1; j <= n; j++)
- { int type;
- if (l[j] == -DBL_MAX && u[j] == +DBL_MAX)
- type = GLP_FR;
- else if (u[j] == +DBL_MAX)
- type = GLP_LO;
- else if (l[j] == -DBL_MAX)
- type = GLP_UP;
- else if (l[j] != u[j])
- type = GLP_DB;
- else
- type = GLP_FX;
- glp_set_col_bnds(mip, j, type, l[j], u[j]);
- }
- done: /* free working arrays and return */
- xfree(L);
- xfree(U);
- xfree(l);
- xfree(u);
- xfree(num);
- return ret;
- }
- /* eof */
|