text: /* wrsol.c (write basic solution in GLPK format) */
  
  /***********************************************************************
  *  This code is part of GLPK (GNU Linear Programming Kit).
  *
  *  Copyright (C) 2010-2016 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 "env.h"
  #include "prob.h"
  
  /***********************************************************************
  *  NAME
  *
  *  glp_write_sol - write basic solution in GLPK format
  *
  *  SYNOPSIS
  *
  *  int glp_write_sol(glp_prob *P, const char *fname);
  *
  *  DESCRIPTION
  *
  *  The routine glp_write_sol writes basic solution to a text file in
  *  GLPK format.
  *
  *  RETURNS
  *
  *  If the operation was successful, the routine returns zero. Otherwise
  *  it prints an error message and returns non-zero. */
  
  int glp_write_sol(glp_prob *P, const char *fname)
  {     glp_file *fp;
        GLPROW *row;
        GLPCOL *col;
        int i, j, count, ret = 1;
        char *s;
  #if 0 /* 04/IV-2016 */
        if (P == NULL || P->magic != GLP_PROB_MAGIC)
           xerror("glp_write_sol: P = %p; invalid problem object\n", P);
  #endif
        if (fname == NULL)
           xerror("glp_write_sol: fname = %d; invalid parameter\n", fname)
              ;
        xprintf("Writing basic solution to '%s'...\n", fname);
        fp = glp_open(fname, "w"), count = 0;
        if (fp == NULL)
        {  xprintf("Unable to create '%s' - %s\n", fname, get_err_msg());
           goto done;
        }
        /* write comment lines */
        glp_format(fp, "c %-12s%s\n", "Problem:",
           P->name == NULL ? "" : P->name), count++;
        glp_format(fp, "c %-12s%d\n", "Rows:", P->m), count++;
        glp_format(fp, "c %-12s%d\n", "Columns:", P->n), count++;
        glp_format(fp, "c %-12s%d\n", "Non-zeros:", P->nnz), count++;
        switch (glp_get_status(P))
        {  case GLP_OPT:    s = "OPTIMAL";                   break;
           case GLP_FEAS:   s = "FEASIBLE";                  break;
           case GLP_INFEAS: s = "INFEASIBLE (INTERMEDIATE)"; break;
           case GLP_NOFEAS: s = "INFEASIBLE (FINAL)";        break;
           case GLP_UNBND:  s = "UNBOUNDED";                 break;
           case GLP_UNDEF:  s = "UNDEFINED";                 break;
           default:         s = "???";                       break;
        }
        glp_format(fp, "c %-12s%s\n", "Status:", s), count++;
        switch (P->dir)
        {  case GLP_MIN: s = "MINimum"; break;
           case GLP_MAX: s = "MAXimum"; break;
           default:      s = "???";     break;
        }
        glp_format(fp, "c %-12s%s%s%.10g (%s)\n", "Objective:",
           P->obj == NULL ? "" : P->obj,
           P->obj == NULL ? "" : " = ", P->obj_val, s), count++;
        glp_format(fp, "c\n"), count++;
        /* write solution line */
        glp_format(fp, "s bas %d %d ", P->m, P->n), count++;
        switch (P->pbs_stat)
        {  case GLP_UNDEF:  glp_format(fp, "u"); break;
           case GLP_FEAS:   glp_format(fp, "f"); break;
           case GLP_INFEAS: glp_format(fp, "i"); break;
           case GLP_NOFEAS: glp_format(fp, "n"); break;
           default:         glp_format(fp, "?"); break;
        }
        glp_format(fp, " ");
        switch (P->dbs_stat)
        {  case GLP_UNDEF:  glp_format(fp, "u"); break;
           case GLP_FEAS:   glp_format(fp, "f"); break;
           case GLP_INFEAS: glp_format(fp, "i"); break;
           case GLP_NOFEAS: glp_format(fp, "n"); break;
           default:         glp_format(fp, "?"); break;
        }
        glp_format(fp, " %.*g\n", DBL_DIG, P->obj_val);
        /* write row solution descriptor lines */
        for (i = 1; i <= P->m; i++)
        {  row = P->row[i];
           glp_format(fp, "i %d ", i), count++;
           switch (row->stat)
           {  case GLP_BS:
                 glp_format(fp, "b");
                 break;
              case GLP_NL:
                 glp_format(fp, "l");
                 break;
              case GLP_NU:
                 glp_format(fp, "u");
                 break;
              case GLP_NF:
                 glp_format(fp, "f");
                 break;
              case GLP_NS:
                 glp_format(fp, "s");
                 break;
              default:
                 xassert(row != row);
           }
           glp_format(fp, " %.*g %.*g\n", DBL_DIG, row->prim, DBL_DIG,
              row->dual);
        }
        /* write column solution descriptor lines */
        for (j = 1; j <= P->n; j++)
        {  col = P->col[j];
           glp_format(fp, "j %d ", j), count++;
           switch (col->stat)
           {  case GLP_BS:
                 glp_format(fp, "b");
                 break;
              case GLP_NL:
                 glp_format(fp, "l");
                 break;
              case GLP_NU:
                 glp_format(fp, "u");
                 break;
              case GLP_NF:
                 glp_format(fp, "f");
                 break;
              case GLP_NS:
                 glp_format(fp, "s");
                 break;
              default:
                 xassert(col != col);
           }
           glp_format(fp, " %.*g %.*g\n", DBL_DIG, col->prim, DBL_DIG,
              col->dual);
        }
        /* write end line */
        glp_format(fp, "e o f\n"), count++;
        if (glp_ioerr(fp))
        {  xprintf("Write error on '%s' - %s\n", fname, get_err_msg());
           goto done;
        }
        /* basic solution has been successfully written */
        xprintf("%d lines were written\n", count);
        ret = 0;
  done: if (fp != NULL)
           glp_close(fp);
        return ret;
  }
  
  /* eof */
  