lemon-project-template-glpk
diff deps/glpk/examples/cplex/cplex.c @ 9:33de93886c88
Import GLPK 4.47
author | Alpar Juttner <alpar@cs.elte.hu> |
---|---|
date | Sun, 06 Nov 2011 20:59:10 +0100 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/deps/glpk/examples/cplex/cplex.c Sun Nov 06 20:59:10 2011 +0100 1.3 @@ -0,0 +1,2130 @@ 1.4 +/* cplex.c (CPLEX-like interface to GLPK API) */ 1.5 + 1.6 +/*********************************************************************** 1.7 +* This code is part of GLPK (GNU Linear Programming Kit). 1.8 +* 1.9 +* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 1.10 +* 2009, 2010, 2011 Andrew Makhorin, Department for Applied Informatics, 1.11 +* Moscow Aviation Institute, Moscow, Russia. All rights reserved. 1.12 +* E-mail: <mao@gnu.org>. 1.13 +* 1.14 +* GLPK is free software: you can redistribute it and/or modify it 1.15 +* under the terms of the GNU General Public License as published by 1.16 +* the Free Software Foundation, either version 3 of the License, or 1.17 +* (at your option) any later version. 1.18 +* 1.19 +* GLPK is distributed in the hope that it will be useful, but WITHOUT 1.20 +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1.21 +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 1.22 +* License for more details. 1.23 +* 1.24 +* You should have received a copy of the GNU General Public License 1.25 +* along with GLPK. If not, see <http://www.gnu.org/licenses/>. 1.26 +***********************************************************************/ 1.27 + 1.28 +#include <ctype.h> 1.29 +#include <stdarg.h> 1.30 +#include <stdio.h> 1.31 +#include <stdlib.h> 1.32 +#include <string.h> 1.33 +#include <glpk.h> 1.34 +#include "cplex.h" 1.35 + 1.36 +struct CPXENV 1.37 +{ /* environment block */ 1.38 + CPXLP *list; 1.39 + /* linked list of problem objects */ 1.40 + int *intparam; /* int intparam[]; */ 1.41 + /* integer control parameters */ 1.42 + double *dblparam; /* double dblparam[]; */ 1.43 + /* floating-point control parameters */ 1.44 +}; 1.45 + 1.46 +struct CPXLP 1.47 +{ /* problem object */ 1.48 + CPXENV *env; 1.49 + /* pointer to environment block */ 1.50 + glp_prob *prob; 1.51 + /* pointer to underlying GLPK problem object */ 1.52 + int rflen; 1.53 + /* length of the array rflag */ 1.54 + char *rflag; /* char rflag[rflen]; */ 1.55 + /* rflag[i], i = 0,...,nrows-1, is a flag of i-th row: */ 1.56 +#define RF_NOT_RANGED 0 /* not ranged */ 1.57 +#define RF_RANGED_POS 1 /* ranged, RHS = lower bound */ 1.58 +#define RF_RANGED_NEG 2 /* ranged, RHS = upper bound */ 1.59 + int stat; 1.60 + /* solution status reported by CPXgetstat; zero means no solution 1.61 + exists */ 1.62 + int meth; 1.63 + /* method indicator reported by CPXgetmethod */ 1.64 + int iwlen; 1.65 + /* length of the working array */ 1.66 + int *iwork; /* int iwork[iwlen] */ 1.67 + /* working array initialized by binary zeros */ 1.68 + CPXLP *link; 1.69 + /* pointer to another problem object */ 1.70 +}; 1.71 + 1.72 +struct intparam 1.73 +{ int which; 1.74 + int defv; 1.75 + int minv; 1.76 + int maxv; 1.77 +}; 1.78 + 1.79 +struct dblparam 1.80 +{ int which; 1.81 + double defv; 1.82 + double minv; 1.83 + double maxv; 1.84 +}; 1.85 + 1.86 +struct errstring 1.87 +{ int code; 1.88 + const char *string; 1.89 +}; 1.90 + 1.91 +#define BIGINT 2100000000 1.92 +#define BIGDBL 1e75 1.93 + 1.94 +static const struct intparam intparam[] = 1.95 +{ {CPX_PARAM_ADVIND, 0, 0, 2}, 1.96 + {CPX_PARAM_AGGIND, -1, -1, BIGINT}, 1.97 + {CPX_PARAM_DATACHECK, CPX_OFF, CPX_OFF, CPX_ON}, 1.98 + {CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO, CPX_DPRIIND_AUTO, 1.99 + CPX_DPRIIND_DEVEX}, 1.100 + {CPX_PARAM_FASTMIP, CPX_OFF, CPX_OFF, CPX_ON}, /* ??? */ 1.101 + {CPX_PARAM_ITLIM, BIGINT, 0, BIGINT}, 1.102 + {CPX_PARAM_PERIND, CPX_OFF, CPX_OFF, CPX_ON}, 1.103 + {CPX_PARAM_PPRIIND, CPX_PPRIIND_AUTO, CPX_PPRIIND_PARTIAL, 1.104 + CPX_PPRIIND_FULL}, 1.105 + {CPX_PARAM_PREIND, CPX_ON, CPX_OFF, CPX_ON}, 1.106 + {CPX_PARAM_REINV, 0, 0, 10000}, 1.107 + {CPX_PARAM_SCRIND, CPX_OFF, CPX_OFF, CPX_ON}, 1.108 + {CPX_PARAM_SIMDISPLAY, 1, 0, 2}, 1.109 +}; 1.110 + 1.111 +static const struct dblparam dblparam[] = 1.112 +{ {CPX_PARAM_EPOPT, 1e-6, 1e-9, 1e-1}, 1.113 + {CPX_PARAM_EPPER, 1e-6, 1e-8, BIGDBL}, 1.114 + {CPX_PARAM_EPRHS, 1e-6, 1e-9, 1e-1}, 1.115 + {CPX_PARAM_OBJLLIM, -BIGDBL, -BIGDBL, +BIGDBL}, 1.116 + {CPX_PARAM_OBJULIM, +BIGDBL, -BIGDBL, +BIGDBL}, 1.117 +}; 1.118 + 1.119 +static const struct errstring errstring[] = 1.120 +{ {CPXERR_ARRAY_NOT_ASCENDING, "Array entry %d not ascending"}, 1.121 + {CPXERR_BAD_ARGUMENT, "Invalid argument"}, 1.122 + {CPXERR_BAD_CTYPE, "Invalid ctype entry %d"}, 1.123 + {CPXERR_BAD_FILETYPE, "Invalid filetype"}, 1.124 + {CPXERR_BAD_LUB, "Invalid bound change indicator entry %d"}, 1.125 + {CPXERR_BAD_PARAM_NUM, "Invalid parameter number"}, 1.126 + {CPXERR_BAD_SENSE, "Invalid sense entry %d"}, 1.127 + {CPXERR_BAD_STATUS, "Invalid status entry %d for basis specificat" 1.128 + "ion"}, 1.129 + {CPXERR_COL_INDEX_RANGE, "Column index %d out of range"}, 1.130 + {CPXERR_COUNT_RANGE, "Count entry %d negative or larger than allo" 1.131 + "wed"}, 1.132 + {CPXERR_DUP_ENTRY, "Duplicate entry"}, 1.133 + {CPXERR_FAIL_OPEN_WRITE, "Could not open file '%s' for writing"}, 1.134 + {CPXERR_INDEX_RANGE, "Index is outside range of valid values"}, 1.135 + {CPXERR_NEGATIVE_SURPLUS, "Insufficient array length"}, 1.136 + {CPXERR_NO_BASIC_SOLN, "No basic solution exists"}, 1.137 + {CPXERR_NO_ENVIRONMENT, "No environment exists"}, 1.138 + {CPXERR_NO_FILENAME, "File name not specified"}, 1.139 + {CPXERR_NO_MEMORY, "Out of memory"}, 1.140 + {CPXERR_NO_PROBLEM, "No problem exists"}, 1.141 + {CPXERR_NO_SOLN, "No solution exists"}, 1.142 + {CPXERR_NOT_FIXED, "Only fixed variables are pivoted out"}, 1.143 + {CPXERR_NULL_NAME, "Null pointer %d in name array"}, 1.144 + {CPXERR_NULL_POINTER, "Null pointer for required data"}, 1.145 + {CPXERR_PARAM_TOO_BIG, "Parameter value too big"}, 1.146 + {CPXERR_PARAM_TOO_SMALL, "Parameter value too small"}, 1.147 + {CPXERR_ROW_INDEX_RANGE, "Row index %d out of range"}, 1.148 +}; 1.149 + 1.150 +/**********************************************************************/ 1.151 + 1.152 +#define xassert glp_assert 1.153 +#define xprintf glp_printf 1.154 +#define xmalloc glp_malloc 1.155 +#define xcalloc glp_calloc 1.156 +#define xfree glp_free 1.157 + 1.158 +/**********************************************************************/ 1.159 + 1.160 +static int findintparam(int whichparam) 1.161 +{ int k, card; 1.162 + card = sizeof(intparam) / sizeof(struct intparam); 1.163 + for (k = 0; k < card; k++) 1.164 + if (intparam[k].which == whichparam) return k; 1.165 + return -1; 1.166 +} 1.167 + 1.168 +static int getintparam(CPXENV *env, int whichparam) 1.169 +{ int k; 1.170 + xassert(env != NULL); 1.171 + k = findintparam(whichparam); 1.172 + xassert(k >= 0); 1.173 + return env->intparam[k]; 1.174 +} 1.175 + 1.176 +static int finddblparam(int whichparam) 1.177 +{ int k, card; 1.178 + card = sizeof(dblparam) / sizeof(struct dblparam); 1.179 + for (k = 0; k < card; k++) 1.180 + if (dblparam[k].which == whichparam) return k; 1.181 + return -1; 1.182 +} 1.183 + 1.184 +static double getdblparam(CPXENV *env, int whichparam) 1.185 +{ int k; 1.186 + xassert(env != NULL); 1.187 + k = finddblparam(whichparam); 1.188 + xassert(k >= 0); 1.189 + return env->dblparam[k]; 1.190 +} 1.191 + 1.192 +static const char *finderrstring(int errcode) 1.193 +{ int k, card; 1.194 + card = sizeof(errstring) / sizeof(struct errstring); 1.195 + for (k = 0; k < card; k++) 1.196 + { if (errstring[k].code == errcode) 1.197 + return errstring[k].string; 1.198 + } 1.199 + return NULL; 1.200 +} 1.201 + 1.202 +static int error(CPXENV *env, int errcode, ...) 1.203 +{ va_list arg; 1.204 + char buffer[510]; 1.205 + xassert(env != NULL); 1.206 + if (getintparam(env, CPX_PARAM_SCRIND) == CPX_ON) 1.207 + { xassert(CPXgeterrorstring(env, errcode, buffer) == buffer); 1.208 + va_start(arg, errcode); 1.209 + vprintf(buffer, arg); 1.210 + va_end(arg); 1.211 + } 1.212 + return errcode; 1.213 +} 1.214 + 1.215 +static int checkenv(CPXENV *env) 1.216 +{ int errcode; 1.217 + if (env == NULL) 1.218 + errcode = CPXERR_NO_ENVIRONMENT; 1.219 + else 1.220 + errcode = 0; 1.221 + return errcode; 1.222 +} 1.223 + 1.224 +static checklp(CPXENV *env, CPXLP *lp) 1.225 +{ int errcode; 1.226 + errcode = checkenv(env); 1.227 + if (errcode) goto done; 1.228 + if (lp == NULL) 1.229 + errcode = error(env, CPXERR_NO_PROBLEM); 1.230 +done: return errcode; 1.231 +} 1.232 + 1.233 +static void invalidate(CPXLP *lp) 1.234 +{ lp->stat = 0; 1.235 + lp->meth = CPX_ALG_NONE; 1.236 + return; 1.237 +} 1.238 + 1.239 +static void enlargerflag(CPXLP *lp) 1.240 +{ int m; 1.241 + xassert(lp != NULL); 1.242 + m = glp_get_num_rows(lp->prob); 1.243 + if (lp->rflen < m) 1.244 + { int rflen = lp->rflen; 1.245 + char *rflag = lp->rflag; 1.246 + while (lp->rflen < m) 1.247 + { lp->rflen += lp->rflen; 1.248 + xassert(lp->rflen > 0); 1.249 + } 1.250 + lp->rflag = xcalloc(lp->rflen, sizeof(char)); 1.251 + memcpy(lp->rflag, rflag, rflen); 1.252 + xfree(rflag); 1.253 + } 1.254 + return; 1.255 +} 1.256 + 1.257 +static void enlargeiwork(CPXLP *lp, int len) 1.258 +{ xassert(len >= 0); 1.259 + if (lp->iwlen < len) 1.260 + { xfree(lp->iwork); 1.261 + while (lp->iwlen < len) 1.262 + { lp->iwlen += lp->iwlen; 1.263 + xassert(lp->iwlen > 0); 1.264 + } 1.265 + lp->iwork = xcalloc(lp->iwlen, sizeof(int)); 1.266 + memset(lp->iwork, 0, lp->iwlen * sizeof(int)); 1.267 + } 1.268 + return; 1.269 +} 1.270 + 1.271 +/**********************************************************************/ 1.272 + 1.273 +int CPXaddcols(CPXENV *env, CPXLP *lp, int ccnt, int nzcnt, 1.274 + const double obj[], const int cmatbeg[], const int cmatind[], 1.275 + const double cmatval[], const double lb[], const double ub[], 1.276 + char *colname[]) 1.277 +{ int j, k, m, n, beg, end, type, errcode; 1.278 + double lbnd, ubnd; 1.279 + errcode = checklp(env, lp); 1.280 + if (errcode) goto done; 1.281 + if (ccnt < 0 || nzcnt < 0) 1.282 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.283 + goto done; 1.284 + } 1.285 + if (ccnt > 0) 1.286 + { if (cmatbeg == NULL || cmatind == NULL || cmatval == NULL) 1.287 + { errcode = error(env, CPXERR_NULL_POINTER); 1.288 + goto done; 1.289 + } 1.290 + } 1.291 + m = glp_get_num_rows(lp->prob); 1.292 + n = glp_get_num_cols(lp->prob); 1.293 + enlargeiwork(lp, m); 1.294 + for (j = 0; j < ccnt; j++) 1.295 + { beg = cmatbeg[j]; 1.296 + if (j > 0 && !(cmatbeg[j-1] <= beg)) 1.297 + { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, j); 1.298 + goto done; 1.299 + } 1.300 + if (!(0 <= beg && beg <= nzcnt)) 1.301 + { errcode = error(env, CPXERR_INDEX_RANGE); 1.302 + goto done; 1.303 + } 1.304 + end = (j < ccnt-1 ? cmatbeg[j+1] : nzcnt); 1.305 + for (k = beg; k < end; k++) 1.306 + { if (!(0 <= cmatind[k] && cmatind[k] < m)) 1.307 + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, k); 1.308 + goto done; 1.309 + } 1.310 + } 1.311 + errcode = 0; 1.312 + for (k = beg; k < end; k++) 1.313 + { if (lp->iwork[cmatind[k]]) 1.314 + { errcode = error(env, CPXERR_DUP_ENTRY); 1.315 + break; 1.316 + } 1.317 + lp->iwork[cmatind[k]] = 1; 1.318 + } 1.319 + for (k = beg; k < end; k++) 1.320 + lp->iwork[cmatind[k]] = 0; 1.321 + if (errcode) goto done; 1.322 + if (colname != NULL) 1.323 + { if (colname[j] == NULL) 1.324 + { errcode = error(env, CPXERR_NULL_NAME, j); 1.325 + goto done; 1.326 + } 1.327 + } 1.328 + } 1.329 + errcode = 0; 1.330 + invalidate(lp); 1.331 + if (ccnt > 0) 1.332 + glp_add_cols(lp->prob, ccnt); 1.333 + for (j = 0; j < ccnt; j++) 1.334 + { if (colname != NULL) 1.335 + glp_set_col_name(lp->prob, n+j+1, colname[j]); 1.336 + lbnd = (lb == NULL ? 0.0 : lb[j]); 1.337 + ubnd = (ub == NULL ? +CPX_INFBOUND : ub[j]); 1.338 + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) 1.339 + type = GLP_FR; 1.340 + else if (ubnd >= +CPX_INFBOUND) 1.341 + type = GLP_LO; 1.342 + else if (lbnd <= -CPX_INFBOUND) 1.343 + type = GLP_UP; 1.344 + else if (lbnd != ubnd) 1.345 + type = GLP_DB; 1.346 + else 1.347 + type = GLP_FX; 1.348 + glp_set_col_bnds(lp->prob, n+j+1, type, lbnd, ubnd); 1.349 + if (obj != NULL) 1.350 + glp_set_obj_coef(lp->prob, n+j+1, obj[j]); 1.351 + beg = cmatbeg[j]; 1.352 + end = (j < ccnt-1 ? cmatbeg[j+1] : nzcnt); 1.353 + for (k = beg; k < end; k++) 1.354 + lp->iwork[k-beg] = cmatind[k]+1; 1.355 + glp_set_mat_col(lp->prob, n+j+1, end-beg, lp->iwork-1, 1.356 + cmatval+beg-1); 1.357 + for (k = beg; k < end; k++) 1.358 + lp->iwork[k-beg] = 0; 1.359 + } 1.360 +done: return errcode; 1.361 +} 1.362 + 1.363 +int CPXaddrows(CPXENV *env, CPXLP *lp, int ccnt, int rcnt, int nzcnt, 1.364 + const double rhs[], const char sense[], const int rmatbeg[], 1.365 + const int rmatind[], const double rmatval[], char *colname[], 1.366 + char *rowname[]) 1.367 +{ int i, j, k, m, n, beg, end, type, errcode; 1.368 + double temp; 1.369 + errcode = checklp(env, lp); 1.370 + if (errcode) goto done; 1.371 + if (ccnt < 0 || rcnt < 0 || nzcnt < 0) 1.372 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.373 + goto done; 1.374 + } 1.375 + if (rcnt > 0) 1.376 + { if (rmatbeg == NULL || rmatind == NULL || rmatval == NULL) 1.377 + { errcode = error(env, CPXERR_NULL_POINTER); 1.378 + goto done; 1.379 + } 1.380 + } 1.381 + m = glp_get_num_rows(lp->prob); 1.382 + n = glp_get_num_cols(lp->prob); 1.383 + enlargeiwork(lp, n+ccnt); 1.384 + for (i = 0; i < rcnt; i++) 1.385 + { if (sense != NULL) 1.386 + { if (!(sense[i] == 'L' || sense[i] == 'E' || 1.387 + sense[i] == 'G' || sense[i] == 'R')) 1.388 + { errcode = error(env, CPXERR_BAD_SENSE, i); 1.389 + goto done; 1.390 + } 1.391 + } 1.392 + beg = rmatbeg[i]; 1.393 + if (i > 0 && !(rmatbeg[i-1] <= beg)) 1.394 + { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, i); 1.395 + goto done; 1.396 + } 1.397 + if (!(0 <= beg && beg <= nzcnt)) 1.398 + { errcode = error(env, CPXERR_INDEX_RANGE); 1.399 + goto done; 1.400 + } 1.401 + end = (i < rcnt-1 ? rmatbeg[i+1] : nzcnt); 1.402 + for (k = beg; k < end; k++) 1.403 + { if (!(0 <= rmatind[k] && rmatind[k] < n+ccnt)) 1.404 + { errcode = error(env, CPXERR_COL_INDEX_RANGE, k); 1.405 + goto done; 1.406 + } 1.407 + } 1.408 + errcode = 0; 1.409 + for (k = beg; k < end; k++) 1.410 + { if (lp->iwork[rmatind[k]]) 1.411 + { errcode = error(env, CPXERR_DUP_ENTRY); 1.412 + break; 1.413 + } 1.414 + lp->iwork[rmatind[k]] = 1; 1.415 + } 1.416 + for (k = beg; k < end; k++) 1.417 + lp->iwork[rmatind[k]] = 0; 1.418 + if (errcode) goto done; 1.419 + if (rowname != NULL) 1.420 + { if (rowname[i] == NULL) 1.421 + { errcode = error(env, CPXERR_NULL_NAME, i); 1.422 + goto done; 1.423 + } 1.424 + } 1.425 + } 1.426 + for (j = 0; j < ccnt; j++) 1.427 + { if (colname != NULL) 1.428 + { if (colname[j] == NULL) 1.429 + { errcode = error(env, CPXERR_NULL_NAME, j); 1.430 + goto done; 1.431 + } 1.432 + } 1.433 + } 1.434 + errcode = 0; 1.435 + invalidate(lp); 1.436 + if (rcnt > 0) 1.437 + glp_add_rows(lp->prob, rcnt); 1.438 + if (ccnt > 0) 1.439 + glp_add_cols(lp->prob, ccnt); 1.440 + enlargerflag(lp); 1.441 + for (i = 0; i < rcnt; i++) 1.442 + { if (rowname != NULL) 1.443 + glp_set_row_name(lp->prob, m+i+1, rowname[i]); 1.444 + temp = (rhs == NULL ? 0.0 : rhs[i]); 1.445 + if (sense == NULL || sense[i] == 'E') 1.446 + { lp->rflag[m+i] = RF_NOT_RANGED; 1.447 + type = GLP_FX; 1.448 + } 1.449 + else if (sense[i] == 'L') 1.450 + { lp->rflag[m+i] = RF_NOT_RANGED; 1.451 + type = GLP_UP; 1.452 + } 1.453 + else if (sense[i] == 'G') 1.454 + { lp->rflag[m+i] = RF_NOT_RANGED; 1.455 + type = GLP_LO; 1.456 + } 1.457 + else if (sense[i] == 'R') 1.458 + { lp->rflag[m+i] = RF_RANGED_POS; 1.459 + type = GLP_FX; 1.460 + } 1.461 + else 1.462 + xassert(sense != sense); 1.463 + glp_set_row_bnds(lp->prob, m+i+1, type, temp, temp); 1.464 + beg = rmatbeg[i]; 1.465 + end = (i < rcnt-1 ? rmatbeg[i+1] : nzcnt); 1.466 + for (k = beg; k < end; k++) 1.467 + lp->iwork[k-beg] = rmatind[k]+1; 1.468 + glp_set_mat_row(lp->prob, m+i+1, end-beg, lp->iwork-1, 1.469 + rmatval+beg-1); 1.470 + for (k = beg; k < end; k++) 1.471 + lp->iwork[k-beg] = 0; 1.472 + } 1.473 + for (j = 0; j < ccnt; j++) 1.474 + { if (colname != NULL) 1.475 + glp_set_col_name(lp->prob, n+j+1, colname[j]); 1.476 + glp_set_col_bnds(lp->prob, n+j+1, GLP_LO, 0.0, 0.0); 1.477 + } 1.478 +done: return errcode; 1.479 +} 1.480 + 1.481 +int CPXbaropt(CPXENV *env, CPXLP *lp) 1.482 +{ xassert(env == env); 1.483 + xassert(lp == lp); 1.484 + xprintf("CPXbaropt: not implemented yet\n"); 1.485 + exit(EXIT_FAILURE); 1.486 + return -1; 1.487 +} 1.488 + 1.489 +int CPXbinvrow(CPXENV *env, CPXLP *lp, int i, double y[]) 1.490 +{ xassert(env == env); 1.491 + xassert(lp == lp); 1.492 + xassert(i == i); 1.493 + xassert(y == y); 1.494 + xprintf("CPXbinvrow: not implemented yet\n"); 1.495 + exit(EXIT_FAILURE); 1.496 + return -1; 1.497 +} 1.498 + 1.499 +int CPXchgbds(CPXENV *env, CPXLP *lp, int cnt, const int indices[], 1.500 + const char lu[], const double bd[]) 1.501 +{ int j, n, type, errcode; 1.502 + double lbnd, ubnd; 1.503 + errcode = checklp(env, lp); 1.504 + if (errcode) goto done; 1.505 + if (cnt < 0) 1.506 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.507 + goto done; 1.508 + } 1.509 + if (cnt > 0) 1.510 + { if (indices == NULL || lu == NULL || bd == NULL) 1.511 + { errcode = error(env, CPXERR_NULL_POINTER); 1.512 + goto done; 1.513 + } 1.514 + } 1.515 + n = glp_get_num_cols(lp->prob); 1.516 + for (j = 0; j < cnt; j++) 1.517 + { if (!(0 <= indices[j] && indices[j] < n)) 1.518 + { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); 1.519 + goto done; 1.520 + } 1.521 + if (!(lu[j] == 'L' || lu[j] == 'U' || lu[j] == 'B')) 1.522 + { errcode = error(env, CPXERR_BAD_LUB, j); 1.523 + goto done; 1.524 + } 1.525 + } 1.526 + errcode = 0; 1.527 + invalidate(lp); 1.528 + for (j = 0; j < cnt; j++) 1.529 + { type = glp_get_col_type(lp->prob, indices[j]+1); 1.530 + lbnd = glp_get_col_lb(lp->prob, indices[j]+1); 1.531 + ubnd = glp_get_col_ub(lp->prob, indices[j]+1); 1.532 + if (type == GLP_FR || type == GLP_UP) 1.533 + lbnd = -CPX_INFBOUND; 1.534 + if (type == GLP_FR || type == GLP_LO) 1.535 + ubnd = +CPX_INFBOUND; 1.536 + if (lu[j] == 'L') 1.537 + lbnd = bd[j]; 1.538 + else if (lu[j] == 'U') 1.539 + ubnd = bd[j]; 1.540 + else if (lu[j] == 'B') 1.541 + lbnd = ubnd = bd[j]; 1.542 + else 1.543 + xassert(lu != lu); 1.544 + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) 1.545 + type = GLP_FR; 1.546 + else if (ubnd >= +CPX_INFBOUND) 1.547 + type = GLP_LO; 1.548 + else if (lbnd <= -CPX_INFBOUND) 1.549 + type = GLP_UP; 1.550 + else if (lbnd != ubnd) 1.551 + type = GLP_DB; 1.552 + else 1.553 + type = GLP_FX; 1.554 + glp_set_col_bnds(lp->prob, indices[j]+1, type, lbnd, ubnd); 1.555 + } 1.556 +done: return errcode; 1.557 +} 1.558 + 1.559 +int CPXchgcoeflist(CPXENV *env, CPXLP *lp, int numcoefs, 1.560 + const int rowlist[], const int collist[], const double vallist[]) 1.561 +{ int i, j, k, m, n, rcnt, ccnt, len, ptr, errcode; 1.562 + int *head, *next, *ind; 1.563 + double *val; 1.564 + errcode = checklp(env, lp); 1.565 + if (errcode) goto done; 1.566 + if (numcoefs < 0) 1.567 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.568 + goto done; 1.569 + } 1.570 + if (numcoefs == 0) 1.571 + { errcode = 0; 1.572 + goto done; 1.573 + } 1.574 + if (rowlist == NULL || collist == NULL || vallist == NULL) 1.575 + { errcode = error(env, CPXERR_NULL_POINTER); 1.576 + goto done; 1.577 + } 1.578 + /* check triplets and determine the number of rows and columns 1.579 + to be changed */ 1.580 + m = glp_get_num_rows(lp->prob); 1.581 + n = glp_get_num_cols(lp->prob); 1.582 + enlargeiwork(lp, m); 1.583 + enlargeiwork(lp, n); 1.584 + rcnt = ccnt = 0; 1.585 + for (k = 0; k < numcoefs; k++) 1.586 + { i = rowlist[k]; 1.587 + if (!(0 <= i && i < m)) 1.588 + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); 1.589 + goto done; 1.590 + } 1.591 + if (!(lp->iwork[i] & 0x01)) 1.592 + rcnt++, lp->iwork[i] |= 0x01; 1.593 + j = collist[k]; 1.594 + if (!(0 <= j && j < n)) 1.595 + { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); 1.596 + goto done; 1.597 + } 1.598 + if (!(lp->iwork[j] & 0x02)) 1.599 + ccnt++, lp->iwork[j] |= 0x02; 1.600 + } 1.601 + memset(lp->iwork, 0, m * sizeof(int)); 1.602 + memset(lp->iwork, 0, n * sizeof(int)); 1.603 + errcode = 0; 1.604 + invalidate(lp); 1.605 + if (rcnt <= ccnt) 1.606 + { /* change the matrix by rows */ 1.607 + /* build the linked list of triplets: 1.608 + head[i] is a pointer to first triplet for row i 1.609 + next[k] is a pointer to next triplet for the same row */ 1.610 + head = xcalloc(m, sizeof(int)); 1.611 + for (i = 0; i < m; i++) 1.612 + head[i] = -1; 1.613 + next = xcalloc(numcoefs, sizeof(int)); 1.614 + for (k = 0; k < numcoefs; k++) 1.615 + { i = rowlist[k]; 1.616 + next[k] = head[i]; 1.617 + head[i] = k; 1.618 + } 1.619 + /* check duplicate columns */ 1.620 + for (i = 0; i < m; i++) 1.621 + { for (k = head[i]; k >= 0; k = next[k]) 1.622 + { j = collist[k]; 1.623 + if (lp->iwork[j]) 1.624 + { xfree(head); 1.625 + xfree(next); 1.626 + errcode = error(env, CPXERR_DUP_ENTRY); 1.627 + goto done; 1.628 + } 1.629 + lp->iwork[j] = 1; 1.630 + } 1.631 + for (k = head[i]; k >= 0; k = next[k]) 1.632 + lp->iwork[collist[k]] = 0; 1.633 + } 1.634 + /* perform operation */ 1.635 + ind = xcalloc(1+n, sizeof(int)); 1.636 + val = xcalloc(1+n, sizeof(double)); 1.637 + for (i = 0; i < m; i++) 1.638 + { if (head[i] < 0) continue; 1.639 + len = glp_get_mat_row(lp->prob, i+1, ind, val); 1.640 + for (ptr = 1; ptr <= len; ptr++) 1.641 + { j = ind[ptr]-1; 1.642 + xassert(lp->iwork[j] == 0); 1.643 + lp->iwork[j] = ptr; 1.644 + } 1.645 + for (k = head[i]; k >= 0; k = next[k]) 1.646 + { j = collist[k]; 1.647 + if (lp->iwork[j] == 0) 1.648 + lp->iwork[j] = ++len; 1.649 + ptr = lp->iwork[j]; 1.650 + ind[ptr] = j+1, val[ptr] = vallist[k]; 1.651 + } 1.652 + glp_set_mat_row(lp->prob, i+1, len, ind, val); 1.653 + for (ptr = 1; ptr <= len; ptr++) 1.654 + lp->iwork[ind[ptr]-1] = 0; 1.655 + } 1.656 + } 1.657 + else 1.658 + { /* change the matrix by columns */ 1.659 + /* build the linked lists of triplets: 1.660 + head[j] is a pointer to first triplet for column j 1.661 + next[k] is a pointer to next triplet for the same column */ 1.662 + head = xcalloc(n, sizeof(int)); 1.663 + for (j = 0; j < n; j++) 1.664 + head[j] = -1; 1.665 + next = xcalloc(numcoefs, sizeof(int)); 1.666 + for (k = 0; k < numcoefs; k++) 1.667 + { j = collist[k]; 1.668 + next[k] = head[j]; 1.669 + head[j] = k; 1.670 + } 1.671 + /* check duplicate rows */ 1.672 + for (j = 0; j < n; j++) 1.673 + { for (k = head[j]; k >= 0; k = next[k]) 1.674 + { i = rowlist[k]; 1.675 + if (lp->iwork[i]) 1.676 + { xfree(head); 1.677 + xfree(next); 1.678 + errcode = error(env, CPXERR_DUP_ENTRY); 1.679 + goto done; 1.680 + } 1.681 + lp->iwork[i] = 1; 1.682 + } 1.683 + for (k = head[j]; k >= 0; k = next[k]) 1.684 + lp->iwork[rowlist[k]] = 0; 1.685 + } 1.686 + /* perform operation */ 1.687 + ind = xcalloc(1+m, sizeof(int)); 1.688 + val = xcalloc(1+m, sizeof(double)); 1.689 + for (j = 0; j < n; j++) 1.690 + { if (head[j] < 0) continue; 1.691 + len = glp_get_mat_col(lp->prob, j+1, ind, val); 1.692 + for (ptr = 1; ptr <= len; ptr++) 1.693 + { i = ind[ptr]-1; 1.694 + xassert(lp->iwork[i] == 0); 1.695 + lp->iwork[i] = ptr; 1.696 + } 1.697 + for (k = head[j]; k >= 0; k = next[k]) 1.698 + { i = rowlist[k]; 1.699 + if (lp->iwork[i] == 0) 1.700 + lp->iwork[i] = ++len; 1.701 + ptr = lp->iwork[i]; 1.702 + ind[ptr] = i+1, val[ptr] = vallist[k]; 1.703 + } 1.704 + glp_set_mat_col(lp->prob, j+1, len, ind, val); 1.705 + for (ptr = 1; ptr <= len; ptr++) 1.706 + lp->iwork[ind[ptr]-1] = 0; 1.707 + } 1.708 + } 1.709 + xfree(head); 1.710 + xfree(next); 1.711 + xfree(ind); 1.712 + xfree(val); 1.713 +done: return errcode; 1.714 +} 1.715 + 1.716 +void CPXchgobjsen(CPXENV *env, CPXLP *lp, int maxormin) 1.717 +{ int errcode; 1.718 + errcode = checklp(env, lp); 1.719 + if (errcode) goto done; 1.720 + if (!(maxormin == CPX_MIN || maxormin == CPX_MAX)) 1.721 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.722 + goto done; 1.723 + } 1.724 + errcode = 0; 1.725 + invalidate(lp); 1.726 + if (maxormin == CPX_MIN) 1.727 + glp_set_obj_dir(lp->prob, GLP_MIN); 1.728 + else 1.729 + glp_set_obj_dir(lp->prob, GLP_MAX); 1.730 +done: xassert(errcode == errcode); 1.731 + return; 1.732 +} 1.733 + 1.734 +int CPXchgsense(CPXENV *env, CPXLP *lp, int cnt, const int indices[], 1.735 + const char sense[]) 1.736 +{ int i, m, type, errcode; 1.737 + double rhs; 1.738 + errcode = checklp(env, lp); 1.739 + if (errcode) goto done; 1.740 + if (cnt < 0) 1.741 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.742 + goto done; 1.743 + } 1.744 + if (cnt > 0 && (indices == NULL || sense == NULL)) 1.745 + { errcode = error(env, CPXERR_NULL_POINTER); 1.746 + goto done; 1.747 + } 1.748 + m = glp_get_num_rows(lp->prob); 1.749 + for (i = 0; i < cnt; i++) 1.750 + { if (!(0 <= indices[i] && indices[i] < m)) 1.751 + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); 1.752 + goto done; 1.753 + } 1.754 + if (!(sense[i] == 'L' || sense[i] == 'E' || sense[i] == 'G' || 1.755 + sense[i] == 'R')) 1.756 + { errcode = error(env, CPXERR_BAD_SENSE, i); 1.757 + goto done; 1.758 + } 1.759 + } 1.760 + errcode = 0; 1.761 + invalidate(lp); 1.762 + for (i = 0; i < cnt; i++) 1.763 + { type = glp_get_row_type(lp->prob, indices[i]+1); 1.764 + if (lp->rflag[indices[i]] == RF_NOT_RANGED) 1.765 + { if (type == GLP_LO || type == GLP_FX) 1.766 + rhs = glp_get_row_lb(lp->prob, indices[i]+1); 1.767 + else if (type == GLP_UP) 1.768 + rhs = glp_get_row_ub(lp->prob, indices[i]+1); 1.769 + else 1.770 + xassert(type != type); 1.771 + } 1.772 + else if (lp->rflag[indices[i]] == RF_RANGED_POS) 1.773 + { xassert(type == GLP_DB || type == GLP_FX); 1.774 + rhs = glp_get_row_lb(lp->prob, indices[i]+1); 1.775 + } 1.776 + else if (lp->rflag[indices[i]] == RF_RANGED_NEG) 1.777 + { xassert(type == GLP_DB); 1.778 + rhs = glp_get_row_ub(lp->prob, indices[i]+1); 1.779 + } 1.780 + else 1.781 + xassert(lp != lp); 1.782 + if (sense[i] == 'L') 1.783 + { lp->rflag[indices[i]] = RF_NOT_RANGED; 1.784 + type = GLP_UP; 1.785 + } 1.786 + else if (sense[i] == 'E') 1.787 + { lp->rflag[indices[i]] = RF_NOT_RANGED; 1.788 + type = GLP_FX; 1.789 + } 1.790 + else if (sense[i] == 'G') 1.791 + { lp->rflag[indices[i]] = RF_NOT_RANGED; 1.792 + type = GLP_LO; 1.793 + } 1.794 + else if (sense[i] == 'R') 1.795 + { lp->rflag[indices[i]] = RF_RANGED_POS; 1.796 + type = GLP_FX; 1.797 + } 1.798 + else 1.799 + xassert(sense != sense); 1.800 + glp_set_row_bnds(lp->prob, indices[i]+1, type, rhs, rhs); 1.801 + } 1.802 +done: return errcode; 1.803 +} 1.804 + 1.805 +int CPXcloseCPLEX(CPXENV **_env) 1.806 +{ CPXENV *env; 1.807 + CPXLP *lp; 1.808 + int errcode; 1.809 + if (_env == NULL) 1.810 + { errcode = CPXERR_NULL_POINTER; 1.811 + goto done; 1.812 + } 1.813 + env = *_env; 1.814 + errcode = checkenv(env); 1.815 + if (errcode) goto done; 1.816 + while (env->list != NULL) 1.817 + { lp = env->list; 1.818 + errcode = CPXfreeprob(env, &lp); 1.819 + xassert(!errcode); 1.820 + } 1.821 + xfree(env->intparam); 1.822 + xfree(env->dblparam); 1.823 + xfree(env); 1.824 + *_env = NULL; 1.825 + errcode = 0; 1.826 +done: return errcode; 1.827 +} 1.828 + 1.829 +int CPXcopybase(CPXENV *env, CPXLP *lp, const int cstat[], 1.830 + const int rstat[]) 1.831 +{ int i, j, m, n, stat, errcode; 1.832 + errcode = checklp(env, lp); 1.833 + if (errcode) goto done; 1.834 + m = glp_get_num_rows(lp->prob); 1.835 + n = glp_get_num_cols(lp->prob); 1.836 + if (m > 0 && rstat == NULL || n > 0 && cstat == NULL) 1.837 + { errcode = error(env, CPXERR_NULL_POINTER); 1.838 + goto done; 1.839 + } 1.840 + for (i = 0; i < m; i++) 1.841 + { if (!(rstat[i] == CPX_AT_LOWER || rstat[i] == CPX_BASIC || 1.842 + rstat[i] == CPX_AT_UPPER)) 1.843 + { errcode = error(env, CPXERR_BAD_STATUS, i); 1.844 + goto done; 1.845 + } 1.846 + } 1.847 + for (j = 0; j < n; j++) 1.848 + { if (!(cstat[j] == CPX_AT_LOWER || cstat[j] == CPX_BASIC || 1.849 + cstat[j] == CPX_AT_UPPER || cstat[j] == CPX_FREE_SUPER)) 1.850 + { errcode = error(env, CPXERR_BAD_STATUS, j); 1.851 + goto done; 1.852 + } 1.853 + } 1.854 + errcode = 0; 1.855 + invalidate(lp); 1.856 + for (i = 0; i < m; i++) 1.857 + { if (rstat[i] == CPX_AT_LOWER) 1.858 + stat = GLP_NL; 1.859 + else if (rstat[i] == CPX_BASIC) 1.860 + stat = GLP_BS; 1.861 + else if (rstat[i] == CPX_AT_UPPER) 1.862 + stat = GLP_NU; 1.863 + else 1.864 + xassert(rstat != rstat); 1.865 + glp_set_row_stat(lp->prob, i+1, stat); 1.866 + } 1.867 + for (j = 0; j < n; j++) 1.868 + { if (cstat[j] == CPX_AT_LOWER) 1.869 + stat = GLP_NL; 1.870 + else if (cstat[j] == CPX_BASIC) 1.871 + stat = GLP_BS; 1.872 + else if (cstat[j] == CPX_AT_UPPER) 1.873 + stat = GLP_NU; 1.874 + else if (cstat[j] == CPX_FREE_SUPER) 1.875 + stat = GLP_NF; 1.876 + else 1.877 + xassert(cstat != cstat); 1.878 + glp_set_col_stat(lp->prob, j+1, stat); 1.879 + } 1.880 +done: return errcode; 1.881 +} 1.882 + 1.883 +int CPXcopybasednorms(CPXENV *env, CPXLP *lp, const int cstat[], 1.884 + const int rstat[], const double dnorm[]) 1.885 +{ int errcode; 1.886 + errcode = CPXcopybase(env, lp, cstat, rstat); 1.887 + xassert(dnorm == dnorm); 1.888 + return errcode; 1.889 +} 1.890 + 1.891 +int CPXcopylp(CPXENV *env, CPXLP *lp, int numcols, int numrows, 1.892 + int objsen, const double obj[], const double rhs[], 1.893 + const char sense[], const int matbeg[], const int matcnt[], 1.894 + const int matind[], const double matval[], const double lb[], 1.895 + const double ub[], const double rngval[]) 1.896 +{ int errcode; 1.897 + errcode = CPXcopylpwnames(env, lp, numcols, numrows, objsen, obj, 1.898 + rhs, sense, matbeg, matcnt, matind, matval, lb, ub, rngval, 1.899 + NULL, NULL); 1.900 + return errcode; 1.901 +} 1.902 + 1.903 +int CPXcopylpwnames(CPXENV *env, CPXLP *lp, int numcols, int numrows, 1.904 + int objsen, const double obj[], const double rhs[], 1.905 + const char sense[], const int matbeg[], const int matcnt[], 1.906 + const int matind[], const double matval[], const double lb[], 1.907 + const double ub[], const double rngval[], char *colname[], 1.908 + char *rowname[]) 1.909 +{ int i, j, k, beg, end, type, errcode; 1.910 + double lbnd, ubnd; 1.911 + char name[255+1]; 1.912 + errcode = checklp(env, lp); 1.913 + if (errcode) goto done; 1.914 + if (numcols < 0 || numrows < 0) 1.915 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.916 + goto done; 1.917 + } 1.918 + if (!(objsen == CPX_MIN || objsen == CPX_MAX)) 1.919 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.920 + goto done; 1.921 + } 1.922 + if (numcols > 0) 1.923 + { if (matbeg == NULL || matcnt == NULL || matind == NULL || 1.924 + matval == NULL) 1.925 + { errcode = error(env, CPXERR_NULL_POINTER); 1.926 + goto done; 1.927 + } 1.928 + } 1.929 + for (i = 0; i < numrows; i++) 1.930 + { if (sense != NULL) 1.931 + { if (!(sense[i] == 'L' || sense[i] == 'E' || 1.932 + sense[i] == 'G' || sense[i] == 'R')) 1.933 + { errcode = error(env, CPXERR_BAD_SENSE, i); 1.934 + goto done; 1.935 + } 1.936 + } 1.937 + if (rowname != NULL) 1.938 + { if (rowname[i] == NULL) 1.939 + { errcode = error(env, CPXERR_NULL_NAME, i); 1.940 + goto done; 1.941 + } 1.942 + } 1.943 + } 1.944 + enlargeiwork(lp, numrows); 1.945 + for (j = 0; j < numcols; j++) 1.946 + { beg = matbeg[j]; 1.947 + if (j > 0 && !(matbeg[j-1] <= beg)) 1.948 + { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, j); 1.949 + goto done; 1.950 + } 1.951 + if (beg < 0) 1.952 + { errcode = error(env, CPXERR_INDEX_RANGE); 1.953 + goto done; 1.954 + } 1.955 + end = beg + matcnt[j]; 1.956 + if (!(beg <= end) || j < numcols-1 && !(end <= matbeg[j+1])) 1.957 + { errcode = error(env, CPXERR_COUNT_RANGE, j); 1.958 + goto done; 1.959 + } 1.960 + for (k = beg; k < end; k++) 1.961 + { if (!(0 <= matind[k] && matind[k] < numrows)) 1.962 + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, k); 1.963 + goto done; 1.964 + } 1.965 + } 1.966 + errcode = 0; 1.967 + for (k = beg; k < end; k++) 1.968 + { if (lp->iwork[matind[k]]) 1.969 + { errcode = error(env, CPXERR_DUP_ENTRY); 1.970 + break; 1.971 + } 1.972 + lp->iwork[matind[k]] = 1; 1.973 + } 1.974 + for (k = beg; k < end; k++) 1.975 + lp->iwork[matind[k]] = 0; 1.976 + if (errcode) goto done; 1.977 + if (colname != NULL) 1.978 + { if (colname[j] != NULL) 1.979 + { errcode = error(env, CPXERR_NULL_NAME, j); 1.980 + goto done; 1.981 + } 1.982 + } 1.983 + } 1.984 + errcode = 0; 1.985 + invalidate(lp); 1.986 + if (glp_get_prob_name(lp->prob) == NULL) 1.987 + name[0] = '\0'; 1.988 + else 1.989 + strcpy(name, glp_get_prob_name(lp->prob)); 1.990 + glp_erase_prob(lp->prob); 1.991 + glp_set_prob_name(lp->prob, name); 1.992 + if (objsen == CPX_MIN) 1.993 + glp_set_obj_dir(lp->prob, GLP_MIN); 1.994 + else if (objsen == CPX_MAX) 1.995 + glp_set_obj_dir(lp->prob, GLP_MAX); 1.996 + else 1.997 + xassert(objsen != objsen); 1.998 + if (numrows > 0) 1.999 + glp_add_rows(lp->prob, numrows); 1.1000 + enlargerflag(lp); 1.1001 + for (i = 0; i < numrows; i++) 1.1002 + { if (rowname != NULL) 1.1003 + glp_set_row_name(lp->prob, i+1, rowname[i]); 1.1004 + lbnd = ubnd = (rhs == NULL ? 0.0 : rhs[i]); 1.1005 + if (sense == NULL || sense[i] == 'E') 1.1006 + { lp->rflag[i] = RF_NOT_RANGED; 1.1007 + type = GLP_FX; 1.1008 + } 1.1009 + else if (sense[i] == 'L') 1.1010 + { lp->rflag[i] = RF_NOT_RANGED; 1.1011 + type = GLP_UP; 1.1012 + } 1.1013 + else if (sense[i] == 'G') 1.1014 + { lp->rflag[i] = RF_NOT_RANGED; 1.1015 + type = GLP_LO; 1.1016 + } 1.1017 + else if (sense[i] == 'R') 1.1018 + { if (rngval == NULL || rngval[i] == 0.0) 1.1019 + { lp->rflag[i] = RF_RANGED_POS; 1.1020 + type = GLP_FX; 1.1021 + } 1.1022 + else if (rngval[i] > 0.0) 1.1023 + { lp->rflag[i] = RF_RANGED_POS; 1.1024 + type = GLP_DB; 1.1025 + ubnd += rngval[i]; 1.1026 + } 1.1027 + else /* rngval[i] < 0.0 */ 1.1028 + { lp->rflag[i] = RF_RANGED_NEG; 1.1029 + type = GLP_DB; 1.1030 + lbnd += rngval[i]; 1.1031 + } 1.1032 + } 1.1033 + else 1.1034 + xassert(sense != sense); 1.1035 + glp_set_row_bnds(lp->prob, i+1, type, lbnd, ubnd); 1.1036 + } 1.1037 + if (numcols > 0) 1.1038 + glp_add_cols(lp->prob, numcols); 1.1039 + for (j = 0; j < numcols; j++) 1.1040 + { if (colname != NULL) 1.1041 + glp_set_col_name(lp->prob, j+1, colname[j]); 1.1042 + lbnd = (lb == NULL ? 0.0 : lb[j]); 1.1043 + ubnd = (ub == NULL ? +CPX_INFBOUND : ub[j]); 1.1044 + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) 1.1045 + type = GLP_FR; 1.1046 + else if (ubnd >= +CPX_INFBOUND) 1.1047 + type = GLP_LO; 1.1048 + else if (lbnd <= -CPX_INFBOUND) 1.1049 + type = GLP_UP; 1.1050 + else if (lbnd != ubnd) 1.1051 + type = GLP_DB; 1.1052 + else 1.1053 + type = GLP_FX; 1.1054 + glp_set_col_bnds(lp->prob, j+1, type, lbnd, ubnd); 1.1055 + if (obj != NULL) 1.1056 + glp_set_obj_coef(lp->prob, j+1, obj[j]); 1.1057 + beg = matbeg[j]; 1.1058 + end = beg + matcnt[j]; 1.1059 + for (k = beg; k < end; k++) 1.1060 + lp->iwork[k-beg] = matind[k]+1; 1.1061 + glp_set_mat_col(lp->prob, j+1, end-beg, lp->iwork-1, 1.1062 + matval+beg-1); 1.1063 + for (k = beg; k < end; k++) 1.1064 + lp->iwork[k-beg] = 0; 1.1065 + } 1.1066 +done: return errcode; 1.1067 +} 1.1068 + 1.1069 +CPXLP *CPXcreateprob(CPXENV *env, int *status, const char *probname) 1.1070 +{ CPXLP *lp = NULL; 1.1071 + int errcode; 1.1072 + errcode = checkenv(env); 1.1073 + if (errcode) goto done; 1.1074 + lp = xmalloc(sizeof(struct CPXLP)); 1.1075 + lp->env = env; 1.1076 + lp->prob = glp_create_prob(); 1.1077 + glp_set_prob_name(lp->prob, probname); 1.1078 + lp->rflen = 100; 1.1079 + lp->rflag = xcalloc(lp->rflen, sizeof(char)); 1.1080 + lp->iwlen = 100; 1.1081 + lp->iwork = xcalloc(lp->iwlen, sizeof(int)); 1.1082 + memset(lp->iwork, 0, lp->iwlen * sizeof(int)); 1.1083 + lp->link = env->list; 1.1084 + env->list = lp; 1.1085 + invalidate(lp); 1.1086 +done: if (status != NULL) *status = errcode; 1.1087 + return lp; 1.1088 +} 1.1089 + 1.1090 +int CPXdelcols(CPXENV *env, CPXLP *lp, int begin, int end) 1.1091 +{ int j, n, errcode; 1.1092 + errcode = checklp(env, lp); 1.1093 + if (errcode) goto done; 1.1094 + n = glp_get_num_cols(lp->prob); 1.1095 + if (!(0 <= begin && begin <= end && end < n)) 1.1096 + { errcode = error(env, CPXERR_INDEX_RANGE); 1.1097 + goto done; 1.1098 + } 1.1099 + errcode = 0; 1.1100 + invalidate(lp); 1.1101 + enlargeiwork(lp, end-begin+1); 1.1102 + for (j = begin; j <= end; j++) 1.1103 + lp->iwork[j-begin] = j+1; 1.1104 + glp_del_cols(lp->prob, end-begin+1, lp->iwork-1); 1.1105 + for (j = begin; j <= end; j++) 1.1106 + lp->iwork[j-begin] = 0; 1.1107 +done: return errcode; 1.1108 +} 1.1109 + 1.1110 +int CPXdelrows(CPXENV *env, CPXLP *lp, int begin, int end) 1.1111 +{ int i, m, errcode; 1.1112 + errcode = checklp(env, lp); 1.1113 + if (errcode) goto done; 1.1114 + m = glp_get_num_rows(lp->prob); 1.1115 + if (!(0 <= begin && begin <= end && end < m)) 1.1116 + { errcode = error(env, CPXERR_INDEX_RANGE); 1.1117 + goto done; 1.1118 + } 1.1119 + errcode = 0; 1.1120 + invalidate(lp); 1.1121 + enlargeiwork(lp, end-begin+1); 1.1122 + for (i = begin; i <= end; i++) 1.1123 + lp->iwork[i-begin] = i+1; 1.1124 + glp_del_rows(lp->prob, end-begin+1, lp->iwork-1); 1.1125 + for (i = begin; i <= end; i++) 1.1126 + lp->iwork[i-begin] = 0; 1.1127 + for (i = end+1; i < m; i++) 1.1128 + lp->rflag[i-(end-begin+1)] = lp->rflag[i]; 1.1129 +done: return errcode; 1.1130 +} 1.1131 + 1.1132 +int CPXdelsetcols(CPXENV *env, CPXLP *lp, int delstat[]) 1.1133 +{ xassert(env == env); 1.1134 + xassert(lp == lp); 1.1135 + xassert(delstat == delstat); 1.1136 + xprintf("CPXdelsetcols: not implemented yet\n"); 1.1137 + exit(EXIT_FAILURE); 1.1138 + return -1; 1.1139 +} 1.1140 + 1.1141 +int CPXdelsetrows(CPXENV *env, CPXLP *lp, int delstat[]) 1.1142 +{ int i, m, cnt, ind, errcode; 1.1143 + errcode = checklp(env, lp); 1.1144 + if (errcode) goto done; 1.1145 + m = glp_get_num_rows(lp->prob); 1.1146 + if (m > 0 && delstat == NULL) 1.1147 + { errcode = error(env, CPXERR_NULL_POINTER); 1.1148 + goto done; 1.1149 + } 1.1150 + errcode = 0; 1.1151 + invalidate(lp); 1.1152 + enlargeiwork(lp, m); 1.1153 + cnt = ind = 0; 1.1154 + for (i = 0; i < m; i++) 1.1155 + { if (delstat[i] == 1) 1.1156 + { delstat[i] = -1; 1.1157 + lp->iwork[cnt++] = i+1; 1.1158 + } 1.1159 + else 1.1160 + { delstat[i] = ind; 1.1161 + lp->rflag[ind++] = lp->rflag[i]; 1.1162 + } 1.1163 + } 1.1164 + if (cnt > 0) 1.1165 + glp_del_rows(lp->prob, cnt, lp->iwork-1); 1.1166 + for (i = 0; i < cnt; i++) 1.1167 + lp->iwork[i] = 0; 1.1168 +done: return errcode; 1.1169 +} 1.1170 + 1.1171 +int CPXdualopt(CPXENV *env, CPXLP *lp); 1.1172 + 1.1173 +int CPXfreeprob(CPXENV *env, CPXLP **_lp) 1.1174 +{ CPXLP *lp; 1.1175 + int errcode; 1.1176 + errcode = checkenv(env); 1.1177 + if (errcode) goto done; 1.1178 + if (_lp == NULL) 1.1179 + { errcode = error(env, CPXERR_NULL_POINTER); 1.1180 + goto done; 1.1181 + } 1.1182 + lp = *_lp; 1.1183 + errcode = checklp(env, lp); 1.1184 + if (errcode) goto done; 1.1185 + errcode = 0; 1.1186 + env = lp->env; 1.1187 + if (env->list == lp) 1.1188 + env->list = lp->link; 1.1189 + else 1.1190 + { CPXLP *pp; 1.1191 + for (pp = env->list; pp != NULL; pp = pp->link) 1.1192 + if (pp->link == lp) break; 1.1193 + xassert(pp != NULL); 1.1194 + pp->link = lp->link; 1.1195 + } 1.1196 + glp_delete_prob(lp->prob); 1.1197 + xfree(lp->rflag); 1.1198 + xfree(lp->iwork); 1.1199 + xfree(lp); 1.1200 + *_lp = NULL; 1.1201 +done: return errcode; 1.1202 +} 1.1203 + 1.1204 +int CPXgetbase(CPXENV *env, CPXLP *lp, int cstat[], int rstat[]) 1.1205 +{ int i, j, m, n, stat, errcode; 1.1206 + errcode = checklp(env, lp); 1.1207 + if (errcode) goto done; 1.1208 + if (!lp->stat) 1.1209 + { errcode = error(env, CPXERR_NO_SOLN); 1.1210 + goto done; 1.1211 + } 1.1212 + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) 1.1213 + ; 1.1214 + else 1.1215 + { errcode = error(env, CPXERR_NO_BASIC_SOLN); 1.1216 + goto done; 1.1217 + } 1.1218 + errcode = 0; 1.1219 + if (rstat != NULL) 1.1220 + { m = glp_get_num_rows(lp->prob); 1.1221 + for (i = 0; i < m; i++) 1.1222 + { stat = glp_get_row_stat(lp->prob, i+1); 1.1223 + if (stat == GLP_BS) 1.1224 + rstat[i] = CPX_BASIC; 1.1225 + else if (lp->rflag[i] == RF_NOT_RANGED || stat != GLP_NU) 1.1226 + rstat[i] = CPX_AT_LOWER; 1.1227 + else 1.1228 + rstat[i] = CPX_AT_UPPER; 1.1229 + } 1.1230 + } 1.1231 + if (cstat != NULL) 1.1232 + { n = glp_get_num_cols(lp->prob); 1.1233 + for (j = 0; j < n; j++) 1.1234 + { stat = glp_get_col_stat(lp->prob, j+1); 1.1235 + if (stat == GLP_BS) 1.1236 + cstat[j] = CPX_BASIC; 1.1237 + else if (stat == GLP_NU) 1.1238 + cstat[j] = CPX_AT_UPPER; 1.1239 + else if (stat == GLP_NF) 1.1240 + cstat[j] = CPX_FREE_SUPER; 1.1241 + else 1.1242 + cstat[j] = CPX_AT_LOWER; 1.1243 + } 1.1244 + } 1.1245 +done: return errcode; 1.1246 +} 1.1247 + 1.1248 +int CPXgetbasednorms(CPXENV *env, CPXLP *lp, int cstat[], int rstat[], 1.1249 + double dnorm[]) 1.1250 +{ int i, m, errcode; 1.1251 + errcode = CPXgetbase(env, lp, cstat, rstat); 1.1252 + if (errcode) goto done; 1.1253 + if (dnorm != NULL) 1.1254 + { m = glp_get_num_rows(lp->prob); 1.1255 + for (i = 0; i < m; i++) dnorm[i] = 1.0; 1.1256 + } 1.1257 +done: return errcode; 1.1258 +} 1.1259 + 1.1260 +int CPXgetbhead(CPXENV *env, CPXLP *lp, int head[], double x[]) 1.1261 +{ xassert(env == env); 1.1262 + xassert(lp == lp); 1.1263 + xassert(head == head); 1.1264 + xassert(x == x); 1.1265 + xprintf("CPXgetbhead: not implemented yet\n"); 1.1266 + exit(EXIT_FAILURE); 1.1267 + return -1; 1.1268 +} 1.1269 + 1.1270 +int CPXgetdblparam(CPXENV *env, int whichparam, double *value) 1.1271 +{ int k, errcode; 1.1272 + errcode = checkenv(env); 1.1273 + if (errcode) goto done; 1.1274 + k = finddblparam(whichparam); 1.1275 + if (k < 0) 1.1276 + { errcode = error(env, CPXERR_BAD_PARAM_NUM); 1.1277 + goto done; 1.1278 + } 1.1279 + errcode = 0; 1.1280 + if (value != NULL) 1.1281 + *value = env->dblparam[k]; 1.1282 +done: return errcode; 1.1283 +} 1.1284 + 1.1285 +int CPXgetdj(CPXENV *env, CPXLP *lp, double dj[], int begin, int end) 1.1286 +{ int j, n, errcode; 1.1287 + errcode = checklp(env, lp); 1.1288 + if (errcode) goto done; 1.1289 + n = glp_get_num_cols(lp->prob); 1.1290 + if (!(0 <= begin && begin <= end && end < n)) 1.1291 + { errcode = error(env, CPXERR_INDEX_RANGE); 1.1292 + goto done; 1.1293 + } 1.1294 + if (!lp->stat) 1.1295 + { errcode = error(env, CPXERR_NO_SOLN); 1.1296 + goto done; 1.1297 + } 1.1298 + errcode = 0; 1.1299 + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) 1.1300 + { if (dj != NULL) 1.1301 + { for (j = begin; j <= end; j++) 1.1302 + dj[j-begin] = glp_get_col_dual(lp->prob, j+1); 1.1303 + } 1.1304 + } 1.1305 + else 1.1306 + xassert(lp != lp); 1.1307 +done: return errcode; 1.1308 +} 1.1309 + 1.1310 +char *CPXgeterrorstring(CPXENV *env, int errcode, char *buffer) 1.1311 +{ const char *string; 1.1312 + xassert(env == env); 1.1313 + string = finderrstring(errcode); 1.1314 + if (string == NULL) 1.1315 + buffer = NULL; 1.1316 + else 1.1317 + sprintf(buffer, "CPLEX Error %5d: %s.\n", errcode, string); 1.1318 + return buffer; 1.1319 +} 1.1320 + 1.1321 +int CPXgetijdiv(CPXENV *env, CPXLP *lp, int *idiv, int *jdiv) 1.1322 +{ xassert(env == env); 1.1323 + xassert(lp == lp); 1.1324 + xassert(idiv == idiv); 1.1325 + xassert(jdiv == jdiv); 1.1326 + xprintf("CPXgetijdiv: not implemented yet\n"); 1.1327 + exit(EXIT_FAILURE); 1.1328 + return -1; 1.1329 +} 1.1330 + 1.1331 +int CPXgetintparam(CPXENV *env, int whichparam, int *value) 1.1332 +{ int k, errcode; 1.1333 + errcode = checkenv(env); 1.1334 + if (errcode) goto done; 1.1335 + k = findintparam(whichparam); 1.1336 + if (k < 0) 1.1337 + { errcode = error(env, CPXERR_BAD_PARAM_NUM); 1.1338 + goto done; 1.1339 + } 1.1340 + errcode = 0; 1.1341 + if (value != NULL) 1.1342 + *value = env->intparam[k]; 1.1343 +done: return errcode; 1.1344 +} 1.1345 + 1.1346 +int CPXgetlb(CPXENV *env, CPXLP *lp, double lb[], int begin, int end) 1.1347 +{ xassert(env == env); 1.1348 + xassert(lp == lp); 1.1349 + xassert(lb == lb); 1.1350 + xassert(begin == begin); 1.1351 + xassert(end == end); 1.1352 + xprintf("CPXgetlb: not implemented yet\n"); 1.1353 + exit(EXIT_FAILURE); 1.1354 + return -1; 1.1355 +} 1.1356 + 1.1357 +int CPXgetmethod(CPXENV *env, CPXLP *lp) 1.1358 +{ int method; 1.1359 + if (checklp(env, lp)) 1.1360 + method = CPX_ALG_NONE; 1.1361 + else 1.1362 + method = lp->meth; 1.1363 + return method; 1.1364 +} 1.1365 + 1.1366 +int CPXgetnumcols(CPXENV *env, CPXLP *lp) 1.1367 +{ int numcols; 1.1368 + if (checklp(env, lp)) 1.1369 + numcols = 0; 1.1370 + else 1.1371 + numcols = glp_get_num_cols(lp->prob); 1.1372 + return numcols; 1.1373 +} 1.1374 + 1.1375 +int CPXgetnumnz(CPXENV *env, CPXLP *lp) 1.1376 +{ int numnz; 1.1377 + if (checklp(env, lp)) 1.1378 + numnz = 0; 1.1379 + else 1.1380 + numnz = glp_get_num_nz(lp->prob); 1.1381 + return numnz; 1.1382 +} 1.1383 + 1.1384 +int CPXgetnumrows(CPXENV *env, CPXLP *lp) 1.1385 +{ int numrows; 1.1386 + if (checklp(env, lp)) 1.1387 + numrows = 0; 1.1388 + else 1.1389 + numrows = glp_get_num_rows(lp->prob); 1.1390 + return numrows; 1.1391 +} 1.1392 + 1.1393 +int CPXgetobjval(CPXENV *env, CPXLP *lp, double *objval) 1.1394 +{ int errcode; 1.1395 + errcode = checklp(env, lp); 1.1396 + if (errcode) goto done; 1.1397 + if (!lp->stat) 1.1398 + { errcode = error(env, CPXERR_NO_SOLN); 1.1399 + goto done; 1.1400 + } 1.1401 + errcode = 0; 1.1402 + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) 1.1403 + { if (objval != NULL) 1.1404 + *objval = glp_get_obj_val(lp->prob); 1.1405 + } 1.1406 + else 1.1407 + xassert(lp != lp); 1.1408 +done: return errcode; 1.1409 +} 1.1410 + 1.1411 +int CPXgetpi(CPXENV *env, CPXLP *lp, double pi[], int begin, int end) 1.1412 +{ int i, m, errcode; 1.1413 + errcode = checklp(env, lp); 1.1414 + if (errcode) goto done; 1.1415 + m = glp_get_num_rows(lp->prob); 1.1416 + if (!(0 <= begin && begin <= end && end < m)) 1.1417 + { errcode = error(env, CPXERR_INDEX_RANGE); 1.1418 + goto done; 1.1419 + } 1.1420 + if (!lp->stat) 1.1421 + { errcode = error(env, CPXERR_NO_SOLN); 1.1422 + goto done; 1.1423 + } 1.1424 + errcode = 0; 1.1425 + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) 1.1426 + { if (pi != NULL) 1.1427 + { for (i = begin; i <= end; i++) 1.1428 + pi[i-begin] = glp_get_row_dual(lp->prob, i+1); 1.1429 + } 1.1430 + } 1.1431 + else 1.1432 + xassert(lp != lp); 1.1433 +done: return errcode; 1.1434 +} 1.1435 + 1.1436 +int CPXgetsense(CPXENV *env, CPXLP *lp, char sense[], int begin, 1.1437 + int end) 1.1438 +{ xassert(env == env); 1.1439 + xassert(lp == lp); 1.1440 + xassert(sense == sense); 1.1441 + xassert(begin == begin); 1.1442 + xassert(end == end); 1.1443 + xprintf("CPXgetsense: not implemented yet\n"); 1.1444 + exit(EXIT_FAILURE); 1.1445 + return -1; 1.1446 +} 1.1447 + 1.1448 +int CPXgetslack(CPXENV *env, CPXLP *lp, double slack[], int begin, 1.1449 + int end) 1.1450 +{ int i, m, type, errcode; 1.1451 + double temp; 1.1452 + errcode = checklp(env, lp); 1.1453 + if (errcode) goto done; 1.1454 + m = glp_get_num_rows(lp->prob); 1.1455 + if (!(0 <= begin && begin <= end && end < m)) 1.1456 + { errcode = error(env, CPXERR_INDEX_RANGE); 1.1457 + goto done; 1.1458 + } 1.1459 + if (!lp->stat) 1.1460 + { errcode = error(env, CPXERR_NO_SOLN); 1.1461 + goto done; 1.1462 + } 1.1463 + errcode = 0; 1.1464 + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) 1.1465 + { if (slack != NULL) 1.1466 + { for (i = begin; i <= end; i++) 1.1467 + { type = glp_get_row_type(lp->prob, i+1); 1.1468 + temp = glp_get_row_prim(lp->prob, i+1); 1.1469 + if (lp->rflag[i] == RF_NOT_RANGED) 1.1470 + { if (type == GLP_LO || type == GLP_FX) 1.1471 + slack[i-begin] = 1.1472 + glp_get_row_lb(lp->prob, i+1) - temp; 1.1473 + else if (type == GLP_UP) 1.1474 + slack[i-begin] = 1.1475 + glp_get_row_ub(lp->prob, i+1) - temp; 1.1476 + else 1.1477 + xassert(type != type); 1.1478 + } 1.1479 + else if (lp->rflag[i] == RF_RANGED_POS) 1.1480 + { xassert(type == GLP_DB || type == GLP_FX); 1.1481 + slack[i-begin] = 1.1482 + temp - glp_get_row_lb(lp->prob, i+1); 1.1483 + } 1.1484 + else if (lp->rflag[i] == RF_RANGED_NEG) 1.1485 + { xassert(type == GLP_DB); 1.1486 + slack[i-begin] = 1.1487 + temp - glp_get_row_ub(lp->prob, i+1); 1.1488 + } 1.1489 + else 1.1490 + xassert(lp != lp); 1.1491 + } 1.1492 + } 1.1493 + } 1.1494 + else 1.1495 + xassert(lp != lp); 1.1496 +done: return errcode; 1.1497 +} 1.1498 + 1.1499 +int CPXgetstat(CPXENV *env, CPXLP *lp) 1.1500 +{ int stat; 1.1501 + if (checklp(env, lp)) 1.1502 + stat = 0; 1.1503 + else 1.1504 + stat = lp->stat; 1.1505 + return stat; 1.1506 +} 1.1507 + 1.1508 +int CPXgetub(CPXENV *env, CPXLP *lp, double ub[], int begin, int end) 1.1509 +{ xassert(env == env); 1.1510 + xassert(lp == lp); 1.1511 + xassert(ub == ub); 1.1512 + xassert(begin == begin); 1.1513 + xassert(end == end); 1.1514 + xprintf("CPXgetub: not implemented yet\n"); 1.1515 + exit(EXIT_FAILURE); 1.1516 + return -1; 1.1517 +} 1.1518 + 1.1519 +int CPXgetweight(CPXENV *env, CPXLP *lp, int rcnt, const int rmatbeg[], 1.1520 + const int rmatind[], const double rmatval[], double weight[], 1.1521 + int dpriind) 1.1522 +{ xassert(env == env); 1.1523 + xassert(lp == lp); 1.1524 + xassert(rcnt == rcnt); 1.1525 + xassert(rmatbeg == rmatbeg); 1.1526 + xassert(rmatind == rmatind); 1.1527 + xassert(rmatval == rmatval); 1.1528 + xassert(weight == weight); 1.1529 + xassert(dpriind == dpriind); 1.1530 + xprintf("CPXgetweight: not implemented yet\n"); 1.1531 + exit(EXIT_FAILURE); 1.1532 + return -1; 1.1533 +} 1.1534 + 1.1535 +int CPXgetx(CPXENV *env, CPXLP *lp, double x[], int begin, int end) 1.1536 +{ int j, n, errcode; 1.1537 + errcode = checklp(env, lp); 1.1538 + if (errcode) goto done; 1.1539 + n = glp_get_num_cols(lp->prob); 1.1540 + if (!(0 <= begin && begin <= end && end < n)) 1.1541 + { errcode = error(env, CPXERR_INDEX_RANGE); 1.1542 + goto done; 1.1543 + } 1.1544 + if (!lp->stat) 1.1545 + { errcode = error(env, CPXERR_NO_SOLN); 1.1546 + goto done; 1.1547 + } 1.1548 + errcode = 0; 1.1549 + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) 1.1550 + { if (x != NULL) 1.1551 + { for (j = begin; j <= end; j++) 1.1552 + x[j-begin] = glp_get_col_prim(lp->prob, j+1); 1.1553 + } 1.1554 + } 1.1555 + else 1.1556 + xassert(lp != lp); 1.1557 +done: return errcode; 1.1558 +} 1.1559 + 1.1560 +int CPXinfodblparam(CPXENV *env, int whichparam, double *defvalue, 1.1561 + double *minvalue, double *maxvalue) 1.1562 +{ int k, errcode; 1.1563 + errcode = checkenv(env); 1.1564 + if (errcode) goto done; 1.1565 + k = finddblparam(whichparam); 1.1566 + if (k < 0) 1.1567 + { errcode = error(env, CPXERR_BAD_PARAM_NUM); 1.1568 + goto done; 1.1569 + } 1.1570 + errcode = 0; 1.1571 + if (defvalue != NULL) 1.1572 + *defvalue = dblparam[k].defv; 1.1573 + if (minvalue != NULL) 1.1574 + *minvalue = dblparam[k].minv; 1.1575 + if (maxvalue != NULL) 1.1576 + *maxvalue = dblparam[k].maxv; 1.1577 +done: return errcode; 1.1578 +} 1.1579 + 1.1580 +int CPXinfointparam(CPXENV *env, int whichparam, int *defvalue, 1.1581 + int *minvalue, int *maxvalue) 1.1582 +{ int k, errcode; 1.1583 + errcode = checkenv(env); 1.1584 + if (errcode) goto done; 1.1585 + k = findintparam(whichparam); 1.1586 + if (k < 0) 1.1587 + { errcode = error(env, CPXERR_BAD_PARAM_NUM); 1.1588 + goto done; 1.1589 + } 1.1590 + errcode = 0; 1.1591 + if (defvalue != NULL) 1.1592 + *defvalue = intparam[k].defv; 1.1593 + if (minvalue != NULL) 1.1594 + *minvalue = intparam[k].minv; 1.1595 + if (maxvalue != NULL) 1.1596 + *maxvalue = intparam[k].maxv; 1.1597 +done: return errcode; 1.1598 +} 1.1599 + 1.1600 +int CPXmdleave(const CPXENV *env, CPXLP *lp, const int goodlist[], 1.1601 + int goodlen, double downratio[], double upratio[]) 1.1602 +{ int k; 1.1603 + xassert(env == env); 1.1604 + xassert(lp == lp); 1.1605 + xassert(goodlist == goodlist); 1.1606 + xassert(goodlen >= 0); 1.1607 + xassert(downratio != NULL); 1.1608 + xassert(upratio != NULL); 1.1609 + /* not implemented yet */ 1.1610 + for (k = 0; k < goodlen; k++) 1.1611 + downratio[k] = upratio[k] = 0.0; 1.1612 + return 0; 1.1613 +} 1.1614 + 1.1615 +int CPXnewcols(CPXENV *env, CPXLP *lp, int ccnt, const double obj[], 1.1616 + const double lb[], const double ub[], const char ctype[], 1.1617 + char *colname[]) 1.1618 +{ int j, n, kind, type, errcode; 1.1619 + double lbnd, ubnd; 1.1620 + errcode = checklp(env, lp); 1.1621 + if (errcode) goto done; 1.1622 + if (ccnt < 0) 1.1623 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.1624 + goto done; 1.1625 + } 1.1626 + for (j = 0; j < ccnt; j++) 1.1627 + { if (ctype != NULL) 1.1628 + { if (!(ctype[j] == 'C' || ctype[j] == 'B' || 1.1629 + ctype[j] == 'I')) 1.1630 + { errcode = error(env, CPXERR_BAD_CTYPE, j); 1.1631 + goto done; 1.1632 + } 1.1633 + } 1.1634 + if (colname != NULL) 1.1635 + { if (colname[j] == NULL) 1.1636 + { errcode = error(env, CPXERR_NULL_NAME, j); 1.1637 + goto done; 1.1638 + } 1.1639 + } 1.1640 + } 1.1641 + errcode = 0; 1.1642 + invalidate(lp); 1.1643 + n = glp_get_num_cols(lp->prob); 1.1644 + if (ccnt > 0) 1.1645 + glp_add_cols(lp->prob, ccnt); 1.1646 + for (j = 0; j < ccnt; j++) 1.1647 + { if (colname != NULL) 1.1648 + glp_set_col_name(lp->prob, n+j+1, colname[j]); 1.1649 + if (obj != NULL) 1.1650 + glp_set_obj_coef(lp->prob, n+j+1, obj[j]); 1.1651 + lbnd = (lb == NULL ? 0.0 : lb[j]); 1.1652 + ubnd = (ub == NULL ? 0.0 : ub[j]); 1.1653 + if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND) 1.1654 + type = GLP_FR; 1.1655 + else if (ubnd >= +CPX_INFBOUND) 1.1656 + type = GLP_LO; 1.1657 + else if (lbnd <= -CPX_INFBOUND) 1.1658 + type = GLP_UP; 1.1659 + else if (lbnd != ubnd) 1.1660 + type = GLP_DB; 1.1661 + else 1.1662 + type = GLP_FX; 1.1663 + glp_set_col_bnds(lp->prob, n+j+1, type, lbnd, ubnd); 1.1664 + if (ctype != NULL) 1.1665 + { if (ctype[j] == 'C') 1.1666 + kind = GLP_CV; 1.1667 + else if (ctype[j] == 'B') 1.1668 + kind = GLP_BV; 1.1669 + else if (ctype[j] == 'I') 1.1670 + kind = GLP_IV; 1.1671 + else 1.1672 + xassert(ctype != ctype); 1.1673 + glp_set_col_kind(lp->prob, n+j+1, kind); 1.1674 + } 1.1675 + } 1.1676 +done: return errcode; 1.1677 +} 1.1678 + 1.1679 +int CPXnewrows(CPXENV *env, CPXLP *lp, int rcnt, const double rhs[], 1.1680 + const char sense[], const double rngval[], char *rowname[]) 1.1681 +{ int i, m, type, errcode; 1.1682 + double lbnd, ubnd; 1.1683 + errcode = checklp(env, lp); 1.1684 + if (errcode) goto done; 1.1685 + if (rcnt < 0) 1.1686 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.1687 + goto done; 1.1688 + } 1.1689 + for (i = 0; i < rcnt; i++) 1.1690 + { if (sense != NULL) 1.1691 + { if (!(sense[i] == 'L' || sense[i] == 'E' || 1.1692 + sense[i] == 'G' || sense[i] == 'R')) 1.1693 + { errcode = error(env, CPXERR_BAD_SENSE, i); 1.1694 + goto done; 1.1695 + } 1.1696 + } 1.1697 + if (rowname != NULL) 1.1698 + { if (rowname[i] == NULL) 1.1699 + { errcode = error(env, CPXERR_NULL_NAME, i); 1.1700 + goto done; 1.1701 + } 1.1702 + } 1.1703 + } 1.1704 + errcode = 0; 1.1705 + invalidate(lp); 1.1706 + m = glp_get_num_rows(lp->prob); 1.1707 + if (rcnt > 0) 1.1708 + glp_add_rows(lp->prob, rcnt); 1.1709 + enlargerflag(lp); 1.1710 + for (i = 0; i < rcnt; i++) 1.1711 + { if (rowname != NULL) 1.1712 + glp_set_row_name(lp->prob, m+i+1, rowname[i]); 1.1713 + lbnd = ubnd = (rhs == NULL ? 0.0 : rhs[i]); 1.1714 + if (sense == NULL || sense[i] == 'E') 1.1715 + { lp->rflag[m+i] = RF_NOT_RANGED; 1.1716 + type = GLP_FX; 1.1717 + } 1.1718 + else if (sense[i] == 'L') 1.1719 + { lp->rflag[m+i] = RF_NOT_RANGED; 1.1720 + type = GLP_UP; 1.1721 + } 1.1722 + else if (sense[i] == 'G') 1.1723 + { lp->rflag[m+i] = RF_NOT_RANGED; 1.1724 + type = GLP_LO; 1.1725 + } 1.1726 + else if (sense[i] == 'R') 1.1727 + { if (rngval == NULL || rngval[i] == 0.0) 1.1728 + { lp->rflag[m+i] = RF_RANGED_POS; 1.1729 + type = GLP_FX; 1.1730 + } 1.1731 + else if (rngval[i] > 0.0) 1.1732 + { lp->rflag[m+i] = RF_RANGED_POS; 1.1733 + type = GLP_DB; 1.1734 + ubnd += rngval[i]; 1.1735 + } 1.1736 + else /* rngval[i] < 0.0 */ 1.1737 + { lp->rflag[m+i] = RF_RANGED_NEG; 1.1738 + type = GLP_DB; 1.1739 + lbnd += rngval[i]; 1.1740 + } 1.1741 + } 1.1742 + else 1.1743 + xassert(sense != sense); 1.1744 + glp_set_row_bnds(lp->prob, m+i+1, type, lbnd, ubnd); 1.1745 + } 1.1746 +done: return errcode; 1.1747 +} 1.1748 + 1.1749 +CPXENV *CPXopenCPLEX(int *status) 1.1750 +{ CPXENV *env; 1.1751 + int k, card; 1.1752 + env = xmalloc(sizeof(CPXENV)); 1.1753 + env->list = NULL; 1.1754 + card = sizeof(intparam) / sizeof(struct intparam); 1.1755 + env->intparam = xcalloc(card, sizeof(int)); 1.1756 + for (k = 0; k < card; k++) 1.1757 + env->intparam[k] = intparam[k].defv; 1.1758 + card = sizeof(dblparam) / sizeof(struct dblparam); 1.1759 + env->dblparam = xcalloc(card, sizeof(double)); 1.1760 + for (k = 0; k < card; k++) 1.1761 + env->dblparam[k] = dblparam[k].defv; 1.1762 + if (status != NULL) *status = 0; 1.1763 + return env; 1.1764 +} 1.1765 + 1.1766 +int CPXpivotin(CPXENV *env, CPXLP *lp, const int rlist[], int rlen) 1.1767 +{ int i, m, errcode; 1.1768 + errcode = checklp(env, lp); 1.1769 + if (errcode) goto done; 1.1770 + if (rlen < 0) 1.1771 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.1772 + goto done; 1.1773 + } 1.1774 + if (rlen > 0 && rlist == NULL) 1.1775 + { errcode = error(env, CPXERR_NULL_POINTER); 1.1776 + goto done; 1.1777 + } 1.1778 + m = glp_get_num_rows(lp->prob); 1.1779 + for (i = 0; i < rlen; i++) 1.1780 + { if (!(0 <= rlist[i] && rlist[i] < m)) 1.1781 + { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i); 1.1782 + goto done; 1.1783 + } 1.1784 + } 1.1785 + errcode = 0; 1.1786 + for (i = 0; i < rlen; i++) 1.1787 + { if (glp_get_row_type(lp->prob, rlist[i]+1) != GLP_FX) 1.1788 + { if (glp_get_row_stat(lp->prob, rlist[i]+1) != GLP_BS) 1.1789 + { /* not implemented yet */ 1.1790 + break; 1.1791 + } 1.1792 + } 1.1793 + } 1.1794 +done: return errcode; 1.1795 +} 1.1796 + 1.1797 +int CPXpivotout(CPXENV *env, CPXLP *lp, const int clist[], int clen) 1.1798 +{ int j, n, errcode; 1.1799 + errcode = checklp(env, lp); 1.1800 + if (errcode) goto done; 1.1801 + if (clen < 0) 1.1802 + { errcode = error(env, CPXERR_BAD_ARGUMENT); 1.1803 + goto done; 1.1804 + } 1.1805 + if (clen > 0 && clist == NULL) 1.1806 + { errcode = error(env, CPXERR_NULL_POINTER); 1.1807 + goto done; 1.1808 + } 1.1809 + n = glp_get_num_cols(lp->prob); 1.1810 + for (j = 0; j < clen; j++) 1.1811 + { if (!(0 <= clist[j] && clist[j] < n)) 1.1812 + { errcode = error(env, CPXERR_COL_INDEX_RANGE, j); 1.1813 + goto done; 1.1814 + } 1.1815 + if (glp_get_col_type(lp->prob, clist[j]+1) != GLP_FX) 1.1816 + { errcode = error(env, CPXERR_NOT_FIXED); 1.1817 + goto done; 1.1818 + } 1.1819 + } 1.1820 + errcode = 0; 1.1821 + for (j = 0; j < clen; j++) 1.1822 + { if (glp_get_col_stat(lp->prob, clist[j]+1) == GLP_BS) 1.1823 + { /* not implemented yet */ 1.1824 + break; 1.1825 + } 1.1826 + } 1.1827 +done: return errcode; 1.1828 +} 1.1829 + 1.1830 +int CPXprimopt(CPXENV *env, CPXLP *lp); 1.1831 + 1.1832 +int CPXsavwrite(CPXENV *env, CPXLP *lp, const char *filename) 1.1833 +{ xassert(env == env); 1.1834 + xassert(lp == lp); 1.1835 + xassert(filename == filename); 1.1836 + xprintf("CPXsavwrite: not implemented yet\n"); 1.1837 + exit(EXIT_FAILURE); 1.1838 + return -1; 1.1839 +} 1.1840 + 1.1841 +int CPXsetdblparam(CPXENV *env, int whichparam, double newvalue) 1.1842 +{ int k, errcode; 1.1843 + errcode = checkenv(env); 1.1844 + if (errcode) goto done; 1.1845 + k = finddblparam(whichparam); 1.1846 + if (k < 0) 1.1847 + { errcode = error(env, CPXERR_BAD_PARAM_NUM); 1.1848 + goto done; 1.1849 + } 1.1850 + if (newvalue < dblparam[k].minv) 1.1851 + { errcode = error(env, CPXERR_PARAM_TOO_SMALL); 1.1852 + goto done; 1.1853 + } 1.1854 + if (newvalue > dblparam[k].maxv) 1.1855 + { errcode = error(env, CPXERR_PARAM_TOO_BIG); 1.1856 + goto done; 1.1857 + } 1.1858 + errcode = 0; 1.1859 + env->dblparam[k] = newvalue; 1.1860 +done: return errcode; 1.1861 +} 1.1862 + 1.1863 +int CPXsetintparam(CPXENV *env, int whichparam, int newvalue) 1.1864 +{ int k, errcode; 1.1865 + errcode = checkenv(env); 1.1866 + if (errcode) goto done; 1.1867 + k = findintparam(whichparam); 1.1868 + if (k < 0) 1.1869 + { errcode = error(env, CPXERR_BAD_PARAM_NUM); 1.1870 + goto done; 1.1871 + } 1.1872 + if (newvalue < intparam[k].minv) 1.1873 + { errcode = error(env, CPXERR_PARAM_TOO_SMALL); 1.1874 + goto done; 1.1875 + } 1.1876 + if (newvalue > intparam[k].maxv) 1.1877 + { errcode = error(env, CPXERR_PARAM_TOO_BIG); 1.1878 + goto done; 1.1879 + } 1.1880 + errcode = 0; 1.1881 + env->intparam[k] = newvalue; 1.1882 +done: return errcode; 1.1883 +} 1.1884 + 1.1885 +int CPXsolninfo(CPXENV *env, CPXLP *lp, int *solnmethod, int *solntype, 1.1886 + int *pfeasind, int *dfeasind) 1.1887 +{ int type, pfeas, dfeas, errcode; 1.1888 + errcode = checklp(env, lp); 1.1889 + if (errcode) goto done; 1.1890 + errcode = 0; 1.1891 + if (!lp->stat) 1.1892 + type = CPX_NO_SOLN, pfeas = dfeas = 0; 1.1893 + else if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) 1.1894 + { type = CPX_BASIC_SOLN; 1.1895 + pfeas = (glp_get_prim_stat(lp->prob) == GLP_FEAS); 1.1896 + dfeas = (glp_get_dual_stat(lp->prob) == GLP_FEAS); 1.1897 + } 1.1898 + else 1.1899 + xassert(lp != lp); 1.1900 + if (solnmethod != NULL) 1.1901 + *solnmethod = lp->meth; 1.1902 + if (solntype != NULL) 1.1903 + *solntype = type; 1.1904 + if (pfeasind != NULL) 1.1905 + *pfeasind = pfeas; 1.1906 + if (dfeasind != NULL) 1.1907 + *dfeasind = dfeas; 1.1908 +done: return errcode; 1.1909 +} 1.1910 + 1.1911 +int CPXsolution(CPXENV *env, CPXLP *lp, int *lpstat, double *objval, 1.1912 + double x[], double pi[], double slack[], double dj[]) 1.1913 +{ int m, n, errcode; 1.1914 + errcode = checklp(env, lp); 1.1915 + if (errcode) goto done; 1.1916 + if (!lp->stat) 1.1917 + { errcode = error(env, CPXERR_NO_SOLN); 1.1918 + goto done; 1.1919 + } 1.1920 + errcode = 0; 1.1921 + m = glp_get_num_rows(lp->prob); 1.1922 + n = glp_get_num_cols(lp->prob); 1.1923 + if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL) 1.1924 + { if (lpstat != NULL) 1.1925 + *lpstat = CPXgetstat(env, lp); 1.1926 + if (objval != NULL) 1.1927 + xassert(CPXgetobjval(env, lp, objval) == 0); 1.1928 + if (x != NULL) 1.1929 + xassert(CPXgetx(env, lp, x, 0, n-1) == 0); 1.1930 + if (pi != NULL) 1.1931 + xassert(CPXgetpi(env, lp, pi, 0, m-1) == 0); 1.1932 + if (slack != NULL) 1.1933 + xassert(CPXgetslack(env, lp, slack, 0, m-1) == 0); 1.1934 + if (dj != NULL) 1.1935 + xassert(CPXgetdj(env, lp, dj, 0, n-1) == 0); 1.1936 + } 1.1937 + else 1.1938 + xassert(lp != lp); 1.1939 +done: return errcode; 1.1940 +} 1.1941 + 1.1942 +int CPXstrongbranch(CPXENV *env, CPXLP *lp, const int goodlist[], 1.1943 + int goodlen, double downpen[], double uppen[], int itlim) 1.1944 +{ int k; 1.1945 + xassert(env == env); 1.1946 + xassert(lp == lp); 1.1947 + xassert(goodlist == goodlist); 1.1948 + xassert(goodlen >= 0); 1.1949 + xassert(downpen != NULL); 1.1950 + xassert(uppen != NULL); 1.1951 + xassert(itlim == itlim); 1.1952 + /* not implemented yet */ 1.1953 + for (k = 0; k < goodlen; k++) 1.1954 + downpen[k] = uppen[k] = 0.0; 1.1955 + return 0; 1.1956 +} 1.1957 + 1.1958 +static int xstrcasecmp(const char *s1, const char *s2) 1.1959 +{ int c1, c2; 1.1960 + for (;;) 1.1961 + { c1 = toupper((unsigned char)*s1++); 1.1962 + c2 = toupper((unsigned char)*s2++); 1.1963 + if (c1 == '\0' || c1 != c2) break; 1.1964 + } 1.1965 + return c1 - c2; 1.1966 +} 1.1967 + 1.1968 +static void getfiletype(const char *filename, char type[3+1]) 1.1969 +{ /* determine filetype from filename */ 1.1970 + int beg, end; 1.1971 + beg = end = strlen(filename); 1.1972 + while (beg > 0 && filename[beg-1] != '.' && end - beg < 3) 1.1973 + beg--; 1.1974 + if (beg > 0 && filename[beg-1] == '.' && 1.1975 + xstrcasecmp(&filename[beg], "gz") == 0) 1.1976 + { end = --beg; 1.1977 + while (beg > 0 && filename[beg-1] != '.' && end - beg < 3) 1.1978 + beg--; 1.1979 + } 1.1980 + if (beg > 0 && filename[beg-1] == '.') 1.1981 + { memcpy(type, &filename[beg], end - beg); 1.1982 + type[end - beg] = '\0'; 1.1983 + } 1.1984 + else 1.1985 + type[0] = '\0'; 1.1986 + return; 1.1987 +} 1.1988 + 1.1989 +int CPXwriteprob(CPXENV *env, CPXLP *lp, const char *filename, 1.1990 + const char *filetype) 1.1991 +{ glp_prob *copy; 1.1992 + int errcode; 1.1993 + char type[3+1]; 1.1994 + errcode = checklp(env, lp); 1.1995 + if (errcode) goto done; 1.1996 + if (filename == NULL) 1.1997 + { errcode = error(env, CPXERR_NO_FILENAME); 1.1998 + goto done; 1.1999 + } 1.2000 + if (filetype == NULL) 1.2001 + getfiletype(filename, type), filetype = type; 1.2002 + if (xstrcasecmp(filetype, "MPS") == 0) 1.2003 + { glp_term_out(GLP_OFF); 1.2004 + errcode = glp_write_mps(lp->prob, GLP_MPS_FILE, NULL, filename) 1.2005 + ; 1.2006 + glp_term_out(GLP_ON); 1.2007 + } 1.2008 + else if (xstrcasecmp(filetype, "LP") == 0) 1.2009 + { glp_term_out(GLP_OFF); 1.2010 + errcode = glp_write_lp(lp->prob, NULL, filename); 1.2011 + glp_term_out(GLP_ON); 1.2012 + } 1.2013 + else if (xstrcasecmp(filetype, "RMP") == 0 || 1.2014 + xstrcasecmp(filetype, "REW") == 0) 1.2015 + { copy = glp_create_prob(); 1.2016 + glp_copy_prob(copy, lp->prob, GLP_OFF); 1.2017 + glp_term_out(GLP_OFF); 1.2018 + errcode = glp_write_mps(copy, GLP_MPS_DECK, NULL, filename); 1.2019 + glp_term_out(GLP_ON); 1.2020 + glp_delete_prob(copy); 1.2021 + } 1.2022 + else if (xstrcasecmp(filetype, "RLP") == 0) 1.2023 + { copy = glp_create_prob(); 1.2024 + glp_copy_prob(copy, lp->prob, GLP_OFF); 1.2025 + glp_term_out(GLP_OFF); 1.2026 + errcode = glp_write_lp(copy, NULL, filename); 1.2027 + glp_term_out(GLP_ON); 1.2028 + glp_delete_prob(copy); 1.2029 + } 1.2030 + else 1.2031 + { errcode = error(env, CPXERR_BAD_FILETYPE); 1.2032 + goto done; 1.2033 + } 1.2034 + if (errcode) 1.2035 + errcode = error(env, CPXERR_FAIL_OPEN_WRITE, filename); 1.2036 +done: return errcode; 1.2037 +} 1.2038 + 1.2039 +/**********************************************************************/ 1.2040 + 1.2041 +static int solvelp(CPXENV *env, CPXLP *lp, int meth) 1.2042 +{ glp_smcp parm; 1.2043 + int errcode; 1.2044 + errcode = checklp(env, lp); 1.2045 + if (errcode) goto done; 1.2046 + errcode = 0; 1.2047 + invalidate(lp); 1.2048 + glp_init_smcp(&parm); 1.2049 + switch (meth) 1.2050 + { case CPX_ALG_PRIMAL: 1.2051 + parm.meth = GLP_PRIMAL; 1.2052 + break; 1.2053 + case CPX_ALG_DUAL: 1.2054 + parm.meth = GLP_DUAL; 1.2055 + break; 1.2056 + default: 1.2057 + xassert(meth != meth); 1.2058 + } 1.2059 + switch (getintparam(env, CPX_PARAM_SIMDISPLAY)) 1.2060 + { case 0: 1.2061 + parm.msg_lev = GLP_MSG_OFF; 1.2062 + break; 1.2063 + case 1: 1.2064 + parm.msg_lev = GLP_MSG_ALL; 1.2065 + break; 1.2066 + case 2: 1.2067 + parm.msg_lev = GLP_MSG_ALL; 1.2068 + parm.out_frq = 1; 1.2069 + break; 1.2070 + default: 1.2071 + xassert(env != env); 1.2072 + } 1.2073 + xassert(getdblparam == getdblparam); 1.2074 + switch (getintparam(env, CPX_PARAM_ADVIND)) 1.2075 + { case 0: 1.2076 + glp_term_out(GLP_OFF); 1.2077 + glp_adv_basis(lp->prob, 0); 1.2078 + glp_term_out(GLP_ON); 1.2079 + break; 1.2080 + case 1: 1.2081 + case 2: 1.2082 + break; 1.2083 + default: 1.2084 + xassert(env != env); 1.2085 + } 1.2086 + if (!glp_bf_exists(lp->prob)) 1.2087 + { if (glp_factorize(lp->prob) != 0) 1.2088 + { glp_term_out(GLP_OFF); 1.2089 + glp_adv_basis(lp->prob, 0); 1.2090 + glp_term_out(GLP_ON); 1.2091 + if (glp_factorize(lp->prob) != 0) 1.2092 + glp_std_basis(lp->prob); 1.2093 + } 1.2094 + } 1.2095 + xassert(glp_simplex(lp->prob, &parm) == 0); 1.2096 + switch (glp_get_status(lp->prob)) 1.2097 + { case GLP_OPT: 1.2098 + lp->stat = CPX_STAT_OPTIMAL; 1.2099 + lp->meth = meth; 1.2100 + break; 1.2101 + case GLP_NOFEAS: 1.2102 + lp->stat = CPX_STAT_INFEASIBLE; 1.2103 + lp->meth = meth; 1.2104 + break; 1.2105 + case GLP_UNBND: 1.2106 + lp->stat = CPX_STAT_UNBOUNDED; 1.2107 + lp->meth = meth; 1.2108 + break; 1.2109 + default: 1.2110 + xassert(lp != lp); 1.2111 + } 1.2112 +done: return errcode; 1.2113 +} 1.2114 + 1.2115 +int CPXprimopt(CPXENV *env, CPXLP *lp) 1.2116 +{ int errcode; 1.2117 + errcode = solvelp(env, lp, CPX_ALG_PRIMAL); 1.2118 + return errcode; 1.2119 +} 1.2120 + 1.2121 +int CPXdualopt(CPXENV *env, CPXLP *lp) 1.2122 +{ int errcode; 1.2123 + errcode = solvelp(env, lp, CPX_ALG_DUAL); 1.2124 + return errcode; 1.2125 +} 1.2126 + 1.2127 +int CPXlpopt(CPXENV *env, CPXLP *lp) 1.2128 +{ int errcode; 1.2129 + errcode = solvelp(env, lp, CPX_ALG_PRIMAL); 1.2130 + return errcode; 1.2131 +} 1.2132 + 1.2133 +/* eof */