lemon-project-template-glpk

annotate 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
rev   line source
alpar@9 1 /* cplex.c (CPLEX-like interface to GLPK API) */
alpar@9 2
alpar@9 3 /***********************************************************************
alpar@9 4 * This code is part of GLPK (GNU Linear Programming Kit).
alpar@9 5 *
alpar@9 6 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
alpar@9 7 * 2009, 2010, 2011 Andrew Makhorin, Department for Applied Informatics,
alpar@9 8 * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
alpar@9 9 * E-mail: <mao@gnu.org>.
alpar@9 10 *
alpar@9 11 * GLPK is free software: you can redistribute it and/or modify it
alpar@9 12 * under the terms of the GNU General Public License as published by
alpar@9 13 * the Free Software Foundation, either version 3 of the License, or
alpar@9 14 * (at your option) any later version.
alpar@9 15 *
alpar@9 16 * GLPK is distributed in the hope that it will be useful, but WITHOUT
alpar@9 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
alpar@9 18 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
alpar@9 19 * License for more details.
alpar@9 20 *
alpar@9 21 * You should have received a copy of the GNU General Public License
alpar@9 22 * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
alpar@9 23 ***********************************************************************/
alpar@9 24
alpar@9 25 #include <ctype.h>
alpar@9 26 #include <stdarg.h>
alpar@9 27 #include <stdio.h>
alpar@9 28 #include <stdlib.h>
alpar@9 29 #include <string.h>
alpar@9 30 #include <glpk.h>
alpar@9 31 #include "cplex.h"
alpar@9 32
alpar@9 33 struct CPXENV
alpar@9 34 { /* environment block */
alpar@9 35 CPXLP *list;
alpar@9 36 /* linked list of problem objects */
alpar@9 37 int *intparam; /* int intparam[]; */
alpar@9 38 /* integer control parameters */
alpar@9 39 double *dblparam; /* double dblparam[]; */
alpar@9 40 /* floating-point control parameters */
alpar@9 41 };
alpar@9 42
alpar@9 43 struct CPXLP
alpar@9 44 { /* problem object */
alpar@9 45 CPXENV *env;
alpar@9 46 /* pointer to environment block */
alpar@9 47 glp_prob *prob;
alpar@9 48 /* pointer to underlying GLPK problem object */
alpar@9 49 int rflen;
alpar@9 50 /* length of the array rflag */
alpar@9 51 char *rflag; /* char rflag[rflen]; */
alpar@9 52 /* rflag[i], i = 0,...,nrows-1, is a flag of i-th row: */
alpar@9 53 #define RF_NOT_RANGED 0 /* not ranged */
alpar@9 54 #define RF_RANGED_POS 1 /* ranged, RHS = lower bound */
alpar@9 55 #define RF_RANGED_NEG 2 /* ranged, RHS = upper bound */
alpar@9 56 int stat;
alpar@9 57 /* solution status reported by CPXgetstat; zero means no solution
alpar@9 58 exists */
alpar@9 59 int meth;
alpar@9 60 /* method indicator reported by CPXgetmethod */
alpar@9 61 int iwlen;
alpar@9 62 /* length of the working array */
alpar@9 63 int *iwork; /* int iwork[iwlen] */
alpar@9 64 /* working array initialized by binary zeros */
alpar@9 65 CPXLP *link;
alpar@9 66 /* pointer to another problem object */
alpar@9 67 };
alpar@9 68
alpar@9 69 struct intparam
alpar@9 70 { int which;
alpar@9 71 int defv;
alpar@9 72 int minv;
alpar@9 73 int maxv;
alpar@9 74 };
alpar@9 75
alpar@9 76 struct dblparam
alpar@9 77 { int which;
alpar@9 78 double defv;
alpar@9 79 double minv;
alpar@9 80 double maxv;
alpar@9 81 };
alpar@9 82
alpar@9 83 struct errstring
alpar@9 84 { int code;
alpar@9 85 const char *string;
alpar@9 86 };
alpar@9 87
alpar@9 88 #define BIGINT 2100000000
alpar@9 89 #define BIGDBL 1e75
alpar@9 90
alpar@9 91 static const struct intparam intparam[] =
alpar@9 92 { {CPX_PARAM_ADVIND, 0, 0, 2},
alpar@9 93 {CPX_PARAM_AGGIND, -1, -1, BIGINT},
alpar@9 94 {CPX_PARAM_DATACHECK, CPX_OFF, CPX_OFF, CPX_ON},
alpar@9 95 {CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO, CPX_DPRIIND_AUTO,
alpar@9 96 CPX_DPRIIND_DEVEX},
alpar@9 97 {CPX_PARAM_FASTMIP, CPX_OFF, CPX_OFF, CPX_ON}, /* ??? */
alpar@9 98 {CPX_PARAM_ITLIM, BIGINT, 0, BIGINT},
alpar@9 99 {CPX_PARAM_PERIND, CPX_OFF, CPX_OFF, CPX_ON},
alpar@9 100 {CPX_PARAM_PPRIIND, CPX_PPRIIND_AUTO, CPX_PPRIIND_PARTIAL,
alpar@9 101 CPX_PPRIIND_FULL},
alpar@9 102 {CPX_PARAM_PREIND, CPX_ON, CPX_OFF, CPX_ON},
alpar@9 103 {CPX_PARAM_REINV, 0, 0, 10000},
alpar@9 104 {CPX_PARAM_SCRIND, CPX_OFF, CPX_OFF, CPX_ON},
alpar@9 105 {CPX_PARAM_SIMDISPLAY, 1, 0, 2},
alpar@9 106 };
alpar@9 107
alpar@9 108 static const struct dblparam dblparam[] =
alpar@9 109 { {CPX_PARAM_EPOPT, 1e-6, 1e-9, 1e-1},
alpar@9 110 {CPX_PARAM_EPPER, 1e-6, 1e-8, BIGDBL},
alpar@9 111 {CPX_PARAM_EPRHS, 1e-6, 1e-9, 1e-1},
alpar@9 112 {CPX_PARAM_OBJLLIM, -BIGDBL, -BIGDBL, +BIGDBL},
alpar@9 113 {CPX_PARAM_OBJULIM, +BIGDBL, -BIGDBL, +BIGDBL},
alpar@9 114 };
alpar@9 115
alpar@9 116 static const struct errstring errstring[] =
alpar@9 117 { {CPXERR_ARRAY_NOT_ASCENDING, "Array entry %d not ascending"},
alpar@9 118 {CPXERR_BAD_ARGUMENT, "Invalid argument"},
alpar@9 119 {CPXERR_BAD_CTYPE, "Invalid ctype entry %d"},
alpar@9 120 {CPXERR_BAD_FILETYPE, "Invalid filetype"},
alpar@9 121 {CPXERR_BAD_LUB, "Invalid bound change indicator entry %d"},
alpar@9 122 {CPXERR_BAD_PARAM_NUM, "Invalid parameter number"},
alpar@9 123 {CPXERR_BAD_SENSE, "Invalid sense entry %d"},
alpar@9 124 {CPXERR_BAD_STATUS, "Invalid status entry %d for basis specificat"
alpar@9 125 "ion"},
alpar@9 126 {CPXERR_COL_INDEX_RANGE, "Column index %d out of range"},
alpar@9 127 {CPXERR_COUNT_RANGE, "Count entry %d negative or larger than allo"
alpar@9 128 "wed"},
alpar@9 129 {CPXERR_DUP_ENTRY, "Duplicate entry"},
alpar@9 130 {CPXERR_FAIL_OPEN_WRITE, "Could not open file '%s' for writing"},
alpar@9 131 {CPXERR_INDEX_RANGE, "Index is outside range of valid values"},
alpar@9 132 {CPXERR_NEGATIVE_SURPLUS, "Insufficient array length"},
alpar@9 133 {CPXERR_NO_BASIC_SOLN, "No basic solution exists"},
alpar@9 134 {CPXERR_NO_ENVIRONMENT, "No environment exists"},
alpar@9 135 {CPXERR_NO_FILENAME, "File name not specified"},
alpar@9 136 {CPXERR_NO_MEMORY, "Out of memory"},
alpar@9 137 {CPXERR_NO_PROBLEM, "No problem exists"},
alpar@9 138 {CPXERR_NO_SOLN, "No solution exists"},
alpar@9 139 {CPXERR_NOT_FIXED, "Only fixed variables are pivoted out"},
alpar@9 140 {CPXERR_NULL_NAME, "Null pointer %d in name array"},
alpar@9 141 {CPXERR_NULL_POINTER, "Null pointer for required data"},
alpar@9 142 {CPXERR_PARAM_TOO_BIG, "Parameter value too big"},
alpar@9 143 {CPXERR_PARAM_TOO_SMALL, "Parameter value too small"},
alpar@9 144 {CPXERR_ROW_INDEX_RANGE, "Row index %d out of range"},
alpar@9 145 };
alpar@9 146
alpar@9 147 /**********************************************************************/
alpar@9 148
alpar@9 149 #define xassert glp_assert
alpar@9 150 #define xprintf glp_printf
alpar@9 151 #define xmalloc glp_malloc
alpar@9 152 #define xcalloc glp_calloc
alpar@9 153 #define xfree glp_free
alpar@9 154
alpar@9 155 /**********************************************************************/
alpar@9 156
alpar@9 157 static int findintparam(int whichparam)
alpar@9 158 { int k, card;
alpar@9 159 card = sizeof(intparam) / sizeof(struct intparam);
alpar@9 160 for (k = 0; k < card; k++)
alpar@9 161 if (intparam[k].which == whichparam) return k;
alpar@9 162 return -1;
alpar@9 163 }
alpar@9 164
alpar@9 165 static int getintparam(CPXENV *env, int whichparam)
alpar@9 166 { int k;
alpar@9 167 xassert(env != NULL);
alpar@9 168 k = findintparam(whichparam);
alpar@9 169 xassert(k >= 0);
alpar@9 170 return env->intparam[k];
alpar@9 171 }
alpar@9 172
alpar@9 173 static int finddblparam(int whichparam)
alpar@9 174 { int k, card;
alpar@9 175 card = sizeof(dblparam) / sizeof(struct dblparam);
alpar@9 176 for (k = 0; k < card; k++)
alpar@9 177 if (dblparam[k].which == whichparam) return k;
alpar@9 178 return -1;
alpar@9 179 }
alpar@9 180
alpar@9 181 static double getdblparam(CPXENV *env, int whichparam)
alpar@9 182 { int k;
alpar@9 183 xassert(env != NULL);
alpar@9 184 k = finddblparam(whichparam);
alpar@9 185 xassert(k >= 0);
alpar@9 186 return env->dblparam[k];
alpar@9 187 }
alpar@9 188
alpar@9 189 static const char *finderrstring(int errcode)
alpar@9 190 { int k, card;
alpar@9 191 card = sizeof(errstring) / sizeof(struct errstring);
alpar@9 192 for (k = 0; k < card; k++)
alpar@9 193 { if (errstring[k].code == errcode)
alpar@9 194 return errstring[k].string;
alpar@9 195 }
alpar@9 196 return NULL;
alpar@9 197 }
alpar@9 198
alpar@9 199 static int error(CPXENV *env, int errcode, ...)
alpar@9 200 { va_list arg;
alpar@9 201 char buffer[510];
alpar@9 202 xassert(env != NULL);
alpar@9 203 if (getintparam(env, CPX_PARAM_SCRIND) == CPX_ON)
alpar@9 204 { xassert(CPXgeterrorstring(env, errcode, buffer) == buffer);
alpar@9 205 va_start(arg, errcode);
alpar@9 206 vprintf(buffer, arg);
alpar@9 207 va_end(arg);
alpar@9 208 }
alpar@9 209 return errcode;
alpar@9 210 }
alpar@9 211
alpar@9 212 static int checkenv(CPXENV *env)
alpar@9 213 { int errcode;
alpar@9 214 if (env == NULL)
alpar@9 215 errcode = CPXERR_NO_ENVIRONMENT;
alpar@9 216 else
alpar@9 217 errcode = 0;
alpar@9 218 return errcode;
alpar@9 219 }
alpar@9 220
alpar@9 221 static checklp(CPXENV *env, CPXLP *lp)
alpar@9 222 { int errcode;
alpar@9 223 errcode = checkenv(env);
alpar@9 224 if (errcode) goto done;
alpar@9 225 if (lp == NULL)
alpar@9 226 errcode = error(env, CPXERR_NO_PROBLEM);
alpar@9 227 done: return errcode;
alpar@9 228 }
alpar@9 229
alpar@9 230 static void invalidate(CPXLP *lp)
alpar@9 231 { lp->stat = 0;
alpar@9 232 lp->meth = CPX_ALG_NONE;
alpar@9 233 return;
alpar@9 234 }
alpar@9 235
alpar@9 236 static void enlargerflag(CPXLP *lp)
alpar@9 237 { int m;
alpar@9 238 xassert(lp != NULL);
alpar@9 239 m = glp_get_num_rows(lp->prob);
alpar@9 240 if (lp->rflen < m)
alpar@9 241 { int rflen = lp->rflen;
alpar@9 242 char *rflag = lp->rflag;
alpar@9 243 while (lp->rflen < m)
alpar@9 244 { lp->rflen += lp->rflen;
alpar@9 245 xassert(lp->rflen > 0);
alpar@9 246 }
alpar@9 247 lp->rflag = xcalloc(lp->rflen, sizeof(char));
alpar@9 248 memcpy(lp->rflag, rflag, rflen);
alpar@9 249 xfree(rflag);
alpar@9 250 }
alpar@9 251 return;
alpar@9 252 }
alpar@9 253
alpar@9 254 static void enlargeiwork(CPXLP *lp, int len)
alpar@9 255 { xassert(len >= 0);
alpar@9 256 if (lp->iwlen < len)
alpar@9 257 { xfree(lp->iwork);
alpar@9 258 while (lp->iwlen < len)
alpar@9 259 { lp->iwlen += lp->iwlen;
alpar@9 260 xassert(lp->iwlen > 0);
alpar@9 261 }
alpar@9 262 lp->iwork = xcalloc(lp->iwlen, sizeof(int));
alpar@9 263 memset(lp->iwork, 0, lp->iwlen * sizeof(int));
alpar@9 264 }
alpar@9 265 return;
alpar@9 266 }
alpar@9 267
alpar@9 268 /**********************************************************************/
alpar@9 269
alpar@9 270 int CPXaddcols(CPXENV *env, CPXLP *lp, int ccnt, int nzcnt,
alpar@9 271 const double obj[], const int cmatbeg[], const int cmatind[],
alpar@9 272 const double cmatval[], const double lb[], const double ub[],
alpar@9 273 char *colname[])
alpar@9 274 { int j, k, m, n, beg, end, type, errcode;
alpar@9 275 double lbnd, ubnd;
alpar@9 276 errcode = checklp(env, lp);
alpar@9 277 if (errcode) goto done;
alpar@9 278 if (ccnt < 0 || nzcnt < 0)
alpar@9 279 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 280 goto done;
alpar@9 281 }
alpar@9 282 if (ccnt > 0)
alpar@9 283 { if (cmatbeg == NULL || cmatind == NULL || cmatval == NULL)
alpar@9 284 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 285 goto done;
alpar@9 286 }
alpar@9 287 }
alpar@9 288 m = glp_get_num_rows(lp->prob);
alpar@9 289 n = glp_get_num_cols(lp->prob);
alpar@9 290 enlargeiwork(lp, m);
alpar@9 291 for (j = 0; j < ccnt; j++)
alpar@9 292 { beg = cmatbeg[j];
alpar@9 293 if (j > 0 && !(cmatbeg[j-1] <= beg))
alpar@9 294 { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, j);
alpar@9 295 goto done;
alpar@9 296 }
alpar@9 297 if (!(0 <= beg && beg <= nzcnt))
alpar@9 298 { errcode = error(env, CPXERR_INDEX_RANGE);
alpar@9 299 goto done;
alpar@9 300 }
alpar@9 301 end = (j < ccnt-1 ? cmatbeg[j+1] : nzcnt);
alpar@9 302 for (k = beg; k < end; k++)
alpar@9 303 { if (!(0 <= cmatind[k] && cmatind[k] < m))
alpar@9 304 { errcode = error(env, CPXERR_ROW_INDEX_RANGE, k);
alpar@9 305 goto done;
alpar@9 306 }
alpar@9 307 }
alpar@9 308 errcode = 0;
alpar@9 309 for (k = beg; k < end; k++)
alpar@9 310 { if (lp->iwork[cmatind[k]])
alpar@9 311 { errcode = error(env, CPXERR_DUP_ENTRY);
alpar@9 312 break;
alpar@9 313 }
alpar@9 314 lp->iwork[cmatind[k]] = 1;
alpar@9 315 }
alpar@9 316 for (k = beg; k < end; k++)
alpar@9 317 lp->iwork[cmatind[k]] = 0;
alpar@9 318 if (errcode) goto done;
alpar@9 319 if (colname != NULL)
alpar@9 320 { if (colname[j] == NULL)
alpar@9 321 { errcode = error(env, CPXERR_NULL_NAME, j);
alpar@9 322 goto done;
alpar@9 323 }
alpar@9 324 }
alpar@9 325 }
alpar@9 326 errcode = 0;
alpar@9 327 invalidate(lp);
alpar@9 328 if (ccnt > 0)
alpar@9 329 glp_add_cols(lp->prob, ccnt);
alpar@9 330 for (j = 0; j < ccnt; j++)
alpar@9 331 { if (colname != NULL)
alpar@9 332 glp_set_col_name(lp->prob, n+j+1, colname[j]);
alpar@9 333 lbnd = (lb == NULL ? 0.0 : lb[j]);
alpar@9 334 ubnd = (ub == NULL ? +CPX_INFBOUND : ub[j]);
alpar@9 335 if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND)
alpar@9 336 type = GLP_FR;
alpar@9 337 else if (ubnd >= +CPX_INFBOUND)
alpar@9 338 type = GLP_LO;
alpar@9 339 else if (lbnd <= -CPX_INFBOUND)
alpar@9 340 type = GLP_UP;
alpar@9 341 else if (lbnd != ubnd)
alpar@9 342 type = GLP_DB;
alpar@9 343 else
alpar@9 344 type = GLP_FX;
alpar@9 345 glp_set_col_bnds(lp->prob, n+j+1, type, lbnd, ubnd);
alpar@9 346 if (obj != NULL)
alpar@9 347 glp_set_obj_coef(lp->prob, n+j+1, obj[j]);
alpar@9 348 beg = cmatbeg[j];
alpar@9 349 end = (j < ccnt-1 ? cmatbeg[j+1] : nzcnt);
alpar@9 350 for (k = beg; k < end; k++)
alpar@9 351 lp->iwork[k-beg] = cmatind[k]+1;
alpar@9 352 glp_set_mat_col(lp->prob, n+j+1, end-beg, lp->iwork-1,
alpar@9 353 cmatval+beg-1);
alpar@9 354 for (k = beg; k < end; k++)
alpar@9 355 lp->iwork[k-beg] = 0;
alpar@9 356 }
alpar@9 357 done: return errcode;
alpar@9 358 }
alpar@9 359
alpar@9 360 int CPXaddrows(CPXENV *env, CPXLP *lp, int ccnt, int rcnt, int nzcnt,
alpar@9 361 const double rhs[], const char sense[], const int rmatbeg[],
alpar@9 362 const int rmatind[], const double rmatval[], char *colname[],
alpar@9 363 char *rowname[])
alpar@9 364 { int i, j, k, m, n, beg, end, type, errcode;
alpar@9 365 double temp;
alpar@9 366 errcode = checklp(env, lp);
alpar@9 367 if (errcode) goto done;
alpar@9 368 if (ccnt < 0 || rcnt < 0 || nzcnt < 0)
alpar@9 369 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 370 goto done;
alpar@9 371 }
alpar@9 372 if (rcnt > 0)
alpar@9 373 { if (rmatbeg == NULL || rmatind == NULL || rmatval == NULL)
alpar@9 374 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 375 goto done;
alpar@9 376 }
alpar@9 377 }
alpar@9 378 m = glp_get_num_rows(lp->prob);
alpar@9 379 n = glp_get_num_cols(lp->prob);
alpar@9 380 enlargeiwork(lp, n+ccnt);
alpar@9 381 for (i = 0; i < rcnt; i++)
alpar@9 382 { if (sense != NULL)
alpar@9 383 { if (!(sense[i] == 'L' || sense[i] == 'E' ||
alpar@9 384 sense[i] == 'G' || sense[i] == 'R'))
alpar@9 385 { errcode = error(env, CPXERR_BAD_SENSE, i);
alpar@9 386 goto done;
alpar@9 387 }
alpar@9 388 }
alpar@9 389 beg = rmatbeg[i];
alpar@9 390 if (i > 0 && !(rmatbeg[i-1] <= beg))
alpar@9 391 { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, i);
alpar@9 392 goto done;
alpar@9 393 }
alpar@9 394 if (!(0 <= beg && beg <= nzcnt))
alpar@9 395 { errcode = error(env, CPXERR_INDEX_RANGE);
alpar@9 396 goto done;
alpar@9 397 }
alpar@9 398 end = (i < rcnt-1 ? rmatbeg[i+1] : nzcnt);
alpar@9 399 for (k = beg; k < end; k++)
alpar@9 400 { if (!(0 <= rmatind[k] && rmatind[k] < n+ccnt))
alpar@9 401 { errcode = error(env, CPXERR_COL_INDEX_RANGE, k);
alpar@9 402 goto done;
alpar@9 403 }
alpar@9 404 }
alpar@9 405 errcode = 0;
alpar@9 406 for (k = beg; k < end; k++)
alpar@9 407 { if (lp->iwork[rmatind[k]])
alpar@9 408 { errcode = error(env, CPXERR_DUP_ENTRY);
alpar@9 409 break;
alpar@9 410 }
alpar@9 411 lp->iwork[rmatind[k]] = 1;
alpar@9 412 }
alpar@9 413 for (k = beg; k < end; k++)
alpar@9 414 lp->iwork[rmatind[k]] = 0;
alpar@9 415 if (errcode) goto done;
alpar@9 416 if (rowname != NULL)
alpar@9 417 { if (rowname[i] == NULL)
alpar@9 418 { errcode = error(env, CPXERR_NULL_NAME, i);
alpar@9 419 goto done;
alpar@9 420 }
alpar@9 421 }
alpar@9 422 }
alpar@9 423 for (j = 0; j < ccnt; j++)
alpar@9 424 { if (colname != NULL)
alpar@9 425 { if (colname[j] == NULL)
alpar@9 426 { errcode = error(env, CPXERR_NULL_NAME, j);
alpar@9 427 goto done;
alpar@9 428 }
alpar@9 429 }
alpar@9 430 }
alpar@9 431 errcode = 0;
alpar@9 432 invalidate(lp);
alpar@9 433 if (rcnt > 0)
alpar@9 434 glp_add_rows(lp->prob, rcnt);
alpar@9 435 if (ccnt > 0)
alpar@9 436 glp_add_cols(lp->prob, ccnt);
alpar@9 437 enlargerflag(lp);
alpar@9 438 for (i = 0; i < rcnt; i++)
alpar@9 439 { if (rowname != NULL)
alpar@9 440 glp_set_row_name(lp->prob, m+i+1, rowname[i]);
alpar@9 441 temp = (rhs == NULL ? 0.0 : rhs[i]);
alpar@9 442 if (sense == NULL || sense[i] == 'E')
alpar@9 443 { lp->rflag[m+i] = RF_NOT_RANGED;
alpar@9 444 type = GLP_FX;
alpar@9 445 }
alpar@9 446 else if (sense[i] == 'L')
alpar@9 447 { lp->rflag[m+i] = RF_NOT_RANGED;
alpar@9 448 type = GLP_UP;
alpar@9 449 }
alpar@9 450 else if (sense[i] == 'G')
alpar@9 451 { lp->rflag[m+i] = RF_NOT_RANGED;
alpar@9 452 type = GLP_LO;
alpar@9 453 }
alpar@9 454 else if (sense[i] == 'R')
alpar@9 455 { lp->rflag[m+i] = RF_RANGED_POS;
alpar@9 456 type = GLP_FX;
alpar@9 457 }
alpar@9 458 else
alpar@9 459 xassert(sense != sense);
alpar@9 460 glp_set_row_bnds(lp->prob, m+i+1, type, temp, temp);
alpar@9 461 beg = rmatbeg[i];
alpar@9 462 end = (i < rcnt-1 ? rmatbeg[i+1] : nzcnt);
alpar@9 463 for (k = beg; k < end; k++)
alpar@9 464 lp->iwork[k-beg] = rmatind[k]+1;
alpar@9 465 glp_set_mat_row(lp->prob, m+i+1, end-beg, lp->iwork-1,
alpar@9 466 rmatval+beg-1);
alpar@9 467 for (k = beg; k < end; k++)
alpar@9 468 lp->iwork[k-beg] = 0;
alpar@9 469 }
alpar@9 470 for (j = 0; j < ccnt; j++)
alpar@9 471 { if (colname != NULL)
alpar@9 472 glp_set_col_name(lp->prob, n+j+1, colname[j]);
alpar@9 473 glp_set_col_bnds(lp->prob, n+j+1, GLP_LO, 0.0, 0.0);
alpar@9 474 }
alpar@9 475 done: return errcode;
alpar@9 476 }
alpar@9 477
alpar@9 478 int CPXbaropt(CPXENV *env, CPXLP *lp)
alpar@9 479 { xassert(env == env);
alpar@9 480 xassert(lp == lp);
alpar@9 481 xprintf("CPXbaropt: not implemented yet\n");
alpar@9 482 exit(EXIT_FAILURE);
alpar@9 483 return -1;
alpar@9 484 }
alpar@9 485
alpar@9 486 int CPXbinvrow(CPXENV *env, CPXLP *lp, int i, double y[])
alpar@9 487 { xassert(env == env);
alpar@9 488 xassert(lp == lp);
alpar@9 489 xassert(i == i);
alpar@9 490 xassert(y == y);
alpar@9 491 xprintf("CPXbinvrow: not implemented yet\n");
alpar@9 492 exit(EXIT_FAILURE);
alpar@9 493 return -1;
alpar@9 494 }
alpar@9 495
alpar@9 496 int CPXchgbds(CPXENV *env, CPXLP *lp, int cnt, const int indices[],
alpar@9 497 const char lu[], const double bd[])
alpar@9 498 { int j, n, type, errcode;
alpar@9 499 double lbnd, ubnd;
alpar@9 500 errcode = checklp(env, lp);
alpar@9 501 if (errcode) goto done;
alpar@9 502 if (cnt < 0)
alpar@9 503 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 504 goto done;
alpar@9 505 }
alpar@9 506 if (cnt > 0)
alpar@9 507 { if (indices == NULL || lu == NULL || bd == NULL)
alpar@9 508 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 509 goto done;
alpar@9 510 }
alpar@9 511 }
alpar@9 512 n = glp_get_num_cols(lp->prob);
alpar@9 513 for (j = 0; j < cnt; j++)
alpar@9 514 { if (!(0 <= indices[j] && indices[j] < n))
alpar@9 515 { errcode = error(env, CPXERR_COL_INDEX_RANGE, j);
alpar@9 516 goto done;
alpar@9 517 }
alpar@9 518 if (!(lu[j] == 'L' || lu[j] == 'U' || lu[j] == 'B'))
alpar@9 519 { errcode = error(env, CPXERR_BAD_LUB, j);
alpar@9 520 goto done;
alpar@9 521 }
alpar@9 522 }
alpar@9 523 errcode = 0;
alpar@9 524 invalidate(lp);
alpar@9 525 for (j = 0; j < cnt; j++)
alpar@9 526 { type = glp_get_col_type(lp->prob, indices[j]+1);
alpar@9 527 lbnd = glp_get_col_lb(lp->prob, indices[j]+1);
alpar@9 528 ubnd = glp_get_col_ub(lp->prob, indices[j]+1);
alpar@9 529 if (type == GLP_FR || type == GLP_UP)
alpar@9 530 lbnd = -CPX_INFBOUND;
alpar@9 531 if (type == GLP_FR || type == GLP_LO)
alpar@9 532 ubnd = +CPX_INFBOUND;
alpar@9 533 if (lu[j] == 'L')
alpar@9 534 lbnd = bd[j];
alpar@9 535 else if (lu[j] == 'U')
alpar@9 536 ubnd = bd[j];
alpar@9 537 else if (lu[j] == 'B')
alpar@9 538 lbnd = ubnd = bd[j];
alpar@9 539 else
alpar@9 540 xassert(lu != lu);
alpar@9 541 if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND)
alpar@9 542 type = GLP_FR;
alpar@9 543 else if (ubnd >= +CPX_INFBOUND)
alpar@9 544 type = GLP_LO;
alpar@9 545 else if (lbnd <= -CPX_INFBOUND)
alpar@9 546 type = GLP_UP;
alpar@9 547 else if (lbnd != ubnd)
alpar@9 548 type = GLP_DB;
alpar@9 549 else
alpar@9 550 type = GLP_FX;
alpar@9 551 glp_set_col_bnds(lp->prob, indices[j]+1, type, lbnd, ubnd);
alpar@9 552 }
alpar@9 553 done: return errcode;
alpar@9 554 }
alpar@9 555
alpar@9 556 int CPXchgcoeflist(CPXENV *env, CPXLP *lp, int numcoefs,
alpar@9 557 const int rowlist[], const int collist[], const double vallist[])
alpar@9 558 { int i, j, k, m, n, rcnt, ccnt, len, ptr, errcode;
alpar@9 559 int *head, *next, *ind;
alpar@9 560 double *val;
alpar@9 561 errcode = checklp(env, lp);
alpar@9 562 if (errcode) goto done;
alpar@9 563 if (numcoefs < 0)
alpar@9 564 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 565 goto done;
alpar@9 566 }
alpar@9 567 if (numcoefs == 0)
alpar@9 568 { errcode = 0;
alpar@9 569 goto done;
alpar@9 570 }
alpar@9 571 if (rowlist == NULL || collist == NULL || vallist == NULL)
alpar@9 572 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 573 goto done;
alpar@9 574 }
alpar@9 575 /* check triplets and determine the number of rows and columns
alpar@9 576 to be changed */
alpar@9 577 m = glp_get_num_rows(lp->prob);
alpar@9 578 n = glp_get_num_cols(lp->prob);
alpar@9 579 enlargeiwork(lp, m);
alpar@9 580 enlargeiwork(lp, n);
alpar@9 581 rcnt = ccnt = 0;
alpar@9 582 for (k = 0; k < numcoefs; k++)
alpar@9 583 { i = rowlist[k];
alpar@9 584 if (!(0 <= i && i < m))
alpar@9 585 { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i);
alpar@9 586 goto done;
alpar@9 587 }
alpar@9 588 if (!(lp->iwork[i] & 0x01))
alpar@9 589 rcnt++, lp->iwork[i] |= 0x01;
alpar@9 590 j = collist[k];
alpar@9 591 if (!(0 <= j && j < n))
alpar@9 592 { errcode = error(env, CPXERR_COL_INDEX_RANGE, j);
alpar@9 593 goto done;
alpar@9 594 }
alpar@9 595 if (!(lp->iwork[j] & 0x02))
alpar@9 596 ccnt++, lp->iwork[j] |= 0x02;
alpar@9 597 }
alpar@9 598 memset(lp->iwork, 0, m * sizeof(int));
alpar@9 599 memset(lp->iwork, 0, n * sizeof(int));
alpar@9 600 errcode = 0;
alpar@9 601 invalidate(lp);
alpar@9 602 if (rcnt <= ccnt)
alpar@9 603 { /* change the matrix by rows */
alpar@9 604 /* build the linked list of triplets:
alpar@9 605 head[i] is a pointer to first triplet for row i
alpar@9 606 next[k] is a pointer to next triplet for the same row */
alpar@9 607 head = xcalloc(m, sizeof(int));
alpar@9 608 for (i = 0; i < m; i++)
alpar@9 609 head[i] = -1;
alpar@9 610 next = xcalloc(numcoefs, sizeof(int));
alpar@9 611 for (k = 0; k < numcoefs; k++)
alpar@9 612 { i = rowlist[k];
alpar@9 613 next[k] = head[i];
alpar@9 614 head[i] = k;
alpar@9 615 }
alpar@9 616 /* check duplicate columns */
alpar@9 617 for (i = 0; i < m; i++)
alpar@9 618 { for (k = head[i]; k >= 0; k = next[k])
alpar@9 619 { j = collist[k];
alpar@9 620 if (lp->iwork[j])
alpar@9 621 { xfree(head);
alpar@9 622 xfree(next);
alpar@9 623 errcode = error(env, CPXERR_DUP_ENTRY);
alpar@9 624 goto done;
alpar@9 625 }
alpar@9 626 lp->iwork[j] = 1;
alpar@9 627 }
alpar@9 628 for (k = head[i]; k >= 0; k = next[k])
alpar@9 629 lp->iwork[collist[k]] = 0;
alpar@9 630 }
alpar@9 631 /* perform operation */
alpar@9 632 ind = xcalloc(1+n, sizeof(int));
alpar@9 633 val = xcalloc(1+n, sizeof(double));
alpar@9 634 for (i = 0; i < m; i++)
alpar@9 635 { if (head[i] < 0) continue;
alpar@9 636 len = glp_get_mat_row(lp->prob, i+1, ind, val);
alpar@9 637 for (ptr = 1; ptr <= len; ptr++)
alpar@9 638 { j = ind[ptr]-1;
alpar@9 639 xassert(lp->iwork[j] == 0);
alpar@9 640 lp->iwork[j] = ptr;
alpar@9 641 }
alpar@9 642 for (k = head[i]; k >= 0; k = next[k])
alpar@9 643 { j = collist[k];
alpar@9 644 if (lp->iwork[j] == 0)
alpar@9 645 lp->iwork[j] = ++len;
alpar@9 646 ptr = lp->iwork[j];
alpar@9 647 ind[ptr] = j+1, val[ptr] = vallist[k];
alpar@9 648 }
alpar@9 649 glp_set_mat_row(lp->prob, i+1, len, ind, val);
alpar@9 650 for (ptr = 1; ptr <= len; ptr++)
alpar@9 651 lp->iwork[ind[ptr]-1] = 0;
alpar@9 652 }
alpar@9 653 }
alpar@9 654 else
alpar@9 655 { /* change the matrix by columns */
alpar@9 656 /* build the linked lists of triplets:
alpar@9 657 head[j] is a pointer to first triplet for column j
alpar@9 658 next[k] is a pointer to next triplet for the same column */
alpar@9 659 head = xcalloc(n, sizeof(int));
alpar@9 660 for (j = 0; j < n; j++)
alpar@9 661 head[j] = -1;
alpar@9 662 next = xcalloc(numcoefs, sizeof(int));
alpar@9 663 for (k = 0; k < numcoefs; k++)
alpar@9 664 { j = collist[k];
alpar@9 665 next[k] = head[j];
alpar@9 666 head[j] = k;
alpar@9 667 }
alpar@9 668 /* check duplicate rows */
alpar@9 669 for (j = 0; j < n; j++)
alpar@9 670 { for (k = head[j]; k >= 0; k = next[k])
alpar@9 671 { i = rowlist[k];
alpar@9 672 if (lp->iwork[i])
alpar@9 673 { xfree(head);
alpar@9 674 xfree(next);
alpar@9 675 errcode = error(env, CPXERR_DUP_ENTRY);
alpar@9 676 goto done;
alpar@9 677 }
alpar@9 678 lp->iwork[i] = 1;
alpar@9 679 }
alpar@9 680 for (k = head[j]; k >= 0; k = next[k])
alpar@9 681 lp->iwork[rowlist[k]] = 0;
alpar@9 682 }
alpar@9 683 /* perform operation */
alpar@9 684 ind = xcalloc(1+m, sizeof(int));
alpar@9 685 val = xcalloc(1+m, sizeof(double));
alpar@9 686 for (j = 0; j < n; j++)
alpar@9 687 { if (head[j] < 0) continue;
alpar@9 688 len = glp_get_mat_col(lp->prob, j+1, ind, val);
alpar@9 689 for (ptr = 1; ptr <= len; ptr++)
alpar@9 690 { i = ind[ptr]-1;
alpar@9 691 xassert(lp->iwork[i] == 0);
alpar@9 692 lp->iwork[i] = ptr;
alpar@9 693 }
alpar@9 694 for (k = head[j]; k >= 0; k = next[k])
alpar@9 695 { i = rowlist[k];
alpar@9 696 if (lp->iwork[i] == 0)
alpar@9 697 lp->iwork[i] = ++len;
alpar@9 698 ptr = lp->iwork[i];
alpar@9 699 ind[ptr] = i+1, val[ptr] = vallist[k];
alpar@9 700 }
alpar@9 701 glp_set_mat_col(lp->prob, j+1, len, ind, val);
alpar@9 702 for (ptr = 1; ptr <= len; ptr++)
alpar@9 703 lp->iwork[ind[ptr]-1] = 0;
alpar@9 704 }
alpar@9 705 }
alpar@9 706 xfree(head);
alpar@9 707 xfree(next);
alpar@9 708 xfree(ind);
alpar@9 709 xfree(val);
alpar@9 710 done: return errcode;
alpar@9 711 }
alpar@9 712
alpar@9 713 void CPXchgobjsen(CPXENV *env, CPXLP *lp, int maxormin)
alpar@9 714 { int errcode;
alpar@9 715 errcode = checklp(env, lp);
alpar@9 716 if (errcode) goto done;
alpar@9 717 if (!(maxormin == CPX_MIN || maxormin == CPX_MAX))
alpar@9 718 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 719 goto done;
alpar@9 720 }
alpar@9 721 errcode = 0;
alpar@9 722 invalidate(lp);
alpar@9 723 if (maxormin == CPX_MIN)
alpar@9 724 glp_set_obj_dir(lp->prob, GLP_MIN);
alpar@9 725 else
alpar@9 726 glp_set_obj_dir(lp->prob, GLP_MAX);
alpar@9 727 done: xassert(errcode == errcode);
alpar@9 728 return;
alpar@9 729 }
alpar@9 730
alpar@9 731 int CPXchgsense(CPXENV *env, CPXLP *lp, int cnt, const int indices[],
alpar@9 732 const char sense[])
alpar@9 733 { int i, m, type, errcode;
alpar@9 734 double rhs;
alpar@9 735 errcode = checklp(env, lp);
alpar@9 736 if (errcode) goto done;
alpar@9 737 if (cnt < 0)
alpar@9 738 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 739 goto done;
alpar@9 740 }
alpar@9 741 if (cnt > 0 && (indices == NULL || sense == NULL))
alpar@9 742 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 743 goto done;
alpar@9 744 }
alpar@9 745 m = glp_get_num_rows(lp->prob);
alpar@9 746 for (i = 0; i < cnt; i++)
alpar@9 747 { if (!(0 <= indices[i] && indices[i] < m))
alpar@9 748 { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i);
alpar@9 749 goto done;
alpar@9 750 }
alpar@9 751 if (!(sense[i] == 'L' || sense[i] == 'E' || sense[i] == 'G' ||
alpar@9 752 sense[i] == 'R'))
alpar@9 753 { errcode = error(env, CPXERR_BAD_SENSE, i);
alpar@9 754 goto done;
alpar@9 755 }
alpar@9 756 }
alpar@9 757 errcode = 0;
alpar@9 758 invalidate(lp);
alpar@9 759 for (i = 0; i < cnt; i++)
alpar@9 760 { type = glp_get_row_type(lp->prob, indices[i]+1);
alpar@9 761 if (lp->rflag[indices[i]] == RF_NOT_RANGED)
alpar@9 762 { if (type == GLP_LO || type == GLP_FX)
alpar@9 763 rhs = glp_get_row_lb(lp->prob, indices[i]+1);
alpar@9 764 else if (type == GLP_UP)
alpar@9 765 rhs = glp_get_row_ub(lp->prob, indices[i]+1);
alpar@9 766 else
alpar@9 767 xassert(type != type);
alpar@9 768 }
alpar@9 769 else if (lp->rflag[indices[i]] == RF_RANGED_POS)
alpar@9 770 { xassert(type == GLP_DB || type == GLP_FX);
alpar@9 771 rhs = glp_get_row_lb(lp->prob, indices[i]+1);
alpar@9 772 }
alpar@9 773 else if (lp->rflag[indices[i]] == RF_RANGED_NEG)
alpar@9 774 { xassert(type == GLP_DB);
alpar@9 775 rhs = glp_get_row_ub(lp->prob, indices[i]+1);
alpar@9 776 }
alpar@9 777 else
alpar@9 778 xassert(lp != lp);
alpar@9 779 if (sense[i] == 'L')
alpar@9 780 { lp->rflag[indices[i]] = RF_NOT_RANGED;
alpar@9 781 type = GLP_UP;
alpar@9 782 }
alpar@9 783 else if (sense[i] == 'E')
alpar@9 784 { lp->rflag[indices[i]] = RF_NOT_RANGED;
alpar@9 785 type = GLP_FX;
alpar@9 786 }
alpar@9 787 else if (sense[i] == 'G')
alpar@9 788 { lp->rflag[indices[i]] = RF_NOT_RANGED;
alpar@9 789 type = GLP_LO;
alpar@9 790 }
alpar@9 791 else if (sense[i] == 'R')
alpar@9 792 { lp->rflag[indices[i]] = RF_RANGED_POS;
alpar@9 793 type = GLP_FX;
alpar@9 794 }
alpar@9 795 else
alpar@9 796 xassert(sense != sense);
alpar@9 797 glp_set_row_bnds(lp->prob, indices[i]+1, type, rhs, rhs);
alpar@9 798 }
alpar@9 799 done: return errcode;
alpar@9 800 }
alpar@9 801
alpar@9 802 int CPXcloseCPLEX(CPXENV **_env)
alpar@9 803 { CPXENV *env;
alpar@9 804 CPXLP *lp;
alpar@9 805 int errcode;
alpar@9 806 if (_env == NULL)
alpar@9 807 { errcode = CPXERR_NULL_POINTER;
alpar@9 808 goto done;
alpar@9 809 }
alpar@9 810 env = *_env;
alpar@9 811 errcode = checkenv(env);
alpar@9 812 if (errcode) goto done;
alpar@9 813 while (env->list != NULL)
alpar@9 814 { lp = env->list;
alpar@9 815 errcode = CPXfreeprob(env, &lp);
alpar@9 816 xassert(!errcode);
alpar@9 817 }
alpar@9 818 xfree(env->intparam);
alpar@9 819 xfree(env->dblparam);
alpar@9 820 xfree(env);
alpar@9 821 *_env = NULL;
alpar@9 822 errcode = 0;
alpar@9 823 done: return errcode;
alpar@9 824 }
alpar@9 825
alpar@9 826 int CPXcopybase(CPXENV *env, CPXLP *lp, const int cstat[],
alpar@9 827 const int rstat[])
alpar@9 828 { int i, j, m, n, stat, errcode;
alpar@9 829 errcode = checklp(env, lp);
alpar@9 830 if (errcode) goto done;
alpar@9 831 m = glp_get_num_rows(lp->prob);
alpar@9 832 n = glp_get_num_cols(lp->prob);
alpar@9 833 if (m > 0 && rstat == NULL || n > 0 && cstat == NULL)
alpar@9 834 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 835 goto done;
alpar@9 836 }
alpar@9 837 for (i = 0; i < m; i++)
alpar@9 838 { if (!(rstat[i] == CPX_AT_LOWER || rstat[i] == CPX_BASIC ||
alpar@9 839 rstat[i] == CPX_AT_UPPER))
alpar@9 840 { errcode = error(env, CPXERR_BAD_STATUS, i);
alpar@9 841 goto done;
alpar@9 842 }
alpar@9 843 }
alpar@9 844 for (j = 0; j < n; j++)
alpar@9 845 { if (!(cstat[j] == CPX_AT_LOWER || cstat[j] == CPX_BASIC ||
alpar@9 846 cstat[j] == CPX_AT_UPPER || cstat[j] == CPX_FREE_SUPER))
alpar@9 847 { errcode = error(env, CPXERR_BAD_STATUS, j);
alpar@9 848 goto done;
alpar@9 849 }
alpar@9 850 }
alpar@9 851 errcode = 0;
alpar@9 852 invalidate(lp);
alpar@9 853 for (i = 0; i < m; i++)
alpar@9 854 { if (rstat[i] == CPX_AT_LOWER)
alpar@9 855 stat = GLP_NL;
alpar@9 856 else if (rstat[i] == CPX_BASIC)
alpar@9 857 stat = GLP_BS;
alpar@9 858 else if (rstat[i] == CPX_AT_UPPER)
alpar@9 859 stat = GLP_NU;
alpar@9 860 else
alpar@9 861 xassert(rstat != rstat);
alpar@9 862 glp_set_row_stat(lp->prob, i+1, stat);
alpar@9 863 }
alpar@9 864 for (j = 0; j < n; j++)
alpar@9 865 { if (cstat[j] == CPX_AT_LOWER)
alpar@9 866 stat = GLP_NL;
alpar@9 867 else if (cstat[j] == CPX_BASIC)
alpar@9 868 stat = GLP_BS;
alpar@9 869 else if (cstat[j] == CPX_AT_UPPER)
alpar@9 870 stat = GLP_NU;
alpar@9 871 else if (cstat[j] == CPX_FREE_SUPER)
alpar@9 872 stat = GLP_NF;
alpar@9 873 else
alpar@9 874 xassert(cstat != cstat);
alpar@9 875 glp_set_col_stat(lp->prob, j+1, stat);
alpar@9 876 }
alpar@9 877 done: return errcode;
alpar@9 878 }
alpar@9 879
alpar@9 880 int CPXcopybasednorms(CPXENV *env, CPXLP *lp, const int cstat[],
alpar@9 881 const int rstat[], const double dnorm[])
alpar@9 882 { int errcode;
alpar@9 883 errcode = CPXcopybase(env, lp, cstat, rstat);
alpar@9 884 xassert(dnorm == dnorm);
alpar@9 885 return errcode;
alpar@9 886 }
alpar@9 887
alpar@9 888 int CPXcopylp(CPXENV *env, CPXLP *lp, int numcols, int numrows,
alpar@9 889 int objsen, const double obj[], const double rhs[],
alpar@9 890 const char sense[], const int matbeg[], const int matcnt[],
alpar@9 891 const int matind[], const double matval[], const double lb[],
alpar@9 892 const double ub[], const double rngval[])
alpar@9 893 { int errcode;
alpar@9 894 errcode = CPXcopylpwnames(env, lp, numcols, numrows, objsen, obj,
alpar@9 895 rhs, sense, matbeg, matcnt, matind, matval, lb, ub, rngval,
alpar@9 896 NULL, NULL);
alpar@9 897 return errcode;
alpar@9 898 }
alpar@9 899
alpar@9 900 int CPXcopylpwnames(CPXENV *env, CPXLP *lp, int numcols, int numrows,
alpar@9 901 int objsen, const double obj[], const double rhs[],
alpar@9 902 const char sense[], const int matbeg[], const int matcnt[],
alpar@9 903 const int matind[], const double matval[], const double lb[],
alpar@9 904 const double ub[], const double rngval[], char *colname[],
alpar@9 905 char *rowname[])
alpar@9 906 { int i, j, k, beg, end, type, errcode;
alpar@9 907 double lbnd, ubnd;
alpar@9 908 char name[255+1];
alpar@9 909 errcode = checklp(env, lp);
alpar@9 910 if (errcode) goto done;
alpar@9 911 if (numcols < 0 || numrows < 0)
alpar@9 912 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 913 goto done;
alpar@9 914 }
alpar@9 915 if (!(objsen == CPX_MIN || objsen == CPX_MAX))
alpar@9 916 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 917 goto done;
alpar@9 918 }
alpar@9 919 if (numcols > 0)
alpar@9 920 { if (matbeg == NULL || matcnt == NULL || matind == NULL ||
alpar@9 921 matval == NULL)
alpar@9 922 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 923 goto done;
alpar@9 924 }
alpar@9 925 }
alpar@9 926 for (i = 0; i < numrows; i++)
alpar@9 927 { if (sense != NULL)
alpar@9 928 { if (!(sense[i] == 'L' || sense[i] == 'E' ||
alpar@9 929 sense[i] == 'G' || sense[i] == 'R'))
alpar@9 930 { errcode = error(env, CPXERR_BAD_SENSE, i);
alpar@9 931 goto done;
alpar@9 932 }
alpar@9 933 }
alpar@9 934 if (rowname != NULL)
alpar@9 935 { if (rowname[i] == NULL)
alpar@9 936 { errcode = error(env, CPXERR_NULL_NAME, i);
alpar@9 937 goto done;
alpar@9 938 }
alpar@9 939 }
alpar@9 940 }
alpar@9 941 enlargeiwork(lp, numrows);
alpar@9 942 for (j = 0; j < numcols; j++)
alpar@9 943 { beg = matbeg[j];
alpar@9 944 if (j > 0 && !(matbeg[j-1] <= beg))
alpar@9 945 { errcode = error(env, CPXERR_ARRAY_NOT_ASCENDING, j);
alpar@9 946 goto done;
alpar@9 947 }
alpar@9 948 if (beg < 0)
alpar@9 949 { errcode = error(env, CPXERR_INDEX_RANGE);
alpar@9 950 goto done;
alpar@9 951 }
alpar@9 952 end = beg + matcnt[j];
alpar@9 953 if (!(beg <= end) || j < numcols-1 && !(end <= matbeg[j+1]))
alpar@9 954 { errcode = error(env, CPXERR_COUNT_RANGE, j);
alpar@9 955 goto done;
alpar@9 956 }
alpar@9 957 for (k = beg; k < end; k++)
alpar@9 958 { if (!(0 <= matind[k] && matind[k] < numrows))
alpar@9 959 { errcode = error(env, CPXERR_ROW_INDEX_RANGE, k);
alpar@9 960 goto done;
alpar@9 961 }
alpar@9 962 }
alpar@9 963 errcode = 0;
alpar@9 964 for (k = beg; k < end; k++)
alpar@9 965 { if (lp->iwork[matind[k]])
alpar@9 966 { errcode = error(env, CPXERR_DUP_ENTRY);
alpar@9 967 break;
alpar@9 968 }
alpar@9 969 lp->iwork[matind[k]] = 1;
alpar@9 970 }
alpar@9 971 for (k = beg; k < end; k++)
alpar@9 972 lp->iwork[matind[k]] = 0;
alpar@9 973 if (errcode) goto done;
alpar@9 974 if (colname != NULL)
alpar@9 975 { if (colname[j] != NULL)
alpar@9 976 { errcode = error(env, CPXERR_NULL_NAME, j);
alpar@9 977 goto done;
alpar@9 978 }
alpar@9 979 }
alpar@9 980 }
alpar@9 981 errcode = 0;
alpar@9 982 invalidate(lp);
alpar@9 983 if (glp_get_prob_name(lp->prob) == NULL)
alpar@9 984 name[0] = '\0';
alpar@9 985 else
alpar@9 986 strcpy(name, glp_get_prob_name(lp->prob));
alpar@9 987 glp_erase_prob(lp->prob);
alpar@9 988 glp_set_prob_name(lp->prob, name);
alpar@9 989 if (objsen == CPX_MIN)
alpar@9 990 glp_set_obj_dir(lp->prob, GLP_MIN);
alpar@9 991 else if (objsen == CPX_MAX)
alpar@9 992 glp_set_obj_dir(lp->prob, GLP_MAX);
alpar@9 993 else
alpar@9 994 xassert(objsen != objsen);
alpar@9 995 if (numrows > 0)
alpar@9 996 glp_add_rows(lp->prob, numrows);
alpar@9 997 enlargerflag(lp);
alpar@9 998 for (i = 0; i < numrows; i++)
alpar@9 999 { if (rowname != NULL)
alpar@9 1000 glp_set_row_name(lp->prob, i+1, rowname[i]);
alpar@9 1001 lbnd = ubnd = (rhs == NULL ? 0.0 : rhs[i]);
alpar@9 1002 if (sense == NULL || sense[i] == 'E')
alpar@9 1003 { lp->rflag[i] = RF_NOT_RANGED;
alpar@9 1004 type = GLP_FX;
alpar@9 1005 }
alpar@9 1006 else if (sense[i] == 'L')
alpar@9 1007 { lp->rflag[i] = RF_NOT_RANGED;
alpar@9 1008 type = GLP_UP;
alpar@9 1009 }
alpar@9 1010 else if (sense[i] == 'G')
alpar@9 1011 { lp->rflag[i] = RF_NOT_RANGED;
alpar@9 1012 type = GLP_LO;
alpar@9 1013 }
alpar@9 1014 else if (sense[i] == 'R')
alpar@9 1015 { if (rngval == NULL || rngval[i] == 0.0)
alpar@9 1016 { lp->rflag[i] = RF_RANGED_POS;
alpar@9 1017 type = GLP_FX;
alpar@9 1018 }
alpar@9 1019 else if (rngval[i] > 0.0)
alpar@9 1020 { lp->rflag[i] = RF_RANGED_POS;
alpar@9 1021 type = GLP_DB;
alpar@9 1022 ubnd += rngval[i];
alpar@9 1023 }
alpar@9 1024 else /* rngval[i] < 0.0 */
alpar@9 1025 { lp->rflag[i] = RF_RANGED_NEG;
alpar@9 1026 type = GLP_DB;
alpar@9 1027 lbnd += rngval[i];
alpar@9 1028 }
alpar@9 1029 }
alpar@9 1030 else
alpar@9 1031 xassert(sense != sense);
alpar@9 1032 glp_set_row_bnds(lp->prob, i+1, type, lbnd, ubnd);
alpar@9 1033 }
alpar@9 1034 if (numcols > 0)
alpar@9 1035 glp_add_cols(lp->prob, numcols);
alpar@9 1036 for (j = 0; j < numcols; j++)
alpar@9 1037 { if (colname != NULL)
alpar@9 1038 glp_set_col_name(lp->prob, j+1, colname[j]);
alpar@9 1039 lbnd = (lb == NULL ? 0.0 : lb[j]);
alpar@9 1040 ubnd = (ub == NULL ? +CPX_INFBOUND : ub[j]);
alpar@9 1041 if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND)
alpar@9 1042 type = GLP_FR;
alpar@9 1043 else if (ubnd >= +CPX_INFBOUND)
alpar@9 1044 type = GLP_LO;
alpar@9 1045 else if (lbnd <= -CPX_INFBOUND)
alpar@9 1046 type = GLP_UP;
alpar@9 1047 else if (lbnd != ubnd)
alpar@9 1048 type = GLP_DB;
alpar@9 1049 else
alpar@9 1050 type = GLP_FX;
alpar@9 1051 glp_set_col_bnds(lp->prob, j+1, type, lbnd, ubnd);
alpar@9 1052 if (obj != NULL)
alpar@9 1053 glp_set_obj_coef(lp->prob, j+1, obj[j]);
alpar@9 1054 beg = matbeg[j];
alpar@9 1055 end = beg + matcnt[j];
alpar@9 1056 for (k = beg; k < end; k++)
alpar@9 1057 lp->iwork[k-beg] = matind[k]+1;
alpar@9 1058 glp_set_mat_col(lp->prob, j+1, end-beg, lp->iwork-1,
alpar@9 1059 matval+beg-1);
alpar@9 1060 for (k = beg; k < end; k++)
alpar@9 1061 lp->iwork[k-beg] = 0;
alpar@9 1062 }
alpar@9 1063 done: return errcode;
alpar@9 1064 }
alpar@9 1065
alpar@9 1066 CPXLP *CPXcreateprob(CPXENV *env, int *status, const char *probname)
alpar@9 1067 { CPXLP *lp = NULL;
alpar@9 1068 int errcode;
alpar@9 1069 errcode = checkenv(env);
alpar@9 1070 if (errcode) goto done;
alpar@9 1071 lp = xmalloc(sizeof(struct CPXLP));
alpar@9 1072 lp->env = env;
alpar@9 1073 lp->prob = glp_create_prob();
alpar@9 1074 glp_set_prob_name(lp->prob, probname);
alpar@9 1075 lp->rflen = 100;
alpar@9 1076 lp->rflag = xcalloc(lp->rflen, sizeof(char));
alpar@9 1077 lp->iwlen = 100;
alpar@9 1078 lp->iwork = xcalloc(lp->iwlen, sizeof(int));
alpar@9 1079 memset(lp->iwork, 0, lp->iwlen * sizeof(int));
alpar@9 1080 lp->link = env->list;
alpar@9 1081 env->list = lp;
alpar@9 1082 invalidate(lp);
alpar@9 1083 done: if (status != NULL) *status = errcode;
alpar@9 1084 return lp;
alpar@9 1085 }
alpar@9 1086
alpar@9 1087 int CPXdelcols(CPXENV *env, CPXLP *lp, int begin, int end)
alpar@9 1088 { int j, n, errcode;
alpar@9 1089 errcode = checklp(env, lp);
alpar@9 1090 if (errcode) goto done;
alpar@9 1091 n = glp_get_num_cols(lp->prob);
alpar@9 1092 if (!(0 <= begin && begin <= end && end < n))
alpar@9 1093 { errcode = error(env, CPXERR_INDEX_RANGE);
alpar@9 1094 goto done;
alpar@9 1095 }
alpar@9 1096 errcode = 0;
alpar@9 1097 invalidate(lp);
alpar@9 1098 enlargeiwork(lp, end-begin+1);
alpar@9 1099 for (j = begin; j <= end; j++)
alpar@9 1100 lp->iwork[j-begin] = j+1;
alpar@9 1101 glp_del_cols(lp->prob, end-begin+1, lp->iwork-1);
alpar@9 1102 for (j = begin; j <= end; j++)
alpar@9 1103 lp->iwork[j-begin] = 0;
alpar@9 1104 done: return errcode;
alpar@9 1105 }
alpar@9 1106
alpar@9 1107 int CPXdelrows(CPXENV *env, CPXLP *lp, int begin, int end)
alpar@9 1108 { int i, m, errcode;
alpar@9 1109 errcode = checklp(env, lp);
alpar@9 1110 if (errcode) goto done;
alpar@9 1111 m = glp_get_num_rows(lp->prob);
alpar@9 1112 if (!(0 <= begin && begin <= end && end < m))
alpar@9 1113 { errcode = error(env, CPXERR_INDEX_RANGE);
alpar@9 1114 goto done;
alpar@9 1115 }
alpar@9 1116 errcode = 0;
alpar@9 1117 invalidate(lp);
alpar@9 1118 enlargeiwork(lp, end-begin+1);
alpar@9 1119 for (i = begin; i <= end; i++)
alpar@9 1120 lp->iwork[i-begin] = i+1;
alpar@9 1121 glp_del_rows(lp->prob, end-begin+1, lp->iwork-1);
alpar@9 1122 for (i = begin; i <= end; i++)
alpar@9 1123 lp->iwork[i-begin] = 0;
alpar@9 1124 for (i = end+1; i < m; i++)
alpar@9 1125 lp->rflag[i-(end-begin+1)] = lp->rflag[i];
alpar@9 1126 done: return errcode;
alpar@9 1127 }
alpar@9 1128
alpar@9 1129 int CPXdelsetcols(CPXENV *env, CPXLP *lp, int delstat[])
alpar@9 1130 { xassert(env == env);
alpar@9 1131 xassert(lp == lp);
alpar@9 1132 xassert(delstat == delstat);
alpar@9 1133 xprintf("CPXdelsetcols: not implemented yet\n");
alpar@9 1134 exit(EXIT_FAILURE);
alpar@9 1135 return -1;
alpar@9 1136 }
alpar@9 1137
alpar@9 1138 int CPXdelsetrows(CPXENV *env, CPXLP *lp, int delstat[])
alpar@9 1139 { int i, m, cnt, ind, errcode;
alpar@9 1140 errcode = checklp(env, lp);
alpar@9 1141 if (errcode) goto done;
alpar@9 1142 m = glp_get_num_rows(lp->prob);
alpar@9 1143 if (m > 0 && delstat == NULL)
alpar@9 1144 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 1145 goto done;
alpar@9 1146 }
alpar@9 1147 errcode = 0;
alpar@9 1148 invalidate(lp);
alpar@9 1149 enlargeiwork(lp, m);
alpar@9 1150 cnt = ind = 0;
alpar@9 1151 for (i = 0; i < m; i++)
alpar@9 1152 { if (delstat[i] == 1)
alpar@9 1153 { delstat[i] = -1;
alpar@9 1154 lp->iwork[cnt++] = i+1;
alpar@9 1155 }
alpar@9 1156 else
alpar@9 1157 { delstat[i] = ind;
alpar@9 1158 lp->rflag[ind++] = lp->rflag[i];
alpar@9 1159 }
alpar@9 1160 }
alpar@9 1161 if (cnt > 0)
alpar@9 1162 glp_del_rows(lp->prob, cnt, lp->iwork-1);
alpar@9 1163 for (i = 0; i < cnt; i++)
alpar@9 1164 lp->iwork[i] = 0;
alpar@9 1165 done: return errcode;
alpar@9 1166 }
alpar@9 1167
alpar@9 1168 int CPXdualopt(CPXENV *env, CPXLP *lp);
alpar@9 1169
alpar@9 1170 int CPXfreeprob(CPXENV *env, CPXLP **_lp)
alpar@9 1171 { CPXLP *lp;
alpar@9 1172 int errcode;
alpar@9 1173 errcode = checkenv(env);
alpar@9 1174 if (errcode) goto done;
alpar@9 1175 if (_lp == NULL)
alpar@9 1176 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 1177 goto done;
alpar@9 1178 }
alpar@9 1179 lp = *_lp;
alpar@9 1180 errcode = checklp(env, lp);
alpar@9 1181 if (errcode) goto done;
alpar@9 1182 errcode = 0;
alpar@9 1183 env = lp->env;
alpar@9 1184 if (env->list == lp)
alpar@9 1185 env->list = lp->link;
alpar@9 1186 else
alpar@9 1187 { CPXLP *pp;
alpar@9 1188 for (pp = env->list; pp != NULL; pp = pp->link)
alpar@9 1189 if (pp->link == lp) break;
alpar@9 1190 xassert(pp != NULL);
alpar@9 1191 pp->link = lp->link;
alpar@9 1192 }
alpar@9 1193 glp_delete_prob(lp->prob);
alpar@9 1194 xfree(lp->rflag);
alpar@9 1195 xfree(lp->iwork);
alpar@9 1196 xfree(lp);
alpar@9 1197 *_lp = NULL;
alpar@9 1198 done: return errcode;
alpar@9 1199 }
alpar@9 1200
alpar@9 1201 int CPXgetbase(CPXENV *env, CPXLP *lp, int cstat[], int rstat[])
alpar@9 1202 { int i, j, m, n, stat, errcode;
alpar@9 1203 errcode = checklp(env, lp);
alpar@9 1204 if (errcode) goto done;
alpar@9 1205 if (!lp->stat)
alpar@9 1206 { errcode = error(env, CPXERR_NO_SOLN);
alpar@9 1207 goto done;
alpar@9 1208 }
alpar@9 1209 if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL)
alpar@9 1210 ;
alpar@9 1211 else
alpar@9 1212 { errcode = error(env, CPXERR_NO_BASIC_SOLN);
alpar@9 1213 goto done;
alpar@9 1214 }
alpar@9 1215 errcode = 0;
alpar@9 1216 if (rstat != NULL)
alpar@9 1217 { m = glp_get_num_rows(lp->prob);
alpar@9 1218 for (i = 0; i < m; i++)
alpar@9 1219 { stat = glp_get_row_stat(lp->prob, i+1);
alpar@9 1220 if (stat == GLP_BS)
alpar@9 1221 rstat[i] = CPX_BASIC;
alpar@9 1222 else if (lp->rflag[i] == RF_NOT_RANGED || stat != GLP_NU)
alpar@9 1223 rstat[i] = CPX_AT_LOWER;
alpar@9 1224 else
alpar@9 1225 rstat[i] = CPX_AT_UPPER;
alpar@9 1226 }
alpar@9 1227 }
alpar@9 1228 if (cstat != NULL)
alpar@9 1229 { n = glp_get_num_cols(lp->prob);
alpar@9 1230 for (j = 0; j < n; j++)
alpar@9 1231 { stat = glp_get_col_stat(lp->prob, j+1);
alpar@9 1232 if (stat == GLP_BS)
alpar@9 1233 cstat[j] = CPX_BASIC;
alpar@9 1234 else if (stat == GLP_NU)
alpar@9 1235 cstat[j] = CPX_AT_UPPER;
alpar@9 1236 else if (stat == GLP_NF)
alpar@9 1237 cstat[j] = CPX_FREE_SUPER;
alpar@9 1238 else
alpar@9 1239 cstat[j] = CPX_AT_LOWER;
alpar@9 1240 }
alpar@9 1241 }
alpar@9 1242 done: return errcode;
alpar@9 1243 }
alpar@9 1244
alpar@9 1245 int CPXgetbasednorms(CPXENV *env, CPXLP *lp, int cstat[], int rstat[],
alpar@9 1246 double dnorm[])
alpar@9 1247 { int i, m, errcode;
alpar@9 1248 errcode = CPXgetbase(env, lp, cstat, rstat);
alpar@9 1249 if (errcode) goto done;
alpar@9 1250 if (dnorm != NULL)
alpar@9 1251 { m = glp_get_num_rows(lp->prob);
alpar@9 1252 for (i = 0; i < m; i++) dnorm[i] = 1.0;
alpar@9 1253 }
alpar@9 1254 done: return errcode;
alpar@9 1255 }
alpar@9 1256
alpar@9 1257 int CPXgetbhead(CPXENV *env, CPXLP *lp, int head[], double x[])
alpar@9 1258 { xassert(env == env);
alpar@9 1259 xassert(lp == lp);
alpar@9 1260 xassert(head == head);
alpar@9 1261 xassert(x == x);
alpar@9 1262 xprintf("CPXgetbhead: not implemented yet\n");
alpar@9 1263 exit(EXIT_FAILURE);
alpar@9 1264 return -1;
alpar@9 1265 }
alpar@9 1266
alpar@9 1267 int CPXgetdblparam(CPXENV *env, int whichparam, double *value)
alpar@9 1268 { int k, errcode;
alpar@9 1269 errcode = checkenv(env);
alpar@9 1270 if (errcode) goto done;
alpar@9 1271 k = finddblparam(whichparam);
alpar@9 1272 if (k < 0)
alpar@9 1273 { errcode = error(env, CPXERR_BAD_PARAM_NUM);
alpar@9 1274 goto done;
alpar@9 1275 }
alpar@9 1276 errcode = 0;
alpar@9 1277 if (value != NULL)
alpar@9 1278 *value = env->dblparam[k];
alpar@9 1279 done: return errcode;
alpar@9 1280 }
alpar@9 1281
alpar@9 1282 int CPXgetdj(CPXENV *env, CPXLP *lp, double dj[], int begin, int end)
alpar@9 1283 { int j, n, errcode;
alpar@9 1284 errcode = checklp(env, lp);
alpar@9 1285 if (errcode) goto done;
alpar@9 1286 n = glp_get_num_cols(lp->prob);
alpar@9 1287 if (!(0 <= begin && begin <= end && end < n))
alpar@9 1288 { errcode = error(env, CPXERR_INDEX_RANGE);
alpar@9 1289 goto done;
alpar@9 1290 }
alpar@9 1291 if (!lp->stat)
alpar@9 1292 { errcode = error(env, CPXERR_NO_SOLN);
alpar@9 1293 goto done;
alpar@9 1294 }
alpar@9 1295 errcode = 0;
alpar@9 1296 if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL)
alpar@9 1297 { if (dj != NULL)
alpar@9 1298 { for (j = begin; j <= end; j++)
alpar@9 1299 dj[j-begin] = glp_get_col_dual(lp->prob, j+1);
alpar@9 1300 }
alpar@9 1301 }
alpar@9 1302 else
alpar@9 1303 xassert(lp != lp);
alpar@9 1304 done: return errcode;
alpar@9 1305 }
alpar@9 1306
alpar@9 1307 char *CPXgeterrorstring(CPXENV *env, int errcode, char *buffer)
alpar@9 1308 { const char *string;
alpar@9 1309 xassert(env == env);
alpar@9 1310 string = finderrstring(errcode);
alpar@9 1311 if (string == NULL)
alpar@9 1312 buffer = NULL;
alpar@9 1313 else
alpar@9 1314 sprintf(buffer, "CPLEX Error %5d: %s.\n", errcode, string);
alpar@9 1315 return buffer;
alpar@9 1316 }
alpar@9 1317
alpar@9 1318 int CPXgetijdiv(CPXENV *env, CPXLP *lp, int *idiv, int *jdiv)
alpar@9 1319 { xassert(env == env);
alpar@9 1320 xassert(lp == lp);
alpar@9 1321 xassert(idiv == idiv);
alpar@9 1322 xassert(jdiv == jdiv);
alpar@9 1323 xprintf("CPXgetijdiv: not implemented yet\n");
alpar@9 1324 exit(EXIT_FAILURE);
alpar@9 1325 return -1;
alpar@9 1326 }
alpar@9 1327
alpar@9 1328 int CPXgetintparam(CPXENV *env, int whichparam, int *value)
alpar@9 1329 { int k, errcode;
alpar@9 1330 errcode = checkenv(env);
alpar@9 1331 if (errcode) goto done;
alpar@9 1332 k = findintparam(whichparam);
alpar@9 1333 if (k < 0)
alpar@9 1334 { errcode = error(env, CPXERR_BAD_PARAM_NUM);
alpar@9 1335 goto done;
alpar@9 1336 }
alpar@9 1337 errcode = 0;
alpar@9 1338 if (value != NULL)
alpar@9 1339 *value = env->intparam[k];
alpar@9 1340 done: return errcode;
alpar@9 1341 }
alpar@9 1342
alpar@9 1343 int CPXgetlb(CPXENV *env, CPXLP *lp, double lb[], int begin, int end)
alpar@9 1344 { xassert(env == env);
alpar@9 1345 xassert(lp == lp);
alpar@9 1346 xassert(lb == lb);
alpar@9 1347 xassert(begin == begin);
alpar@9 1348 xassert(end == end);
alpar@9 1349 xprintf("CPXgetlb: not implemented yet\n");
alpar@9 1350 exit(EXIT_FAILURE);
alpar@9 1351 return -1;
alpar@9 1352 }
alpar@9 1353
alpar@9 1354 int CPXgetmethod(CPXENV *env, CPXLP *lp)
alpar@9 1355 { int method;
alpar@9 1356 if (checklp(env, lp))
alpar@9 1357 method = CPX_ALG_NONE;
alpar@9 1358 else
alpar@9 1359 method = lp->meth;
alpar@9 1360 return method;
alpar@9 1361 }
alpar@9 1362
alpar@9 1363 int CPXgetnumcols(CPXENV *env, CPXLP *lp)
alpar@9 1364 { int numcols;
alpar@9 1365 if (checklp(env, lp))
alpar@9 1366 numcols = 0;
alpar@9 1367 else
alpar@9 1368 numcols = glp_get_num_cols(lp->prob);
alpar@9 1369 return numcols;
alpar@9 1370 }
alpar@9 1371
alpar@9 1372 int CPXgetnumnz(CPXENV *env, CPXLP *lp)
alpar@9 1373 { int numnz;
alpar@9 1374 if (checklp(env, lp))
alpar@9 1375 numnz = 0;
alpar@9 1376 else
alpar@9 1377 numnz = glp_get_num_nz(lp->prob);
alpar@9 1378 return numnz;
alpar@9 1379 }
alpar@9 1380
alpar@9 1381 int CPXgetnumrows(CPXENV *env, CPXLP *lp)
alpar@9 1382 { int numrows;
alpar@9 1383 if (checklp(env, lp))
alpar@9 1384 numrows = 0;
alpar@9 1385 else
alpar@9 1386 numrows = glp_get_num_rows(lp->prob);
alpar@9 1387 return numrows;
alpar@9 1388 }
alpar@9 1389
alpar@9 1390 int CPXgetobjval(CPXENV *env, CPXLP *lp, double *objval)
alpar@9 1391 { int errcode;
alpar@9 1392 errcode = checklp(env, lp);
alpar@9 1393 if (errcode) goto done;
alpar@9 1394 if (!lp->stat)
alpar@9 1395 { errcode = error(env, CPXERR_NO_SOLN);
alpar@9 1396 goto done;
alpar@9 1397 }
alpar@9 1398 errcode = 0;
alpar@9 1399 if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL)
alpar@9 1400 { if (objval != NULL)
alpar@9 1401 *objval = glp_get_obj_val(lp->prob);
alpar@9 1402 }
alpar@9 1403 else
alpar@9 1404 xassert(lp != lp);
alpar@9 1405 done: return errcode;
alpar@9 1406 }
alpar@9 1407
alpar@9 1408 int CPXgetpi(CPXENV *env, CPXLP *lp, double pi[], int begin, int end)
alpar@9 1409 { int i, m, errcode;
alpar@9 1410 errcode = checklp(env, lp);
alpar@9 1411 if (errcode) goto done;
alpar@9 1412 m = glp_get_num_rows(lp->prob);
alpar@9 1413 if (!(0 <= begin && begin <= end && end < m))
alpar@9 1414 { errcode = error(env, CPXERR_INDEX_RANGE);
alpar@9 1415 goto done;
alpar@9 1416 }
alpar@9 1417 if (!lp->stat)
alpar@9 1418 { errcode = error(env, CPXERR_NO_SOLN);
alpar@9 1419 goto done;
alpar@9 1420 }
alpar@9 1421 errcode = 0;
alpar@9 1422 if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL)
alpar@9 1423 { if (pi != NULL)
alpar@9 1424 { for (i = begin; i <= end; i++)
alpar@9 1425 pi[i-begin] = glp_get_row_dual(lp->prob, i+1);
alpar@9 1426 }
alpar@9 1427 }
alpar@9 1428 else
alpar@9 1429 xassert(lp != lp);
alpar@9 1430 done: return errcode;
alpar@9 1431 }
alpar@9 1432
alpar@9 1433 int CPXgetsense(CPXENV *env, CPXLP *lp, char sense[], int begin,
alpar@9 1434 int end)
alpar@9 1435 { xassert(env == env);
alpar@9 1436 xassert(lp == lp);
alpar@9 1437 xassert(sense == sense);
alpar@9 1438 xassert(begin == begin);
alpar@9 1439 xassert(end == end);
alpar@9 1440 xprintf("CPXgetsense: not implemented yet\n");
alpar@9 1441 exit(EXIT_FAILURE);
alpar@9 1442 return -1;
alpar@9 1443 }
alpar@9 1444
alpar@9 1445 int CPXgetslack(CPXENV *env, CPXLP *lp, double slack[], int begin,
alpar@9 1446 int end)
alpar@9 1447 { int i, m, type, errcode;
alpar@9 1448 double temp;
alpar@9 1449 errcode = checklp(env, lp);
alpar@9 1450 if (errcode) goto done;
alpar@9 1451 m = glp_get_num_rows(lp->prob);
alpar@9 1452 if (!(0 <= begin && begin <= end && end < m))
alpar@9 1453 { errcode = error(env, CPXERR_INDEX_RANGE);
alpar@9 1454 goto done;
alpar@9 1455 }
alpar@9 1456 if (!lp->stat)
alpar@9 1457 { errcode = error(env, CPXERR_NO_SOLN);
alpar@9 1458 goto done;
alpar@9 1459 }
alpar@9 1460 errcode = 0;
alpar@9 1461 if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL)
alpar@9 1462 { if (slack != NULL)
alpar@9 1463 { for (i = begin; i <= end; i++)
alpar@9 1464 { type = glp_get_row_type(lp->prob, i+1);
alpar@9 1465 temp = glp_get_row_prim(lp->prob, i+1);
alpar@9 1466 if (lp->rflag[i] == RF_NOT_RANGED)
alpar@9 1467 { if (type == GLP_LO || type == GLP_FX)
alpar@9 1468 slack[i-begin] =
alpar@9 1469 glp_get_row_lb(lp->prob, i+1) - temp;
alpar@9 1470 else if (type == GLP_UP)
alpar@9 1471 slack[i-begin] =
alpar@9 1472 glp_get_row_ub(lp->prob, i+1) - temp;
alpar@9 1473 else
alpar@9 1474 xassert(type != type);
alpar@9 1475 }
alpar@9 1476 else if (lp->rflag[i] == RF_RANGED_POS)
alpar@9 1477 { xassert(type == GLP_DB || type == GLP_FX);
alpar@9 1478 slack[i-begin] =
alpar@9 1479 temp - glp_get_row_lb(lp->prob, i+1);
alpar@9 1480 }
alpar@9 1481 else if (lp->rflag[i] == RF_RANGED_NEG)
alpar@9 1482 { xassert(type == GLP_DB);
alpar@9 1483 slack[i-begin] =
alpar@9 1484 temp - glp_get_row_ub(lp->prob, i+1);
alpar@9 1485 }
alpar@9 1486 else
alpar@9 1487 xassert(lp != lp);
alpar@9 1488 }
alpar@9 1489 }
alpar@9 1490 }
alpar@9 1491 else
alpar@9 1492 xassert(lp != lp);
alpar@9 1493 done: return errcode;
alpar@9 1494 }
alpar@9 1495
alpar@9 1496 int CPXgetstat(CPXENV *env, CPXLP *lp)
alpar@9 1497 { int stat;
alpar@9 1498 if (checklp(env, lp))
alpar@9 1499 stat = 0;
alpar@9 1500 else
alpar@9 1501 stat = lp->stat;
alpar@9 1502 return stat;
alpar@9 1503 }
alpar@9 1504
alpar@9 1505 int CPXgetub(CPXENV *env, CPXLP *lp, double ub[], int begin, int end)
alpar@9 1506 { xassert(env == env);
alpar@9 1507 xassert(lp == lp);
alpar@9 1508 xassert(ub == ub);
alpar@9 1509 xassert(begin == begin);
alpar@9 1510 xassert(end == end);
alpar@9 1511 xprintf("CPXgetub: not implemented yet\n");
alpar@9 1512 exit(EXIT_FAILURE);
alpar@9 1513 return -1;
alpar@9 1514 }
alpar@9 1515
alpar@9 1516 int CPXgetweight(CPXENV *env, CPXLP *lp, int rcnt, const int rmatbeg[],
alpar@9 1517 const int rmatind[], const double rmatval[], double weight[],
alpar@9 1518 int dpriind)
alpar@9 1519 { xassert(env == env);
alpar@9 1520 xassert(lp == lp);
alpar@9 1521 xassert(rcnt == rcnt);
alpar@9 1522 xassert(rmatbeg == rmatbeg);
alpar@9 1523 xassert(rmatind == rmatind);
alpar@9 1524 xassert(rmatval == rmatval);
alpar@9 1525 xassert(weight == weight);
alpar@9 1526 xassert(dpriind == dpriind);
alpar@9 1527 xprintf("CPXgetweight: not implemented yet\n");
alpar@9 1528 exit(EXIT_FAILURE);
alpar@9 1529 return -1;
alpar@9 1530 }
alpar@9 1531
alpar@9 1532 int CPXgetx(CPXENV *env, CPXLP *lp, double x[], int begin, int end)
alpar@9 1533 { int j, n, errcode;
alpar@9 1534 errcode = checklp(env, lp);
alpar@9 1535 if (errcode) goto done;
alpar@9 1536 n = glp_get_num_cols(lp->prob);
alpar@9 1537 if (!(0 <= begin && begin <= end && end < n))
alpar@9 1538 { errcode = error(env, CPXERR_INDEX_RANGE);
alpar@9 1539 goto done;
alpar@9 1540 }
alpar@9 1541 if (!lp->stat)
alpar@9 1542 { errcode = error(env, CPXERR_NO_SOLN);
alpar@9 1543 goto done;
alpar@9 1544 }
alpar@9 1545 errcode = 0;
alpar@9 1546 if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL)
alpar@9 1547 { if (x != NULL)
alpar@9 1548 { for (j = begin; j <= end; j++)
alpar@9 1549 x[j-begin] = glp_get_col_prim(lp->prob, j+1);
alpar@9 1550 }
alpar@9 1551 }
alpar@9 1552 else
alpar@9 1553 xassert(lp != lp);
alpar@9 1554 done: return errcode;
alpar@9 1555 }
alpar@9 1556
alpar@9 1557 int CPXinfodblparam(CPXENV *env, int whichparam, double *defvalue,
alpar@9 1558 double *minvalue, double *maxvalue)
alpar@9 1559 { int k, errcode;
alpar@9 1560 errcode = checkenv(env);
alpar@9 1561 if (errcode) goto done;
alpar@9 1562 k = finddblparam(whichparam);
alpar@9 1563 if (k < 0)
alpar@9 1564 { errcode = error(env, CPXERR_BAD_PARAM_NUM);
alpar@9 1565 goto done;
alpar@9 1566 }
alpar@9 1567 errcode = 0;
alpar@9 1568 if (defvalue != NULL)
alpar@9 1569 *defvalue = dblparam[k].defv;
alpar@9 1570 if (minvalue != NULL)
alpar@9 1571 *minvalue = dblparam[k].minv;
alpar@9 1572 if (maxvalue != NULL)
alpar@9 1573 *maxvalue = dblparam[k].maxv;
alpar@9 1574 done: return errcode;
alpar@9 1575 }
alpar@9 1576
alpar@9 1577 int CPXinfointparam(CPXENV *env, int whichparam, int *defvalue,
alpar@9 1578 int *minvalue, int *maxvalue)
alpar@9 1579 { int k, errcode;
alpar@9 1580 errcode = checkenv(env);
alpar@9 1581 if (errcode) goto done;
alpar@9 1582 k = findintparam(whichparam);
alpar@9 1583 if (k < 0)
alpar@9 1584 { errcode = error(env, CPXERR_BAD_PARAM_NUM);
alpar@9 1585 goto done;
alpar@9 1586 }
alpar@9 1587 errcode = 0;
alpar@9 1588 if (defvalue != NULL)
alpar@9 1589 *defvalue = intparam[k].defv;
alpar@9 1590 if (minvalue != NULL)
alpar@9 1591 *minvalue = intparam[k].minv;
alpar@9 1592 if (maxvalue != NULL)
alpar@9 1593 *maxvalue = intparam[k].maxv;
alpar@9 1594 done: return errcode;
alpar@9 1595 }
alpar@9 1596
alpar@9 1597 int CPXmdleave(const CPXENV *env, CPXLP *lp, const int goodlist[],
alpar@9 1598 int goodlen, double downratio[], double upratio[])
alpar@9 1599 { int k;
alpar@9 1600 xassert(env == env);
alpar@9 1601 xassert(lp == lp);
alpar@9 1602 xassert(goodlist == goodlist);
alpar@9 1603 xassert(goodlen >= 0);
alpar@9 1604 xassert(downratio != NULL);
alpar@9 1605 xassert(upratio != NULL);
alpar@9 1606 /* not implemented yet */
alpar@9 1607 for (k = 0; k < goodlen; k++)
alpar@9 1608 downratio[k] = upratio[k] = 0.0;
alpar@9 1609 return 0;
alpar@9 1610 }
alpar@9 1611
alpar@9 1612 int CPXnewcols(CPXENV *env, CPXLP *lp, int ccnt, const double obj[],
alpar@9 1613 const double lb[], const double ub[], const char ctype[],
alpar@9 1614 char *colname[])
alpar@9 1615 { int j, n, kind, type, errcode;
alpar@9 1616 double lbnd, ubnd;
alpar@9 1617 errcode = checklp(env, lp);
alpar@9 1618 if (errcode) goto done;
alpar@9 1619 if (ccnt < 0)
alpar@9 1620 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 1621 goto done;
alpar@9 1622 }
alpar@9 1623 for (j = 0; j < ccnt; j++)
alpar@9 1624 { if (ctype != NULL)
alpar@9 1625 { if (!(ctype[j] == 'C' || ctype[j] == 'B' ||
alpar@9 1626 ctype[j] == 'I'))
alpar@9 1627 { errcode = error(env, CPXERR_BAD_CTYPE, j);
alpar@9 1628 goto done;
alpar@9 1629 }
alpar@9 1630 }
alpar@9 1631 if (colname != NULL)
alpar@9 1632 { if (colname[j] == NULL)
alpar@9 1633 { errcode = error(env, CPXERR_NULL_NAME, j);
alpar@9 1634 goto done;
alpar@9 1635 }
alpar@9 1636 }
alpar@9 1637 }
alpar@9 1638 errcode = 0;
alpar@9 1639 invalidate(lp);
alpar@9 1640 n = glp_get_num_cols(lp->prob);
alpar@9 1641 if (ccnt > 0)
alpar@9 1642 glp_add_cols(lp->prob, ccnt);
alpar@9 1643 for (j = 0; j < ccnt; j++)
alpar@9 1644 { if (colname != NULL)
alpar@9 1645 glp_set_col_name(lp->prob, n+j+1, colname[j]);
alpar@9 1646 if (obj != NULL)
alpar@9 1647 glp_set_obj_coef(lp->prob, n+j+1, obj[j]);
alpar@9 1648 lbnd = (lb == NULL ? 0.0 : lb[j]);
alpar@9 1649 ubnd = (ub == NULL ? 0.0 : ub[j]);
alpar@9 1650 if (lbnd <= -CPX_INFBOUND && ubnd >= +CPX_INFBOUND)
alpar@9 1651 type = GLP_FR;
alpar@9 1652 else if (ubnd >= +CPX_INFBOUND)
alpar@9 1653 type = GLP_LO;
alpar@9 1654 else if (lbnd <= -CPX_INFBOUND)
alpar@9 1655 type = GLP_UP;
alpar@9 1656 else if (lbnd != ubnd)
alpar@9 1657 type = GLP_DB;
alpar@9 1658 else
alpar@9 1659 type = GLP_FX;
alpar@9 1660 glp_set_col_bnds(lp->prob, n+j+1, type, lbnd, ubnd);
alpar@9 1661 if (ctype != NULL)
alpar@9 1662 { if (ctype[j] == 'C')
alpar@9 1663 kind = GLP_CV;
alpar@9 1664 else if (ctype[j] == 'B')
alpar@9 1665 kind = GLP_BV;
alpar@9 1666 else if (ctype[j] == 'I')
alpar@9 1667 kind = GLP_IV;
alpar@9 1668 else
alpar@9 1669 xassert(ctype != ctype);
alpar@9 1670 glp_set_col_kind(lp->prob, n+j+1, kind);
alpar@9 1671 }
alpar@9 1672 }
alpar@9 1673 done: return errcode;
alpar@9 1674 }
alpar@9 1675
alpar@9 1676 int CPXnewrows(CPXENV *env, CPXLP *lp, int rcnt, const double rhs[],
alpar@9 1677 const char sense[], const double rngval[], char *rowname[])
alpar@9 1678 { int i, m, type, errcode;
alpar@9 1679 double lbnd, ubnd;
alpar@9 1680 errcode = checklp(env, lp);
alpar@9 1681 if (errcode) goto done;
alpar@9 1682 if (rcnt < 0)
alpar@9 1683 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 1684 goto done;
alpar@9 1685 }
alpar@9 1686 for (i = 0; i < rcnt; i++)
alpar@9 1687 { if (sense != NULL)
alpar@9 1688 { if (!(sense[i] == 'L' || sense[i] == 'E' ||
alpar@9 1689 sense[i] == 'G' || sense[i] == 'R'))
alpar@9 1690 { errcode = error(env, CPXERR_BAD_SENSE, i);
alpar@9 1691 goto done;
alpar@9 1692 }
alpar@9 1693 }
alpar@9 1694 if (rowname != NULL)
alpar@9 1695 { if (rowname[i] == NULL)
alpar@9 1696 { errcode = error(env, CPXERR_NULL_NAME, i);
alpar@9 1697 goto done;
alpar@9 1698 }
alpar@9 1699 }
alpar@9 1700 }
alpar@9 1701 errcode = 0;
alpar@9 1702 invalidate(lp);
alpar@9 1703 m = glp_get_num_rows(lp->prob);
alpar@9 1704 if (rcnt > 0)
alpar@9 1705 glp_add_rows(lp->prob, rcnt);
alpar@9 1706 enlargerflag(lp);
alpar@9 1707 for (i = 0; i < rcnt; i++)
alpar@9 1708 { if (rowname != NULL)
alpar@9 1709 glp_set_row_name(lp->prob, m+i+1, rowname[i]);
alpar@9 1710 lbnd = ubnd = (rhs == NULL ? 0.0 : rhs[i]);
alpar@9 1711 if (sense == NULL || sense[i] == 'E')
alpar@9 1712 { lp->rflag[m+i] = RF_NOT_RANGED;
alpar@9 1713 type = GLP_FX;
alpar@9 1714 }
alpar@9 1715 else if (sense[i] == 'L')
alpar@9 1716 { lp->rflag[m+i] = RF_NOT_RANGED;
alpar@9 1717 type = GLP_UP;
alpar@9 1718 }
alpar@9 1719 else if (sense[i] == 'G')
alpar@9 1720 { lp->rflag[m+i] = RF_NOT_RANGED;
alpar@9 1721 type = GLP_LO;
alpar@9 1722 }
alpar@9 1723 else if (sense[i] == 'R')
alpar@9 1724 { if (rngval == NULL || rngval[i] == 0.0)
alpar@9 1725 { lp->rflag[m+i] = RF_RANGED_POS;
alpar@9 1726 type = GLP_FX;
alpar@9 1727 }
alpar@9 1728 else if (rngval[i] > 0.0)
alpar@9 1729 { lp->rflag[m+i] = RF_RANGED_POS;
alpar@9 1730 type = GLP_DB;
alpar@9 1731 ubnd += rngval[i];
alpar@9 1732 }
alpar@9 1733 else /* rngval[i] < 0.0 */
alpar@9 1734 { lp->rflag[m+i] = RF_RANGED_NEG;
alpar@9 1735 type = GLP_DB;
alpar@9 1736 lbnd += rngval[i];
alpar@9 1737 }
alpar@9 1738 }
alpar@9 1739 else
alpar@9 1740 xassert(sense != sense);
alpar@9 1741 glp_set_row_bnds(lp->prob, m+i+1, type, lbnd, ubnd);
alpar@9 1742 }
alpar@9 1743 done: return errcode;
alpar@9 1744 }
alpar@9 1745
alpar@9 1746 CPXENV *CPXopenCPLEX(int *status)
alpar@9 1747 { CPXENV *env;
alpar@9 1748 int k, card;
alpar@9 1749 env = xmalloc(sizeof(CPXENV));
alpar@9 1750 env->list = NULL;
alpar@9 1751 card = sizeof(intparam) / sizeof(struct intparam);
alpar@9 1752 env->intparam = xcalloc(card, sizeof(int));
alpar@9 1753 for (k = 0; k < card; k++)
alpar@9 1754 env->intparam[k] = intparam[k].defv;
alpar@9 1755 card = sizeof(dblparam) / sizeof(struct dblparam);
alpar@9 1756 env->dblparam = xcalloc(card, sizeof(double));
alpar@9 1757 for (k = 0; k < card; k++)
alpar@9 1758 env->dblparam[k] = dblparam[k].defv;
alpar@9 1759 if (status != NULL) *status = 0;
alpar@9 1760 return env;
alpar@9 1761 }
alpar@9 1762
alpar@9 1763 int CPXpivotin(CPXENV *env, CPXLP *lp, const int rlist[], int rlen)
alpar@9 1764 { int i, m, errcode;
alpar@9 1765 errcode = checklp(env, lp);
alpar@9 1766 if (errcode) goto done;
alpar@9 1767 if (rlen < 0)
alpar@9 1768 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 1769 goto done;
alpar@9 1770 }
alpar@9 1771 if (rlen > 0 && rlist == NULL)
alpar@9 1772 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 1773 goto done;
alpar@9 1774 }
alpar@9 1775 m = glp_get_num_rows(lp->prob);
alpar@9 1776 for (i = 0; i < rlen; i++)
alpar@9 1777 { if (!(0 <= rlist[i] && rlist[i] < m))
alpar@9 1778 { errcode = error(env, CPXERR_ROW_INDEX_RANGE, i);
alpar@9 1779 goto done;
alpar@9 1780 }
alpar@9 1781 }
alpar@9 1782 errcode = 0;
alpar@9 1783 for (i = 0; i < rlen; i++)
alpar@9 1784 { if (glp_get_row_type(lp->prob, rlist[i]+1) != GLP_FX)
alpar@9 1785 { if (glp_get_row_stat(lp->prob, rlist[i]+1) != GLP_BS)
alpar@9 1786 { /* not implemented yet */
alpar@9 1787 break;
alpar@9 1788 }
alpar@9 1789 }
alpar@9 1790 }
alpar@9 1791 done: return errcode;
alpar@9 1792 }
alpar@9 1793
alpar@9 1794 int CPXpivotout(CPXENV *env, CPXLP *lp, const int clist[], int clen)
alpar@9 1795 { int j, n, errcode;
alpar@9 1796 errcode = checklp(env, lp);
alpar@9 1797 if (errcode) goto done;
alpar@9 1798 if (clen < 0)
alpar@9 1799 { errcode = error(env, CPXERR_BAD_ARGUMENT);
alpar@9 1800 goto done;
alpar@9 1801 }
alpar@9 1802 if (clen > 0 && clist == NULL)
alpar@9 1803 { errcode = error(env, CPXERR_NULL_POINTER);
alpar@9 1804 goto done;
alpar@9 1805 }
alpar@9 1806 n = glp_get_num_cols(lp->prob);
alpar@9 1807 for (j = 0; j < clen; j++)
alpar@9 1808 { if (!(0 <= clist[j] && clist[j] < n))
alpar@9 1809 { errcode = error(env, CPXERR_COL_INDEX_RANGE, j);
alpar@9 1810 goto done;
alpar@9 1811 }
alpar@9 1812 if (glp_get_col_type(lp->prob, clist[j]+1) != GLP_FX)
alpar@9 1813 { errcode = error(env, CPXERR_NOT_FIXED);
alpar@9 1814 goto done;
alpar@9 1815 }
alpar@9 1816 }
alpar@9 1817 errcode = 0;
alpar@9 1818 for (j = 0; j < clen; j++)
alpar@9 1819 { if (glp_get_col_stat(lp->prob, clist[j]+1) == GLP_BS)
alpar@9 1820 { /* not implemented yet */
alpar@9 1821 break;
alpar@9 1822 }
alpar@9 1823 }
alpar@9 1824 done: return errcode;
alpar@9 1825 }
alpar@9 1826
alpar@9 1827 int CPXprimopt(CPXENV *env, CPXLP *lp);
alpar@9 1828
alpar@9 1829 int CPXsavwrite(CPXENV *env, CPXLP *lp, const char *filename)
alpar@9 1830 { xassert(env == env);
alpar@9 1831 xassert(lp == lp);
alpar@9 1832 xassert(filename == filename);
alpar@9 1833 xprintf("CPXsavwrite: not implemented yet\n");
alpar@9 1834 exit(EXIT_FAILURE);
alpar@9 1835 return -1;
alpar@9 1836 }
alpar@9 1837
alpar@9 1838 int CPXsetdblparam(CPXENV *env, int whichparam, double newvalue)
alpar@9 1839 { int k, errcode;
alpar@9 1840 errcode = checkenv(env);
alpar@9 1841 if (errcode) goto done;
alpar@9 1842 k = finddblparam(whichparam);
alpar@9 1843 if (k < 0)
alpar@9 1844 { errcode = error(env, CPXERR_BAD_PARAM_NUM);
alpar@9 1845 goto done;
alpar@9 1846 }
alpar@9 1847 if (newvalue < dblparam[k].minv)
alpar@9 1848 { errcode = error(env, CPXERR_PARAM_TOO_SMALL);
alpar@9 1849 goto done;
alpar@9 1850 }
alpar@9 1851 if (newvalue > dblparam[k].maxv)
alpar@9 1852 { errcode = error(env, CPXERR_PARAM_TOO_BIG);
alpar@9 1853 goto done;
alpar@9 1854 }
alpar@9 1855 errcode = 0;
alpar@9 1856 env->dblparam[k] = newvalue;
alpar@9 1857 done: return errcode;
alpar@9 1858 }
alpar@9 1859
alpar@9 1860 int CPXsetintparam(CPXENV *env, int whichparam, int newvalue)
alpar@9 1861 { int k, errcode;
alpar@9 1862 errcode = checkenv(env);
alpar@9 1863 if (errcode) goto done;
alpar@9 1864 k = findintparam(whichparam);
alpar@9 1865 if (k < 0)
alpar@9 1866 { errcode = error(env, CPXERR_BAD_PARAM_NUM);
alpar@9 1867 goto done;
alpar@9 1868 }
alpar@9 1869 if (newvalue < intparam[k].minv)
alpar@9 1870 { errcode = error(env, CPXERR_PARAM_TOO_SMALL);
alpar@9 1871 goto done;
alpar@9 1872 }
alpar@9 1873 if (newvalue > intparam[k].maxv)
alpar@9 1874 { errcode = error(env, CPXERR_PARAM_TOO_BIG);
alpar@9 1875 goto done;
alpar@9 1876 }
alpar@9 1877 errcode = 0;
alpar@9 1878 env->intparam[k] = newvalue;
alpar@9 1879 done: return errcode;
alpar@9 1880 }
alpar@9 1881
alpar@9 1882 int CPXsolninfo(CPXENV *env, CPXLP *lp, int *solnmethod, int *solntype,
alpar@9 1883 int *pfeasind, int *dfeasind)
alpar@9 1884 { int type, pfeas, dfeas, errcode;
alpar@9 1885 errcode = checklp(env, lp);
alpar@9 1886 if (errcode) goto done;
alpar@9 1887 errcode = 0;
alpar@9 1888 if (!lp->stat)
alpar@9 1889 type = CPX_NO_SOLN, pfeas = dfeas = 0;
alpar@9 1890 else if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL)
alpar@9 1891 { type = CPX_BASIC_SOLN;
alpar@9 1892 pfeas = (glp_get_prim_stat(lp->prob) == GLP_FEAS);
alpar@9 1893 dfeas = (glp_get_dual_stat(lp->prob) == GLP_FEAS);
alpar@9 1894 }
alpar@9 1895 else
alpar@9 1896 xassert(lp != lp);
alpar@9 1897 if (solnmethod != NULL)
alpar@9 1898 *solnmethod = lp->meth;
alpar@9 1899 if (solntype != NULL)
alpar@9 1900 *solntype = type;
alpar@9 1901 if (pfeasind != NULL)
alpar@9 1902 *pfeasind = pfeas;
alpar@9 1903 if (dfeasind != NULL)
alpar@9 1904 *dfeasind = dfeas;
alpar@9 1905 done: return errcode;
alpar@9 1906 }
alpar@9 1907
alpar@9 1908 int CPXsolution(CPXENV *env, CPXLP *lp, int *lpstat, double *objval,
alpar@9 1909 double x[], double pi[], double slack[], double dj[])
alpar@9 1910 { int m, n, errcode;
alpar@9 1911 errcode = checklp(env, lp);
alpar@9 1912 if (errcode) goto done;
alpar@9 1913 if (!lp->stat)
alpar@9 1914 { errcode = error(env, CPXERR_NO_SOLN);
alpar@9 1915 goto done;
alpar@9 1916 }
alpar@9 1917 errcode = 0;
alpar@9 1918 m = glp_get_num_rows(lp->prob);
alpar@9 1919 n = glp_get_num_cols(lp->prob);
alpar@9 1920 if (lp->meth == CPX_ALG_PRIMAL || lp->meth == CPX_ALG_DUAL)
alpar@9 1921 { if (lpstat != NULL)
alpar@9 1922 *lpstat = CPXgetstat(env, lp);
alpar@9 1923 if (objval != NULL)
alpar@9 1924 xassert(CPXgetobjval(env, lp, objval) == 0);
alpar@9 1925 if (x != NULL)
alpar@9 1926 xassert(CPXgetx(env, lp, x, 0, n-1) == 0);
alpar@9 1927 if (pi != NULL)
alpar@9 1928 xassert(CPXgetpi(env, lp, pi, 0, m-1) == 0);
alpar@9 1929 if (slack != NULL)
alpar@9 1930 xassert(CPXgetslack(env, lp, slack, 0, m-1) == 0);
alpar@9 1931 if (dj != NULL)
alpar@9 1932 xassert(CPXgetdj(env, lp, dj, 0, n-1) == 0);
alpar@9 1933 }
alpar@9 1934 else
alpar@9 1935 xassert(lp != lp);
alpar@9 1936 done: return errcode;
alpar@9 1937 }
alpar@9 1938
alpar@9 1939 int CPXstrongbranch(CPXENV *env, CPXLP *lp, const int goodlist[],
alpar@9 1940 int goodlen, double downpen[], double uppen[], int itlim)
alpar@9 1941 { int k;
alpar@9 1942 xassert(env == env);
alpar@9 1943 xassert(lp == lp);
alpar@9 1944 xassert(goodlist == goodlist);
alpar@9 1945 xassert(goodlen >= 0);
alpar@9 1946 xassert(downpen != NULL);
alpar@9 1947 xassert(uppen != NULL);
alpar@9 1948 xassert(itlim == itlim);
alpar@9 1949 /* not implemented yet */
alpar@9 1950 for (k = 0; k < goodlen; k++)
alpar@9 1951 downpen[k] = uppen[k] = 0.0;
alpar@9 1952 return 0;
alpar@9 1953 }
alpar@9 1954
alpar@9 1955 static int xstrcasecmp(const char *s1, const char *s2)
alpar@9 1956 { int c1, c2;
alpar@9 1957 for (;;)
alpar@9 1958 { c1 = toupper((unsigned char)*s1++);
alpar@9 1959 c2 = toupper((unsigned char)*s2++);
alpar@9 1960 if (c1 == '\0' || c1 != c2) break;
alpar@9 1961 }
alpar@9 1962 return c1 - c2;
alpar@9 1963 }
alpar@9 1964
alpar@9 1965 static void getfiletype(const char *filename, char type[3+1])
alpar@9 1966 { /* determine filetype from filename */
alpar@9 1967 int beg, end;
alpar@9 1968 beg = end = strlen(filename);
alpar@9 1969 while (beg > 0 && filename[beg-1] != '.' && end - beg < 3)
alpar@9 1970 beg--;
alpar@9 1971 if (beg > 0 && filename[beg-1] == '.' &&
alpar@9 1972 xstrcasecmp(&filename[beg], "gz") == 0)
alpar@9 1973 { end = --beg;
alpar@9 1974 while (beg > 0 && filename[beg-1] != '.' && end - beg < 3)
alpar@9 1975 beg--;
alpar@9 1976 }
alpar@9 1977 if (beg > 0 && filename[beg-1] == '.')
alpar@9 1978 { memcpy(type, &filename[beg], end - beg);
alpar@9 1979 type[end - beg] = '\0';
alpar@9 1980 }
alpar@9 1981 else
alpar@9 1982 type[0] = '\0';
alpar@9 1983 return;
alpar@9 1984 }
alpar@9 1985
alpar@9 1986 int CPXwriteprob(CPXENV *env, CPXLP *lp, const char *filename,
alpar@9 1987 const char *filetype)
alpar@9 1988 { glp_prob *copy;
alpar@9 1989 int errcode;
alpar@9 1990 char type[3+1];
alpar@9 1991 errcode = checklp(env, lp);
alpar@9 1992 if (errcode) goto done;
alpar@9 1993 if (filename == NULL)
alpar@9 1994 { errcode = error(env, CPXERR_NO_FILENAME);
alpar@9 1995 goto done;
alpar@9 1996 }
alpar@9 1997 if (filetype == NULL)
alpar@9 1998 getfiletype(filename, type), filetype = type;
alpar@9 1999 if (xstrcasecmp(filetype, "MPS") == 0)
alpar@9 2000 { glp_term_out(GLP_OFF);
alpar@9 2001 errcode = glp_write_mps(lp->prob, GLP_MPS_FILE, NULL, filename)
alpar@9 2002 ;
alpar@9 2003 glp_term_out(GLP_ON);
alpar@9 2004 }
alpar@9 2005 else if (xstrcasecmp(filetype, "LP") == 0)
alpar@9 2006 { glp_term_out(GLP_OFF);
alpar@9 2007 errcode = glp_write_lp(lp->prob, NULL, filename);
alpar@9 2008 glp_term_out(GLP_ON);
alpar@9 2009 }
alpar@9 2010 else if (xstrcasecmp(filetype, "RMP") == 0 ||
alpar@9 2011 xstrcasecmp(filetype, "REW") == 0)
alpar@9 2012 { copy = glp_create_prob();
alpar@9 2013 glp_copy_prob(copy, lp->prob, GLP_OFF);
alpar@9 2014 glp_term_out(GLP_OFF);
alpar@9 2015 errcode = glp_write_mps(copy, GLP_MPS_DECK, NULL, filename);
alpar@9 2016 glp_term_out(GLP_ON);
alpar@9 2017 glp_delete_prob(copy);
alpar@9 2018 }
alpar@9 2019 else if (xstrcasecmp(filetype, "RLP") == 0)
alpar@9 2020 { copy = glp_create_prob();
alpar@9 2021 glp_copy_prob(copy, lp->prob, GLP_OFF);
alpar@9 2022 glp_term_out(GLP_OFF);
alpar@9 2023 errcode = glp_write_lp(copy, NULL, filename);
alpar@9 2024 glp_term_out(GLP_ON);
alpar@9 2025 glp_delete_prob(copy);
alpar@9 2026 }
alpar@9 2027 else
alpar@9 2028 { errcode = error(env, CPXERR_BAD_FILETYPE);
alpar@9 2029 goto done;
alpar@9 2030 }
alpar@9 2031 if (errcode)
alpar@9 2032 errcode = error(env, CPXERR_FAIL_OPEN_WRITE, filename);
alpar@9 2033 done: return errcode;
alpar@9 2034 }
alpar@9 2035
alpar@9 2036 /**********************************************************************/
alpar@9 2037
alpar@9 2038 static int solvelp(CPXENV *env, CPXLP *lp, int meth)
alpar@9 2039 { glp_smcp parm;
alpar@9 2040 int errcode;
alpar@9 2041 errcode = checklp(env, lp);
alpar@9 2042 if (errcode) goto done;
alpar@9 2043 errcode = 0;
alpar@9 2044 invalidate(lp);
alpar@9 2045 glp_init_smcp(&parm);
alpar@9 2046 switch (meth)
alpar@9 2047 { case CPX_ALG_PRIMAL:
alpar@9 2048 parm.meth = GLP_PRIMAL;
alpar@9 2049 break;
alpar@9 2050 case CPX_ALG_DUAL:
alpar@9 2051 parm.meth = GLP_DUAL;
alpar@9 2052 break;
alpar@9 2053 default:
alpar@9 2054 xassert(meth != meth);
alpar@9 2055 }
alpar@9 2056 switch (getintparam(env, CPX_PARAM_SIMDISPLAY))
alpar@9 2057 { case 0:
alpar@9 2058 parm.msg_lev = GLP_MSG_OFF;
alpar@9 2059 break;
alpar@9 2060 case 1:
alpar@9 2061 parm.msg_lev = GLP_MSG_ALL;
alpar@9 2062 break;
alpar@9 2063 case 2:
alpar@9 2064 parm.msg_lev = GLP_MSG_ALL;
alpar@9 2065 parm.out_frq = 1;
alpar@9 2066 break;
alpar@9 2067 default:
alpar@9 2068 xassert(env != env);
alpar@9 2069 }
alpar@9 2070 xassert(getdblparam == getdblparam);
alpar@9 2071 switch (getintparam(env, CPX_PARAM_ADVIND))
alpar@9 2072 { case 0:
alpar@9 2073 glp_term_out(GLP_OFF);
alpar@9 2074 glp_adv_basis(lp->prob, 0);
alpar@9 2075 glp_term_out(GLP_ON);
alpar@9 2076 break;
alpar@9 2077 case 1:
alpar@9 2078 case 2:
alpar@9 2079 break;
alpar@9 2080 default:
alpar@9 2081 xassert(env != env);
alpar@9 2082 }
alpar@9 2083 if (!glp_bf_exists(lp->prob))
alpar@9 2084 { if (glp_factorize(lp->prob) != 0)
alpar@9 2085 { glp_term_out(GLP_OFF);
alpar@9 2086 glp_adv_basis(lp->prob, 0);
alpar@9 2087 glp_term_out(GLP_ON);
alpar@9 2088 if (glp_factorize(lp->prob) != 0)
alpar@9 2089 glp_std_basis(lp->prob);
alpar@9 2090 }
alpar@9 2091 }
alpar@9 2092 xassert(glp_simplex(lp->prob, &parm) == 0);
alpar@9 2093 switch (glp_get_status(lp->prob))
alpar@9 2094 { case GLP_OPT:
alpar@9 2095 lp->stat = CPX_STAT_OPTIMAL;
alpar@9 2096 lp->meth = meth;
alpar@9 2097 break;
alpar@9 2098 case GLP_NOFEAS:
alpar@9 2099 lp->stat = CPX_STAT_INFEASIBLE;
alpar@9 2100 lp->meth = meth;
alpar@9 2101 break;
alpar@9 2102 case GLP_UNBND:
alpar@9 2103 lp->stat = CPX_STAT_UNBOUNDED;
alpar@9 2104 lp->meth = meth;
alpar@9 2105 break;
alpar@9 2106 default:
alpar@9 2107 xassert(lp != lp);
alpar@9 2108 }
alpar@9 2109 done: return errcode;
alpar@9 2110 }
alpar@9 2111
alpar@9 2112 int CPXprimopt(CPXENV *env, CPXLP *lp)
alpar@9 2113 { int errcode;
alpar@9 2114 errcode = solvelp(env, lp, CPX_ALG_PRIMAL);
alpar@9 2115 return errcode;
alpar@9 2116 }
alpar@9 2117
alpar@9 2118 int CPXdualopt(CPXENV *env, CPXLP *lp)
alpar@9 2119 { int errcode;
alpar@9 2120 errcode = solvelp(env, lp, CPX_ALG_DUAL);
alpar@9 2121 return errcode;
alpar@9 2122 }
alpar@9 2123
alpar@9 2124 int CPXlpopt(CPXENV *env, CPXLP *lp)
alpar@9 2125 { int errcode;
alpar@9 2126 errcode = solvelp(env, lp, CPX_ALG_PRIMAL);
alpar@9 2127 return errcode;
alpar@9 2128 }
alpar@9 2129
alpar@9 2130 /* eof */