src/glpssx.h
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
alpar@1
     1
/* glpssx.h (simplex method, bignum arithmetic) */
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
#ifndef GLPSSX_H
alpar@1
    26
#define GLPSSX_H
alpar@1
    27
alpar@1
    28
#include "glpbfx.h"
alpar@1
    29
#include "glpenv.h"
alpar@1
    30
alpar@1
    31
typedef struct SSX SSX;
alpar@1
    32
alpar@1
    33
struct SSX
alpar@1
    34
{     /* simplex solver workspace */
alpar@1
    35
/*----------------------------------------------------------------------
alpar@1
    36
// LP PROBLEM DATA
alpar@1
    37
//
alpar@1
    38
// It is assumed that LP problem has the following statement:
alpar@1
    39
//
alpar@1
    40
//    minimize (or maximize)
alpar@1
    41
//
alpar@1
    42
//       z = c[1]*x[1] + ... + c[m+n]*x[m+n] + c[0]                  (1)
alpar@1
    43
//
alpar@1
    44
//    subject to equality constraints
alpar@1
    45
//
alpar@1
    46
//       x[1] - a[1,1]*x[m+1] - ... - a[1,n]*x[m+n] = 0
alpar@1
    47
//
alpar@1
    48
//          .  .  .  .  .  .  .                                      (2)
alpar@1
    49
//
alpar@1
    50
//       x[m] - a[m,1]*x[m+1] + ... - a[m,n]*x[m+n] = 0
alpar@1
    51
//
alpar@1
    52
//    and bounds of variables
alpar@1
    53
//
alpar@1
    54
//         l[1] <= x[1]   <= u[1]
alpar@1
    55
//
alpar@1
    56
//          .  .  .  .  .  .  .                                      (3)
alpar@1
    57
//
alpar@1
    58
//       l[m+n] <= x[m+n] <= u[m+n]
alpar@1
    59
//
alpar@1
    60
// where:
alpar@1
    61
// x[1], ..., x[m]      - auxiliary variables;
alpar@1
    62
// x[m+1], ..., x[m+n]  - structural variables;
alpar@1
    63
// z                    - objective function;
alpar@1
    64
// c[1], ..., c[m+n]    - coefficients of the objective function;
alpar@1
    65
// c[0]                 - constant term of the objective function;
alpar@1
    66
// a[1,1], ..., a[m,n]  - constraint coefficients;
alpar@1
    67
// l[1], ..., l[m+n]    - lower bounds of variables;
alpar@1
    68
// u[1], ..., u[m+n]    - upper bounds of variables.
alpar@1
    69
//
alpar@1
    70
// Bounds of variables can be finite as well as inifinite. Besides,
alpar@1
    71
// lower and upper bounds can be equal to each other. So the following
alpar@1
    72
// five types of variables are possible:
alpar@1
    73
//
alpar@1
    74
//    Bounds of variable      Type of variable
alpar@1
    75
//    -------------------------------------------------
alpar@1
    76
//    -inf <  x[k] <  +inf    Free (unbounded) variable
alpar@1
    77
//    l[k] <= x[k] <  +inf    Variable with lower bound
alpar@1
    78
//    -inf <  x[k] <= u[k]    Variable with upper bound
alpar@1
    79
//    l[k] <= x[k] <= u[k]    Double-bounded variable
alpar@1
    80
//    l[k] =  x[k] =  u[k]    Fixed variable
alpar@1
    81
//
alpar@1
    82
// Using vector-matrix notations the LP problem (1)-(3) can be written
alpar@1
    83
// as follows:
alpar@1
    84
//
alpar@1
    85
//    minimize (or maximize)
alpar@1
    86
//
alpar@1
    87
//       z = c * x + c[0]                                            (4)
alpar@1
    88
//
alpar@1
    89
//    subject to equality constraints
alpar@1
    90
//
alpar@1
    91
//       xR - A * xS = 0                                             (5)
alpar@1
    92
//
alpar@1
    93
//    and bounds of variables
alpar@1
    94
//
alpar@1
    95
//       l <= x <= u                                                 (6)
alpar@1
    96
//
alpar@1
    97
// where:
alpar@1
    98
// xR                   - vector of auxiliary variables;
alpar@1
    99
// xS                   - vector of structural variables;
alpar@1
   100
// x = (xR, xS)         - vector of all variables;
alpar@1
   101
// z                    - objective function;
alpar@1
   102
// c                    - vector of objective coefficients;
alpar@1
   103
// c[0]                 - constant term of the objective function;
alpar@1
   104
// A                    - matrix of constraint coefficients (has m rows
alpar@1
   105
//                        and n columns);
alpar@1
   106
// l                    - vector of lower bounds of variables;
alpar@1
   107
// u                    - vector of upper bounds of variables.
alpar@1
   108
//
alpar@1
   109
// The simplex method makes no difference between auxiliary and
alpar@1
   110
// structural variables, so it is convenient to think the system of
alpar@1
   111
// equality constraints (5) written in a homogeneous form:
alpar@1
   112
//
alpar@1
   113
//    (I | -A) * x = 0,                                              (7)
alpar@1
   114
//
alpar@1
   115
// where (I | -A) is an augmented (m+n)xm constraint matrix, I is mxm
alpar@1
   116
// unity matrix whose columns correspond to auxiliary variables, and A
alpar@1
   117
// is the original mxn constraint matrix whose columns correspond to
alpar@1
   118
// structural variables. Note that only the matrix A is stored.
alpar@1
   119
----------------------------------------------------------------------*/
alpar@1
   120
      int m;
alpar@1
   121
      /* number of rows (auxiliary variables), m > 0 */
alpar@1
   122
      int n;
alpar@1
   123
      /* number of columns (structural variables), n > 0 */
alpar@1
   124
      int *type; /* int type[1+m+n]; */
alpar@1
   125
      /* type[0] is not used;
alpar@1
   126
         type[k], 1 <= k <= m+n, is the type of variable x[k]: */
alpar@1
   127
#define SSX_FR          0     /* free (unbounded) variable */
alpar@1
   128
#define SSX_LO          1     /* variable with lower bound */
alpar@1
   129
#define SSX_UP          2     /* variable with upper bound */
alpar@1
   130
#define SSX_DB          3     /* double-bounded variable */
alpar@1
   131
#define SSX_FX          4     /* fixed variable */
alpar@1
   132
      mpq_t *lb; /* mpq_t lb[1+m+n]; alias: l */
alpar@1
   133
      /* lb[0] is not used;
alpar@1
   134
         lb[k], 1 <= k <= m+n, is an lower bound of variable x[k];
alpar@1
   135
         if x[k] has no lower bound, lb[k] is zero */
alpar@1
   136
      mpq_t *ub; /* mpq_t ub[1+m+n]; alias: u */
alpar@1
   137
      /* ub[0] is not used;
alpar@1
   138
         ub[k], 1 <= k <= m+n, is an upper bound of variable x[k];
alpar@1
   139
         if x[k] has no upper bound, ub[k] is zero;
alpar@1
   140
         if x[k] is of fixed type, ub[k] is equal to lb[k] */
alpar@1
   141
      int dir;
alpar@1
   142
      /* optimization direction (sense of the objective function): */
alpar@1
   143
#define SSX_MIN         0     /* minimization */
alpar@1
   144
#define SSX_MAX         1     /* maximization */
alpar@1
   145
      mpq_t *coef; /* mpq_t coef[1+m+n]; alias: c */
alpar@1
   146
      /* coef[0] is a constant term of the objective function;
alpar@1
   147
         coef[k], 1 <= k <= m+n, is a coefficient of the objective
alpar@1
   148
         function at variable x[k];
alpar@1
   149
         note that auxiliary variables also may have non-zero objective
alpar@1
   150
         coefficients */
alpar@1
   151
      int *A_ptr; /* int A_ptr[1+n+1]; */
alpar@1
   152
      int *A_ind; /* int A_ind[A_ptr[n+1]]; */
alpar@1
   153
      mpq_t *A_val; /* mpq_t A_val[A_ptr[n+1]]; */
alpar@1
   154
      /* constraint matrix A (see (5)) in storage-by-columns format */
alpar@1
   155
/*----------------------------------------------------------------------
alpar@1
   156
// LP BASIS AND CURRENT BASIC SOLUTION
alpar@1
   157
//
alpar@1
   158
// The LP basis is defined by the following partition of the augmented
alpar@1
   159
// constraint matrix (7):
alpar@1
   160
//
alpar@1
   161
//    (B | N) = (I | -A) * Q,                                        (8)
alpar@1
   162
//
alpar@1
   163
// where B is a mxm non-singular basis matrix whose columns correspond
alpar@1
   164
// to basic variables xB, N is a mxn matrix whose columns correspond to
alpar@1
   165
// non-basic variables xN, and Q is a permutation (m+n)x(m+n) matrix.
alpar@1
   166
//
alpar@1
   167
// From (7) and (8) it follows that
alpar@1
   168
//
alpar@1
   169
//    (I | -A) * x = (I | -A) * Q * Q' * x = (B | N) * (xB, xN),
alpar@1
   170
//
alpar@1
   171
// therefore
alpar@1
   172
//
alpar@1
   173
//    (xB, xN) = Q' * x,                                             (9)
alpar@1
   174
//
alpar@1
   175
// where x is the vector of all variables in the original order, xB is
alpar@1
   176
// a vector of basic variables, xN is a vector of non-basic variables,
alpar@1
   177
// Q' = inv(Q) is a matrix transposed to Q.
alpar@1
   178
//
alpar@1
   179
// Current values of non-basic variables xN[j], j = 1, ..., n, are not
alpar@1
   180
// stored; they are defined implicitly by their statuses as follows:
alpar@1
   181
//
alpar@1
   182
//    0,             if xN[j] is free variable
alpar@1
   183
//    lN[j],         if xN[j] is on its lower bound                 (10)
alpar@1
   184
//    uN[j],         if xN[j] is on its upper bound
alpar@1
   185
//    lN[j] = uN[j], if xN[j] is fixed variable
alpar@1
   186
//
alpar@1
   187
// where lN[j] and uN[j] are lower and upper bounds of xN[j].
alpar@1
   188
//
alpar@1
   189
// Current values of basic variables xB[i], i = 1, ..., m, are computed
alpar@1
   190
// as follows:
alpar@1
   191
//
alpar@1
   192
//    beta = - inv(B) * N * xN,                                     (11)
alpar@1
   193
//
alpar@1
   194
// where current values of xN are defined by (10).
alpar@1
   195
//
alpar@1
   196
// Current values of simplex multipliers pi[i], i = 1, ..., m (which
alpar@1
   197
// are values of Lagrange multipliers for equality constraints (7) also
alpar@1
   198
// called shadow prices) are computed as follows:
alpar@1
   199
//
alpar@1
   200
//    pi = inv(B') * cB,                                            (12)
alpar@1
   201
//
alpar@1
   202
// where B' is a matrix transposed to B, cB is a vector of objective
alpar@1
   203
// coefficients at basic variables xB.
alpar@1
   204
//
alpar@1
   205
// Current values of reduced costs d[j], j = 1, ..., n, (which are
alpar@1
   206
// values of Langrange multipliers for active inequality constraints
alpar@1
   207
// corresponding to non-basic variables) are computed as follows:
alpar@1
   208
//
alpar@1
   209
//    d = cN - N' * pi,                                             (13)
alpar@1
   210
//
alpar@1
   211
// where N' is a matrix transposed to N, cN is a vector of objective
alpar@1
   212
// coefficients at non-basic variables xN.
alpar@1
   213
----------------------------------------------------------------------*/
alpar@1
   214
      int *stat; /* int stat[1+m+n]; */
alpar@1
   215
      /* stat[0] is not used;
alpar@1
   216
         stat[k], 1 <= k <= m+n, is the status of variable x[k]: */
alpar@1
   217
#define SSX_BS          0     /* basic variable */
alpar@1
   218
#define SSX_NL          1     /* non-basic variable on lower bound */
alpar@1
   219
#define SSX_NU          2     /* non-basic variable on upper bound */
alpar@1
   220
#define SSX_NF          3     /* non-basic free variable */
alpar@1
   221
#define SSX_NS          4     /* non-basic fixed variable */
alpar@1
   222
      int *Q_row; /* int Q_row[1+m+n]; */
alpar@1
   223
      /* matrix Q in row-like format;
alpar@1
   224
         Q_row[0] is not used;
alpar@1
   225
         Q_row[i] = j means that q[i,j] = 1 */
alpar@1
   226
      int *Q_col; /* int Q_col[1+m+n]; */
alpar@1
   227
      /* matrix Q in column-like format;
alpar@1
   228
         Q_col[0] is not used;
alpar@1
   229
         Q_col[j] = i means that q[i,j] = 1 */
alpar@1
   230
      /* if k-th column of the matrix (I | A) is k'-th column of the
alpar@1
   231
         matrix (B | N), then Q_row[k] = k' and Q_col[k'] = k;
alpar@1
   232
         if x[k] is xB[i], then Q_row[k] = i and Q_col[i] = k;
alpar@1
   233
         if x[k] is xN[j], then Q_row[k] = m+j and Q_col[m+j] = k */
alpar@1
   234
      BFX *binv;
alpar@1
   235
      /* invertable form of the basis matrix B */
alpar@1
   236
      mpq_t *bbar; /* mpq_t bbar[1+m]; alias: beta */
alpar@1
   237
      /* bbar[0] is a value of the objective function;
alpar@1
   238
         bbar[i], 1 <= i <= m, is a value of basic variable xB[i] */
alpar@1
   239
      mpq_t *pi; /* mpq_t pi[1+m]; */
alpar@1
   240
      /* pi[0] is not used;
alpar@1
   241
         pi[i], 1 <= i <= m, is a simplex multiplier corresponding to
alpar@1
   242
         i-th row (equality constraint) */
alpar@1
   243
      mpq_t *cbar; /* mpq_t cbar[1+n]; alias: d */
alpar@1
   244
      /* cbar[0] is not used;
alpar@1
   245
         cbar[j], 1 <= j <= n, is a reduced cost of non-basic variable
alpar@1
   246
         xN[j] */
alpar@1
   247
/*----------------------------------------------------------------------
alpar@1
   248
// SIMPLEX TABLE
alpar@1
   249
//
alpar@1
   250
// Due to (8) and (9) the system of equality constraints (7) for the
alpar@1
   251
// current basis can be written as follows:
alpar@1
   252
//
alpar@1
   253
//    xB = A~ * xN,                                                 (14)
alpar@1
   254
//
alpar@1
   255
// where
alpar@1
   256
//
alpar@1
   257
//    A~ = - inv(B) * N                                             (15)
alpar@1
   258
//
alpar@1
   259
// is a mxn matrix called the simplex table.
alpar@1
   260
//
alpar@1
   261
// The revised simplex method uses only two components of A~, namely,
alpar@1
   262
// pivot column corresponding to non-basic variable xN[q] chosen to
alpar@1
   263
// enter the basis, and pivot row corresponding to basic variable xB[p]
alpar@1
   264
// chosen to leave the basis.
alpar@1
   265
//
alpar@1
   266
// Pivot column alfa_q is q-th column of A~, so
alpar@1
   267
//
alpar@1
   268
//    alfa_q = A~ * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q],   (16)
alpar@1
   269
//
alpar@1
   270
// where N[q] is q-th column of the matrix N.
alpar@1
   271
//
alpar@1
   272
// Pivot row alfa_p is p-th row of A~ or, equivalently, p-th column of
alpar@1
   273
// A~', a matrix transposed to A~, so
alpar@1
   274
//
alpar@1
   275
//    alfa_p = A~' * e[p] = - N' * inv(B') * e[p] = - N' * rho_p,   (17)
alpar@1
   276
//
alpar@1
   277
// where (*)' means transposition, and
alpar@1
   278
//
alpar@1
   279
//    rho_p = inv(B') * e[p],                                       (18)
alpar@1
   280
//
alpar@1
   281
// is p-th column of inv(B') or, that is the same, p-th row of inv(B).
alpar@1
   282
----------------------------------------------------------------------*/
alpar@1
   283
      int p;
alpar@1
   284
      /* number of basic variable xB[p], 1 <= p <= m, chosen to leave
alpar@1
   285
         the basis */
alpar@1
   286
      mpq_t *rho; /* mpq_t rho[1+m]; */
alpar@1
   287
      /* p-th row of the inverse inv(B); see (18) */
alpar@1
   288
      mpq_t *ap; /* mpq_t ap[1+n]; */
alpar@1
   289
      /* p-th row of the simplex table; see (17) */
alpar@1
   290
      int q;
alpar@1
   291
      /* number of non-basic variable xN[q], 1 <= q <= n, chosen to
alpar@1
   292
         enter the basis */
alpar@1
   293
      mpq_t *aq; /* mpq_t aq[1+m]; */
alpar@1
   294
      /* q-th column of the simplex table; see (16) */
alpar@1
   295
/*--------------------------------------------------------------------*/
alpar@1
   296
      int q_dir;
alpar@1
   297
      /* direction in which non-basic variable xN[q] should change on
alpar@1
   298
         moving to the adjacent vertex of the polyhedron:
alpar@1
   299
         +1 means that xN[q] increases
alpar@1
   300
         -1 means that xN[q] decreases */
alpar@1
   301
      int p_stat;
alpar@1
   302
      /* non-basic status which should be assigned to basic variable
alpar@1
   303
         xB[p] when it has left the basis and become xN[q] */
alpar@1
   304
      mpq_t delta;
alpar@1
   305
      /* actual change of xN[q] in the adjacent basis (it has the same
alpar@1
   306
         sign as q_dir) */
alpar@1
   307
/*--------------------------------------------------------------------*/
alpar@1
   308
      int it_lim;
alpar@1
   309
      /* simplex iterations limit; if this value is positive, it is
alpar@1
   310
         decreased by one each time when one simplex iteration has been
alpar@1
   311
         performed, and reaching zero value signals the solver to stop
alpar@1
   312
         the search; negative value means no iterations limit */
alpar@1
   313
      int it_cnt;
alpar@1
   314
      /* simplex iterations count; this count is increased by one each
alpar@1
   315
         time when one simplex iteration has been performed */
alpar@1
   316
      double tm_lim;
alpar@1
   317
      /* searching time limit, in seconds; if this value is positive,
alpar@1
   318
         it is decreased each time when one simplex iteration has been
alpar@1
   319
         performed by the amount of time spent for the iteration, and
alpar@1
   320
         reaching zero value signals the solver to stop the search;
alpar@1
   321
         negative value means no time limit */
alpar@1
   322
      double out_frq;
alpar@1
   323
      /* output frequency, in seconds; this parameter specifies how
alpar@1
   324
         frequently the solver sends information about the progress of
alpar@1
   325
         the search to the standard output */
alpar@1
   326
      glp_long tm_beg;
alpar@1
   327
      /* starting time of the search, in seconds; the total time of the
alpar@1
   328
         search is the difference between xtime() and tm_beg */
alpar@1
   329
      glp_long tm_lag;
alpar@1
   330
      /* the most recent time, in seconds, at which the progress of the
alpar@1
   331
         the search was displayed */
alpar@1
   332
};
alpar@1
   333
