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