src/glpapi14.c
author Alpar Juttner <alpar@cs.elte.hu>
Mon, 06 Dec 2010 13:09:21 +0100
changeset 1 c445c931472f
permissions -rw-r--r--
Import glpk-4.45

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