src/glpapi14.c
author Alpar Juttner <alpar@cs.elte.hu>
Sun, 05 Dec 2010 17:35:23 +0100
changeset 2 4c8956a7bdf4
permissions -rw-r--r--
Set up CMAKE build environment
     1 /* glpapi14.c (processing models in GNU MathProg language) */
     2 
     3 /***********************************************************************
     4 *  This code is part of GLPK (GNU Linear Programming Kit).
     5 *
     6 *  Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
     7 *  2009, 2010 Andrew Makhorin, Department for Applied Informatics,
     8 *  Moscow Aviation Institute, Moscow, Russia. All rights reserved.
     9 *  E-mail: <mao@gnu.org>.
    10 *
    11 *  GLPK is free software: you can redistribute it and/or modify it
    12 *  under the terms of the GNU General Public License as published by
    13 *  the Free Software Foundation, either version 3 of the License, or
    14 *  (at your option) any later version.
    15 *
    16 *  GLPK is distributed in the hope that it will be useful, but WITHOUT
    17 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    18 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
    19 *  License for more details.
    20 *
    21 *  You should have received a copy of the GNU General Public License
    22 *  along with GLPK. If not, see <http://www.gnu.org/licenses/>.
    23 ***********************************************************************/
    24 
    25 #define GLP_TRAN_DEFINED
    26 typedef struct MPL glp_tran;
    27 
    28 #include "glpmpl.h"
    29 #include "glpapi.h"
    30 
    31 glp_tran *glp_mpl_alloc_wksp(void)
    32 {     /* allocate the MathProg translator workspace */
    33       glp_tran *tran;
    34       tran = mpl_initialize();
    35       return tran;
    36 }
    37 
    38 #if 1 /* 08/XII-2009 */
    39 void _glp_mpl_init_rand(glp_tran *tran, int seed)
    40 {     if (tran->phase != 0)
    41          xerror("glp_mpl_init_rand: invalid call sequence\n");
    42       rng_init_rand(tran->rand, seed);
    43       return;
    44 }
    45 #endif
    46 
    47 int glp_mpl_read_model(glp_tran *tran, const char *fname, int skip)
    48 {     /* read and translate model section */
    49       int ret;
    50       if (tran->phase != 0)
    51          xerror("glp_mpl_read_model: invalid call sequence\n");
    52       ret = mpl_read_model(tran, (char *)fname, skip);
    53       if (ret == 1 || ret == 2)
    54          ret = 0;
    55       else if (ret == 4)
    56          ret = 1;
    57       else
    58          xassert(ret != ret);
    59       return ret;
    60 }
    61 
    62 int glp_mpl_read_data(glp_tran *tran, const char *fname)
    63 {     /* read and translate data section */
    64       int ret;
    65       if (!(tran->phase == 1 || tran->phase == 2))
    66          xerror("glp_mpl_read_data: invalid call sequence\n");
    67       ret = mpl_read_data(tran, (char *)fname);
    68       if (ret == 2)
    69          ret = 0;
    70       else if (ret == 4)
    71          ret = 1;
    72       else
    73          xassert(ret != ret);
    74       return ret;
    75 }
    76 
    77 int glp_mpl_generate(glp_tran *tran, const char *fname)
    78 {     /* generate the model */
    79       int ret;
    80       if (!(tran->phase == 1 || tran->phase == 2))
    81          xerror("glp_mpl_generate: invalid call sequence\n");
    82       ret = mpl_generate(tran, (char *)fname);
    83       if (ret == 3)
    84          ret = 0;
    85       else if (ret == 4)
    86          ret = 1;
    87       return ret;
    88 }
    89 
    90 void glp_mpl_build_prob(glp_tran *tran, glp_prob *prob)
    91 {     /* build LP/MIP problem instance from the model */
    92       int m, n, i, j, t, kind, type, len, *ind;
    93       double lb, ub, *val;
    94       if (tran->phase != 3)
    95          xerror("glp_mpl_build_prob: invalid call sequence\n");
    96       /* erase the problem object */
    97       glp_erase_prob(prob);
    98       /* set problem name */
    99       glp_set_prob_name(prob, mpl_get_prob_name(tran));
   100       /* build rows (constraints) */
   101       m = mpl_get_num_rows(tran);
   102       if (m > 0)
   103          glp_add_rows(prob, m);
   104       for (i = 1; i <= m; i++)
   105       {  /* set row name */
   106          glp_set_row_name(prob, i, mpl_get_row_name(tran, i));
   107          /* set row bounds */
   108          type = mpl_get_row_bnds(tran, i, &lb, &ub);
   109          switch (type)
   110          {  case MPL_FR: type = GLP_FR; break;
   111             case MPL_LO: type = GLP_LO; break;
   112             case MPL_UP: type = GLP_UP; break;
   113             case MPL_DB: type = GLP_DB; break;
   114             case MPL_FX: type = GLP_FX; break;
   115             default: xassert(type != type);
   116          }
   117          if (type == GLP_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb)))
   118          {  type = GLP_FX;
   119             if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub;
   120          }
   121          glp_set_row_bnds(prob, i, type, lb, ub);
   122          /* warn about non-zero constant term */
   123          if (mpl_get_row_c0(tran, i) != 0.0)
   124             xprintf("glp_mpl_build_prob: row %s; constant term %.12g ig"
   125                "nored\n",
   126                mpl_get_row_name(tran, i), mpl_get_row_c0(tran, i));
   127       }
   128       /* build columns (variables) */
   129       n = mpl_get_num_cols(tran);
   130       if (n > 0)
   131          glp_add_cols(prob, n);
   132       for (j = 1; j <= n; j++)
   133       {  /* set column name */
   134          glp_set_col_name(prob, j, mpl_get_col_name(tran, j));
   135          /* set column kind */
   136          kind = mpl_get_col_kind(tran, j);
   137          switch (kind)
   138          {  case MPL_NUM:
   139                break;
   140             case MPL_INT:
   141             case MPL_BIN:
   142                glp_set_col_kind(prob, j, GLP_IV);
   143                break;
   144             default:
   145                xassert(kind != kind);
   146          }
   147          /* set column bounds */
   148          type = mpl_get_col_bnds(tran, j, &lb, &ub);
   149          switch (type)
   150          {  case MPL_FR: type = GLP_FR; break;
   151             case MPL_LO: type = GLP_LO; break;
   152             case MPL_UP: type = GLP_UP; break;
   153             case MPL_DB: type = GLP_DB; break;
   154             case MPL_FX: type = GLP_FX; break;
   155             default: xassert(type != type);
   156          }
   157          if (kind == MPL_BIN)
   158          {  if (type == GLP_FR || type == GLP_UP || lb < 0.0) lb = 0.0;
   159             if (type == GLP_FR || type == GLP_LO || ub > 1.0) ub = 1.0;
   160             type = GLP_DB;
   161          }
   162          if (type == GLP_DB && fabs(lb - ub) < 1e-9 * (1.0 + fabs(lb)))
   163          {  type = GLP_FX;
   164             if (fabs(lb) <= fabs(ub)) ub = lb; else lb = ub;
   165          }
   166          glp_set_col_bnds(prob, j, type, lb, ub);
   167       }
   168       /* load the constraint matrix */
   169       ind = xcalloc(1+n, sizeof(int));
   170       val = xcalloc(1+n, sizeof(double));
   171       for (i = 1; i <= m; i++)
   172       {  len = mpl_get_mat_row(tran, i, ind, val);
   173          glp_set_mat_row(prob, i, len, ind, val);
   174       }
   175       /* build objective function (the first objective is used) */
   176       for (i = 1; i <= m; i++)
   177       {  kind = mpl_get_row_kind(tran, i);
   178          if (kind == MPL_MIN || kind == MPL_MAX)
   179          {  /* set objective name */
   180             glp_set_obj_name(prob, mpl_get_row_name(tran, i));
   181             /* set optimization direction */
   182             glp_set_obj_dir(prob, kind == MPL_MIN ? GLP_MIN : GLP_MAX);
   183             /* set constant term */
   184             glp_set_obj_coef(prob, 0, mpl_get_row_c0(tran, i));
   185             /* set objective coefficients */
   186             len = mpl_get_mat_row(tran, i, ind, val);
   187             for (t = 1; t <= len; t++)
   188                glp_set_obj_coef(prob, ind[t], val[t]);
   189             break;
   190          }
   191       }
   192       /* free working arrays */
   193       xfree(ind);
   194       xfree(val);
   195       return;
   196 }
   197 
   198 int glp_mpl_postsolve(glp_tran *tran, glp_prob *prob, int sol)
   199 {     /* postsolve the model */
   200       int i, j, m, n, stat, ret;
   201       double prim, dual;
   202       if (!(tran->phase == 3 && !tran->flag_p))
   203          xerror("glp_mpl_postsolve: invalid call sequence\n");
   204       if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP))
   205          xerror("glp_mpl_postsolve: sol = %d; invalid parameter\n",
   206             sol);
   207       m = mpl_get_num_rows(tran);
   208       n = mpl_get_num_cols(tran);
   209       if (!(m == glp_get_num_rows(prob) &&
   210             n == glp_get_num_cols(prob)))
   211          xerror("glp_mpl_postsolve: wrong problem object\n");
   212       if (!mpl_has_solve_stmt(tran))
   213       {  ret = 0;
   214          goto done;
   215       }
   216       for (i = 1; i <= m; i++)
   217       {  if (sol == GLP_SOL)
   218          {  stat = glp_get_row_stat(prob, i);
   219             prim = glp_get_row_prim(prob, i);
   220             dual = glp_get_row_dual(prob, i);
   221          }
   222          else if (sol == GLP_IPT)
   223          {  stat = 0;
   224             prim = glp_ipt_row_prim(prob, i);
   225             dual = glp_ipt_row_dual(prob, i);
   226          }
   227          else if (sol == GLP_MIP)
   228          {  stat = 0;
   229             prim = glp_mip_row_val(prob, i);
   230             dual = 0.0;
   231          }
   232          else
   233             xassert(sol != sol);
   234          if (fabs(prim) < 1e-9) prim = 0.0;
   235          if (fabs(dual) < 1e-9) dual = 0.0;
   236          mpl_put_row_soln(tran, i, stat, prim, dual);
   237       }
   238       for (j = 1; j <= n; j++)
   239       {  if (sol == GLP_SOL)
   240          {  stat = glp_get_col_stat(prob, j);
   241             prim = glp_get_col_prim(prob, j);
   242             dual = glp_get_col_dual(prob, j);
   243          }
   244          else if (sol == GLP_IPT)
   245          {  stat = 0;
   246             prim = glp_ipt_col_prim(prob, j);
   247             dual = glp_ipt_col_dual(prob, j);
   248          }
   249          else if (sol == GLP_MIP)
   250          {  stat = 0;
   251             prim = glp_mip_col_val(prob, j);
   252             dual = 0.0;
   253          }
   254          else
   255             xassert(sol != sol);
   256          if (fabs(prim) < 1e-9) prim = 0.0;
   257          if (fabs(dual) < 1e-9) dual = 0.0;
   258          mpl_put_col_soln(tran, j, stat, prim, dual);
   259       }
   260       ret = mpl_postsolve(tran);
   261       if (ret == 3)
   262          ret = 0;
   263       else if (ret == 4)
   264          ret = 1;
   265 done: return ret;
   266 }
   267 
   268 void glp_mpl_free_wksp(glp_tran *tran)
   269 {     /* free the MathProg translator workspace */
   270       mpl_terminate(tran);
   271       return;
   272 }
   273 
   274 /* eof */