1/* BEGIN LICENSE BLOCK 2 * Version: CMPL 1.1 3 * 4 * The contents of this file are subject to the Cisco-style Mozilla Public 5 * License Version 1.1 (the "License"); you may not use this file except 6 * in compliance with the License. You may obtain a copy of the License 7 * at www.eclipse-clp.org/license. 8 * 9 * Software distributed under the License is distributed on an "AS IS" 10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11 * the License for the specific language governing rights and limitations 12 * under the License. 13 * 14 * The Original Code is The ECLiPSe/Gurobi Interface 15 * The Initial Developer of the Original Code is Joachim Schimpf 16 * Portions created by the Initial Developer are 17 * Copyright (C) 2012 Joachim Schimpf 18 * 19 * Contributor(s): Joachim Schimpf, Coninfer Ltd 20 * 21 * END LICENSE BLOCK */ 22 23/* 24 * ECLiPSe/Gurobi interface (for inclusion in eplex.c) 25 */ 26 27#ifdef GUROBI 28 29/* 30 * Notes on Gurobi 31 * 32 * Parameters 33 * Parameters are part of the "environment". When a model is created, 34 * it gets a copy of the specified environment. 35 * Strangely uses strings for attribute/param identifiers 36 * Methods 37 * auto 38 * primal 39 * dual 40 * barrier 41 * barrier(auto|none|1|2|3|4) 42 * concurrent 43 * concurrent_det 44 * sift(auto|primal|dual|barrier) 45 * Node_methods 46 * primal 47 * dual 48 * barrier 49 * Need to "flush" model modifications with GRBupdatemodel() 50 * between adding columns and rows with these columns, 51 * and on many other occasions after the model changed. 52 * No notion of different message streams (log,warning,error,result) 53 * we send everything to Log 54 * 55 * Licence 56 * license file gurobi.lic in HOME, C:\gurobiVV or /opt/gurobiVV 57 * alternatively GRB_LICENSE_FILE contains path name of license file 58 */ 59 60static int 61grb_getintattr(GRBmodel* lp, const char* attr) 62{ 63 int value = 0; 64 GRBgetintattr(lp, attr, &value); 65 return value; 66} 67 68 69static int 70grb_chgbds(GRBmodel* lp, int cnt, int* idxs, char* lu, double* bd) 71{ 72 int err, i, nvars; 73 if (GRBgetintattr(lp, GRB_INT_ATTR_NUMVARS, &nvars)) 74 goto _return_err_; 75 for (i=0; i<cnt; i++) 76 { 77 int j=idxs[i]; 78 if (j < 0 || j >= nvars) return -1; 79 switch(lu[i]) 80 { 81 case 'L': err = GRBsetdblattrelement(lp,GRB_DBL_ATTR_LB,j,bd[i]); 82 break; 83 case 'B': err = GRBsetdblattrelement(lp,GRB_DBL_ATTR_LB,j,bd[i]); 84 /*fall through*/ 85 case 'U': err = GRBsetdblattrelement(lp,GRB_DBL_ATTR_UB,j,bd[i]); 86 break; 87 default: 88 return -1; 89 } 90 if (err) goto _return_err_; 91 } 92 return 0; 93_return_err_: 94 Report_Solver_Error(cpx_env); 95 return -1; 96} 97 98 99/* caution: this function assumes that the arrays are the right size */ 100static int 101grb_loadbasis(GRBmodel* lp, int* cbase, int* rbase) 102{ 103 int nvars, ncstr; 104 if (GRBgetintattr(lp, GRB_INT_ATTR_NUMVARS, &nvars)) 105 goto _return_err_; 106 if (GRBgetintattr(lp, GRB_INT_ATTR_NUMCONSTRS, &ncstr)) 107 goto _return_err_; 108 if (GRBsetintattrarray(lp,GRB_INT_ATTR_CBASIS,0,ncstr,cbase)) 109 goto _return_err_; 110 if (GRBsetintattrarray(lp,GRB_INT_ATTR_VBASIS,0,nvars,rbase)) 111 goto _return_err_; 112 return 0; 113_return_err_: 114 Report_Solver_Error(cpx_env); 115 return -1; 116} 117 118 119static int 120cpx_loadstart(lp_desc* lpd, int option, double *sols, int sz) 121{ 122 int nvars, i; 123 124 if (GRBgetintattr(lpd->lp, GRB_INT_ATTR_NUMVARS, &nvars)) 125 goto _return_err_; 126 if (sz == 0) option = MIPSTART_NONE; 127 if (sz > nvars) sz = nvars; 128 129 switch(option) 130 { 131 case MIPSTART_NONE: 132 if (lpd->mipstart_dirty) 133 { 134 for (i=0; i<nvars; ++i) 135 { 136 if (GRBsetdblattrelement(lpd->lp,GRB_DBL_ATTR_START,i,GRB_UNDEFINED)) 137 goto _return_err_; 138 } 139 lpd->mipstart_dirty = 0; 140 } 141 break; 142 143 case MIPSTART_ALL: 144 if (GRBsetdblattrarray(lpd->lp,GRB_DBL_ATTR_START,0,sz,sols)) 145 goto _return_err_; 146 for (i=sz; i<nvars; ++i) 147 { 148 if (GRBsetdblattrelement(lpd->lp,GRB_DBL_ATTR_START,i,GRB_UNDEFINED)) 149 goto _return_err_; 150 } 151 lpd->mipstart_dirty = 1; 152 break; 153 154 case MIPSTART_INT: 155 { 156 char *vtype = (char*) Malloc(nvars*sizeof(char)); 157 if (GRBgetcharattrarray(lpd->lp,GRB_CHAR_ATTR_VTYPE,0,nvars,vtype)) 158 { 159 Free(vtype); 160 goto _return_err_; 161 } 162 for (i=0; i<sz; ++i) 163 { 164 if (GRBsetdblattrelement(lpd->lp,GRB_DBL_ATTR_START,i, 165 vtype[i]=='C' ? GRB_UNDEFINED : sols[i])) 166 { 167 Free(vtype); 168 goto _return_err_; 169 } 170 } 171 Free(vtype); 172 for (i=sz; i<nvars; ++i) 173 { 174 if (GRBsetdblattrelement(lpd->lp,GRB_DBL_ATTR_START,i,GRB_UNDEFINED)) 175 goto _return_err_; 176 } 177 lpd->mipstart_dirty = 1; 178 } 179 break; 180 } 181 return 0; 182 183_return_err_: 184 Report_Solver_Error(cpx_env); 185 return -1; 186} 187 188 189/* caution: this function assumes that the arrays are the right size */ 190static int 191grb_getbasis(GRBmodel* lp, int* cbase, int* rbase) 192{ 193 int nvars, ncstr; 194 if (GRBgetintattr(lp, GRB_INT_ATTR_NUMVARS, &nvars)) 195 goto _return_err_; 196 if (GRBgetintattr(lp, GRB_INT_ATTR_NUMCONSTRS, &ncstr)) 197 goto _return_err_; 198 if (GRBgetintattrarray(lp,GRB_INT_ATTR_CBASIS,0,ncstr,cbase)) 199 goto _return_err_; 200 if (GRBgetintattrarray(lp,GRB_INT_ATTR_VBASIS,0,nvars,rbase)) 201 goto _return_err_; 202 return 0; 203_return_err_: 204 Report_Solver_Error(cpx_env); 205 return -1; 206} 207 208 209static int 210grb_setname(GRBmodel* lp, char ntype, int idx, char * name) 211{ 212 switch(ntype) 213 { 214 case 'c': 215 if (GRBsetstrattrelement(lp,GRB_STR_ATTR_VARNAME,idx,name)) 216 goto _return_err_; 217 break; 218 case 'r': 219 if (GRBsetstrattrelement(lp,GRB_STR_ATTR_CONSTRNAME,idx,name)) 220 goto _return_err_; 221 break; 222 default: 223 return -1; 224 } 225 return 0; 226_return_err_: 227 Report_Solver_Error(cpx_env); 228 return -1; 229} 230 231 232/* 233 * Set parameters for methods and timeout 234 */ 235static int 236cpx_prepare_solve(lp_desc* lpd, struct lp_meth *meth, double timeout) 237{ 238 int method, val, min, max; 239 GRBenv* grb_env = GRBgetenv(lpd->lp); 240 241 if (timeout <= 0.0) 242 timeout = HUGE_VAL; 243 if (GRBsetdblparam(grb_env, GRB_DBL_PAR_TIMELIMIT, timeout)) 244 goto _return_err_; 245 246 if (meth->meth != METHOD_DEFAULT) 247 { 248 switch(meth->meth) 249 { 250 case METHOD_AUTO: method = GRB_METHOD_AUTO; break; 251 case METHOD_PRIMAL: method = GRB_METHOD_PRIMAL; break; 252 case METHOD_DUAL: method = GRB_METHOD_DUAL; break; 253 case METHOD_CONCURRENT: method = GRB_METHOD_CONCURRENT; break; 254 case METHOD_CONCURRENTDET: method = GRB_METHOD_DETERMINISTIC_CONCURRENT; break; 255 case METHOD_BAR: 256 if (meth->auxmeth != METHOD_DEFAULT) 257 { 258 switch(meth->auxmeth) 259 { 260 case METHOD_AUTO: method = -1; break; 261 case METHOD_NONE: method = 0; break; 262 case METHOD_PRIMAL: method = 3; break; 263 case METHOD_DUAL: method = 2; break; 264 default: goto _illegal_method_; 265 } 266 if (GRBsetintparam(grb_env, GRB_INT_PAR_CROSSOVER, method)) 267 goto _return_err_; 268 } 269 method = GRB_METHOD_BARRIER; 270 break; 271 case METHOD_SIFT: 272 if (meth->auxmeth != METHOD_DEFAULT) 273 { 274 switch(meth->auxmeth) 275 { 276 case METHOD_AUTO: method = -1; break; 277 case METHOD_PRIMAL: method = 0; break; 278 case METHOD_DUAL: method = 1; break; 279 case METHOD_BAR: method = 2; break; 280 default: goto _illegal_method_; 281 } 282 if (GRBsetintparam(grb_env, GRB_INT_PAR_SIFTMETHOD, method)) 283 goto _return_err_; 284 } 285 /* We leave the SIFTING parameter untouched! */ 286 method = GRB_METHOD_DUAL; 287 break; 288 default: goto _illegal_method_; 289 } 290 if (GRBsetintparam(grb_env, GRB_INT_PAR_METHOD, method)) 291 goto _return_err_; 292 } 293 294 if (meth->node_meth != METHOD_DEFAULT) 295 { 296 switch(meth->node_meth) 297 { 298 case METHOD_PRIMAL: method = GRB_METHOD_PRIMAL; break; 299 case METHOD_DUAL: method = GRB_METHOD_DUAL; break; 300 case METHOD_BAR: 301 if (meth->meth != METHOD_BAR && meth->node_auxmeth != METHOD_DEFAULT) 302 { 303 switch(meth->node_auxmeth) 304 { 305 case METHOD_AUTO: method = -1; break; 306 case METHOD_NONE: method = 0; break; 307 case METHOD_PRIMAL: method = 3; break; 308 case METHOD_DUAL: method = 2; break; 309 default: goto _illegal_method_; 310 } 311 if (GRBsetintparam(grb_env, GRB_INT_PAR_CROSSOVER, method)) 312 goto _return_err_; 313 } 314 method = GRB_METHOD_BARRIER; 315 break; 316 case METHOD_SIFT: 317 if (meth->meth != METHOD_SIFT && meth->node_auxmeth != METHOD_DEFAULT) 318 { 319 switch(meth->node_auxmeth) 320 { 321 case METHOD_AUTO: method = -1; break; 322 case METHOD_PRIMAL: method = 0; break; 323 case METHOD_DUAL: method = 1; break; 324 case METHOD_BAR: method = 2; break; 325 default: goto _illegal_method_; 326 } 327 if (GRBsetintparam(grb_env, GRB_INT_PAR_SIFTMETHOD, method)) 328 goto _return_err_; 329 } 330 /* We leave the SIFTING parameter untouched! */ 331 method = GRB_METHOD_DUAL; 332 break; 333 default: goto _illegal_method_; 334 } 335 if (GRBsetintparam(grb_env, GRB_INT_PAR_NODEMETHOD, method)) 336 goto _return_err_; 337 } 338 339 return 0; 340 341_illegal_method_: 342 Report_Error("Unsupported solver method"); 343 return -1; 344_return_err_: 345 Report_Solver_Error(cpx_env); 346 return -1; 347} 348 349 350static int 351cpx_solve(lp_desc* lpd, struct lp_meth *meth, struct lp_sol *sol, double* bestbound, double* worstbound) 352{ 353 int sol_count; 354 int rev_state = GRB_LOADED; 355 356 if (cpx_loadstart(lpd, meth->option_mipstart, sol->oldsols, sol->oldmac)) 357 return -1; 358 359_retry_: 360 if (GRBoptimize(lpd->lp)) 361 goto _return_err_; 362 363 if (GRBgetintattr(lpd->lp, GRB_INT_ATTR_STATUS, &lpd->sol_state)) 364 goto _return_err_; 365 366 switch(lpd->sol_state) 367 { 368 case GRB_OPTIMAL: /* SuccessState */ 369 lpd->descr_state = DESCR_SOLVED_SOL; 370 lpd->optimum_ctr++; 371 if (GRBgetdblattr(lpd->lp, GRB_DBL_ATTR_OBJVAL, &lpd->objval)) 372 goto _return_err_; 373 *worstbound = *bestbound = lpd->objval; 374 break; 375 376 case GRB_INFEASIBLE: /* FailState */ 377_grb_infeasible_: 378 lpd->descr_state = DESCR_SOLVED_NOSOL; 379 lpd->infeas_ctr++; 380 lpd->objval = 0.0; 381 *worstbound = (lpd->sense == SENSE_MIN ? -HUGE_VAL : HUGE_VAL); 382 *bestbound = (lpd->sense == SENSE_MIN ? HUGE_VAL : -HUGE_VAL); 383 break; 384 385 case GRB_CUTOFF: /* FailState */ 386 lpd->descr_state = DESCR_SOLVED_NOSOL; 387 lpd->infeas_ctr++; 388 lpd->objval = 0.0; 389 *worstbound = (lpd->sense == SENSE_MIN ? -HUGE_VAL : HUGE_VAL); 390 if (GRBgetdblparam(GRBgetenv(lpd->lp), GRB_DBL_PAR_CUTOFF, bestbound)) 391 goto _return_err_; 392 break; 393 394 case GRB_INF_OR_UNBD: /* MaybeFailState */ 395#ifdef TRY_RESOLVE_UNCERTAIN_RESULT 396 /* try to check for infeasibility by reversing the sense */ 397 switch(rev_state) 398 { 399 case GRB_LOADED: 400 { 401 int sense, res; 402 GRBgetintattr(lpd->lp, GRB_INT_ATTR_MODELSENSE, &sense); 403 GRBsetintattr(lpd->lp, GRB_INT_ATTR_MODELSENSE, -sense); 404 res = GRBoptimize(lpd->lp); 405 GRBsetintattr(lpd->lp, GRB_INT_ATTR_MODELSENSE, sense); 406 GRBgetintattr(lpd->lp, GRB_INT_ATTR_STATUS, &rev_state); 407 if (res == 0) 408 goto _retry_; 409 } 410 break; 411 case GRB_INFEASIBLE: 412 goto _grb_infeasible_; 413 case GRB_OPTIMAL: 414 case GRB_SUBOPTIMAL: 415 case GRB_CUTOFF: 416 case GRB_UNBOUNDED: 417 goto _grb_unbounded_; 418 } 419#endif 420 421 /* can't get a more precise result */ 422 lpd->descr_state = DESCR_UNKNOWN_NOSOL; 423 lpd->infeas_ctr++; 424 lpd->objval = 0.0; 425 *worstbound = (lpd->sense == SENSE_MIN ? HUGE_VAL : -HUGE_VAL); 426 *bestbound = (lpd->sense == SENSE_MIN ? -HUGE_VAL : HUGE_VAL); 427 break; 428 429 case GRB_UNBOUNDED: /* UnboundedState */ 430_grb_unbounded_: 431 /* From Gurobi manual: an unbounded status indicates the presence 432 * of an unbounded ray that allows the objective to improve 433 * without limit. It says nothing about whether the model has a 434 * feasible solution. If you require information on feasibility, 435 * you should set the objective to zero and reoptimize. 436 */ 437 lpd->descr_state = DESCR_UNBOUNDED_NOSOL; 438 lpd->abort_ctr++; 439 *bestbound = (lpd->sense == SENSE_MIN ? -HUGE_VAL : HUGE_VAL); 440 /* try to obtain a better worstbound */ 441 if (GRBgetintattr(lpd->lp, GRB_INT_ATTR_SOLCOUNT, &sol_count)) 442 goto _return_err_; 443 if (sol_count > 0) { 444 if (GRBgetdblattr(lpd->lp, GRB_DBL_ATTR_OBJVAL, worstbound)) 445 goto _return_err_; 446 *worstbound = lpd->objval; 447 } else { 448 lpd->objval = 0.0; 449 *worstbound = (lpd->sense == SENSE_MIN ? HUGE_VAL : -HUGE_VAL); 450 } 451 break; 452 453 case GRB_ITERATION_LIMIT: 454 case GRB_NODE_LIMIT: 455 case GRB_TIME_LIMIT: 456 case GRB_SOLUTION_LIMIT: 457 case GRB_INTERRUPTED: 458 case GRB_NUMERIC: 459 lpd->abort_ctr++; 460 if (GRBgetintattr(lpd->lp, GRB_INT_ATTR_SOLCOUNT, &sol_count)) 461 goto _return_err_; 462 if (sol_count > 0) { 463 lpd->descr_state = DESCR_ABORTED_SOL; 464 if (GRBgetdblattr(lpd->lp, GRB_DBL_ATTR_OBJVAL, &lpd->objval)) 465 goto _return_err_; 466 *worstbound = lpd->objval; 467 } else { 468 lpd->descr_state = DESCR_ABORTED_NOSOL; 469 /* KISH: what worstbound value? */ 470 *worstbound = (lpd->sense == SENSE_MIN ? HUGE_VAL : -HUGE_VAL); 471 lpd->objval = 0.0; 472 } 473 if (GRBgetdblattr(lpd->lp, GRB_DBL_ATTR_OBJBOUND, bestbound)) 474 goto _return_err_; 475 break; 476 477 case GRB_SUBOPTIMAL: 478 lpd->descr_state = DESCR_ABORTED_SOL; 479 lpd->abort_ctr++; 480 if (GRBgetdblattr(lpd->lp, GRB_DBL_ATTR_OBJVAL, &lpd->objval)) 481 goto _return_err_; 482 *worstbound = lpd->objval; 483 if (GRBgetdblattr(lpd->lp, GRB_DBL_ATTR_OBJBOUND, bestbound)) 484 goto _return_err_; 485 break; 486 487 default: 488 return -1; 489 } 490 return 0; 491_return_err_: 492 Report_Solver_Error(cpx_env); 493 return -1; 494} 495 496 497static int 498cpx_get_soln_state(lp_desc* lpd, struct lp_sol *sol) 499{ 500 if (lpd->mac > 0) /* columns/variables */ 501 { 502 if (sol->sols && GRBgetdblattrarray(lpd->lp, GRB_DBL_ATTR_X, 0, lpd->mac, sol->sols)) 503 goto _return_err_; 504 if (sol->djs && GRBgetdblattrarray(lpd->lp, GRB_DBL_ATTR_RC, 0, lpd->mac, sol->djs)) 505 goto _return_err_; 506 if (sol->cbase && GRBgetintattrarray(lpd->lp, GRB_INT_ATTR_VBASIS, 0, lpd->mac, sol->cbase)) 507 goto _return_err_; 508 } 509 if (lpd->mar > 0) /* rows/constraints */ 510 { 511 if (sol->slacks && GRBgetdblattrarray(lpd->lp, GRB_DBL_ATTR_SLACK, 0, lpd->mar, sol->slacks)) 512 goto _return_err_; 513 if (sol->pis && GRBgetdblattrarray(lpd->lp, GRB_DBL_ATTR_PI, 0, lpd->mar, sol->pis)) 514 goto _return_err_; 515 if (sol->rbase && GRBgetintattrarray(lpd->lp, GRB_INT_ATTR_CBASIS, 0, lpd->mar, sol->rbase)) 516 goto _return_err_; 517 } 518 return 0; 519_return_err_: 520 Report_Solver_Error(cpx_env); 521 return -1; 522} 523 524 525/* Model callback function, currently only for messages */ 526static int 527_grb_callback(GRBmodel *model, void *cbdata, int where, void *usrdata) 528{ 529 switch(where) 530 { 531 case GRB_CB_MESSAGE: 532 { 533 char *msg; 534 if (solver_streams[LogType] == Current_Null) 535 return 0; 536 if (GRBcbget(cbdata, where, GRB_CB_MSG_STRING, &msg)) 537 return 0; 538 (void) ec_outfs(solver_streams[LogType], msg); 539 (void) ec_flush(solver_streams[LogType]); 540 break; 541 } 542 } 543 return 0; 544} 545 546 547/* Extra initialisation for new models, if needed */ 548static int 549cpx_newmodel(GRBmodel *lp) 550{ 551 int grb_output; 552 /* install messaging callback */ 553 if (GRBsetcallbackfunc(lp, _grb_callback, NULL)) 554 return -1; 555 return 0; 556} 557 558 559static int 560cpx_loadprob(lp_desc *lpd) 561{ 562 if (GRBloadmodel(cpx_env, &lpd->lp, "eclipse", 563 lpd->mac, lpd->mar, lpd->sense, 564 0.0, /*objcon*/ 565 lpd->objx, lpd->senx, lpd->rhsx, 566 lpd->matbeg, lpd->matcnt, lpd->matind, lpd->matval, 567 lpd->bdl, lpd->bdu, lpd->ctype, 568 NULL, /*varnames*/ 569 NULL /*cstrnames*/ 570 )) 571 goto _return_err_; 572 573 if (lpd->nsos && GRBaddsos(lpd->lp, lpd->nsos, lpd->nsosnz, 574 lpd->sostype, lpd->sosbeg, lpd->sosind, lpd->sosref)) 575 goto _return_err_; 576 577 /* Switch presolve off if requested, otherwise leave cpx_env's defaults */ 578 if (lpd->presolve == 0) 579 GRBsetintparam(GRBgetenv(lpd->lp), GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF); 580 581 return cpx_newmodel(lpd->lp); 582_return_err_: 583 Report_Solver_Error(cpx_env); 584 return -1; 585} 586 587 588static int 589cpx_delsos(lp_desc *lpd, int from, int to) 590{ 591 _grow_numbers_array(lpd, to); /* if necessary */ 592 return GRBdelsos(lpd->lp, to-from, &lpd->numbers[from]); 593} 594 595 596static int 597cpx_write(lp_desc *lpd, char *file, char *fmt) 598{ 599 char buf[1000]; 600 int suflen; 601 int flen = strlen(file); 602 suflen = strlen(fmt); 603 /* append the correct suffix, unless already there */ 604 if (!(flen>suflen && file[flen-suflen-1] == '.' && !strcmp(file+flen-suflen,fmt))) 605 file = strcat(strcat(strcpy(buf,file),"."),fmt); 606 CPXupdatemodel(lpd->lp); 607 if (GRBwrite(lpd->lp, file)) 608 goto _return_err_; 609 return 0; 610_return_err_: 611 Report_Solver_Error(cpx_env); 612 return -1; 613} 614 615 616static int 617cpx_read(lp_desc *lpd, char *file, char *fmt) 618{ 619 int sen, pre, mip, qp; 620 char buf[1000]; 621 char *suf; 622 623 /* append correct suffix, if not already there */ 624 suf = strrchr(file, '.'); 625 if (!suf || strcmp(suf+1, fmt)) 626 file = strcat(strcat(strcpy(buf,file),"."),fmt); 627 628 if (GRBreadmodel(cpx_env, file, &lpd->lp)) 629 goto _return_err_; 630 631 /* initialize non-zero fields in lp_desc */ 632 CallN(lpd->lpcopy = lpd->lp); /* no need for a copy */ 633 GRBgetintattr(lpd->lp, GRB_INT_ATTR_MODELSENSE, &sen); 634 lpd->sense = sen == GRB_MINIMIZE ? SENSE_MIN : SENSE_MAX; 635 GRBgetintattr(lpd->lp, GRB_INT_ATTR_NUMVARS, &lpd->mac); 636 GRBgetintattr(lpd->lp, GRB_INT_ATTR_NUMCONSTRS, &lpd->mar); 637 GRBgetintattr(lpd->lp, GRB_INT_ATTR_IS_MIP, &mip); 638 GRBgetintattr(lpd->lp, GRB_INT_ATTR_IS_QP, &qp); 639 lpd->prob_type = mip ? ( qp ? PROBLEM_MIQP : PROBLEM_MIP ) 640 : ( qp ? PROBLEM_QP : PROBLEM_LP ); 641 642 return cpx_newmodel(lpd->lp); 643_return_err_: 644 Report_Solver_Error(cpx_env); 645 return -1; 646} 647 648 649/* 650 * Parameter Table 651 * 652 * Extract #define GRB_xxx_PAR_ lines from gurobi_c.h and substitute as follows: 653 * s/^#define[ ]GRB_INT_PAR_\([^ ]*\).*$/{"\L\1\E", GRB_INT_PAR_\1, 0},/ 654 * s/^#define[ ]GRB_DBL_PAR_\([^ ]*\).*$/{"\L\1\E", GRB_DBL_PAR_\1, 1},/ 655 * s/^#define[ ]GRB_STR_PAR_\([^ ]*\).*$/{"\L\1\E", GRB_STR_PAR_\1, 2},/ 656 */ 657 658#define NUMPARAMS 83 659#define NUMALIASES 10 660static struct param_desc params[NUMPARAMS+NUMALIASES] = { 661{"bariterlimit", GRB_INT_PAR_BARITERLIMIT, 0}, 662{"cutoff", GRB_DBL_PAR_CUTOFF, 1}, 663{"iterationlimit", GRB_DBL_PAR_ITERATIONLIMIT, 1}, 664{"nodelimit", GRB_DBL_PAR_NODELIMIT, 1}, 665{"solutionlimit", GRB_INT_PAR_SOLUTIONLIMIT, 0}, 666{"timelimit", GRB_DBL_PAR_TIMELIMIT, 1}, 667{"feasibilitytol", GRB_DBL_PAR_FEASIBILITYTOL, 1}, 668{"intfeastol", GRB_DBL_PAR_INTFEASTOL, 1}, 669{"markowitztol", GRB_DBL_PAR_MARKOWITZTOL, 1}, 670{"mipgap", GRB_DBL_PAR_MIPGAP, 1}, 671{"mipgapabs", GRB_DBL_PAR_MIPGAPABS, 1}, 672{"optimalitytol", GRB_DBL_PAR_OPTIMALITYTOL, 1}, 673{"psdtol", GRB_DBL_PAR_PSDTOL, 1}, 674{"method", GRB_INT_PAR_METHOD, 0}, 675{"perturbvalue", GRB_DBL_PAR_PERTURBVALUE, 1}, 676{"objscale", GRB_DBL_PAR_OBJSCALE, 1}, 677{"scaleflag", GRB_INT_PAR_SCALEFLAG, 0}, 678{"simplexpricing", GRB_INT_PAR_SIMPLEXPRICING, 0}, 679{"quad", GRB_INT_PAR_QUAD, 0}, 680{"normadjust", GRB_INT_PAR_NORMADJUST, 0}, 681{"sifting", GRB_INT_PAR_SIFTING, 0}, 682{"siftmethod", GRB_INT_PAR_SIFTMETHOD, 0}, 683{"barconvtol", GRB_DBL_PAR_BARCONVTOL, 1}, 684{"barcorrectors", GRB_INT_PAR_BARCORRECTORS, 0}, 685{"barhomogeneous", GRB_INT_PAR_BARHOMOGENEOUS, 0}, 686{"barorder", GRB_INT_PAR_BARORDER, 0}, 687{"barqcpconvtol", GRB_DBL_PAR_BARQCPCONVTOL, 1}, 688{"crossover", GRB_INT_PAR_CROSSOVER, 0}, 689{"crossoverbasis", GRB_INT_PAR_CROSSOVERBASIS, 0}, 690{"branchdir", GRB_INT_PAR_BRANCHDIR, 0}, 691{"heuristics", GRB_DBL_PAR_HEURISTICS, 1}, 692{"improvestartgap", GRB_DBL_PAR_IMPROVESTARTGAP, 1}, 693{"improvestarttime", GRB_DBL_PAR_IMPROVESTARTTIME, 1}, 694{"minrelnodes", GRB_INT_PAR_MINRELNODES, 0}, 695{"mipfocus", GRB_INT_PAR_MIPFOCUS, 0}, 696{"nodefiledir", GRB_STR_PAR_NODEFILEDIR, 2}, 697{"nodefilestart", GRB_DBL_PAR_NODEFILESTART, 1}, 698{"nodemethod", GRB_INT_PAR_NODEMETHOD, 0}, 699{"pumppasses", GRB_INT_PAR_PUMPPASSES, 0}, 700{"rins", GRB_INT_PAR_RINS, 0}, 701{"submipnodes", GRB_INT_PAR_SUBMIPNODES, 0}, 702{"symmetry", GRB_INT_PAR_SYMMETRY, 0}, 703{"varbranch", GRB_INT_PAR_VARBRANCH, 0}, 704{"solutionnumber", GRB_INT_PAR_SOLUTIONNUMBER, 0}, 705{"zeroobjnodes", GRB_INT_PAR_ZEROOBJNODES, 0}, 706{"cuts", GRB_INT_PAR_CUTS, 0}, 707{"cliquecuts", GRB_INT_PAR_CLIQUECUTS, 0}, 708{"covercuts", GRB_INT_PAR_COVERCUTS, 0}, 709{"flowcovercuts", GRB_INT_PAR_FLOWCOVERCUTS, 0}, 710{"flowpathcuts", GRB_INT_PAR_FLOWPATHCUTS, 0}, 711{"gubcovercuts", GRB_INT_PAR_GUBCOVERCUTS, 0}, 712{"impliedcuts", GRB_INT_PAR_IMPLIEDCUTS, 0}, 713{"mipsepcuts", GRB_INT_PAR_MIPSEPCUTS, 0}, 714{"mircuts", GRB_INT_PAR_MIRCUTS, 0}, 715{"modkcuts", GRB_INT_PAR_MODKCUTS, 0}, 716{"zerohalfcuts", GRB_INT_PAR_ZEROHALFCUTS, 0}, 717{"networkcuts", GRB_INT_PAR_NETWORKCUTS, 0}, 718{"submipcuts", GRB_INT_PAR_SUBMIPCUTS, 0}, 719{"cutaggpasses", GRB_INT_PAR_CUTAGGPASSES, 0}, 720{"cutpasses", GRB_INT_PAR_CUTPASSES, 0}, 721{"gomorypasses", GRB_INT_PAR_GOMORYPASSES, 0}, 722{"aggregate", GRB_INT_PAR_AGGREGATE, 0}, 723{"aggfill", GRB_INT_PAR_AGGFILL, 0}, 724{"displayinterval", GRB_INT_PAR_DISPLAYINTERVAL, 0}, 725{"dualreductions", GRB_INT_PAR_DUALREDUCTIONS, 0}, 726{"iismethod", GRB_INT_PAR_IISMETHOD, 0}, 727{"infunbdinfo", GRB_INT_PAR_INFUNBDINFO, 0}, 728{"logfile", GRB_STR_PAR_LOGFILE, 2}, 729{"logtoconsole", GRB_INT_PAR_LOGTOCONSOLE, 0}, 730{"miqcpmethod", GRB_INT_PAR_MIQCPMETHOD, 0}, 731{"outputflag", GRB_INT_PAR_OUTPUTFLAG, 0}, 732{"precrush", GRB_INT_PAR_PRECRUSH, 0}, 733{"predeprow", GRB_INT_PAR_PREDEPROW, 0}, 734{"predual", GRB_INT_PAR_PREDUAL, 0}, 735{"prepasses", GRB_INT_PAR_PREPASSES, 0}, 736{"preqlinearize", GRB_INT_PAR_PREQLINEARIZE, 0}, 737{"presolve", GRB_INT_PAR_PRESOLVE, 0}, 738{"presparsify", GRB_INT_PAR_PRESPARSIFY, 0}, 739{"qcpdual", GRB_INT_PAR_QCPDUAL, 0}, 740{"resultfile", GRB_STR_PAR_RESULTFILE, 2}, 741{"threads", GRB_INT_PAR_THREADS, 0}, 742{"feasrelaxbigm", GRB_DBL_PAR_FEASRELAXBIGM, 1}, 743{"dummy", GRB_STR_PAR_DUMMY, 2}, 744 745/* NUMALIASES lines follow */ 746{"time_limit", GRB_DBL_PAR_TIMELIMIT, 1}, 747{"perturbation_const", GRB_DBL_PAR_PERTURBVALUE, 1}, 748{"feasibility_tol", GRB_DBL_PAR_FEASIBILITYTOL, 1}, 749{"markowitz_tol", GRB_DBL_PAR_MARKOWITZTOL, 1}, 750{"absmipgap", GRB_DBL_PAR_MIPGAPABS, 1}, 751{"optimality_tol", GRB_DBL_PAR_OPTIMALITYTOL, 1}, 752{"integrality", GRB_DBL_PAR_INTFEASTOL, 1}, 753{"iteration_limit", GRB_DBL_PAR_ITERATIONLIMIT, 1}, 754{"solution_limit", GRB_INT_PAR_SOLUTIONLIMIT, 0}, 755{"node_limit", GRB_DBL_PAR_NODELIMIT, 1}, 756 757}; 758 759#endif 760