alpar@1
   334
#define ssx_create            _glp_ssx_create
alpar@1
   335
#define ssx_factorize         _glp_ssx_factorize
alpar@1
   336
#define ssx_get_xNj           _glp_ssx_get_xNj
alpar@1
   337
#define ssx_eval_bbar         _glp_ssx_eval_bbar
alpar@1
   338
#define ssx_eval_pi           _glp_ssx_eval_pi
alpar@1
   339
#define ssx_eval_dj           _glp_ssx_eval_dj
alpar@1
   340
#define ssx_eval_cbar         _glp_ssx_eval_cbar
alpar@1
   341
#define ssx_eval_rho          _glp_ssx_eval_rho
alpar@1
   342
#define ssx_eval_row          _glp_ssx_eval_row
alpar@1
   343
#define ssx_eval_col          _glp_ssx_eval_col
alpar@1
   344
#define ssx_chuzc             _glp_ssx_chuzc
alpar@1
   345
#define ssx_chuzr             _glp_ssx_chuzr
alpar@1
   346
#define ssx_update_bbar       _glp_ssx_update_bbar
alpar@1
   347
#define ssx_update_pi         _glp_ssx_update_pi
alpar@1
   348
#define ssx_update_cbar       _glp_ssx_update_cbar
alpar@1
   349
