00001
00002
00003
00004
00005
00006
00007 #include "CoinPragma.hpp"
00008
00009 #include <math.h>
00010
00011 #include "CoinHelperFunctions.hpp"
00012 #include "ClpHelperFunctions.hpp"
00013 #include "CoinSort.hpp"
00014 #include "ClpFactorization.hpp"
00015 #include "ClpSimplex.hpp"
00016 #include "ClpInterior.hpp"
00017 #include "ClpSolve.hpp"
00018 #include "ClpPackedMatrix.hpp"
00019 #include "ClpPlusMinusOneMatrix.hpp"
00020 #include "ClpNetworkMatrix.hpp"
00021 #include "ClpMessage.hpp"
00022 #include "CoinTime.hpp"
00023
00024 #include "ClpPresolve.hpp"
00025 #include "Idiot.hpp"
00026
00027
00028
00029
00030
00031 #include "CoinSignal.hpp"
00032 static ClpSimplex * currentModel = NULL;
00033
00034 extern "C" {
00035 static void signal_handler(int whichSignal)
00036 {
00037 if (currentModel!=NULL)
00038 currentModel->setMaximumIterations(0);
00039 return;
00040 }
00041 }
00042
00052 int
00053 ClpSimplex::initialSolve(ClpSolve & options)
00054 {
00055 ClpSolve::SolveType method=options.getSolveType();
00056 ClpSolve::PresolveType presolve = options.getPresolveType();
00057 int saveMaxIterations = maximumIterations();
00058 int finalStatus=-1;
00059 int numberIterations=0;
00060 double time1 = CoinCpuTime();
00061 double timeX = time1;
00062 double time2;
00063 ClpMatrixBase * saveMatrix=NULL;
00064 ClpSimplex * model2 = this;
00065 bool interrupt = (options.getSpecialOption(2)==0);
00066 CoinSighandler_t saveSignal=SIG_DFL;
00067 if (interrupt) {
00068 currentModel = model2;
00069
00070 saveSignal = signal(SIGINT,signal_handler);
00071 }
00072 ClpPresolve pinfo;
00073 double timePresolve=0.0;
00074 double timeIdiot=0.0;
00075 double timeCore=0.0;
00076 int savePerturbation=perturbation_;
00077 int saveScaling = scalingFlag_;
00078 if (dynamic_cast< ClpNetworkMatrix*>(matrix_)) {
00079
00080 presolve = ClpSolve::presolveOff;
00081 }
00082
00083
00084 int doIdiot=0;
00085 int doCrash=0;
00086 int doSprint=0;
00087 if (method!=ClpSolve::useDual) {
00088 switch (options.getSpecialOption(1)) {
00089 case 0:
00090 doIdiot=-1;
00091 doCrash=-1;
00092 doSprint=-1;
00093 break;
00094 case 1:
00095 doIdiot=0;
00096 doCrash=1;
00097 doSprint=0;
00098 break;
00099 case 2:
00100 doIdiot=1;
00101 doCrash=0;
00102 doSprint=0;
00103 break;
00104 case 3:
00105 doIdiot=0;
00106 doCrash=0;
00107 doSprint=1;
00108 break;
00109 case 4:
00110 doIdiot=0;
00111 doCrash=0;
00112 doSprint=0;
00113 break;
00114 case 5:
00115 doIdiot=0;
00116 doCrash=-1;
00117 doSprint=-1;
00118 break;
00119 case 6:
00120 doIdiot=-1;
00121 doCrash=-1;
00122 doSprint=0;
00123 break;
00124 case 7:
00125 doIdiot=-1;
00126 doCrash=0;
00127 doSprint=-1;
00128 break;
00129 case 8:
00130 doIdiot=-1;
00131 doCrash=0;
00132 doSprint=0;
00133 break;
00134 case 9:
00135 doIdiot=0;
00136 doCrash=0;
00137 doSprint=-1;
00138 break;
00139 default:
00140 abort();
00141 }
00142 } else {
00143
00144 switch (options.getSpecialOption(0)) {
00145 case 0:
00146 doIdiot=0;
00147 doCrash=0;
00148 doSprint=0;
00149 break;
00150 case 1:
00151 doIdiot=0;
00152 doCrash=1;
00153 doSprint=0;
00154 break;
00155 case 2:
00156 doIdiot=-1;
00157 if (options.getExtraInfo(0)>0)
00158 doIdiot = options.getExtraInfo(0);
00159 doCrash=0;
00160 doSprint=0;
00161 break;
00162 default:
00163 abort();
00164 }
00165 }
00166
00167 int maxSprintPass=100;
00168
00169 bool presolveToFile=false;
00170
00171 if (presolve!=ClpSolve::presolveOff) {
00172 int numberPasses=5;
00173 if (presolve==ClpSolve::presolveNumber) {
00174 numberPasses=options.getPresolvePasses();
00175 presolve = ClpSolve::presolveOn;
00176 }
00177 if (presolveToFile) {
00178 printf("***** temp test\n");
00179 pinfo.presolvedModelToFile(*this,"ss.sav",1.0e-8,
00180 false,numberPasses);
00181 model2=this;
00182 } else {
00183 model2 = pinfo.presolvedModel(*this,1.0e-8,
00184 false,numberPasses,true);
00185 }
00186 time2 = CoinCpuTime();
00187 timePresolve = time2-timeX;
00188 handler_->message(CLP_INTERVAL_TIMING,messages_)
00189 <<"Presolve"<<timePresolve<<time2-time1
00190 <<CoinMessageEol;
00191 timeX=time2;
00192 if (model2) {
00193 } else {
00194 handler_->message(CLP_INFEASIBLE,messages_)
00195 <<CoinMessageEol;
00196 model2 = this;
00197 presolve=ClpSolve::presolveOff;
00198 }
00199
00200 if (presolve!=ClpSolve::presolveOff&&
00201 numberRows_<1.01*model2->numberRows_&&numberColumns_<1.01*model2->numberColumns_
00202 &&method!=ClpSolve::useDual&&model2!=this) {
00203 delete model2;
00204 model2 = this;
00205 presolve=ClpSolve::presolveOff;
00206 }
00207 }
00208 if (interrupt)
00209 currentModel = model2;
00210
00211 bool plusMinus=false;
00212 int numberElements=model2->getNumElements();
00213 if (dynamic_cast< ClpNetworkMatrix*>(matrix_)) {
00214
00215 doIdiot=0;
00216 doSprint=0;
00217 }
00218 int numberColumns = model2->numberColumns();
00219 int numberRows = model2->numberRows();
00220
00221 int number=0;
00222 int iRow;
00223 for (iRow=0;iRow<numberRows;iRow++)
00224 if (model2->getRowStatus(iRow)==basic)
00225 number++;
00226 if (number<numberRows) {
00227 doIdiot=0;
00228 doCrash=0;
00229 doSprint=0;
00230 }
00231 if (options.getSpecialOption(3)==0) {
00232 if(numberElements>100000)
00233 plusMinus=true;
00234 if(numberElements>10000&&(doIdiot||doSprint))
00235 plusMinus=true;
00236 }
00237 if (plusMinus) {
00238 saveMatrix = model2->clpMatrix();
00239 ClpPackedMatrix* clpMatrix =
00240 dynamic_cast< ClpPackedMatrix*>(saveMatrix);
00241 if (clpMatrix) {
00242 ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
00243 if (newMatrix->getIndices()) {
00244 model2->replaceMatrix(newMatrix);
00245 } else {
00246 handler_->message(CLP_MATRIX_CHANGE,messages_)
00247 <<"+- 1"
00248 <<CoinMessageEol;
00249 saveMatrix=NULL;
00250 plusMinus=false;
00251 delete newMatrix;
00252 }
00253 } else {
00254 saveMatrix=NULL;
00255 plusMinus=false;
00256 }
00257 }
00258 if (model2->factorizationFrequency()==200) {
00259
00260 model2->setFactorizationFrequency(min(2000,100+model2->numberRows()/200));
00261 }
00262 if (method==ClpSolve::usePrimalorSprint) {
00263 if (doSprint<0) {
00264 if (numberElements<500000) {
00265
00266 if(numberRows*10>numberColumns||numberColumns<6000
00267 ||(numberRows*20>numberColumns&&!plusMinus))
00268 method=ClpSolve::usePrimal;
00269 } else {
00270
00271 if(numberRows*8>numberColumns)
00272 method=ClpSolve::usePrimal;
00273
00274 if(numberRows*10>numberColumns||numberColumns<6000
00275 ||(numberRows*20>numberColumns&&!plusMinus))
00276 maxSprintPass=5;
00277 }
00278 } else if (doSprint==0) {
00279 method=ClpSolve::usePrimal;
00280 }
00281 }
00282 if (method==ClpSolve::useDual) {
00283
00284 int nPasses=0;
00285 int numberNotE=0;
00286 if ((doIdiot<0&&plusMinus)||doIdiot>0) {
00287
00288 nPasses=0;
00289 Idiot info(*model2);
00290
00291 double ratio = ((double) numberElements/(double) numberColumns);
00292
00293 int iRow;
00294 double largest=0.0;
00295 double smallest = 1.0e30;
00296 double largestGap=0.0;
00297 for (iRow=0;iRow<numberRows;iRow++) {
00298 double value1 = model2->rowLower_[iRow];
00299 if (value1&&value1>-1.0e31) {
00300 largest = max(largest,fabs(value1));
00301 smallest=min(smallest,fabs(value1));
00302 }
00303 double value2 = model2->rowUpper_[iRow];
00304 if (value2&&value2<1.0e31) {
00305 largest = max(largest,fabs(value2));
00306 smallest=min(smallest,fabs(value2));
00307 }
00308 if (value2>value1) {
00309 numberNotE++;
00310 if (value2>1.0e31||value1<-1.0e31)
00311 largestGap = COIN_DBL_MAX;
00312 else
00313 largestGap = value2-value1;
00314 }
00315 }
00316 if (doIdiot<0) {
00317 if (numberRows>200&&numberColumns>5000&&ratio>=3.0&&
00318 largest/smallest<1.1&&!numberNotE) {
00319 nPasses = 71;
00320 }
00321 }
00322 if (doIdiot>0) {
00323 nPasses=max(nPasses,doIdiot);
00324 if (nPasses>70)
00325 info.setStartingWeight(1.0e3);
00326 }
00327 if (nPasses) {
00328 info.setReduceIterations(5);
00329 doCrash=0;
00330 info.crash(nPasses,model2->messageHandler(),model2->messagesPointer());
00331 time2 = CoinCpuTime();
00332 timeIdiot = time2-timeX;
00333 handler_->message(CLP_INTERVAL_TIMING,messages_)
00334 <<"Idiot Crash"<<timeIdiot<<time2-time1
00335 <<CoinMessageEol;
00336 timeX=time2;
00337 }
00338 }
00339 if (presolve==ClpSolve::presolveOn) {
00340 int numberInfeasibilities = model2->tightenPrimalBounds();
00341 if (numberInfeasibilities) {
00342 handler_->message(CLP_INFEASIBLE,messages_)
00343 <<CoinMessageEol;
00344 model2 = this;
00345 presolve=ClpSolve::presolveOff;
00346 }
00347 }
00348 if (options.getSpecialOption(0)==1)
00349 model2->crash(1000,1);
00350 if (!nPasses) {
00351 model2->dual(0);
00352 } else if (!numberNotE&&0) {
00353
00354 double * pi = model2->dualRowSolution();
00355 int i;
00356 int numberColumns = model2->numberColumns();
00357 int numberRows = model2->numberRows();
00358 double * saveObj = new double[numberColumns];
00359 memcpy(saveObj,model2->objective(),numberColumns*sizeof(double));
00360 memcpy(model2->dualColumnSolution(),model2->objective(),
00361 numberColumns*sizeof(double));
00362 model2->clpMatrix()->transposeTimes(-1.0,pi,model2->dualColumnSolution());
00363 memcpy(model2->objective(),model2->dualColumnSolution(),
00364 numberColumns*sizeof(double));
00365 const double * rowsol = model2->primalRowSolution();
00366 double offset=0.0;
00367 for (i=0;i<numberRows;i++) {
00368 offset += pi[i]*rowsol[i];
00369 }
00370 double value2;
00371 model2->getDblParam(ClpObjOffset,value2);
00372 printf("Offset %g %g\n",offset,value2);
00373 model2->setRowObjective(pi);
00374
00375 memset(pi,0,numberRows*sizeof(double));
00376
00377 model2->allSlackBasis();
00378 model2->factorization()->maximumPivots(200);
00379
00380
00381 model2->dual(1);
00382 memcpy(model2->objective(),saveObj,numberColumns*sizeof(double));
00383
00384 memset(pi,0,numberRows*sizeof(double));
00385 model2->setRowObjective(pi);
00386 delete [] saveObj;
00387 model2->primal();
00388 } else {
00389
00390 model2->dual(1);
00391 }
00392 time2 = CoinCpuTime();
00393 timeCore = time2-timeX;
00394 handler_->message(CLP_INTERVAL_TIMING,messages_)
00395 <<"Dual"<<timeCore<<time2-time1
00396 <<CoinMessageEol;
00397 timeX=time2;
00398 } else if (method==ClpSolve::usePrimal) {
00399 if (doIdiot) {
00400 int nPasses=0;
00401 Idiot info(*model2);
00402
00403 double ratio = ((double) numberElements/(double) numberColumns);
00404
00405 int iRow;
00406 double largest=0.0;
00407 double smallest = 1.0e30;
00408 double largestGap=0.0;
00409 int numberNotE=0;
00410 for (iRow=0;iRow<numberRows;iRow++) {
00411 double value1 = model2->rowLower_[iRow];
00412 if (value1&&value1>-1.0e31) {
00413 largest = max(largest,fabs(value1));
00414 smallest=min(smallest,fabs(value1));
00415 }
00416 double value2 = model2->rowUpper_[iRow];
00417 if (value2&&value2<1.0e31) {
00418 largest = max(largest,fabs(value2));
00419 smallest=min(smallest,fabs(value2));
00420 }
00421 if (value2>value1) {
00422 numberNotE++;
00423 if (value2>1.0e31||value1<-1.0e31)
00424 largestGap = COIN_DBL_MAX;
00425 else
00426 largestGap = value2-value1;
00427 }
00428 }
00429 if (numberRows>200&&numberColumns>5000&&numberColumns>2*numberRows) {
00430 if (plusMinus) {
00431 if (largest/smallest>2.0) {
00432 nPasses = 10+numberColumns/100000;
00433 nPasses = min(nPasses,50);
00434 nPasses = max(nPasses,15);
00435 if (numberRows>25000&&nPasses>5) {
00436
00437 nPasses = max(nPasses,71);
00438 } else if (numberElements<3*numberColumns) {
00439 nPasses=min(nPasses,10);
00440 }
00441 if (doIdiot<0)
00442 info.setLightweight(1);
00443 } else if (largest/smallest>1.01||numberElements<=3*numberColumns) {
00444 nPasses = 10+numberColumns/1000;
00445 nPasses = min(nPasses,100);
00446 nPasses = max(nPasses,30);
00447 if (numberRows>25000) {
00448
00449 nPasses = max(nPasses,71);
00450 }
00451 if (!largestGap)
00452 nPasses *= 2;
00453 } else {
00454 nPasses = 10+numberColumns/1000;
00455 nPasses = min(nPasses,200);
00456 nPasses = max(nPasses,100);
00457 info.setStartingWeight(1.0e-1);
00458 info.setReduceIterations(6);
00459 if (!largestGap)
00460 nPasses *= 2;
00461
00462 }
00463
00464 if (nPasses<=5)
00465 nPasses=0;
00466 } else {
00467 if (doIdiot<0)
00468 info.setLightweight(1);
00469 if (largest/smallest>1.01||numberNotE) {
00470 if (numberRows>25000||numberColumns>5*numberRows) {
00471 nPasses = 50;
00472 } else if (numberColumns>4*numberRows) {
00473 nPasses = 20;
00474 } else {
00475 nPasses=5;
00476 }
00477 } else {
00478 if (numberRows>25000||numberColumns>5*numberRows) {
00479 nPasses = 50;
00480 info.setLightweight(0);
00481 } else if (numberColumns>4*numberRows) {
00482 nPasses = 20;
00483 } else {
00484 nPasses=15;
00485 }
00486 }
00487 if (numberElements<3*numberColumns) {
00488 nPasses=(int) ((2.0*(double) nPasses)/ratio);
00489 } else {
00490 nPasses = max(nPasses,5);
00491 nPasses = (int) (((double) nPasses)*5.0/ratio);
00492 }
00493 if (numberRows>25000&&nPasses>5) {
00494
00495 nPasses = max(nPasses,71);
00496 } else if (plusMinus) {
00497 nPasses *= 2;
00498 nPasses=min(nPasses,71);
00499 }
00500 if (nPasses<=5)
00501 nPasses=0;
00502
00503 }
00504 }
00505 if (doIdiot>0) {
00506
00507 nPasses=options.getExtraInfo(1);
00508 if (nPasses>70) {
00509 info.setStartingWeight(1.0e3);
00510 info.setReduceIterations(6);
00511
00512 info.setDropEnoughFeasibility(0.5*info.getDropEnoughFeasibility());
00513 info.setDropEnoughWeighted(-2.0);
00514 } else if (nPasses>=50) {
00515 info.setStartingWeight(1.0e3);
00516
00517 }
00518
00519 if (nPasses<70&&(nPasses%10)>0&&(nPasses%10)<4) {
00520 info.setStartingWeight(1.0e3);
00521 info.setLightweight(nPasses%10);
00522
00523 }
00524 }
00525 if (nPasses) {
00526 doCrash=0;
00527 #if 0
00528 double * solution = model2->primalColumnSolution();
00529 int iColumn;
00530 double * saveLower = new double[numberColumns];
00531 memcpy(saveLower,model2->columnLower(),numberColumns*sizeof(double));
00532 double * saveUpper = new double[numberColumns];
00533 memcpy(saveUpper,model2->columnUpper(),numberColumns*sizeof(double));
00534 printf("doing tighten before idiot\n");
00535 model2->tightenPrimalBounds();
00536
00537 double * columnLower = model2->columnLower();
00538 double * columnUpper = model2->columnUpper();
00539 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00540 if (columnLower[iColumn]>0.0)
00541 solution[iColumn]=columnLower[iColumn];
00542 else if (columnUpper[iColumn]<0.0)
00543 solution[iColumn]=columnUpper[iColumn];
00544 else
00545 solution[iColumn]=0.0;
00546 }
00547 memcpy(columnLower,saveLower,numberColumns*sizeof(double));
00548 memcpy(columnUpper,saveUpper,numberColumns*sizeof(double));
00549 delete [] saveLower;
00550 delete [] saveUpper;
00551 #else
00552
00553 info.setStrategy(512|info.getStrategy());
00554
00555 info.setStrategy(32|info.getStrategy());
00556 info.crash(nPasses,model2->messageHandler(),model2->messagesPointer());
00557 #endif
00558 time2 = CoinCpuTime();
00559 timeIdiot = time2-timeX;
00560 handler_->message(CLP_INTERVAL_TIMING,messages_)
00561 <<"Idiot Crash"<<timeIdiot<<time2-time1
00562 <<CoinMessageEol;
00563 timeX=time2;
00564 }
00565 }
00566
00567 if (doCrash)
00568 model2->crash(1000,1);
00569 model2->primal(1);
00570 time2 = CoinCpuTime();
00571 timeCore = time2-timeX;
00572 handler_->message(CLP_INTERVAL_TIMING,messages_)
00573 <<"Primal"<<timeCore<<time2-time1
00574 <<CoinMessageEol;
00575 timeX=time2;
00576 } else if (method==ClpSolve::usePrimalorSprint) {
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 int originalNumberColumns = model2->numberColumns();
00594 int numberRows = model2->numberRows();
00595
00596
00597 double * weight = new double [numberRows+originalNumberColumns];
00598 int * sort = new int [numberRows+originalNumberColumns];
00599 int numberSort=0;
00600
00601
00602
00603 int iColumn;
00604 const double * columnLower = model2->columnLower();
00605 const double * columnUpper = model2->columnUpper();
00606 double * columnSolution = model2->primalColumnSolution();
00607
00608 for (iColumn=0;iColumn<originalNumberColumns;iColumn++) {
00609 double value =0.0;
00610 if (columnLower[iColumn]>0.0)
00611 value = columnLower[iColumn];
00612 else if (columnUpper[iColumn]<0.0)
00613 value = columnUpper[iColumn];
00614 columnSolution[iColumn]=value;
00615 }
00616
00617 double * rowSolution = model2->primalRowSolution();
00618 memset (rowSolution,0,numberRows*sizeof(double));
00619 model2->times(1.0,columnSolution,rowSolution);
00620
00621 int * addStarts = new int [numberRows+1];
00622 int * addRow = new int[numberRows];
00623 double * addElement = new double[numberRows];
00624 const double * lower = model2->rowLower();
00625 const double * upper = model2->rowUpper();
00626 addStarts[0]=0;
00627 int numberArtificials=0;
00628 double * addCost = new double [numberRows];
00629 const double penalty=1.0e8;
00630 int iRow;
00631 for (iRow=0;iRow<numberRows;iRow++) {
00632 if (lower[iRow]>rowSolution[iRow]) {
00633 addRow[numberArtificials]=iRow;
00634 addElement[numberArtificials]=1.0;
00635 addCost[numberArtificials]=penalty;
00636 numberArtificials++;
00637 addStarts[numberArtificials]=numberArtificials;
00638 } else if (upper[iRow]<rowSolution[iRow]) {
00639 addRow[numberArtificials]=iRow;
00640 addElement[numberArtificials]=-1.0;
00641 addCost[numberArtificials]=penalty;
00642 numberArtificials++;
00643 addStarts[numberArtificials]=numberArtificials;
00644 }
00645 }
00646 model2->addColumns(numberArtificials,NULL,NULL,addCost,
00647 addStarts,addRow,addElement);
00648 delete [] addStarts;
00649 delete [] addRow;
00650 delete [] addElement;
00651 delete [] addCost;
00652
00653 double largest=0.0;
00654 double smallest = 1.0e30;
00655 for (iRow=0;iRow<numberRows;iRow++) {
00656 double value;
00657 value = fabs(model2->rowLower_[iRow]);
00658 if (value&&value<1.0e30) {
00659 largest = max(largest,value);
00660 smallest=min(smallest,value);
00661 }
00662 value = fabs(model2->rowUpper_[iRow]);
00663 if (value&&value<1.0e30) {
00664 largest = max(largest,value);
00665 smallest=min(smallest,value);
00666 }
00667 }
00668 double * saveLower = NULL;
00669 double * saveUpper = NULL;
00670 if (largest<2.01*smallest) {
00671
00672 model2->setPerturbation(100);
00673 saveLower = new double[numberRows];
00674 memcpy(saveLower,model2->rowLower_,numberRows*sizeof(double));
00675 saveUpper = new double[numberRows];
00676 memcpy(saveUpper,model2->rowUpper_,numberRows*sizeof(double));
00677 double * lower = model2->rowLower();
00678 double * upper = model2->rowUpper();
00679 for (iRow=0;iRow<numberRows;iRow++) {
00680 double lowerValue=lower[iRow], upperValue=upper[iRow];
00681 double value = CoinDrand48();
00682 if (upperValue>lowerValue+primalTolerance_) {
00683 if (lowerValue>-1.0e20&&lowerValue)
00684 lowerValue -= value * 1.0e-4*fabs(lowerValue);
00685 if (upperValue<1.0e20&&upperValue)
00686 upperValue += value * 1.0e-4*fabs(upperValue);
00687 } else if (upperValue>0.0) {
00688 upperValue -= value * 1.0e-4*fabs(lowerValue);
00689 lowerValue -= value * 1.0e-4*fabs(lowerValue);
00690 } else if (upperValue<0.0) {
00691 upperValue += value * 1.0e-4*fabs(lowerValue);
00692 lowerValue += value * 1.0e-4*fabs(lowerValue);
00693 } else {
00694 }
00695 lower[iRow]=lowerValue;
00696 upper[iRow]=upperValue;
00697 }
00698 }
00699 int i;
00700
00701 if (numberArtificials) {
00702 numberSort=numberArtificials;
00703 for (i=0;i<numberSort;i++)
00704 sort[i] = i+originalNumberColumns;
00705 } else {
00706 numberSort = min(numberRows_,numberColumns_);
00707 for (i=0;i<numberSort;i++)
00708 sort[i] = i;
00709 }
00710
00711
00712 columnLower = model2->columnLower();
00713 columnUpper = model2->columnUpper();
00714 int numberColumns = model2->numberColumns();
00715 double * fullSolution = model2->primalColumnSolution();
00716
00717
00718 if (doSprint>0)
00719 maxSprintPass=options.getExtraInfo(1);
00720 int iPass;
00721 double lastObjective=1.0e31;
00722
00723 model2->setInitialDenseFactorization(true);
00724
00725
00726 int smallNumberColumns = min(3*numberRows,numberColumns);
00727 smallNumberColumns = max(smallNumberColumns,3000);
00728
00729
00730
00731
00732 int * whichRows = new int [numberRows];
00733 for (iRow=0;iRow<numberRows;iRow++)
00734 whichRows[iRow]=iRow;
00735 double originalOffset;
00736 model2->getDblParam(ClpObjOffset,originalOffset);
00737 int totalIterations=0;
00738 for (iPass=0;iPass<maxSprintPass;iPass++) {
00739
00740
00741
00742 ClpSimplex small(model2,numberRows,whichRows,numberSort,sort);
00743 small.setPerturbation(model2->perturbation());
00744
00745 double * rowSolution = model2->primalRowSolution();
00746 double * sumFixed = new double[numberRows];
00747 memset (sumFixed,0,numberRows*sizeof(double));
00748 int iRow,iColumn;
00749
00750 for (iColumn=0;iColumn<numberSort;iColumn++) {
00751 int kColumn = sort[iColumn];
00752 fullSolution[kColumn]=0.0;
00753 }
00754
00755 double offset=0.0;
00756 const double * objective = model2->objective();
00757 for (iColumn=0;iColumn<numberColumns;iColumn++)
00758 offset += fullSolution[iColumn]*objective[iColumn];
00759 small.setDblParam(ClpObjOffset,originalOffset-offset);
00760 model2->times(1.0,fullSolution,sumFixed);
00761
00762 double * lower = small.rowLower();
00763 double * upper = small.rowUpper();
00764 for (iRow=0;iRow<numberRows;iRow++) {
00765 if (lower[iRow]>-1.0e50)
00766 lower[iRow] -= sumFixed[iRow];
00767 if (upper[iRow]<1.0e50)
00768 upper[iRow] -= sumFixed[iRow];
00769 rowSolution[iRow] -= sumFixed[iRow];
00770 }
00771 delete [] sumFixed;
00772
00773 if (interrupt)
00774 currentModel = &small;
00775 small.primal();
00776 totalIterations += small.numberIterations();
00777
00778 const double * solution = small.primalColumnSolution();
00779 for (iColumn=0;iColumn<numberSort;iColumn++) {
00780 int kColumn = sort[iColumn];
00781 model2->setColumnStatus(kColumn,small.getColumnStatus(iColumn));
00782 fullSolution[kColumn]=solution[iColumn];
00783 }
00784 for (iRow=0;iRow<numberRows;iRow++)
00785 model2->setRowStatus(iRow,small.getRowStatus(iRow));
00786 memcpy(model2->primalRowSolution(),small.primalRowSolution(),
00787 numberRows*sizeof(double));
00788
00789 memcpy(weight,model2->objective(),numberColumns*sizeof(double));
00790 model2->transposeTimes(-1.0,small.dualRowSolution(),weight);
00791 int numberNegative=0;
00792 double sumNegative = 0.0;
00793
00794 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00795 double dj = weight[iColumn]*optimizationDirection_;
00796 double value = fullSolution[iColumn];
00797 if (model2->getColumnStatus(iColumn)==ClpSimplex::basic)
00798 dj = -1.0e50;
00799 else if (dj<0.0&&value<columnUpper[iColumn])
00800 dj = dj;
00801 else if (dj>0.0&&value>columnLower[iColumn])
00802 dj = -dj;
00803 else if (columnUpper[iColumn]>columnLower[iColumn])
00804 dj = fabs(dj);
00805 else
00806 dj = 1.0e50;
00807 weight[iColumn] = dj;
00808 if (dj<-dualTolerance_&&dj>-1.0e50) {
00809 numberNegative++;
00810 sumNegative -= dj;
00811 }
00812 sort[iColumn] = iColumn;
00813 }
00814 handler_->message(CLP_SPRINT,messages_)
00815 <<iPass+1<<small.numberIterations()<<small.objectiveValue()<<sumNegative
00816 <<numberNegative
00817 <<CoinMessageEol;
00818 if ((small.objectiveValue()*optimizationDirection_>lastObjective-1.0e-7&&iPass>5)||
00819 !small.numberIterations()||
00820 iPass==maxSprintPass-1||small.status()==3) {
00821
00822 break;
00823 } else {
00824 lastObjective = small.objectiveValue()*optimizationDirection_;
00825
00826 CoinSort_2(weight,weight+numberColumns,sort);
00827 numberSort = smallNumberColumns;
00828 }
00829 }
00830 if (interrupt)
00831 currentModel = model2;
00832 for (i=0;i<numberArtificials;i++)
00833 sort[i] = i + originalNumberColumns;
00834 model2->deleteColumns(numberArtificials,sort);
00835 delete [] weight;
00836 delete [] sort;
00837 delete [] whichRows;
00838 if (saveLower) {
00839
00840 for (iRow=0;iRow<numberRows;iRow++) {
00841 double diffLower = saveLower[iRow]-model2->rowLower_[iRow];
00842 double diffUpper = saveUpper[iRow]-model2->rowUpper_[iRow];
00843 model2->rowLower_[iRow]=saveLower[iRow];
00844 model2->rowUpper_[iRow]=saveUpper[iRow];
00845 if (diffLower)
00846 assert (!diffUpper||fabs(diffLower-diffUpper)<1.0e-5);
00847 else
00848 diffLower = diffUpper;
00849 model2->rowActivity_[iRow] += diffLower;
00850 }
00851 delete [] saveLower;
00852 delete [] saveUpper;
00853 }
00854 model2->primal(0);
00855 model2->setPerturbation(savePerturbation);
00856 time2 = CoinCpuTime();
00857 timeCore = time2-timeX;
00858 handler_->message(CLP_INTERVAL_TIMING,messages_)
00859 <<"Sprint"<<timeCore<<time2-time1
00860 <<CoinMessageEol;
00861 timeX=time2;
00862 model2->setNumberIterations(model2->numberIterations()+totalIterations);
00863 } else if (method==ClpSolve::useBarrier) {
00864 printf("***** experimental pretty crude barrier\n");
00865 ClpInterior barrier(*model2);
00866 barrier.primalDual();
00867 time2 = CoinCpuTime();
00868 timeCore = time2-timeX;
00869 handler_->message(CLP_INTERVAL_TIMING,messages_)
00870 <<"Barrier"<<timeCore<<time2-time1
00871 <<CoinMessageEol;
00872 timeX=time2;
00873 printf("***** crude crossover - I will improve\n");
00874
00875 CoinMemcpyN(barrier.primalRowSolution(),
00876 model2->numberRows(),model2->primalRowSolution());
00877 CoinMemcpyN(barrier.dualRowSolution(),
00878 model2->numberRows(),model2->dualRowSolution());
00879 CoinMemcpyN(barrier.primalColumnSolution(),
00880 model2->numberColumns(),model2->primalColumnSolution());
00881 CoinMemcpyN(barrier.dualColumnSolution(),
00882 model2->numberColumns(),model2->dualColumnSolution());
00883
00884 model2->createStatus();
00885
00886 model2->setPerturbation(100);
00887 model2->primal(1);
00888 model2->setPerturbation(savePerturbation);
00889 time2 = CoinCpuTime();
00890 timeCore = time2-timeX;
00891 handler_->message(CLP_INTERVAL_TIMING,messages_)
00892 <<"Crossover"<<timeCore<<time2-time1
00893 <<CoinMessageEol;
00894 timeX=time2;
00895 } else {
00896 assert (method!=ClpSolve::automatic);
00897 time2=0.0;
00898 }
00899 if (saveMatrix) {
00900
00901 delete model2->clpMatrix();
00902 model2->replaceMatrix(saveMatrix);
00903 }
00904 numberIterations = model2->numberIterations();
00905 finalStatus=model2->status();
00906 if (presolve==ClpSolve::presolveOn) {
00907 int saveLevel = logLevel();
00908 setLogLevel(1);
00909 pinfo.postsolve(true);
00910 time2 = CoinCpuTime();
00911 timePresolve += time2-timeX;
00912 handler_->message(CLP_INTERVAL_TIMING,messages_)
00913 <<"Postsolve"<<time2-timeX<<time2-time1
00914 <<CoinMessageEol;
00915 timeX=time2;
00916 if (!presolveToFile)
00917 delete model2;
00918 if (interrupt)
00919 currentModel = this;
00920 checkSolution();
00921 setLogLevel(saveLevel);
00922 if (finalStatus!=3&&(finalStatus||status()==-1)) {
00923 int savePerturbation = perturbation();
00924 setPerturbation(100);
00925 primal(1);
00926 setPerturbation(savePerturbation);
00927 numberIterations += this->numberIterations();
00928 finalStatus=status();
00929 time2 = CoinCpuTime();
00930 handler_->message(CLP_INTERVAL_TIMING,messages_)
00931 <<"Cleanup"<<time2-timeX<<time2-time1
00932 <<CoinMessageEol;
00933 timeX=time2;
00934 }
00935 }
00936 setMaximumIterations(saveMaxIterations);
00937 std::string statusMessage[]={"Unknown","Optimal","PrimalInfeasible","DualInfeasible","Stopped"};
00938 assert (finalStatus>=-1&&finalStatus<=3);
00939 handler_->message(CLP_TIMING,messages_)
00940 <<statusMessage[finalStatus+1]<<objectiveValue()<<numberIterations<<time2-time1;
00941 handler_->printing(presolve==ClpSolve::presolveOn)
00942 <<timePresolve;
00943 handler_->printing(timeIdiot)
00944 <<timeIdiot;
00945 handler_->message()<<CoinMessageEol;
00946 if (interrupt)
00947 signal(SIGINT,saveSignal);
00948 perturbation_=savePerturbation;
00949 scalingFlag_=saveScaling;
00950 return finalStatus;
00951 }
00952
00953 int
00954 ClpSimplex::initialSolve()
00955 {
00956
00957 ClpSolve options;
00958 return initialSolve(options);
00959 }
00960
00961 int
00962 ClpSimplex::initialDualSolve()
00963 {
00964 ClpSolve options;
00965
00966 options.setSolveType(ClpSolve::useDual);
00967 return initialSolve(options);
00968 }
00969
00970 int
00971 ClpSimplex::initialPrimalSolve()
00972 {
00973 ClpSolve options;
00974
00975 options.setSolveType(ClpSolve::usePrimal);
00976 return initialSolve(options);
00977 }
00978
00979 ClpSolve::ClpSolve ( )
00980 {
00981 method_ = useDual;
00982 presolveType_=presolveOn;
00983 numberPasses_=5;
00984 int i;
00985 for (i=0;i<4;i++)
00986 options_[i]=0;
00987 for (i=0;i<4;i++)
00988 extraInfo_[i]=-1;
00989 }
00990
00991
00992 ClpSolve::ClpSolve(const ClpSolve & rhs)
00993 {
00994 method_ = rhs.method_;
00995 presolveType_=rhs.presolveType_;
00996 numberPasses_=rhs.numberPasses_;
00997 int i;
00998 for ( i=0;i<4;i++)
00999 options_[i]=rhs.options_[i];
01000 for ( i=0;i<4;i++)
01001 extraInfo_[i]=rhs.extraInfo_[i];
01002 }
01003
01004 ClpSolve &
01005 ClpSolve::operator=(const ClpSolve & rhs)
01006 {
01007 if (this != &rhs) {
01008 method_ = rhs.method_;
01009 presolveType_=rhs.presolveType_;
01010 numberPasses_=rhs.numberPasses_;
01011 int i;
01012 for (i=0;i<4;i++)
01013 options_[i]=rhs.options_[i];
01014 for (i=0;i<4;i++)
01015 extraInfo_[i]=rhs.extraInfo_[i];
01016 }
01017 return *this;
01018
01019 }
01020
01021 ClpSolve::~ClpSolve ( )
01022 {
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 void
01043 ClpSolve::setSpecialOption(int which,int value,int extraInfo)
01044 {
01045 options_[which]=value;
01046 extraInfo_[which]=extraInfo;
01047 }
01048 int
01049 ClpSolve::getSpecialOption(int which) const
01050 {
01051 return options_[which];
01052 }
01053
01054
01055 void
01056 ClpSolve::setSolveType(SolveType method, int extraInfo)
01057 {
01058 method_=method;
01059 }
01060
01061 ClpSolve::SolveType
01062 ClpSolve::getSolveType()
01063 {
01064 return method_;
01065 }
01066
01067
01068 void
01069 ClpSolve::setPresolveType(PresolveType amount, int extraInfo)
01070 {
01071 presolveType_=amount;
01072 numberPasses_=extraInfo;
01073 }
01074 ClpSolve::PresolveType
01075 ClpSolve::getPresolveType()
01076 {
01077 return presolveType_;
01078 }
01079
01080 int
01081 ClpSolve::getExtraInfo(int which) const
01082 {
01083 return extraInfo_[which];
01084 }
01085 int
01086 ClpSolve::getPresolvePasses() const
01087 {
01088 return numberPasses_;
01089 }