alpar@1: /* glplpx02.c */ alpar@1: alpar@1: /*********************************************************************** alpar@1: * This code is part of GLPK (GNU Linear Programming Kit). alpar@1: * alpar@1: * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, alpar@1: * 2009, 2010 Andrew Makhorin, Department for Applied Informatics, alpar@1: * Moscow Aviation Institute, Moscow, Russia. All rights reserved. alpar@1: * E-mail: . alpar@1: * alpar@1: * GLPK is free software: you can redistribute it and/or modify it alpar@1: * under the terms of the GNU General Public License as published by alpar@1: * the Free Software Foundation, either version 3 of the License, or alpar@1: * (at your option) any later version. alpar@1: * alpar@1: * GLPK is distributed in the hope that it will be useful, but WITHOUT alpar@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY alpar@1: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public alpar@1: * License for more details. alpar@1: * alpar@1: * You should have received a copy of the GNU General Public License alpar@1: * along with GLPK. If not, see . alpar@1: ***********************************************************************/ alpar@1: alpar@1: #include "glpapi.h" alpar@1: alpar@1: /*********************************************************************** alpar@1: * NAME alpar@1: * alpar@1: * lpx_put_solution - store basic solution components alpar@1: * alpar@1: * SYNOPSIS alpar@1: * alpar@1: * void lpx_put_solution(glp_prob *lp, int inval, const int *p_stat, alpar@1: * const int *d_stat, const double *obj_val, const int r_stat[], alpar@1: * const double r_prim[], const double r_dual[], const int c_stat[], alpar@1: * const double c_prim[], const double c_dual[]) alpar@1: * alpar@1: * DESCRIPTION alpar@1: * alpar@1: * The routine lpx_put_solution stores basic solution components to the alpar@1: * specified problem object. alpar@1: * alpar@1: * The parameter inval is the basis factorization invalidity flag. alpar@1: * If this flag is clear, the current status of the basis factorization alpar@1: * remains unchanged. If this flag is set, the routine invalidates the alpar@1: * basis factorization. alpar@1: * alpar@1: * The parameter p_stat is a pointer to the status of primal basic alpar@1: * solution, which should be specified as follows: alpar@1: * alpar@1: * GLP_UNDEF - primal solution is undefined; alpar@1: * GLP_FEAS - primal solution is feasible; alpar@1: * GLP_INFEAS - primal solution is infeasible; alpar@1: * GLP_NOFEAS - no primal feasible solution exists. alpar@1: * alpar@1: * If the parameter p_stat is NULL, the current status of primal basic alpar@1: * solution remains unchanged. alpar@1: * alpar@1: * The parameter d_stat is a pointer to the status of dual basic alpar@1: * solution, which should be specified as follows: alpar@1: * alpar@1: * GLP_UNDEF - dual solution is undefined; alpar@1: * GLP_FEAS - dual solution is feasible; alpar@1: * GLP_INFEAS - dual solution is infeasible; alpar@1: * GLP_NOFEAS - no dual feasible solution exists. alpar@1: * alpar@1: * If the parameter d_stat is NULL, the current status of dual basic alpar@1: * solution remains unchanged. alpar@1: * alpar@1: * The parameter obj_val is a pointer to the objective function value. alpar@1: * If it is NULL, the current value of the objective function remains alpar@1: * unchanged. alpar@1: * alpar@1: * The array element r_stat[i], 1 <= i <= m (where m is the number of alpar@1: * rows in the problem object), specifies the status of i-th auxiliary alpar@1: * variable, which should be specified as follows: alpar@1: * alpar@1: * GLP_BS - basic variable; alpar@1: * GLP_NL - non-basic variable on lower bound; alpar@1: * GLP_NU - non-basic variable on upper bound; alpar@1: * GLP_NF - non-basic free variable; alpar@1: * GLP_NS - non-basic fixed variable. alpar@1: * alpar@1: * If the parameter r_stat is NULL, the current statuses of auxiliary alpar@1: * variables remain unchanged. alpar@1: * alpar@1: * The array element r_prim[i], 1 <= i <= m (where m is the number of alpar@1: * rows in the problem object), specifies a primal value of i-th alpar@1: * auxiliary variable. If the parameter r_prim is NULL, the current alpar@1: * primal values of auxiliary variables remain unchanged. alpar@1: * alpar@1: * The array element r_dual[i], 1 <= i <= m (where m is the number of alpar@1: * rows in the problem object), specifies a dual value (reduced cost) alpar@1: * of i-th auxiliary variable. If the parameter r_dual is NULL, the alpar@1: * current dual values of auxiliary variables remain unchanged. alpar@1: * alpar@1: * The array element c_stat[j], 1 <= j <= n (where n is the number of alpar@1: * columns in the problem object), specifies the status of j-th alpar@1: * structural variable, which should be specified as follows: alpar@1: * alpar@1: * GLP_BS - basic variable; alpar@1: * GLP_NL - non-basic variable on lower bound; alpar@1: * GLP_NU - non-basic variable on upper bound; alpar@1: * GLP_NF - non-basic free variable; alpar@1: * GLP_NS - non-basic fixed variable. alpar@1: * alpar@1: * If the parameter c_stat is NULL, the current statuses of structural alpar@1: * variables remain unchanged. alpar@1: * alpar@1: * The array element c_prim[j], 1 <= j <= n (where n is the number of alpar@1: * columns in the problem object), specifies a primal value of j-th alpar@1: * structural variable. If the parameter c_prim is NULL, the current alpar@1: * primal values of structural variables remain unchanged. alpar@1: * alpar@1: * The array element c_dual[j], 1 <= j <= n (where n is the number of alpar@1: * columns in the problem object), specifies a dual value (reduced cost) alpar@1: * of j-th structural variable. If the parameter c_dual is NULL, the alpar@1: * current dual values of structural variables remain unchanged. */ alpar@1: alpar@1: void lpx_put_solution(glp_prob *lp, int inval, const int *p_stat, alpar@1: const int *d_stat, const double *obj_val, const int r_stat[], alpar@1: const double r_prim[], const double r_dual[], const int c_stat[], alpar@1: const double c_prim[], const double c_dual[]) alpar@1: { GLPROW *row; alpar@1: GLPCOL *col; alpar@1: int i, j; alpar@1: /* invalidate the basis factorization, if required */ alpar@1: if (inval) lp->valid = 0; alpar@1: /* store primal status */ alpar@1: if (p_stat != NULL) alpar@1: { if (!(*p_stat == GLP_UNDEF || *p_stat == GLP_FEAS || alpar@1: *p_stat == GLP_INFEAS || *p_stat == GLP_NOFEAS)) alpar@1: xerror("lpx_put_solution: p_stat = %d; invalid primal statu" alpar@1: "s\n", *p_stat); alpar@1: lp->pbs_stat = *p_stat; alpar@1: } alpar@1: /* store dual status */ alpar@1: if (d_stat != NULL) alpar@1: { if (!(*d_stat == GLP_UNDEF || *d_stat == GLP_FEAS || alpar@1: *d_stat == GLP_INFEAS || *d_stat == GLP_NOFEAS)) alpar@1: xerror("lpx_put_solution: d_stat = %d; invalid dual status " alpar@1: "\n", *d_stat); alpar@1: lp->dbs_stat = *d_stat; alpar@1: } alpar@1: /* store objective function value */ alpar@1: if (obj_val != NULL) lp->obj_val = *obj_val; alpar@1: /* store row solution components */ alpar@1: for (i = 1; i <= lp->m; i++) alpar@1: { row = lp->row[i]; alpar@1: if (r_stat != NULL) alpar@1: { if (!(r_stat[i] == GLP_BS || alpar@1: row->type == GLP_FR && r_stat[i] == GLP_NF || alpar@1: row->type == GLP_LO && r_stat[i] == GLP_NL || alpar@1: row->type == GLP_UP && r_stat[i] == GLP_NU || alpar@1: row->type == GLP_DB && r_stat[i] == GLP_NL || alpar@1: row->type == GLP_DB && r_stat[i] == GLP_NU || alpar@1: row->type == GLP_FX && r_stat[i] == GLP_NS)) alpar@1: xerror("lpx_put_solution: r_stat[%d] = %d; invalid row s" alpar@1: "tatus\n", i, r_stat[i]); alpar@1: row->stat = r_stat[i]; alpar@1: } alpar@1: if (r_prim != NULL) row->prim = r_prim[i]; alpar@1: if (r_dual != NULL) row->dual = r_dual[i]; alpar@1: } alpar@1: /* store column solution components */ alpar@1: for (j = 1; j <= lp->n; j++) alpar@1: { col = lp->col[j]; alpar@1: if (c_stat != NULL) alpar@1: { if (!(c_stat[j] == GLP_BS || alpar@1: col->type == GLP_FR && c_stat[j] == GLP_NF || alpar@1: col->type == GLP_LO && c_stat[j] == GLP_NL || alpar@1: col->type == GLP_UP && c_stat[j] == GLP_NU || alpar@1: col->type == GLP_DB && c_stat[j] == GLP_NL || alpar@1: col->type == GLP_DB && c_stat[j] == GLP_NU || alpar@1: col->type == GLP_FX && c_stat[j] == GLP_NS)) alpar@1: xerror("lpx_put_solution: c_stat[%d] = %d; invalid colum" alpar@1: "n status\n", j, c_stat[j]); alpar@1: col->stat = c_stat[j]; alpar@1: } alpar@1: if (c_prim != NULL) col->prim = c_prim[j]; alpar@1: if (c_dual != NULL) col->dual = c_dual[j]; alpar@1: } alpar@1: return; alpar@1: } alpar@1: alpar@1: /*---------------------------------------------------------------------- alpar@1: -- lpx_put_mip_soln - store mixed integer solution components. alpar@1: -- alpar@1: -- *Synopsis* alpar@1: -- alpar@1: -- #include "glplpx.h" alpar@1: -- void lpx_put_mip_soln(glp_prob *lp, int i_stat, double row_mipx[], alpar@1: -- double col_mipx[]); alpar@1: -- alpar@1: -- *Description* alpar@1: -- alpar@1: -- The routine lpx_put_mip_soln stores solution components obtained by alpar@1: -- branch-and-bound solver into the specified problem object. alpar@1: -- alpar@1: -- NOTE: This routine is intended for internal use only. */ alpar@1: alpar@1: void lpx_put_mip_soln(glp_prob *lp, int i_stat, double row_mipx[], alpar@1: double col_mipx[]) alpar@1: { GLPROW *row; alpar@1: GLPCOL *col; alpar@1: int i, j; alpar@1: double sum; alpar@1: /* store mixed integer status */ alpar@1: #if 0 alpar@1: if (!(i_stat == LPX_I_UNDEF || i_stat == LPX_I_OPT || alpar@1: i_stat == LPX_I_FEAS || i_stat == LPX_I_NOFEAS)) alpar@1: fault("lpx_put_mip_soln: i_stat = %d; invalid mixed integer st" alpar@1: "atus", i_stat); alpar@1: lp->i_stat = i_stat; alpar@1: #else alpar@1: switch (i_stat) alpar@1: { case LPX_I_UNDEF: alpar@1: lp->mip_stat = GLP_UNDEF; break; alpar@1: case LPX_I_OPT: alpar@1: lp->mip_stat = GLP_OPT; break; alpar@1: case LPX_I_FEAS: alpar@1: lp->mip_stat = GLP_FEAS; break; alpar@1: case LPX_I_NOFEAS: alpar@1: lp->mip_stat = GLP_NOFEAS; break; alpar@1: default: alpar@1: xerror("lpx_put_mip_soln: i_stat = %d; invalid mixed intege" alpar@1: "r status\n", i_stat); alpar@1: } alpar@1: #endif alpar@1: /* store row solution components */ alpar@1: if (row_mipx != NULL) alpar@1: { for (i = 1; i <= lp->m; i++) alpar@1: { row = lp->row[i]; alpar@1: row->mipx = row_mipx[i]; alpar@1: } alpar@1: } alpar@1: /* store column solution components */ alpar@1: if (col_mipx != NULL) alpar@1: { for (j = 1; j <= lp->n; j++) alpar@1: { col = lp->col[j]; alpar@1: col->mipx = col_mipx[j]; alpar@1: } alpar@1: } alpar@1: /* if the solution is claimed to be integer feasible, check it */ alpar@1: if (lp->mip_stat == GLP_OPT || lp->mip_stat == GLP_FEAS) alpar@1: { for (j = 1; j <= lp->n; j++) alpar@1: { col = lp->col[j]; alpar@1: if (col->kind == GLP_IV && col->mipx != floor(col->mipx)) alpar@1: xerror("lpx_put_mip_soln: col_mipx[%d] = %.*g; must be i" alpar@1: "ntegral\n", j, DBL_DIG, col->mipx); alpar@1: } alpar@1: } alpar@1: /* compute the objective function value */ alpar@1: sum = lp->c0; alpar@1: for (j = 1; j <= lp->n; j++) alpar@1: { col = lp->col[j]; alpar@1: sum += col->coef * col->mipx; alpar@1: } alpar@1: lp->mip_obj = sum; alpar@1: return; alpar@1: } alpar@1: alpar@1: /* eof */