#define ssx_change_basis      _glp_ssx_change_basis
alpar@1
   350
#define ssx_delete            _glp_ssx_delete
alpar@1
   351
alpar@1
   352
#define ssx_phase_I           _glp_ssx_phase_I
alpar@1
   353
#define ssx_phase_II          _glp_ssx_phase_II
alpar@1
   354
#define ssx_driver            _glp_ssx_driver
alpar@1
   355
alpar@1
   356
SSX *ssx_create(int m, int n, int nnz);
alpar@1
   357
/* create simplex solver workspace */
alpar@1
   358
alpar@1
   359
int ssx_factorize(SSX *ssx);
alpar@1
   360
/* factorize the current basis matrix */
alpar@1
   361
alpar@1
   362
void ssx_get_xNj(SSX *ssx, int j, mpq_t x);
alpar@1
   363
/* determine value of non-basic variable */
alpar@1
   364
alpar@1
   365
void ssx_eval_bbar(SSX *ssx);
alpar@1
   366
/* compute values of basic variables */
alpar@1
   367
alpar@1
   368
void ssx_eval_pi(SSX *ssx);
alpar@1
   369
/* compute values of simplex multipliers */
alpar@1
   370
alpar@1
   371
void ssx_eval_dj(SSX *ssx, int j, mpq_t dj);
alpar@1
   372
