1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/glplpx02.c Mon Dec 06 13:09:21 2010 +0100
1.3 @@ -0,0 +1,264 @@
1.4 +/* glplpx02.c */
1.5 +
1.6 +/***********************************************************************
1.7 +* This code is part of GLPK (GNU Linear Programming Kit).
1.8 +*
1.9 +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
1.10 +* 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
1.11 +* Moscow Aviation Institute, Moscow, Russia. All rights reserved.
1.12 +* E-mail: <mao@gnu.org>.
1.13 +*
1.14 +* GLPK is free software: you can redistribute it and/or modify it
1.15 +* under the terms of the GNU General Public License as published by
1.16 +* the Free Software Foundation, either version 3 of the License, or
1.17 +* (at your option) any later version.
1.18 +*
1.19 +* GLPK is distributed in the hope that it will be useful, but WITHOUT
1.20 +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1.21 +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1.22 +* License for more details.
1.23 +*
1.24 +* You should have received a copy of the GNU General Public License
1.25 +* along with GLPK. If not, see <http://www.gnu.org/licenses/>.
1.26 +***********************************************************************/
1.27 +
1.28 +#include "glpapi.h"
1.29 +
1.30 +/***********************************************************************
1.31 +* NAME
1.32 +*
1.33 +* lpx_put_solution - store basic solution components
1.34 +*
1.35 +* SYNOPSIS
1.36 +*
1.37 +* void lpx_put_solution(glp_prob *lp, int inval, const int *p_stat,
1.38 +* const int *d_stat, const double *obj_val, const int r_stat[],
1.39 +* const double r_prim[], const double r_dual[], const int c_stat[],
1.40 +* const double c_prim[], const double c_dual[])
1.41 +*
1.42 +* DESCRIPTION
1.43 +*
1.44 +* The routine lpx_put_solution stores basic solution components to the
1.45 +* specified problem object.
1.46 +*
1.47 +* The parameter inval is the basis factorization invalidity flag.
1.48 +* If this flag is clear, the current status of the basis factorization
1.49 +* remains unchanged. If this flag is set, the routine invalidates the
1.50 +* basis factorization.
1.51 +*
1.52 +* The parameter p_stat is a pointer to the status of primal basic
1.53 +* solution, which should be specified as follows:
1.54 +*
1.55 +* GLP_UNDEF - primal solution is undefined;
1.56 +* GLP_FEAS - primal solution is feasible;
1.57 +* GLP_INFEAS - primal solution is infeasible;
1.58 +* GLP_NOFEAS - no primal feasible solution exists.
1.59 +*
1.60 +* If the parameter p_stat is NULL, the current status of primal basic
1.61 +* solution remains unchanged.
1.62 +*
1.63 +* The parameter d_stat is a pointer to the status of dual basic
1.64 +* solution, which should be specified as follows:
1.65 +*
1.66 +* GLP_UNDEF - dual solution is undefined;
1.67 +* GLP_FEAS - dual solution is feasible;
1.68 +* GLP_INFEAS - dual solution is infeasible;
1.69 +* GLP_NOFEAS - no dual feasible solution exists.
1.70 +*
1.71 +* If the parameter d_stat is NULL, the current status of dual basic
1.72 +* solution remains unchanged.
1.73 +*
1.74 +* The parameter obj_val is a pointer to the objective function value.
1.75 +* If it is NULL, the current value of the objective function remains
1.76 +* unchanged.
1.77 +*
1.78 +* The array element r_stat[i], 1 <= i <= m (where m is the number of
1.79 +* rows in the problem object), specifies the status of i-th auxiliary
1.80 +* variable, which should be specified as follows:
1.81 +*
1.82 +* GLP_BS - basic variable;
1.83 +* GLP_NL - non-basic variable on lower bound;
1.84 +* GLP_NU - non-basic variable on upper bound;
1.85 +* GLP_NF - non-basic free variable;
1.86 +* GLP_NS - non-basic fixed variable.
1.87 +*
1.88 +* If the parameter r_stat is NULL, the current statuses of auxiliary
1.89 +* variables remain unchanged.
1.90 +*
1.91 +* The array element r_prim[i], 1 <= i <= m (where m is the number of
1.92 +* rows in the problem object), specifies a primal value of i-th
1.93 +* auxiliary variable. If the parameter r_prim is NULL, the current
1.94 +* primal values of auxiliary variables remain unchanged.
1.95 +*
1.96 +* The array element r_dual[i], 1 <= i <= m (where m is the number of
1.97 +* rows in the problem object), specifies a dual value (reduced cost)
1.98 +* of i-th auxiliary variable. If the parameter r_dual is NULL, the
1.99 +* current dual values of auxiliary variables remain unchanged.
1.100 +*
1.101 +* The array element c_stat[j], 1 <= j <= n (where n is the number of
1.102 +* columns in the problem object), specifies the status of j-th
1.103 +* structural variable, which should be specified as follows:
1.104 +*
1.105 +* GLP_BS - basic variable;
1.106 +* GLP_NL - non-basic variable on lower bound;
1.107 +* GLP_NU - non-basic variable on upper bound;
1.108 +* GLP_NF - non-basic free variable;
1.109 +* GLP_NS - non-basic fixed variable.
1.110 +*
1.111 +* If the parameter c_stat is NULL, the current statuses of structural
1.112 +* variables remain unchanged.
1.113 +*
1.114 +* The array element c_prim[j], 1 <= j <= n (where n is the number of
1.115 +* columns in the problem object), specifies a primal value of j-th
1.116 +* structural variable. If the parameter c_prim is NULL, the current
1.117 +* primal values of structural variables remain unchanged.
1.118 +*
1.119 +* The array element c_dual[j], 1 <= j <= n (where n is the number of
1.120 +* columns in the problem object), specifies a dual value (reduced cost)
1.121 +* of j-th structural variable. If the parameter c_dual is NULL, the
1.122 +* current dual values of structural variables remain unchanged. */
1.123 +
1.124 +void lpx_put_solution(glp_prob *lp, int inval, const int *p_stat,
1.125 + const int *d_stat, const double *obj_val, const int r_stat[],
1.126 + const double r_prim[], const double r_dual[], const int c_stat[],
1.127 + const double c_prim[], const double c_dual[])
1.128 +{ GLPROW *row;
1.129 + GLPCOL *col;
1.130 + int i, j;
1.131 + /* invalidate the basis factorization, if required */
1.132 + if (inval) lp->valid = 0;
1.133 + /* store primal status */
1.134 + if (p_stat != NULL)
1.135 + { if (!(*p_stat == GLP_UNDEF || *p_stat == GLP_FEAS ||
1.136 + *p_stat == GLP_INFEAS || *p_stat == GLP_NOFEAS))
1.137 + xerror("lpx_put_solution: p_stat = %d; invalid primal statu"
1.138 + "s\n", *p_stat);
1.139 + lp->pbs_stat = *p_stat;
1.140 + }
1.141 + /* store dual status */
1.142 + if (d_stat != NULL)
1.143 + { if (!(*d_stat == GLP_UNDEF || *d_stat == GLP_FEAS ||
1.144 + *d_stat == GLP_INFEAS || *d_stat == GLP_NOFEAS))
1.145 + xerror("lpx_put_solution: d_stat = %d; invalid dual status "
1.146 + "\n", *d_stat);
1.147 + lp->dbs_stat = *d_stat;
1.148 + }
1.149 + /* store objective function value */
1.150 + if (obj_val != NULL) lp->obj_val = *obj_val;
1.151 + /* store row solution components */
1.152 + for (i = 1; i <= lp->m; i++)
1.153 + { row = lp->row[i];
1.154 + if (r_stat != NULL)
1.155 + { if (!(r_stat[i] == GLP_BS ||
1.156 + row->type == GLP_FR && r_stat[i] == GLP_NF ||
1.157 + row->type == GLP_LO && r_stat[i] == GLP_NL ||
1.158 + row->type == GLP_UP && r_stat[i] == GLP_NU ||
1.159 + row->type == GLP_DB && r_stat[i] == GLP_NL ||
1.160 + row->type == GLP_DB && r_stat[i] == GLP_NU ||
1.161 + row->type == GLP_FX && r_stat[i] == GLP_NS))
1.162 + xerror("lpx_put_solution: r_stat[%d] = %d; invalid row s"
1.163 + "tatus\n", i, r_stat[i]);
1.164 + row->stat = r_stat[i];
1.165 + }
1.166 + if (r_prim != NULL) row->prim = r_prim[i];
1.167 + if (r_dual != NULL) row->dual = r_dual[i];
1.168 + }
1.169 + /* store column solution components */
1.170 + for (j = 1; j <= lp->n; j++)
1.171 + { col = lp->col[j];
1.172 + if (c_stat != NULL)
1.173 + { if (!(c_stat[j] == GLP_BS ||
1.174 + col->type == GLP_FR && c_stat[j] == GLP_NF ||
1.175 + col->type == GLP_LO && c_stat[j] == GLP_NL ||
1.176 + col->type == GLP_UP && c_stat[j] == GLP_NU ||
1.177 + col->type == GLP_DB && c_stat[j] == GLP_NL ||
1.178 + col->type == GLP_DB && c_stat[j] == GLP_NU ||
1.179 + col->type == GLP_FX && c_stat[j] == GLP_NS))
1.180 + xerror("lpx_put_solution: c_stat[%d] = %d; invalid colum"
1.181 + "n status\n", j, c_stat[j]);
1.182 + col->stat = c_stat[j];
1.183 + }
1.184 + if (c_prim != NULL) col->prim = c_prim[j];
1.185 + if (c_dual != NULL) col->dual = c_dual[j];
1.186 + }
1.187 + return;
1.188 +}
1.189 +
1.190 +/*----------------------------------------------------------------------
1.191 +-- lpx_put_mip_soln - store mixed integer solution components.
1.192 +--
1.193 +-- *Synopsis*
1.194 +--
1.195 +-- #include "glplpx.h"
1.196 +-- void lpx_put_mip_soln(glp_prob *lp, int i_stat, double row_mipx[],
1.197 +-- double col_mipx[]);
1.198 +--
1.199 +-- *Description*
1.200 +--
1.201 +-- The routine lpx_put_mip_soln stores solution components obtained by
1.202 +-- branch-and-bound solver into the specified problem object.
1.203 +--
1.204 +-- NOTE: This routine is intended for internal use only. */
1.205 +
1.206 +void lpx_put_mip_soln(glp_prob *lp, int i_stat, double row_mipx[],
1.207 + double col_mipx[])
1.208 +{ GLPROW *row;
1.209 + GLPCOL *col;
1.210 + int i, j;
1.211 + double sum;
1.212 + /* store mixed integer status */
1.213 +#if 0
1.214 + if (!(i_stat == LPX_I_UNDEF || i_stat == LPX_I_OPT ||
1.215 + i_stat == LPX_I_FEAS || i_stat == LPX_I_NOFEAS))
1.216 + fault("lpx_put_mip_soln: i_stat = %d; invalid mixed integer st"
1.217 + "atus", i_stat);
1.218 + lp->i_stat = i_stat;
1.219 +#else
1.220 + switch (i_stat)
1.221 + { case LPX_I_UNDEF:
1.222 + lp->mip_stat = GLP_UNDEF; break;
1.223 + case LPX_I_OPT:
1.224 + lp->mip_stat = GLP_OPT; break;
1.225 + case LPX_I_FEAS:
1.226 + lp->mip_stat = GLP_FEAS; break;
1.227 + case LPX_I_NOFEAS:
1.228 + lp->mip_stat = GLP_NOFEAS; break;
1.229 + default:
1.230 + xerror("lpx_put_mip_soln: i_stat = %d; invalid mixed intege"
1.231 + "r status\n", i_stat);
1.232 + }
1.233 +#endif
1.234 + /* store row solution components */
1.235 + if (row_mipx != NULL)
1.236 + { for (i = 1; i <= lp->m; i++)
1.237 + { row = lp->row[i];
1.238 + row->mipx = row_mipx[i];
1.239 + }
1.240 + }
1.241 + /* store column solution components */
1.242 + if (col_mipx != NULL)
1.243 + { for (j = 1; j <= lp->n; j++)
1.244 + { col = lp->col[j];
1.245 + col->mipx = col_mipx[j];
1.246 + }
1.247 + }
1.248 + /* if the solution is claimed to be integer feasible, check it */
1.249 + if (lp->mip_stat == GLP_OPT || lp->mip_stat == GLP_FEAS)
1.250 + { for (j = 1; j <= lp->n; j++)
1.251 + { col = lp->col[j];
1.252 + if (col->kind == GLP_IV && col->mipx != floor(col->mipx))
1.253 + xerror("lpx_put_mip_soln: col_mipx[%d] = %.*g; must be i"
1.254 + "ntegral\n", j, DBL_DIG, col->mipx);
1.255 + }
1.256 + }
1.257 + /* compute the objective function value */
1.258 + sum = lp->c0;
1.259 + for (j = 1; j <= lp->n; j++)
1.260 + { col = lp->col[j];
1.261 + sum += col->coef * col->mipx;
1.262 + }
1.263 + lp->mip_obj = sum;
1.264 + return;
1.265 +}
1.266 +
1.267 +/* eof */