00001
00002
00003
00004 #if defined(_MSC_VER)
00005
00006 # pragma warning(disable:4786)
00007 #endif
00008
00009 #include <cassert>
00010
00011 #include "CoinPackedMatrix.hpp"
00012 #include "OsiOslSolverInterface.hpp"
00013 #include "OsiCuts.hpp"
00014 #include "OsiRowCut.hpp"
00015 #include "OsiColCut.hpp"
00016
00017
00018
00019
00020
00021
00022 static const CoinPackedMatrix *
00023 toColumnOrderedGapFree(const CoinPackedMatrix& matrix)
00024 {
00025 CoinPackedMatrix * m = 0;
00026 if (matrix.isColOrdered()) {
00027 const int * start = matrix.getVectorStarts();
00028 const int * length = matrix.getVectorLengths();
00029 int i;
00030 for (i = matrix.getNumCols() - 1; i >= 0; --i)
00031 if (start[i+1] - start[i] != length[i])
00032 break;
00033 if (i >= 0) {
00034
00035 m = new CoinPackedMatrix();
00036 m->setExtraGap(0.0);
00037 m->setExtraMajor(0.0);
00038 m->operator=(matrix);
00039 }
00040 } else {
00041
00042 m = new CoinPackedMatrix();
00043 m->setExtraGap(0.0);
00044 m->setExtraMajor(0.0);
00045 m->reverseOrderedCopyOf(matrix);
00046 }
00047 return m ? m : &matrix;
00048 }
00049
00050
00051
00052
00053 void OsiOslSolverInterface::initialSolve()
00054 {
00055 EKKModel* model = getMutableModelPtr();
00056 int rtcod;
00057
00058 bool takeHint;
00059 OsiHintStrength strength;
00060 bool gotHint = getHintParam(OsiDoReducePrint,takeHint,strength);
00061 assert(gotHint);
00062 if (strength!=OsiHintIgnore&&takeHint) {
00063 if (!messageHandler()->logLevel())
00064 ekk_messagesPrintOff(model,1,5999);
00065 else if (messageHandler()->logLevel()==1)
00066 ekk_messagePrintOff(model,317);
00067 }
00068 #if 0
00069 ekk_crash(model,1);
00070 rtcod=ekk_primalSimplex(model,1);
00071 #elif 0
00072 ekk_setIiternum(model, 0);
00073 rtcod=ekk_simplex(model, 2);
00074 #else
00075 ekk_setIiternum(model, 0);
00076 rtcod=ekk_simplex(model, 0);
00077 #endif
00078
00079 if (rtcod>200)
00080 ekk_setIprobstat(model,6);
00081 }
00082
00083 void OsiOslSolverInterface::resolve()
00084 {
00085 EKKModel* model = getMutableModelPtr();
00086 int rtcod;
00087
00088 ekk_mergeBlocks(model, 1);
00089 ekk_setIiternum(model, 0);
00090
00091 bool takeHint;
00092 OsiHintStrength strength;
00093 bool gotHint = getHintParam(OsiDoReducePrint,takeHint,strength);
00094 assert(gotHint);
00095 if (strength!=OsiHintIgnore&&takeHint) {
00096 if (!messageHandler()->logLevel())
00097 ekk_messagesPrintOff(model,1,5999);
00098 else if (messageHandler()->logLevel()==1)
00099 ekk_messagePrintOff(model,317);
00100 }
00101 #if 0
00102 rtcod=ekk_dualSimplex(model);
00103 #else
00104 rtcod=ekk_simplex(model, 256 + 32);
00105 #endif
00106
00107 if (rtcod>200)
00108 ekk_setIprobstat(model,6);
00109 }
00110
00111 void OsiOslSolverInterface::branchAndBound()
00112 {
00113 EKKModel* model = getMutableModelPtr();
00114
00115 ekk_primalSimplex(model,1);
00116 #if 0
00117 EKKCuts cuts;
00118 cuts.numberCuts = 0;
00119 cuts.maxCuts = 0;
00120 cuts.cut = NULL;
00121
00122 EKKIntegerPresolve info;
00123 info.number01 = 0;
00124 info.sequence = NULL;
00125 info.numberClique = 0;
00126 info.cliqueType = NULL;
00127 info.cliqueMember = NULL;
00128 info.cliqueStart = NULL;
00129 info.implicationStart = NULL;
00130 info.implication = NULL;
00131 info.numberChains = 0;
00132 info.chainInformation = NULL;
00133
00134 ekk_integerPresolve(model, &info, &cuts, 0);
00135
00136
00137 ekk_setRthreshold(model, CoinMax(1.0e-3, ekk_getRthreshold(model)));
00138 ekk_branchAndCut(model, NULL, NULL, &info, &cuts, 0, 0);
00139 ekk_deleteCuts(&cuts);
00140 ekk_deleteIntegerPresolve(&info);
00141 #else
00142
00143
00144
00145 ekk_branchAndBound(model, NULL, NULL);
00146
00147 #endif
00148 }
00149
00150
00151
00152
00153
00154 bool
00155 OsiOslSolverInterface::setIntParam(OsiIntParam key, int value)
00156 {
00157 switch (key) {
00158 case OsiMaxNumIteration:
00159 if (value < 0)
00160 return false;
00161
00162
00163 ekk_setImaxiter(getMutableModelPtr(), value);
00164 break;
00165 case OsiMaxNumIterationHotStart:
00166 if (value < 0)
00167 return false;
00168 OsiSolverInterface::setIntParam(key, value);
00169 break;
00170 case OsiLastIntParam:
00171 return false;
00172 }
00173 return true;
00174 }
00175
00176
00177
00178 bool
00179 OsiOslSolverInterface::setDblParam(OsiDblParam key, double value)
00180 {
00181 int retval;
00182
00183 switch (key) {
00184 case OsiDualObjectiveLimit:
00185 retval = ekk_setRbbcutoff(getMutableModelPtr(), value);
00186
00187 return retval == 0;
00188
00189 case OsiPrimalObjectiveLimit:
00190 return OsiSolverInterface::setDblParam(key, value);
00191
00192 case OsiDualTolerance:
00193 retval = ekk_setRtoldinf(getMutableModelPtr(), value);
00194 return retval == 0;
00195
00196 case OsiPrimalTolerance:
00197 retval = ekk_setRtolpinf(getMutableModelPtr(), value);
00198 return retval == 0;
00199
00200 case OsiObjOffset:
00201 retval = ekk_setRobjectiveOffset(getMutableModelPtr(), value);
00202 return retval == 0;
00203
00204 case OsiLastDblParam:
00205 return false;
00206 }
00207 return true;
00208 }
00209
00210
00211
00212 bool
00213 OsiOslSolverInterface::setStrParam(OsiStrParam key, const std::string & value)
00214 {
00215 int retval;
00216 switch (key) {
00217 case OsiProbName:
00218 retval = ekk_setCname(getMutableModelPtr(), value.c_str());
00219 return retval == 0;
00220
00221 case OsiSolverName:
00222 return false;
00223 case OsiLastStrParam:
00224 return false;
00225 }
00226 return false;
00227 }
00228
00229
00230
00231
00232 bool
00233 OsiOslSolverInterface::getIntParam(OsiIntParam key, int& value) const
00234 {
00235 switch (key) {
00236 case OsiMaxNumIteration:
00237 value = ekk_getImaxiter(getMutableModelPtr());
00238 break;
00239 case OsiMaxNumIterationHotStart:
00240 OsiSolverInterface::getIntParam(key, value);
00241 break;
00242 case OsiLastIntParam:
00243 return false;
00244 }
00245 return true;
00246 }
00247
00248
00249
00250 bool
00251 OsiOslSolverInterface::getDblParam(OsiDblParam key, double& value) const
00252 {
00253
00254 switch (key) {
00255 case OsiDualObjectiveLimit:
00256 value = ekk_getRbbcutoff(getMutableModelPtr());
00257
00258 break;
00259 case OsiPrimalObjectiveLimit:
00260 OsiSolverInterface::getDblParam(key, value);
00261 break;
00262 case OsiDualTolerance:
00263 value = ekk_getRtoldinf(getMutableModelPtr());
00264 break;
00265 case OsiPrimalTolerance:
00266 value = ekk_getRtolpinf(getMutableModelPtr());
00267 break;
00268 case OsiObjOffset:
00269 value = ekk_getRobjectiveOffset(getMutableModelPtr());
00270 break;
00271 case OsiLastDblParam:
00272 return false;
00273 }
00274 return true;
00275 }
00276
00277
00278
00279 bool
00280 OsiOslSolverInterface::getStrParam(OsiStrParam key, std::string & value) const
00281 {
00282 switch (key) {
00283 case OsiProbName:
00284 value = ekk_getCname(getMutableModelPtr());
00285 break;
00286 case OsiSolverName:
00287 value = "osl";
00288 break;
00289 case OsiLastStrParam:
00290 return false;
00291 }
00292 return true;
00293 }
00294
00295
00296
00297
00298
00299
00300 bool OsiOslSolverInterface::isAbandoned() const
00301 {
00302 EKKModel* model = getMutableModelPtr();
00303 return (ekk_getIprobstat(model)==6);
00304 }
00305
00306 bool OsiOslSolverInterface::isProvenOptimal() const
00307 {
00308 EKKModel* model = getMutableModelPtr();
00309 const int stat = ekk_getIprobstat(model);
00310 return (stat == 0);
00311 }
00312
00313 bool OsiOslSolverInterface::isProvenPrimalInfeasible() const
00314 {
00315
00316 EKKModel* model = getMutableModelPtr();
00317 const int stat = ekk_getIprobstat(model);
00318 if (stat != 1)
00319 return false;
00320 if (ekk_lastAlgorithm(model) == 2) {
00321 const int stat2 = ekk_getIprobstat2(model);
00322 if (stat2 == 11)
00323 return false;
00324 }
00325 return true;
00326 }
00327
00328 bool OsiOslSolverInterface::isProvenDualInfeasible() const
00329 {
00330 EKKModel* model = getMutableModelPtr();
00331 const int stat = ekk_getIprobstat(model);
00332 return stat == 2;
00333 }
00334
00335 bool OsiOslSolverInterface::isPrimalObjectiveLimitReached() const
00336 {
00337
00338 double limit = 0.0;
00339 getDblParam(OsiPrimalObjectiveLimit, limit);
00340 if (limit > 1e30) {
00341
00342 return false;
00343 }
00344
00345 EKKModel* model = getMutableModelPtr();
00346 if (ekk_getIprobstat(model)==6)
00347 return false;
00348 const int lastalgo = ekk_lastAlgorithm(model);
00349 const double obj = ekk_getRobjvalue(model);
00350 const double maxmin = ekk_getRmaxmin(model);
00351
00352 switch (lastalgo) {
00353 case 0:
00354 return maxmin > 0 ? (obj < limit) : (obj > limit) ;
00355 case 2:
00356 if (ekk_getIprobstat(model) == 0)
00357 return maxmin > 0 ? (obj < limit) : (obj > limit) ;
00358 return false;
00359 case 1:
00360 return maxmin > 0 ? (obj < limit) : (obj > limit) ;
00361 }
00362 return false;
00363 }
00364
00365 bool OsiOslSolverInterface::isDualObjectiveLimitReached() const
00366 {
00367
00368 double limit = 0.0;
00369 getDblParam(OsiDualObjectiveLimit, limit);
00370 if (limit > 1e30) {
00371
00372 return false;
00373 }
00374
00375 EKKModel* model = getMutableModelPtr();
00376 if (ekk_getIprobstat(model)==6)
00377 return false;
00378 const int lastalgo = ekk_lastAlgorithm(model);
00379 const double obj = ekk_getRobjvalue(model);
00380 const double maxmin = ekk_getRmaxmin(model);
00381
00382 switch (lastalgo) {
00383 case 0:
00384 return maxmin > 0 ? (obj > limit) : (obj < limit) ;
00385 case 1:
00386 if (ekk_getIprobstat(model) == 0)
00387 return maxmin > 0 ? (obj > limit) : (obj < limit) ;
00388 return false;
00389 case 2:
00390 if (ekk_getIprobstat(model) != 0 && ekk_getIprobstat2(model) == 11)
00391
00392 return true;
00393 return maxmin > 0 ? (obj > limit) : (obj < limit) ;
00394 }
00395 return false;
00396 }
00397
00398 bool OsiOslSolverInterface::isIterationLimitReached() const
00399 {
00400
00401 EKKModel* model = getMutableModelPtr();
00402 if (ekk_getIprobstat(model)==6)
00403 return false;
00404 const int stat = ekk_getIprobstat(model);
00405 return (stat == 3);
00406 }
00407
00408
00409
00410
00411
00412 CoinWarmStart* OsiOslSolverInterface::getWarmStart() const
00413 {
00414
00415 EKKModel* model = getMutableModelPtr();
00416 const int numcols = getNumCols();
00417 const int numrows = getNumRows();
00418
00419 CoinWarmStartBasis* ws = new CoinWarmStartBasis;
00420 ws->setSize(numcols, numrows);
00421
00422 int i;
00423
00424 for (i = 0; i < numrows; ++i) {
00425 switch (ekk_rowStatus(model, i)) {
00426 case -2:
00427 case -1:
00428 ws->setArtifStatus(i, CoinWarmStartBasis::atLowerBound);
00429 break;
00430 case 0:
00431 ws->setArtifStatus(i, CoinWarmStartBasis::basic);
00432 break;
00433 case 1:
00434 case 2:
00435 ws->setArtifStatus(i, CoinWarmStartBasis::atUpperBound);
00436 break;
00437 }
00438 }
00439
00440 for (i = 0; i < numcols; ++i) {
00441 switch (ekk_columnStatus(model, i)) {
00442 case -2:
00443 case -1:
00444 ws->setStructStatus(i, CoinWarmStartBasis::atLowerBound);
00445 break;
00446 case 0:
00447 ws->setStructStatus(i, CoinWarmStartBasis::basic);
00448 break;
00449 case 1:
00450 case 2:
00451 ws->setStructStatus(i, CoinWarmStartBasis::atUpperBound);
00452 break;
00453 }
00454 }
00455
00456 return ws;
00457 }
00458
00459
00460
00461 bool OsiOslSolverInterface::setWarmStart(const CoinWarmStart* warmstart)
00462 {
00463
00464 const CoinWarmStartBasis* ws =
00465 dynamic_cast<const CoinWarmStartBasis*>(warmstart);
00466
00467 if (! ws)
00468 return false;
00469
00470 const int numcols = ws->getNumStructural();
00471 const int numrows = ws->getNumArtificial();
00472
00473 EKKModel* model = getMutableModelPtr();
00474
00475 const int maxdim = CoinMax(numcols, numrows);
00476 int * atLower = new int[maxdim];
00477 int * atUpper = new int[maxdim];
00478 int * basic = new int[maxdim];
00479 int numLower = 0;
00480 int numUpper = 0;
00481 int numBasic = 0;
00482 int i;
00483
00484 for (i = 0; i < numrows; ++i) {
00485 switch (ws->getArtifStatus(i)) {
00486 case CoinWarmStartBasis::atUpperBound:
00487 atUpper[numUpper++] = i;
00488 break;
00489 case CoinWarmStartBasis::atLowerBound:
00490 atLower[numLower++] = i;
00491 break;
00492 case CoinWarmStartBasis::basic:
00493 basic[numBasic++] = i;
00494 break;
00495 case CoinWarmStartBasis::isFree:
00496 basic[numBasic++] = i;
00497 break;
00498 }
00499 }
00500 if (ekk_setRowsNonBasicAtLower(model, numLower, atLower) != 0)
00501 goto setWarmStart_Error;
00502 if (ekk_setRowsNonBasicAtUpper(model, numUpper, atUpper) != 0)
00503 goto setWarmStart_Error;
00504 if (ekk_markRowsAsBasic(model, numBasic, basic) != 0)
00505 goto setWarmStart_Error;
00506
00507 numLower = 0;
00508 numUpper = 0;
00509 numBasic = 0;
00510 for (i = 0; i < numcols; ++i) {
00511 switch (ws->getStructStatus(i)) {
00512 case CoinWarmStartBasis::atUpperBound:
00513 atUpper[numUpper++] = i;
00514 break;
00515 case CoinWarmStartBasis::atLowerBound:
00516 atLower[numLower++] = i;
00517 break;
00518 case CoinWarmStartBasis::basic:
00519 basic[numBasic++] = i;
00520 break;
00521 case CoinWarmStartBasis::isFree:
00522 basic[numBasic++] = i;
00523 break;
00524 }
00525 }
00526 if (ekk_setColumnsNonBasicAtLower(model, numLower, atLower) != 0)
00527 goto setWarmStart_Error;
00528 if (ekk_setColumnsNonBasicAtUpper(model, numUpper, atUpper) != 0)
00529 goto setWarmStart_Error;
00530 if (ekk_markColumnsAsBasic(model, numBasic, basic) != 0)
00531 goto setWarmStart_Error;
00532
00533 delete[] basic;
00534 delete[] atUpper;
00535 delete[] atLower;
00536 return true;
00537
00538 setWarmStart_Error:
00539 delete[] basic;
00540 delete[] atUpper;
00541 delete[] atLower;
00542 return false;
00543 }
00544
00545
00546
00547
00548
00549 void OsiOslSolverInterface::markHotStart()
00550 {
00551
00552
00553 delete ws_;
00554 ws_ = dynamic_cast<CoinWarmStartBasis*>(getWarmStart());
00555
00556 }
00557
00558 void OsiOslSolverInterface::solveFromHotStart()
00559 {
00560 EKKModel* model = getMutableModelPtr();
00561
00562 ekk_setIiternum(model, 0);
00563 setWarmStart(ws_);
00564
00565 itlimOrig_ = ekk_getImaxiter(model);
00566 int itlim;
00567 OsiSolverInterface::getIntParam(OsiMaxNumIterationHotStart, itlim);
00568 ekk_setImaxiter(model, itlim);
00569 resolve();
00570 ekk_setImaxiter(model, itlimOrig_);
00571 }
00572
00573 void OsiOslSolverInterface::unmarkHotStart()
00574 {
00575
00576 EKKModel* model = getMutableModelPtr();
00577
00578 ekk_setImaxiter(model, itlimOrig_);
00579 delete ws_;
00580 ws_ = NULL;
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590 int OsiOslSolverInterface::getNumCols() const
00591 {
00592 return ekk_getInumcols(getMutableModelPtr());
00593 }
00594 int OsiOslSolverInterface::getNumRows() const
00595 {
00596 return ekk_getInumrows(getMutableModelPtr());
00597 }
00598 int OsiOslSolverInterface::getNumElements() const
00599 {
00600 return ekk_getInumels(getMutableModelPtr());
00601 }
00602
00603
00604
00605
00606 const double * OsiOslSolverInterface::getColLower() const
00607 {
00608 return ekk_collower(getMutableModelPtr());
00609 }
00610
00611 const double * OsiOslSolverInterface::getColUpper() const
00612 {
00613 return ekk_colupper(getMutableModelPtr());
00614 }
00615
00616 const char * OsiOslSolverInterface::getRowSense() const
00617 {
00618 extractSenseRhsRange();
00619 return rowsense_;
00620 }
00621
00622 const double * OsiOslSolverInterface::getRightHandSide() const
00623 {
00624 extractSenseRhsRange();
00625 return rhs_;
00626 }
00627
00628 const double * OsiOslSolverInterface::getRowRange() const
00629 {
00630 extractSenseRhsRange();
00631 return rowrange_;
00632 }
00633
00634 const double * OsiOslSolverInterface::getRowLower() const
00635 {
00636 return ekk_rowlower(getMutableModelPtr());
00637 }
00638
00639 const double * OsiOslSolverInterface::getRowUpper() const
00640 {
00641 return ekk_rowupper(getMutableModelPtr());
00642 }
00643
00644 const double * OsiOslSolverInterface::getObjCoefficients() const
00645 {
00646 return ekk_objective(getMutableModelPtr());
00647 }
00648
00649 double OsiOslSolverInterface::getObjSense() const
00650 {
00651 return ekk_getRmaxmin(getMutableModelPtr());
00652 }
00653
00654
00655
00656
00657 bool OsiOslSolverInterface::isContinuous(int colNumber) const
00658 {
00659 const char * intType = ekk_integerType(getMutableModelPtr());
00660 if ( intType==NULL ) return true;
00661 if ( intType[colNumber]==0 ) return true;
00662 return false;
00663 }
00664
00665 #if 0
00666 bool OsiOslSolverInterface::isInteger(
00667 int columnNumber ) const
00668 {
00669 return !(isContinuous(columnNumber));
00670 }
00671
00672 bool OsiOslSolverInterface::isBinary(
00673 int columnNumber ) const
00674 {
00675 if ( isContinuous(columnNumber) ) return false;
00676 EKKModel * m=getMutableModelPtr();
00677 const double * upper = ekk_colupper(m);
00678 const double * lower = ekk_collower(m);
00679 if (
00680 (upper[columnNumber]== 1 || upper[columnNumber]== 0) &&
00681 (lower[columnNumber]== 0 || lower[columnNumber]==1)
00682 ) return true;
00683 else return false;
00684 }
00685
00686 bool OsiOslSolverInterface::isIntegerNonBinary(
00687 int columnNumber ) const
00688 {
00689 if ( isInteger(columnNumber) && !isBinary(columnNumber) )
00690 return true;
00691 else return false;
00692 }
00693
00694 bool OsiOslSolverInterface::isFreeBinary(
00695 int columnNumber ) const
00696 {
00697 if ( isContinuous(columnNumber) ) return false;
00698 EKKModel * m=getMutableModelPtr();
00699 const double * upper = ekk_colupper(m);
00700 const double * lower = ekk_collower(m);
00701 if (
00702 (upper[columnNumber]== 1) &&
00703 (lower[columnNumber]== 0)
00704 ) return true;
00705 else return false;
00706 }
00707 #endif
00708
00709
00710
00711
00712 const CoinPackedMatrix * OsiOslSolverInterface::getMatrixByRow() const
00713 {
00714 if ( matrixByRow_ == NULL ) {
00715 EKKMatrixCopy rowCopy;
00716 ekk_createRowCopy(getMutableModelPtr(), &rowCopy);
00717 matrixByRow_ = new CoinPackedMatrix();
00718 matrixByRow_->copyOf(false ,
00719 getNumCols(), getNumRows(), getNumElements(),
00720 rowCopy.element, rowCopy.index, rowCopy.start,
00721 NULL );
00722 ekk_free(rowCopy.element);
00723 ekk_free(rowCopy.index);
00724 ekk_free(rowCopy.start);
00725 }
00726 return matrixByRow_;
00727 }
00728
00729 const CoinPackedMatrix * OsiOslSolverInterface::getMatrixByCol() const
00730 {
00731 if ( matrixByColumn_ == NULL ) {
00732 EKKMatrixCopy colCopy;
00733 ekk_createColumnCopy(getMutableModelPtr(), &colCopy);
00734 matrixByColumn_ = new CoinPackedMatrix();
00735 matrixByColumn_->copyOf(true ,
00736 getNumRows(), getNumCols(), getNumElements(),
00737 colCopy.element, colCopy.index, colCopy.start,
00738 NULL );
00739 ekk_free(colCopy.element);
00740 ekk_free(colCopy.index);
00741 ekk_free(colCopy.start);
00742 }
00743 return matrixByColumn_;
00744 }
00745
00746
00747
00748 double OsiOslSolverInterface::getInfinity() const
00749 {
00750 return OSL_INFINITY;
00751 }
00752
00753
00754
00755
00756
00757 const double * OsiOslSolverInterface::getColSolution() const
00758 {
00759 return ekk_colsol(getMutableModelPtr());
00760 }
00761
00762
00763 const double * OsiOslSolverInterface::getRowPrice() const
00764 {
00765 return ekk_rowduals(getMutableModelPtr());
00766 }
00767
00768 const double * OsiOslSolverInterface::getReducedCost() const
00769 {
00770
00771 return ekk_colrcosts(getMutableModelPtr());
00772 }
00773
00774 const double * OsiOslSolverInterface::getRowActivity() const
00775 {
00776
00777 return ekk_rowacts(getMutableModelPtr());
00778 }
00779
00780 double OsiOslSolverInterface::getObjValue() const
00781 {
00782 #if 0
00783
00784
00785 return ekk_getRobjvalue(getMutableModelPtr());
00786 #else
00787 return OsiSolverInterface::getObjValue();
00788 #endif
00789 }
00790
00791 int OsiOslSolverInterface::getIterationCount() const
00792 {
00793 return ekk_getIiternum(getMutableModelPtr());
00794 }
00795
00796 std::vector<double*> OsiOslSolverInterface::getDualRays(int maxNumRays) const
00797 {
00798 const int m = getNumRows();
00799 double* ray = new double[m];
00800 const double* negray = ekk_rowaux(getMutableModelPtr());
00801 for (int i = 0; i < m; ++i) {
00802 ray[i] = -negray[i];
00803 }
00804 return std::vector<double*>(1, ray);
00805 }
00806
00807 std::vector<double*> OsiOslSolverInterface::getPrimalRays(int maxNumRays) const
00808 {
00809 const int n = getNumCols();
00810 double* ray = new double[n];
00811 CoinDisjointCopyN(ekk_colaux(getMutableModelPtr()), n, ray);
00812 return std::vector<double*>(1, ray);
00813 }
00814
00815 #if 0
00816 OsiVectorInt
00817 OsiOslSolverInterface::getFractionalIndices(const double etol) const
00818 {
00819 OsiVectorInt retVal;
00820 EKKModel * m = getMutableModelPtr();
00821 int numInts = ekk_getInumints(m);
00822 int * intInx = ekk_listOfIntegers(m);
00823 const double * colSolVec = ekk_colsol(m);
00824 OsiAbsFltEq eq(etol);
00825 for ( int i=0; i<numInts; i++ ) {
00826 const double colSolElem = colSolVec[intInx[i]];
00827 const double distanceFromInteger = colSolElem - floor(colSolElem + 0.5);
00828 if ( !eq( distanceFromInteger, 0.0 ) ) {
00829 retVal.push_back(intInx[i]);
00830 }
00831 }
00832 ekk_free( intInx );
00833 return retVal;
00834 }
00835 #endif
00836
00837
00838
00839
00840 void
00841 OsiOslSolverInterface::setObjCoeff( int elementIndex, double elementValue )
00842 {
00843
00844 EKKModel* model = getMutableModelPtr();
00845 ekk_copyObjective(model, &elementValue, elementIndex, elementIndex+1 );
00846 }
00847
00848 void
00849 OsiOslSolverInterface::setColLower( int elementIndex, double elementValue )
00850 {
00851
00852 EKKModel* model = getMutableModelPtr();
00853 const double newVal =
00854 forceIntoRange(elementValue, -OSL_INFINITY, OSL_INFINITY);
00855 ekk_copyCollower(model, &newVal, elementIndex, elementIndex+1 );
00856 }
00857
00858 void
00859 OsiOslSolverInterface::setColUpper( int elementIndex, double elementValue )
00860 {
00861
00862 EKKModel* model = getMutableModelPtr();
00863 const double newVal =
00864 forceIntoRange(elementValue, -OSL_INFINITY, OSL_INFINITY);
00865 ekk_copyColupper(model, &newVal, elementIndex, elementIndex+1 );
00866 }
00867
00868 void OsiOslSolverInterface::setColSetBounds(const int* indexFirst,
00869 const int* indexLast,
00870 const double* boundList)
00871 {
00872
00873 const int numcols = getNumCols();
00874 if (indexLast - indexFirst < numcols/8) {
00875
00876 while (indexFirst != indexLast) {
00877 setColBounds(*indexFirst, boundList[0], boundList[1]);
00878 ++indexFirst;
00879 boundList += 2;
00880 }
00881 } else {
00882
00883 EKKModel* model = getMutableModelPtr();
00884 double * lower = ekk_getCollower(model);
00885 double * upper = ekk_getColupper(model);
00886 while (indexFirst != indexLast) {
00887 const int iCol=*indexFirst++;
00888 lower[iCol]= forceIntoRange(*boundList++, -OSL_INFINITY, OSL_INFINITY);
00889 upper[iCol]= forceIntoRange(*boundList++, -OSL_INFINITY, OSL_INFINITY);
00890 }
00891 ekk_setCollower(model, lower);
00892 ekk_setColupper(model, upper);
00893 ekk_free(lower);
00894 ekk_free(upper);
00895 }
00896 }
00897
00898 void
00899 OsiOslSolverInterface::setRowLower( int i, double elementValue )
00900 {
00901
00902 EKKModel* model = getMutableModelPtr();
00903 const double newVal =
00904 forceIntoRange(elementValue, -OSL_INFINITY, OSL_INFINITY);
00905 ekk_copyRowlower(model, &newVal, i, i+1 );
00906 if (rowsense_ != NULL) {
00907 assert ((rhs_ != NULL) && (rowrange_ != NULL));
00908 convertBoundToSense(newVal, getRowUpper()[i],
00909 rowsense_[i], rhs_[i], rowrange_[i]);
00910 }
00911 }
00912
00913 void
00914 OsiOslSolverInterface::setRowUpper( int i, double elementValue )
00915 {
00916
00917 const double newVal =
00918 forceIntoRange(elementValue, -OSL_INFINITY, OSL_INFINITY);
00919 ekk_copyRowupper(getMutableModelPtr(), &newVal, i, i+1 );
00920 if (rowsense_ != NULL) {
00921 assert ((rhs_ != NULL) && (rowrange_ != NULL));
00922 convertBoundToSense(getRowLower()[i], newVal,
00923 rowsense_[i], rhs_[i], rowrange_[i]);
00924 }
00925 }
00926
00927 void
00928 OsiOslSolverInterface::setRowBounds( int i,
00929 double lower, double upper )
00930 {
00931
00932 const double newLower = forceIntoRange(lower, -OSL_INFINITY, OSL_INFINITY);
00933 const double newUpper = forceIntoRange(upper, -OSL_INFINITY, OSL_INFINITY);
00934 EKKModel* model = getMutableModelPtr();
00935 ekk_copyRowlower(model, &newLower, i, i+1 );
00936 ekk_copyRowupper(model, &newUpper, i, i+1 );
00937 if (rowsense_ != NULL) {
00938 assert ((rhs_ != NULL) && (rowrange_ != NULL));
00939 convertBoundToSense(newLower, newUpper,
00940 rowsense_[i], rhs_[i], rowrange_[i]);
00941 }
00942 }
00943
00944 void
00945 OsiOslSolverInterface::setRowType(int i, char sense, double rightHandSide,
00946 double range)
00947 {
00948
00949 double lower, upper;
00950 convertSenseToBound(sense, rightHandSide, range, lower, upper);
00951 setRowBounds(i, lower, upper);
00952 }
00953
00954 void OsiOslSolverInterface::setRowSetBounds(const int* indexFirst,
00955 const int* indexLast,
00956 const double* boundList)
00957 {
00958
00959 const int numrows = getNumRows();
00960 if (indexLast - indexFirst < numrows / 16) {
00961
00962 while (indexFirst != indexLast) {
00963 setRowBounds(*indexFirst, boundList[0], boundList[1]);
00964 ++indexFirst;
00965 boundList += 2;
00966 }
00967 } else {
00968
00969 EKKModel* model = getMutableModelPtr();
00970 double * lower = ekk_getRowlower(model);
00971 double * upper = ekk_getRowupper(model);
00972 const int len = indexLast - indexFirst;
00973 while (indexFirst != indexLast) {
00974 const int iRow=*indexFirst++;
00975 lower[iRow]= forceIntoRange(*boundList++, -OSL_INFINITY, OSL_INFINITY);
00976 upper[iRow]= forceIntoRange(*boundList++, -OSL_INFINITY, OSL_INFINITY);
00977 }
00978 if (rowsense_ != NULL) {
00979 assert ((rhs_ != NULL) && (rowrange_ != NULL));
00980 indexFirst -= len;
00981 while (indexFirst != indexLast) {
00982 const int iRow=*indexFirst++;
00983 convertBoundToSense(lower[iRow], upper[iRow],
00984 rowsense_[iRow], rhs_[iRow], rowrange_[iRow]);
00985 }
00986 }
00987 ekk_setRowlower(model, lower);
00988 ekk_setRowupper(model, upper);
00989 ekk_free(lower);
00990 ekk_free(upper);
00991 }
00992 }
00993
00994 void
00995 OsiOslSolverInterface::setRowSetTypes(const int* indexFirst,
00996 const int* indexLast,
00997 const char* senseList,
00998 const double* rhsList,
00999 const double* rangeList)
01000 {
01001
01002 const int numrows = getNumRows();
01003 if (indexLast - indexFirst < numrows / 16) {
01004
01005 while (indexFirst != indexLast) {
01006 if (rangeList){
01007 setRowType(*indexFirst++, *senseList++, *rhsList++, *rangeList++);
01008 } else {
01009 setRowType(*indexFirst++, *senseList++, *rhsList++, 0);
01010 }
01011 }
01012 } else {
01013
01014 EKKModel* model = getMutableModelPtr();
01015 double * lower = ekk_getRowlower(model);
01016 double * upper = ekk_getRowupper(model);
01017 const int len = indexLast - indexFirst;
01018 while (indexFirst != indexLast) {
01019 const int iRow= *indexFirst++;
01020 if (rangeList){
01021 convertSenseToBound(*senseList++, *rhsList++, *rangeList++,
01022 lower[iRow], upper[iRow]);
01023 } else {
01024 convertSenseToBound(*senseList++, *rhsList++, 0,
01025 lower[iRow], upper[iRow]);
01026 }
01027 }
01028 if (rowsense_ != NULL) {
01029 assert ((rhs_ != NULL) && (rowrange_ != NULL));
01030 indexFirst -= len;
01031 senseList -= len;
01032 rhsList -= len;
01033 if (rangeList)
01034 rangeList -= len;
01035 while (indexFirst != indexLast) {
01036 const int iRow=*indexFirst++;
01037 rowsense_[iRow] = *senseList++;
01038 rhs_[iRow] = *rhsList++;
01039 if (rangeList)
01040 rowrange_[iRow] = *rangeList++;
01041 }
01042 }
01043 ekk_setRowlower(model, lower);
01044 ekk_setRowupper(model, upper);
01045 ekk_free(lower);
01046 ekk_free(upper);
01047 }
01048 }
01049
01050 void
01051 OsiOslSolverInterface::setContinuous(int index)
01052 {
01053
01054 EKKModel* model = getMutableModelPtr();
01055 int intnum = ekk_getInumints(model);
01056 if (intnum > 0) {
01057 int * intlist = ekk_listOfIntegers(model);
01058 int * inspoint = std::lower_bound(intlist, intlist + intnum, index);
01059 if (*inspoint == index) {
01060 ekk_deleteIntegerInformation(model);
01061 if (intnum > 1) {
01062
01063 CoinCopy(inspoint + 1, intlist + intnum, inspoint);
01064 ekk_addIntegerSet(model, 100, intnum - 1, intlist, NULL, NULL);
01065 }
01066 }
01067 ekk_free(intlist);
01068 }
01069 }
01070
01071 void
01072 OsiOslSolverInterface::setInteger(int index)
01073 {
01074 ekk_markAsInteger(getMutableModelPtr(), index);
01075 }
01076
01077 void
01078 OsiOslSolverInterface::setContinuous(const int* indices, int len)
01079 {
01080
01081 EKKModel* model = getMutableModelPtr();
01082 int intnum = ekk_getInumints(model);
01083 if (intnum > 0 && len > 0) {
01084 int * intlist = ekk_listOfIntegers(model);
01085 int * sorted = new int[len];
01086 CoinDisjointCopyN(indices, len, sorted);
01087 std::sort(sorted, sorted+len);
01088 int * diff = new int[intnum];
01089 int numdiff = std::set_difference(intlist, intlist+intnum,
01090 indices, indices+len, diff) - diff;
01091 if (numdiff < intnum) {
01092 ekk_deleteIntegerInformation(model);
01093 if (numdiff > 0) {
01094 ekk_addIntegerSet(model, 100, numdiff, diff, NULL, NULL);
01095 }
01096 }
01097 delete[] diff;
01098 delete[] sorted;
01099 ekk_free(intlist);
01100 }
01101 }
01102
01103 void
01104 OsiOslSolverInterface::setInteger(const int* indices, int len)
01105 {
01106 ekk_addIntegerSet(getMutableModelPtr(), 100, len, indices, NULL, NULL);
01107 }
01108
01109 void OsiOslSolverInterface::setObjSense(double s)
01110 {
01111 ekk_setRmaxmin(getMutableModelPtr(),s);
01112 }
01113
01114 void OsiOslSolverInterface::setColSolution(const double * cs)
01115 {
01116 EKKModel * m = getMutableModelPtr();
01117 ekk_copyColsol(m,cs,0,ekk_getInumcols(m));
01118 }
01119
01120 void OsiOslSolverInterface::setRowPrice(const double * rs)
01121 {
01122 EKKModel * m = getMutableModelPtr();
01123 ekk_copyRowduals(m,rs,0,ekk_getInumrows(m));
01124 }
01125
01126
01127
01128
01129 void
01130 OsiOslSolverInterface::addCol(const CoinPackedVectorBase& vec,
01131 const double collb, const double colub,
01132 const double obj)
01133 {
01134
01135 ekk_addOneColumn(getModelPtr(), obj, collb, colub,
01136 vec.getNumElements(), vec.getIndices(), vec.getElements());
01137 }
01138
01139 void
01140 OsiOslSolverInterface::addCols(const int numcols,
01141 const CoinPackedVectorBase * const * cols,
01142 const double* collb, const double* colub,
01143 const double* obj)
01144 {
01145
01146 int i;
01147 int nz = 0;
01148 for (i = 0; i < numcols; ++i)
01149 nz += cols[i]->getNumElements();
01150
01151 int* index = new int[nz];
01152 double* elem = new double[nz];
01153 int* start = new int[numcols+1];
01154
01155 nz = 0;
01156 start[0] = 0;
01157 for (i = 0; i < numcols; ++i) {
01158 const CoinPackedVectorBase* col = cols[i];
01159 const int len = col->getNumElements();
01160 CoinDisjointCopyN(col->getIndices(), len, index+nz);
01161 CoinDisjointCopyN(col->getElements(), len, elem+nz);
01162 nz += len;
01163 start[i+1] = nz;
01164 }
01165 ekk_addColumns(getModelPtr(), numcols, obj, collb, colub,
01166 start, index, elem);
01167 delete[] start;
01168 delete[] elem;
01169 delete[] index;
01170 }
01171
01172 void
01173 OsiOslSolverInterface::deleteCols(const int num, const int * columnIndices)
01174 {
01175
01176 ekk_deleteColumns(getModelPtr(), num, columnIndices);
01177 }
01178
01179 void
01180 OsiOslSolverInterface::addRow(const CoinPackedVectorBase& vec,
01181 const double rowlb, const double rowub)
01182 {
01183
01184 ekk_addOneRow(getModelPtr(), rowlb, rowub,
01185 vec.getNumElements(), vec.getIndices(), vec.getElements());
01186 }
01187
01188 void
01189 OsiOslSolverInterface::addRow(const CoinPackedVectorBase& vec,
01190 const char rowsen, const double rowrhs,
01191 const double rowrng)
01192 {
01193
01194 double rowlb, rowub;
01195 convertSenseToBound(rowsen, rowrhs, rowrng, rowlb, rowub);
01196 ekk_addOneRow(getModelPtr(), rowlb, rowub,
01197 vec.getNumElements(), vec.getIndices(), vec.getElements());
01198 }
01199
01200 void
01201 OsiOslSolverInterface::addRows(const int numrows,
01202 const CoinPackedVectorBase * const * rows,
01203 const double* rowlb, const double* rowub)
01204 {
01205
01206 int i;
01207 int nz = 0;
01208 for (i = 0; i < numrows; ++i)
01209 nz += rows[i]->getNumElements();
01210
01211 int* index = new int[nz];
01212 double* elem = new double[nz];
01213 int* start = new int[numrows+1];
01214
01215 nz = 0;
01216 start[0] = 0;
01217 for (i = 0; i < numrows; ++i) {
01218 const CoinPackedVectorBase* row = rows[i];
01219 const int len = row->getNumElements();
01220 CoinDisjointCopyN(row->getIndices(), len, index+nz);
01221 CoinDisjointCopyN(row->getElements(), len, elem+nz);
01222 nz += len;
01223 start[i+1] = nz;
01224 }
01225 ekk_addRows(getModelPtr(), numrows, rowlb, rowub, start, index, elem);
01226 delete[] start;
01227 delete[] elem;
01228 delete[] index;
01229 }
01230
01231 void
01232 OsiOslSolverInterface::addRows(const int numrows,
01233 const CoinPackedVectorBase * const * rows,
01234 const char* rowsen, const double* rowrhs,
01235 const double* rowrng)
01236 {
01237
01238 int i;
01239 int nz = 0;
01240 for (i = 0; i < numrows; ++i)
01241 nz += rows[i]->getNumElements();
01242
01243 int* index = new int[nz];
01244 double* elem = new double[nz];
01245 int* start = new int[numrows+1];
01246 double* rowlb = new double[numrows];
01247 double* rowub = new double[numrows];
01248
01249 nz = 0;
01250 start[0] = 0;
01251 for (i = 0; i < numrows; ++i) {
01252 convertSenseToBound(rowsen[i], rowrhs[i], rowrng[i], rowlb[i], rowub[i]);
01253 const CoinPackedVectorBase* row = rows[i];
01254 const int len = row->getNumElements();
01255 CoinDisjointCopyN(row->getIndices(), len, index+nz);
01256 CoinDisjointCopyN(row->getElements(), len, elem+nz);
01257 nz += len;
01258 start[i+1] = nz;
01259 }
01260 ekk_addRows(getModelPtr(), numrows, rowlb, rowub, start, index, elem);
01261 delete[] rowub;
01262 delete[] rowlb;
01263 delete[] start;
01264 delete[] elem;
01265 delete[] index;
01266 }
01267
01268 void
01269 OsiOslSolverInterface::deleteRows(const int num, const int * rowIndices)
01270 {
01271
01272 ekk_deleteRows(getModelPtr(), num, rowIndices);
01273 }
01274
01275
01276
01277
01278
01279 void
01280 OsiOslSolverInterface::loadProblem(const CoinPackedMatrix& matrix,
01281 const double* collb, const double* colub,
01282 const double* obj,
01283 const double* rowlb, const double* rowub)
01284 {
01285 const CoinPackedMatrix * m = toColumnOrderedGapFree(matrix);
01286 loadProblem(m->getNumCols(), m->getNumRows(),
01287 m->getVectorStarts(), m->getIndices(), m->getElements(),
01288 collb, colub, obj, rowlb, rowub);
01289 if (m != &matrix)
01290 delete m;
01291 }
01292
01293
01294
01295 void
01296 OsiOslSolverInterface::assignProblem(CoinPackedMatrix*& matrix,
01297 double*& collb, double*& colub,
01298 double*& obj,
01299 double*& rowlb, double*& rowub)
01300 {
01301 loadProblem(*matrix, collb, colub, obj, rowlb, rowub);
01302 delete matrix; matrix = 0;
01303 delete[] collb; collb = 0;
01304 delete[] colub; colub = 0;
01305 delete[] obj; obj = 0;
01306 delete[] rowlb; rowlb = 0;
01307 delete[] rowub; rowub = 0;
01308 }
01309
01310
01311
01312 void
01313 OsiOslSolverInterface::loadProblem(const CoinPackedMatrix& matrix,
01314 const double* collb, const double* colub,
01315 const double* obj,
01316 const char* rowsen, const double* rowrhs,
01317 const double* rowrng)
01318 {
01319 const CoinPackedMatrix * m = toColumnOrderedGapFree(matrix);
01320 loadProblem(m->getNumCols(), m->getNumRows(),
01321 m->getVectorStarts(), m->getIndices(), m->getElements(),
01322 collb, colub, obj, rowsen, rowrhs, rowrng);
01323 if (m != &matrix)
01324 delete m;
01325 }
01326
01327
01328
01329 void
01330 OsiOslSolverInterface::assignProblem(CoinPackedMatrix*& matrix,
01331 double*& collb, double*& colub,
01332 double*& obj,
01333 char*& rowsen, double*& rowrhs,
01334 double*& rowrng)
01335 {
01336 loadProblem(*matrix, collb, colub, obj, rowsen, rowrhs, rowrng);
01337 delete matrix; matrix = 0;
01338 delete[] collb; collb = 0;
01339 delete[] colub; colub = 0;
01340 delete[] obj; obj = 0;
01341 delete[] rowsen; rowsen = 0;
01342 delete[] rowrhs; rowrhs = 0;
01343 delete[] rowrng; rowrng = 0;
01344 }
01345
01346
01347
01348 void
01349 OsiOslSolverInterface::loadProblem(const int numcols, const int numrows,
01350 const int* start, const int* index,
01351 const double* value,
01352 const double* collb, const double* colub,
01353 const double* obj,
01354 const double* rowlb, const double* rowub)
01355 {
01356
01357
01358 ekk_loadRimModel(getMutableModelPtr(),
01359 numrows, rowlb, rowub, numcols, obj, collb, colub);
01360 ekk_addColumnElementBlock(getMutableModelPtr(),
01361 numcols, index, start, value);
01362
01363 freeCachedResults();
01364 }
01365
01366
01367 void
01368 OsiOslSolverInterface::loadProblem(const int numcols, const int numrows,
01369 const int* start, const int* index,
01370 const double* value,
01371 const double* collb, const double* colub,
01372 const double* obj,
01373 const char* rowsen, const double* rowrhs,
01374 const double* rowrng)
01375 {
01376 assert( rowsen != NULL );
01377 assert( rowrhs != NULL );
01378 double * rowlb = new double[numrows];
01379 double * rowub = new double[numrows];
01380 for (int i = numrows-1; i >= 0; --i) {
01381 convertSenseToBound(rowsen[i],rowrhs[i],rowrng[i],rowlb[i],rowub[i]);
01382 }
01383
01384
01385 ekk_loadRimModel(getMutableModelPtr(),
01386 numrows, rowlb, rowub, numcols, obj, collb, colub);
01387 ekk_addColumnElementBlock(getMutableModelPtr(),
01388 numcols, index, start, value);
01389
01390 freeCachedResults();
01391 delete[] rowlb;
01392 delete[] rowub;
01393 }
01394
01395
01396
01397
01398
01399 int OsiOslSolverInterface::readMps(const char *filename,
01400 const char *extension)
01401 {
01402 return OsiSolverInterface::readMps(filename, extension);
01403 }
01404
01405
01406
01407
01408
01409 void OsiOslSolverInterface::writeMps(const char * filename,
01410 const char * extension,
01411 double objSense) const
01412 {
01413 std::string f(filename);
01414 std::string e(extension);
01415 std::string fullname;
01416 if (e!="") {
01417 fullname = f + "." + e;
01418 } else {
01419
01420 fullname = f;
01421 }
01422 ekk_exportModel(getMutableModelPtr(), fullname.c_str(), 1, 2);
01423 }
01424
01425
01426
01427
01428
01429 EKKModel * OsiOslSolverInterface::getModelPtr()
01430 {
01431 freeCachedResults();
01432 return getMutableModelPtr();
01433 }
01434
01435
01436
01437 void OsiOslSolverInterface::incrementInstanceCounter()
01438 {
01439 if ( numInstances_ == 0 ) {
01440 contextPtr_ = ekk_initializeContext();
01441 assert( contextPtr_ != NULL );
01442 ekk_messagesPrintOff(ekk_baseModel(contextPtr_), 1, 5999);
01443
01444
01445
01446 }
01447 numInstances_++;
01448 }
01449
01450
01451
01452 void OsiOslSolverInterface::decrementInstanceCounter()
01453 {
01454 assert( getNumInstances() != 0 );
01455 numInstances_--;
01456 if ( numInstances_ == 0 ) {
01457
01458
01459
01460 ekk_endContext(contextPtr_);
01461 contextPtr_ = NULL;
01462 }
01463 }
01464
01465
01466
01467 unsigned int OsiOslSolverInterface::getNumInstances()
01468 {
01469 return numInstances_;
01470 }
01471
01472
01473
01474
01475
01476
01477
01478
01479 OsiOslSolverInterface::OsiOslSolverInterface ()
01480 :
01481 OsiSolverInterface(),
01482 modelPtr_(NULL),
01483 rowsense_(NULL),
01484 rhs_(NULL),
01485 rowrange_(NULL),
01486 ws_(NULL),
01487 matrixByRow_(NULL),
01488 matrixByColumn_(NULL)
01489 {
01490 incrementInstanceCounter();
01491 }
01492
01493
01494
01495
01496 OsiSolverInterface * OsiOslSolverInterface::clone(bool CopyData) const
01497 {
01498 if (CopyData) {
01499 return new OsiOslSolverInterface(*this);
01500 } else {
01501 return new OsiOslSolverInterface();
01502 }
01503 }
01504
01505 #if 0
01506
01507
01508
01509 OsiOslSolverInterface::OsiOslSolverInterface (EKKModel * m)
01510 :
01511 OsiSolverInterface(),
01512 modelPtr_(m)
01513 {
01514
01515 }
01516 #endif
01517
01518
01519
01520
01521 OsiOslSolverInterface::OsiOslSolverInterface (
01522 const OsiOslSolverInterface & source)
01523 :
01524 OsiSolverInterface(source),
01525 modelPtr_(NULL),
01526 rowsense_(NULL),
01527 rhs_(NULL),
01528 rowrange_(NULL),
01529 ws_(NULL),
01530 matrixByRow_(NULL),
01531 matrixByColumn_(NULL)
01532 {
01533 incrementInstanceCounter();
01534 if ( source.modelPtr_ !=NULL ) {
01535 ekk_copyModel(getModelPtr(),source.modelPtr_);
01536
01537
01538
01539 }
01540 }
01541
01542
01543
01544
01545
01546 OsiOslSolverInterface::~OsiOslSolverInterface ()
01547 {
01548 gutsOfDestructor();
01549 decrementInstanceCounter();
01550 }
01551
01552
01553
01554
01555 OsiOslSolverInterface &
01556 OsiOslSolverInterface::operator=(const OsiOslSolverInterface& rhs)
01557 {
01558 if (this != &rhs) {
01559 OsiSolverInterface::operator=(rhs);
01560 gutsOfDestructor();
01561 if ( rhs.modelPtr_ !=NULL ) {
01562 ekk_copyModel(getModelPtr(),rhs.modelPtr_);
01563 }
01564 delete ws_;
01565 ws_ = NULL;
01566 }
01567 return *this;
01568 }
01569
01570
01571
01572
01573
01574 void OsiOslSolverInterface::applyRowCut( const OsiRowCut & rowCut )
01575 {
01576 EKKModel * m = getModelPtr();
01577 const CoinPackedVector & row=rowCut.row();
01578 ekk_addOneRow(m, rowCut.lb(),rowCut.ub(),
01579 row.getNumElements(),row.getIndices(),row.getElements() );
01580 }
01581
01582
01583
01584 void OsiOslSolverInterface::applyColCut( const OsiColCut & cc )
01585 {
01586 EKKModel * m = getModelPtr();
01587 const double * oslColLB = ekk_collower(m);
01588 const double * oslColUB = ekk_colupper(m);
01589 const CoinPackedVector & lbs = cc.lbs();
01590 const CoinPackedVector & ubs = cc.ubs();
01591 int i;
01592
01593 for ( i=0; i<lbs.getNumElements(); i++ ) {
01594 if ( lbs.getElements()[i] > oslColLB[lbs.getIndices()[i]] )
01595
01596 ekk_copyCollower(m, &(lbs.getElements()[i]),
01597 lbs.getIndices()[i],lbs.getIndices()[i]+1);
01598 }
01599 for ( i=0; i<ubs.getNumElements(); i++ ) {
01600 if ( ubs.getElements()[i] < oslColUB[ubs.getIndices()[i]] )
01601
01602 ekk_copyColupper(m, &(ubs.getElements()[i]),
01603 ubs.getIndices()[i],ubs.getIndices()[i]+1);
01604 }
01605 }
01606
01607
01608
01609
01610
01611 EKKContext * OsiOslSolverInterface::getContextPtr()
01612 {
01613 assert( contextPtr_ != NULL );
01614 return contextPtr_;
01615 }
01616
01617
01618
01619 EKKContext * OsiOslSolverInterface::contextPtr_ = NULL;
01620
01621
01622
01623 unsigned int OsiOslSolverInterface::numInstances_ = 0;
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 EKKModel * OsiOslSolverInterface::getMutableModelPtr() const
01635 {
01636 if ( modelPtr_ == NULL ) {
01637 modelPtr_ = ekk_newModel(getContextPtr(),NULL);
01638 }
01639 return modelPtr_;
01640 }
01641
01642
01643
01644 #if 0
01645 void OsiOslSolverInterface::gutsOfCopy( const OsiOslSolverInterface & source )
01646 {
01647 modelPtr_ = source.modelPtr_;
01648 }
01649 #endif
01650
01651
01652
01653 void OsiOslSolverInterface::gutsOfDestructor()
01654 {
01655 if ( modelPtr_ != NULL ) {
01656 ekk_deleteModel(modelPtr_);
01657 modelPtr_=NULL;
01658 freeCachedResults();
01659 }
01660 assert( modelPtr_==NULL );
01661 assert( rowsense_==NULL );
01662 assert( rhs_==NULL );
01663 assert( rowrange_==NULL );
01664 assert( ws_==NULL );
01665 assert( matrixByRow_==NULL );
01666 assert( matrixByColumn_==NULL );
01667 }
01668
01669
01670
01671 void OsiOslSolverInterface::freeCachedResults()
01672 {
01673 delete [] rowsense_;
01674 delete [] rhs_;
01675 delete [] rowrange_;
01676 delete matrixByRow_;
01677 delete matrixByColumn_;
01678 delete ws_;
01679 rowsense_=NULL;
01680 rhs_=NULL;
01681 rowrange_=NULL;
01682 matrixByRow_=NULL;
01683 matrixByColumn_=NULL;
01684 ws_ = NULL;
01685 }
01686
01687
01688 void OsiOslSolverInterface::extractSenseRhsRange() const
01689 {
01690 if (rowsense_ == NULL) {
01691
01692 assert ((rhs_ == NULL) && (rowrange_ == NULL));
01693
01694 EKKModel * m = getMutableModelPtr();
01695
01696 int nr=ekk_getInumrows(m);
01697 if ( nr != 0 ) {
01698 rowsense_ = new char[nr];
01699 rhs_ = new double[nr];
01700 rowrange_ = new double[nr];
01701 std::fill(rowrange_,rowrange_+nr,0.0);
01702
01703 const double * lb = ekk_rowlower(m);
01704 const double * ub = ekk_rowupper(m);
01705
01706 int i;
01707 for ( i=0; i<nr; i++ ) {
01708 convertBoundToSense(lb[i], ub[i], rowsense_[i], rhs_[i], rowrange_[i]);
01709 }
01710 }
01711 }
01712 }
01713
01714
01715
01716 void
01717 OsiOslSolverInterface::reset()
01718 {
01719 setInitialData();
01720 gutsOfDestructor();
01721 itlimOrig_=9999999;
01722 }