/* compute reduced cost of non-basic variable */
alpar@1
   373
alpar@1
   374
void ssx_eval_cbar(SSX *ssx);
alpar@1
   375
/* compute reduced costs of all non-basic variables */
alpar@1
   376
alpar@1
   377
void ssx_eval_rho(SSX *ssx);
alpar@1
   378
/* compute p-th row of the inverse */
alpar@1
   379
alpar@1
   380
void ssx_eval_row(SSX *ssx);
alpar@1
   381
/* compute pivot row of the simplex table */
alpar@1
   382
alpar@1
   383
void ssx_eval_col(SSX *ssx);
alpar@1
   384
/* compute pivot column of the simplex table */
alpar@1
   385
alpar@1
   386
void ssx_chuzc(SSX *ssx);
alpar@1
   387
/* choose pivot column */
alpar@1
   388
alpar@1
   389
void ssx_chuzr(SSX *ssx);
alpar@1
   390
/* choose pivot row */
alpar@1
   391
alpar@1
   392
void ssx_update_bbar(SSX *ssx);
alpar@1
   393
/* update values of basic variables */
alpar@1
   394
alpar@1
   395
void ssx_update_pi(SSX *ssx);
alpar@1
   396
/* update simplex multipliers */
alpar@1
   397
alpar@1
   398
void ssx_update_cbar(SSX *ssx);
alpar@1
   399
/* update reduced costs of non-basic variables */
alpar@1
   400
alpar@1
   401
void ssx_change_basis(SSX *ssx);
alpar@1
   402
/* change current basis to adjacent one */
alpar@1
   403
alpar@1
   404
void ssx_delete(SSX *ssx);
alpar@1
   405
/* delete simplex solver workspace */
alpar@1
   406
alpar@1
   407
int ssx_phase_I(SSX *ssx);
alpar@1
   408
/* find primal feasible solution */
alpar@1
   409
alpar@1
   410
int ssx_phase_II(SSX *ssx);
alpar@1
   411
/* find optimal solution */
alpar@1
   412
alpar@1
   413
int ssx_driver(SSX *ssx);
alpar@1
   414
/* base driver to exact simplex method */
alpar@1
   415
alpar@1
   416
#endif
alpar@1
   417
alpar@1
   418
/* eof */