00001
00002
00003
00004 #include "CoinPragma.hpp"
00005 #include <stdio.h>
00006 #include <stdarg.h>
00007 #include <stdlib.h>
00008 #include <math.h>
00009 #include "ClpPresolve.hpp"
00010 #include "Idiot.hpp"
00011 #include "CoinTime.hpp"
00012 #include "CoinMessageHandler.hpp"
00013
00014 #ifndef OSI_IDIOT
00015 #include "ClpMessage.hpp"
00016 #define OsiObjOffset ClpObjOffset
00017 #endif
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define IDIOT_FIX_TOLERANCE 1e-6
00036 #define SMALL_IDIOT_FIX_TOLERANCE 1e-10
00037 int
00038 Idiot::dropping(IdiotResult result,
00039 double tolerance,
00040 double small,
00041 int *nbad)
00042 {
00043 if (result.infeas<=small) {
00044 double value=max(fabs(result.objval),fabs(result.dropThis))+1.0;
00045 if (result.dropThis>tolerance*value) {
00046 *nbad=0;
00047 return 1;
00048 } else {
00049 (*nbad)++;
00050 if (*nbad>4) {
00051 return 0;
00052 } else {
00053 return 1;
00054 }
00055 }
00056 } else {
00057 *nbad=0;
00058 return 1;
00059 }
00060 }
00061
00062
00063 static int countCostedSlacks(OsiSolverInterface * model)
00064 {
00065 #ifdef OSI_IDIOT
00066 const CoinPackedMatrix * matrix = model->getMatrixByCol();
00067 #else
00068 ClpMatrixBase * matrix = model->clpMatrix();
00069 #endif
00070 const int * row = matrix->getIndices();
00071 const CoinBigIndex * columnStart = matrix->getVectorStarts();
00072 const int * columnLength = matrix->getVectorLengths();
00073 const double * element = matrix->getElements();
00074 const double * rowupper = model->getRowUpper();
00075 int nrows=model->getNumRows();
00076 int ncols=model->getNumCols();
00077 int slackStart = ncols-nrows;
00078 int nSlacks=nrows;
00079 int i;
00080
00081 if (ncols<=nrows) return -1;
00082 while (1) {
00083 for (i=0;i<nrows;i++) {
00084 int j=i+slackStart;
00085 CoinBigIndex k=columnStart[j];
00086 if (columnLength[j]==1) {
00087 if (row[k]!=i||element[k]!=1.0) {
00088 nSlacks=0;
00089 break;
00090 }
00091 } else {
00092 nSlacks=0;
00093 break;
00094 }
00095 if (rowupper[i]<=0.0) {
00096 nSlacks=0;
00097 break;
00098 }
00099 }
00100 if (nSlacks||!slackStart) break;
00101 slackStart=0;
00102 }
00103 if (!nSlacks) slackStart=-1;
00104 return slackStart;
00105 }
00106 void
00107 Idiot::crash(int numberPass, CoinMessageHandler * handler,const CoinMessages *messages)
00108 {
00109
00110 int numberColumns = model_->getNumCols();
00111 const double * objective = model_->getObjCoefficients();
00112 int nnzero=0;
00113 double sum=0.0;
00114 int i;
00115 for (i=0;i<numberColumns;i++) {
00116 if (objective[i]) {
00117 sum += fabs(objective[i]);
00118 nnzero++;
00119 }
00120 }
00121 sum /= (double) (nnzero+1);
00122 maxIts_=2;
00123 if (numberPass<=0)
00124
00125 majorIterations_=(int)(2+log10((double)(numberColumns+1)));
00126 else
00127 majorIterations_=numberPass;
00128
00129 if (mu_==1e-4)
00130 mu_= max(1.0e-3,sum*1.0e-5);
00131 if (!lightWeight_) {
00132 maxIts2_=105;
00133 } else if (lightWeight_==1) {
00134 mu_ *= 1000.0;
00135 maxIts2_=23;
00136 } else if (lightWeight_==2) {
00137 maxIts2_=11;
00138 } else {
00139 maxIts2_=23;
00140 }
00141
00142 solve2(handler,messages);
00143 #ifndef OSI_IDIOT
00144 double averageInfeas = model_->sumPrimalInfeasibilities()/((double) model_->numberRows());
00145 if (averageInfeas<0.01&&(strategy_&512)!=0)
00146 crossOver(16+1);
00147 else
00148 crossOver(3);
00149 #endif
00150 }
00151 void
00152 Idiot::solve()
00153 {
00154 CoinMessages dummy;
00155 solve2(NULL,&dummy);
00156 }
00157 void
00158 Idiot::solve2(CoinMessageHandler * handler,const CoinMessages * messages)
00159 {
00160 int strategy=0;
00161 double d2;
00162 int i,n;
00163 int allOnes=1;
00164 int iteration=0;
00165 int iterationTotal=0;
00166 int nTry=0;
00167 double fixTolerance=IDIOT_FIX_TOLERANCE;
00168 int maxBigIts=maxBigIts_;
00169 int maxIts=maxIts_;
00170 int logLevel=logLevel_;
00171 int saveMajorIterations = majorIterations_;
00172 if (handler) {
00173 if (handler->logLevel()>0&&handler->logLevel()<3)
00174 logLevel=1;
00175 else if (!handler->logLevel())
00176 logLevel=0;
00177 else
00178 logLevel=7;
00179 }
00180 double djExit=djTolerance_;
00181 double djFlag=1.0+100.0*djExit;
00182 double djTol=0.00001;
00183 double mu =mu_;
00184 double drop=drop_;
00185 int maxIts2=maxIts2_;
00186 double factor=muFactor_;
00187 double smallInfeas=smallInfeas_;
00188 double reasonableInfeas=reasonableInfeas_;
00189 double stopMu=stopMu_;
00190 double maxmin,offset;
00191 double lastWeighted=1.0e50;
00192 double exitDrop=exitDrop_;
00193 double fakeSmall=smallInfeas;
00194 double firstInfeas;
00195 int badIts=0;
00196 int slackStart,slackEnd,ordStart,ordEnd;
00197 int checkIteration=0;
00198 int lambdaIteration=0;
00199 int belowReasonable=0;
00200 double bestWeighted=1.0e60;
00201 double bestFeasible=1.0e60;
00202 IdiotResult result,lastResult;
00203 int saveStrategy=strategy_;
00204 const int strategies[]={0,2,128};
00205 double saveLambdaScale=0.0;
00206 if ((saveStrategy&128)!=0) {
00207 fixTolerance=SMALL_IDIOT_FIX_TOLERANCE;
00208 }
00209 #ifdef OSI_IDIOT
00210 const CoinPackedMatrix * matrix = model_->getMatrixByCol();
00211 #else
00212 ClpMatrixBase * matrix = model_->clpMatrix();
00213 #endif
00214 const int * row = matrix->getIndices();
00215 const CoinBigIndex * columnStart = matrix->getVectorStarts();
00216 const int * columnLength = matrix->getVectorLengths();
00217 const double * element = matrix->getElements();
00218 int nrows=model_->getNumRows();
00219 int ncols=model_->getNumCols();
00220 double * rowsol, * colsol;
00221 double * pi, * dj;
00222 #ifndef OSI_IDIOT
00223 double * cost = model_->objective();
00224 double * lower = model_->columnLower();
00225 double * upper = model_->columnUpper();
00226 double * rowlower= model_->rowLower();
00227 #else
00228 double * cost = new double [ncols];
00229 memcpy( cost, model_->getObjCoefficients(), ncols*sizeof(double));
00230 const double * lower = model_->getColLower();
00231 const double * upper = model_->getColUpper();
00232 const double * rowlower= model_->getRowLower();
00233 #endif
00234 const double *elemXX;
00235 double * saveSol;
00236 double * rowupper= new double[nrows];
00237 memcpy(rowupper,model_->getRowUpper(),nrows*sizeof(double));
00238 int * whenUsed;
00239 double * lambda;
00240 saveSol=new double[ncols];
00241 lambda=new double [nrows];
00242 rowsol= new double[nrows];
00243 colsol= new double [ncols];
00244 memcpy(colsol,model_->getColSolution(),ncols*sizeof(double));
00245 pi= new double[nrows];
00246 dj=new double[ncols];
00247 delete [] whenUsed_;
00248 whenUsed=whenUsed_=new int[ncols];
00249 if (model_->getObjSense()==-1.0) {
00250 maxmin=-1.0;
00251 } else {
00252 maxmin=1.0;
00253 }
00254 model_->getDblParam(OsiObjOffset,offset);
00255 if (!maxIts2) maxIts2=maxIts;
00256 strategy=strategy_;
00257 strategy &= 3;
00258 memset(lambda,0,nrows*sizeof(double));
00259 slackStart=countCostedSlacks(model_);
00260 if (slackStart>=0) {
00261 printf("This model has costed slacks\n");
00262 slackEnd=slackStart+nrows;
00263 if (slackStart) {
00264 ordStart=0;
00265 ordEnd=slackStart;
00266 } else {
00267 ordStart=nrows;
00268 ordEnd=ncols;
00269 }
00270 } else {
00271 slackEnd=slackStart;
00272 ordStart=0;
00273 ordEnd=ncols;
00274 }
00275 if (offset&&logLevel>2) {
00276 printf("** Objective offset is %g\n",offset);
00277 }
00278
00279 for (i=0;i<nrows;i++) {
00280 rowsol[i]=1.0e31;
00281 }
00282 for (i=0;i<ncols;i++) {
00283 CoinBigIndex j;
00284 for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
00285 if (element[j]!=1.0) {
00286 allOnes=0;
00287 break;
00288 }
00289 }
00290 }
00291 if (allOnes) {
00292 elemXX=NULL;
00293 } else {
00294 elemXX=element;
00295 }
00296
00297 bool scaled=false;
00298 #ifndef OSI_IDIOT
00299 if ((strategy_&32)!=0&&!allOnes) {
00300 scaled = model_->clpMatrix()->scale(model_)==0;
00301 if (scaled) {
00302 const double * rowScale = model_->rowScale();
00303 const double * columnScale = model_->columnScale();
00304 double * oldLower = lower;
00305 double * oldUpper = upper;
00306 double * oldCost = cost;
00307 lower = new double[ncols];
00308 upper = new double[ncols];
00309 cost = new double[ncols];
00310 memcpy(lower,oldLower,ncols*sizeof(double));
00311 memcpy(upper,oldUpper,ncols*sizeof(double));
00312 memcpy(cost,oldCost,ncols*sizeof(double));
00313 int icol,irow;
00314 for (icol=0;icol<ncols;icol++) {
00315 double multiplier = 1.0/columnScale[icol];
00316 if (lower[icol]>-1.0e50)
00317 lower[icol] *= multiplier;
00318 if (upper[icol]<1.0e50)
00319 upper[icol] *= multiplier;
00320 colsol[icol] *= multiplier;
00321 cost[icol] *= columnScale[icol];
00322 }
00323 rowlower = new double[nrows];
00324 memcpy(rowlower,model_->rowLower(),nrows*sizeof(double));
00325 for (irow=0;irow<nrows;irow++) {
00326 double multiplier = rowScale[irow];
00327 if (rowlower[irow]>-1.0e50)
00328 rowlower[irow] *= multiplier;
00329 if (rowupper[irow]<1.0e50)
00330 rowupper[irow] *= multiplier;
00331 rowsol[irow] *= multiplier;
00332 }
00333 int length = columnStart[ncols-1]+columnLength[ncols-1];
00334 double * elemYY = new double[length];
00335 for (i=0;i<ncols;i++) {
00336 CoinBigIndex j;
00337 double scale = columnScale[i];
00338 for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
00339 int irow=row[j];
00340 elemYY[j] = element[j]*scale*rowScale[irow];
00341 }
00342 }
00343 elemXX=elemYY;
00344 }
00345 }
00346 #endif
00347 for (i=0;i<ncols;i++) {
00348 CoinBigIndex j;
00349 double dd=columnLength[i];
00350 dd=cost[i]/dd;
00351 for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
00352 int irow=row[j];
00353 if (dd<rowsol[irow]) {
00354 rowsol[irow]=dd;
00355 }
00356 }
00357 }
00358 d2=0.0;
00359 for (i=0;i<nrows;i++) {
00360 d2+=rowsol[i];
00361 }
00362 d2*=2.0;
00363
00364 d2=d2/((double) (4*nrows+8000));
00365 d2*=0.5;
00366 if (d2<5.0) d2=5.0;
00367 if (djExit==0.0) {
00368 djExit=d2;
00369 }
00370 if ((saveStrategy&4)!=0) {
00371
00372 djExit=1.0e-10;
00373 djFlag=1.0e-5;
00374 drop=1.0e-10;
00375 }
00376 memset(whenUsed,0,ncols*sizeof(int));
00377 strategy=strategies[strategy];
00378 if ((saveStrategy&8)!=0) strategy |= 64;
00379 memcpy(saveSol,colsol,ncols*sizeof(double));
00380
00381 lastResult=IdiSolve(nrows,ncols,rowsol ,colsol,pi,
00382 dj,cost,rowlower,rowupper,
00383 lower,upper,elemXX,row,columnStart,columnLength,lambda,
00384 0,mu,drop,
00385 maxmin,offset,strategy,djTol,djExit,djFlag);
00386 n=0;
00387 for (i=ordStart;i<ordEnd;i++) {
00388 if (colsol[i]>lower[i]+fixTolerance) {
00389 if (colsol[i]<upper[i]-fixTolerance) {
00390 n++;
00391 } else {
00392 colsol[i]=upper[i];
00393 }
00394 whenUsed[i]=iteration;
00395 } else {
00396 colsol[i]=lower[i];
00397 }
00398 }
00399 if ((logLevel_&1)!=0) {
00400 #ifndef OSI_IDIOT
00401 if (!handler) {
00402 #endif
00403 printf("Iteration %d infeasibility %g, objective %g - mu %g, its %d, %d interior\n",
00404 iteration,lastResult.infeas,lastResult.objval,mu,lastResult.iteration,n);
00405 #ifndef OSI_IDIOT
00406 } else {
00407 handler->message(CLP_IDIOT_ITERATION,*messages)
00408 <<iteration<<lastResult.infeas<<lastResult.objval<<mu<<lastResult.iteration<<n
00409 <<CoinMessageEol;
00410 }
00411 #endif
00412 }
00413 int numberAway=-1;
00414 iterationTotal = lastResult.iteration;
00415 firstInfeas=lastResult.infeas;
00416 if ((strategy_&1024)!=0) reasonableInfeas=0.5*firstInfeas;
00417 if (lastResult.infeas<reasonableInfeas) lastResult.infeas=reasonableInfeas;
00418 double keepinfeas=1.0e31;
00419 double lastInfeas=1.0e31;
00420 double bestInfeas=1.0e31;
00421 while ((mu>stopMu&&lastResult.infeas>smallInfeas)||
00422 (lastResult.infeas<=smallInfeas&&
00423 dropping(lastResult,exitDrop,smallInfeas,&badIts))||
00424 checkIteration<2||lambdaIteration<lambdaIterations_) {
00425 if (lastResult.infeas<=exitFeasibility_)
00426 break;
00427 iteration++;
00428 checkIteration++;
00429 if (lastResult.infeas<=smallInfeas&&lastResult.objval<bestFeasible) {
00430 bestFeasible=lastResult.objval;
00431 }
00432 if ((saveStrategy&4096)) strategy |=256;
00433 if ((saveStrategy&4)!=0&&iteration>2) {
00434
00435 double weighted=10.0+fabs(lastWeighted);
00436 djExit=djTolerance_*weighted;
00437 djFlag=2.0*djExit;
00438 drop=drop_*weighted;
00439 djTol=0.01*djExit;
00440 }
00441 result=IdiSolve(nrows,ncols,rowsol ,colsol,pi,dj,
00442 cost,rowlower,rowupper,
00443 lower,upper,elemXX,row,columnStart,columnLength,lambda,
00444 maxIts,mu,drop,
00445 maxmin,offset,strategy,djTol,djExit,djFlag);
00446 n=0;
00447 for (i=ordStart;i<ordEnd;i++) {
00448 if (colsol[i]>lower[i]+fixTolerance) {
00449 if (colsol[i]<upper[i]-fixTolerance) {
00450 n++;
00451 } else {
00452 colsol[i]=upper[i];
00453 }
00454 whenUsed[i]=iteration;
00455 } else {
00456 colsol[i]=lower[i];
00457 }
00458 }
00459 if ((logLevel_&1)!=0) {
00460 #ifndef OSI_IDIOT
00461 if (!handler) {
00462 #endif
00463 printf("Iteration %d infeasibility %g, objective %g - mu %g, its %d, %d interior\n",
00464 iteration,result.infeas,result.objval,mu,result.iteration,n);
00465 #ifndef OSI_IDIOT
00466 } else {
00467 handler->message(CLP_IDIOT_ITERATION,*messages)
00468 <<iteration<<result.infeas<<result.objval<<mu<<result.iteration<<n
00469 <<CoinMessageEol;
00470 }
00471 #endif
00472 }
00473 if (iteration>50&&n==numberAway&&result.infeas<1.0e-4)
00474 break;
00475 if (lightWeight_==1&&iteration>10&&result.infeas>1.0&&maxIts!=7) {
00476 if (lastInfeas!=bestInfeas&&min(result.infeas,lastInfeas)>0.95*bestInfeas)
00477 majorIterations_ = min(majorIterations_,iteration);
00478 }
00479 bestInfeas=min(bestInfeas,result.infeas);
00480 lastInfeas = result.infeas;
00481 numberAway=n;
00482 keepinfeas = result.infeas;
00483 lastWeighted=result.weighted;
00484 iterationTotal += result.iteration;
00485 if (iteration==1) {
00486 if ((strategy_&1024)!=0&&mu<1.0e-10)
00487 result.infeas=firstInfeas*0.8;
00488 if (result.infeas>firstInfeas*0.9
00489 &&result.infeas>reasonableInfeas) {
00490 iteration--;
00491 memcpy(colsol,saveSol,ncols*sizeof(double));
00492 if (majorIterations_<50)
00493 mu*=1.0e-1;
00494 else
00495 mu*=0.7;
00496 bestFeasible=1.0e31;
00497 bestWeighted=1.0e60;
00498 if (mu<1.0e-30) break;
00499 } else {
00500 delete [] saveSol;
00501 saveSol=0;
00502 maxIts=maxIts2;
00503 checkIteration=0;
00504 if ((strategy_&1024)!=0) mu *= 1.0e-1;
00505 }
00506 }
00507 if (iteration) {
00508
00509 double changeMu=factor;
00510 if ((saveStrategy&64)!=0) {
00511 keepinfeas=0.0;
00512 fakeSmall=smallInfeas;
00513 } else {
00514 fakeSmall=-1.0;
00515 }
00516 saveLambdaScale=0.0;
00517 if (result.infeas>reasonableInfeas||
00518 (nTry+1==maxBigIts&&result.infeas>fakeSmall)) {
00519 if (result.infeas>lastResult.infeas*(1.0-dropEnoughFeasibility_)||
00520 nTry+1==maxBigIts||
00521 (result.infeas>lastResult.infeas*0.9
00522 &&result.weighted>lastResult.weighted
00523 -dropEnoughWeighted_*fabs(lastResult.weighted))) {
00524 mu*=changeMu;
00525 if ((saveStrategy&32)!=0&&result.infeas<reasonableInfeas&&0) {
00526 reasonableInfeas=max(smallInfeas,reasonableInfeas*sqrt(changeMu));
00527 printf("reasonable infeas now %g\n",reasonableInfeas);
00528 }
00529 nTry=0;
00530 bestFeasible=1.0e31;
00531 bestWeighted=1.0e60;
00532 checkIteration=0;
00533 lambdaIteration=0;
00534 #define LAMBDA
00535 #ifdef LAMBDA
00536 if ((saveStrategy&2048)==0) {
00537 memset(lambda,0,nrows*sizeof(double));
00538 }
00539 #else
00540 memset(lambda,0,nrows*sizeof(double));
00541 #endif
00542 } else {
00543 nTry++;
00544 }
00545 } else if (lambdaIterations_>=0) {
00546
00547 double scale=1.0/mu;
00548 int i,nnz=0;
00549 saveLambdaScale=scale;
00550 lambdaIteration++;
00551 if ((saveStrategy&4)==0) drop = drop_/50.0;
00552 if (lambdaIteration>4 &&
00553 (((lambdaIteration%10)==0 && smallInfeas<keepinfeas) ||
00554 (lambdaIteration%5)==0 && 1.5*smallInfeas<keepinfeas)) {
00555
00556 smallInfeas *= 1.5;
00557 }
00558 if ((saveStrategy&2048)==0) {
00559 for (i=0;i<nrows;i++) {
00560 if (lambda[i]) nnz++;
00561 lambda[i]+= scale*rowsol[i];
00562 }
00563 } else {
00564 nnz=1;
00565 #ifdef LAMBDA
00566 for (i=0;i<nrows;i++) {
00567 lambda[i]+= scale*rowsol[i];
00568 }
00569 #else
00570 for (i=0;i<nrows;i++) {
00571 lambda[i] = scale*rowsol[i];
00572 }
00573 for (i=0;i<ncols;i++) {
00574 CoinBigIndex j;
00575 double value=cost[i]*maxmin;
00576 for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
00577 int irow=row[j];
00578 value+=element[j]*lambda[irow];
00579 }
00580 cost[i]=value*maxmin;
00581 }
00582 for (i=0;i<nrows;i++) {
00583 offset+=lambda[i]*rowupper[i];
00584 lambda[i]=0.0;
00585 }
00586 #ifdef DEBUG
00587 printf("offset %g\n",offset);
00588 #endif
00589 model_->setDblParam(OsiObjOffset,offset);
00590 #endif
00591 }
00592 nTry++;
00593 if (!nnz) {
00594 bestFeasible=1.0e32;
00595 bestWeighted=1.0e60;
00596 checkIteration=0;
00597 result.weighted=1.0e31;
00598 }
00599 #ifdef DEBUG
00600 for (i=0;i<ncols;i++) {
00601 int j;
00602 trueCost+=cost[i]*colsol[i];
00603 }
00604 printf("True objective %g\n",trueCost-offset);
00605 #endif
00606 } else {
00607 nTry++;
00608 }
00609 lastResult=result;
00610 if (result.infeas<reasonableInfeas&&!belowReasonable) {
00611 belowReasonable=1;
00612 bestFeasible=1.0e32;
00613 bestWeighted=1.0e60;
00614 checkIteration=0;
00615 result.weighted=1.0e31;
00616 }
00617 }
00618 if (iteration>=majorIterations_) {
00619
00620 if (0&&result.infeas>1.0&&majorIterations_<30&&(maxIts2_==11||maxIts2_==23)) {
00621 maxIts=7;
00622 majorIterations_=100;
00623 } else {
00624 if (logLevel>2)
00625 printf("Exiting due to number of major iterations\n");
00626 break;
00627 }
00628 }
00629 }
00630 majorIterations_ = saveMajorIterations;
00631 #ifndef OSI_IDIOT
00632 if (scaled) {
00633
00634 const double * rowScale = model_->rowScale();
00635 const double * columnScale = model_->columnScale();
00636 int icol,irow;
00637 for (icol=0;icol<ncols;icol++) {
00638 colsol[icol] *= columnScale[icol];
00639 dj[icol] /= columnScale[icol];
00640 }
00641 for (irow=0;irow<nrows;irow++) {
00642 rowsol[irow] /= rowScale[irow];
00643 pi[irow] *= rowScale[irow];
00644 }
00645
00646 #if defined (_MSC_VER)
00647 delete [] ( double *)rowScale;
00648 delete [] ( double *) columnScale;
00649 delete [] ( double *) elemXX;
00650 #else
00651 delete [] rowScale;
00652 delete [] columnScale;
00653 delete [] elemXX;
00654 #endif
00655 model_->setRowScale(NULL);
00656 model_->setColumnScale(NULL);
00657 delete [] lower;
00658 delete [] upper;
00659 delete [] cost;
00660 lower = model_->columnLower();
00661 upper = model_->columnUpper();
00662 cost = model_->objective();
00663 rowlower = model_->rowLower();
00664 }
00665 #endif
00666 #define TRYTHIS
00667 #ifdef TRYTHIS
00668 if ((saveStrategy&2048)!=0) {
00669 double offset;
00670 model_->getDblParam(OsiObjOffset,offset);
00671 for (i=0;i<ncols;i++) {
00672 CoinBigIndex j;
00673 double djval=cost[i]*maxmin;
00674 for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
00675 int irow=row[j];
00676 djval -= element[j]*lambda[irow];
00677 }
00678 cost[i]=djval;
00679 }
00680 for (i=0;i<nrows;i++) {
00681 offset+=lambda[i]*rowupper[i];
00682 }
00683 model_->setDblParam(OsiObjOffset,offset);
00684 }
00685 #endif
00686 if (saveLambdaScale) {
00687
00688 for (i=0;i<nrows;i++) {
00689 lambda[i]-= saveLambdaScale*rowsol[i];
00690 }
00691 }
00692 muAtExit_=mu;
00693 n=0;
00694 for (i=ordStart;i<ordEnd;i++) {
00695 if (colsol[i]>lower[i]+fixTolerance) {
00696 n++;
00697 whenUsed[i]=iteration;
00698 } else {
00699 colsol[i]=lower[i];
00700 }
00701 }
00702 if ((logLevel&1)==0) {
00703 printf(
00704 "%d - mu %g, infeasibility %g, objective %g, %d interior\n",
00705 iteration,mu,lastResult.infeas,lastResult.objval,n);
00706 }
00707 #ifndef OSI_IDIOT
00708 model_->setSumPrimalInfeasibilities(lastResult.infeas);
00709 #endif
00710 {
00711 double large=0.0;
00712 int i;
00713 memset(rowsol,0,nrows*sizeof(double));
00714 for (i=0;i<ncols;i++) {
00715 CoinBigIndex j;
00716 double value=colsol[i];
00717 for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
00718 int irow=row[j];
00719 rowsol[irow] += element[j]*value;
00720 }
00721 }
00722 for (i=0;i<nrows;i++) {
00723 if (rowsol[i] > rowupper[i]) {
00724 double diff=rowsol[i]-rowupper[i];
00725 if (diff>large)
00726 large=diff;
00727 } else if (rowsol[i] < rowlower[i]) {
00728 double diff=rowlower[i]-rowsol[i];
00729 if (diff>large)
00730 large=diff;
00731 }
00732 }
00733 if (logLevel>2)
00734 printf("largest infeasibility is %g\n",large);
00735 }
00736
00737 for (i=0;i<nrows;i++) {
00738 pi[i]-=lambda[i];
00739 }
00740 for (i=0;i<ncols;i++) {
00741 CoinBigIndex j;
00742 double djval=cost[i]*maxmin;
00743 for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
00744 int irow=row[j];
00745 djval -= element[j]*pi[irow];
00746 }
00747 dj[i]=djval;
00748 }
00749 if ((strategy_&1024)!=0) {
00750 double ratio = ((double) ncols)/((double) nrows);
00751 printf("col/row ratio %g infeas ratio %g\n",ratio,lastResult.infeas/firstInfeas);
00752 if (lastResult.infeas>0.01*firstInfeas*ratio) {
00753 strategy_ &= (~1024);
00754 printf(" - layer off\n");
00755 } else {
00756 printf(" - layer on\n");
00757 }
00758 }
00759 delete [] saveSol;
00760 delete [] lambda;
00761
00762
00763 #ifndef OSI_IDIOT
00764 memcpy(model_->primalRowSolution(),rowsol,nrows*sizeof(double));
00765 memcpy(model_->primalColumnSolution(),colsol,ncols*sizeof(double));
00766 memcpy(model_->dualRowSolution(),pi,nrows*sizeof(double));
00767 memcpy(model_->dualColumnSolution(),dj,ncols*sizeof(double));
00768 #else
00769 model_->setColSolution(colsol);
00770 model_->setRowPrice(pi);
00771 delete [] cost;
00772 #endif
00773 delete [] rowsol;
00774 delete [] colsol;
00775 delete [] pi;
00776 delete [] dj;
00777 return ;
00778 }
00779 #ifndef OSI_IDIOT
00780 void
00781 Idiot::crossOver(int mode)
00782 {
00783 double fixTolerance=IDIOT_FIX_TOLERANCE;
00784 double startTime = CoinCpuTime();
00785 ClpSimplex * saveModel=NULL;
00786 ClpMatrixBase * matrix = model_->clpMatrix();
00787 const int * row = matrix->getIndices();
00788 const CoinBigIndex * columnStart = matrix->getVectorStarts();
00789 const int * columnLength = matrix->getVectorLengths();
00790 const double * element = matrix->getElements();
00791 const double * rowupper = model_->getRowUpper();
00792 int nrows=model_->getNumRows();
00793 int ncols=model_->getNumCols();
00794 double * rowsol, * colsol;
00795
00796 double * lower = model_->columnLower();
00797 double * upper = model_->columnUpper();
00798 const double * rowlower= model_->getRowLower();
00799 int * whenUsed=whenUsed_;
00800 rowsol= model_->primalRowSolution();
00801 colsol= model_->primalColumnSolution();;
00802 double * cost=model_->objective();
00803
00804 int slackEnd,ordStart,ordEnd;
00805 int slackStart = countCostedSlacks(model_);
00806
00807 int addAll = mode&7;
00808 int presolve=0;
00809
00810 double djTolerance = djTolerance_;
00811 if (djTolerance>0.0&&djTolerance<1.0)
00812 djTolerance=1.0;
00813 int iteration;
00814 int i, n=0;
00815 double ratio=1.0;
00816 double objValue=0.0;
00817 if ((strategy_&128)!=0) {
00818 fixTolerance=SMALL_IDIOT_FIX_TOLERANCE;
00819 }
00820 if ((mode&16)!=0&&addAll<3) presolve=1;
00821 double * saveUpper = NULL;
00822 double * saveLower = NULL;
00823 if (addAll<3) {
00824 saveUpper = new double [ncols];
00825 saveLower = new double [ncols];
00826 memcpy(saveUpper,upper,ncols*sizeof(double));
00827 memcpy(saveLower,lower,ncols*sizeof(double));
00828 }
00829 if (slackStart>=0) {
00830 slackEnd=slackStart+nrows;
00831 if (slackStart) {
00832 ordStart=0;
00833 ordEnd=slackStart;
00834 } else {
00835 ordStart=nrows;
00836 ordEnd=ncols;
00837 }
00838 } else {
00839 slackEnd=slackStart;
00840 ordStart=0;
00841 ordEnd=ncols;
00842 }
00843
00844 memset(rowsol,0,nrows*sizeof(double));
00845 for (i=ordStart;i<ordEnd;i++) {
00846 CoinBigIndex j;
00847 double value=colsol[i];
00848 if (value<lower[i]+fixTolerance) {
00849 value=lower[i];
00850 colsol[i]=value;
00851 }
00852 for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
00853 int irow=row[j];
00854 rowsol[irow]+=value*element[j];
00855 }
00856 }
00857 if (slackStart>=0) {
00858 for (i=0;i<nrows;i++) {
00859 if (ratio*rowsol[i]>rowlower[i]&&rowsol[i]>1.0e-8) {
00860 ratio=rowlower[i]/rowsol[i];
00861 }
00862 }
00863 for (i=0;i<nrows;i++) {
00864 rowsol[i]*=ratio;
00865 }
00866 for (i=ordStart;i<ordEnd;i++) {
00867 double value=colsol[i]*ratio;
00868 colsol[i]=value;
00869 objValue+=value*cost[i];
00870 }
00871 for (i=0;i<nrows;i++) {
00872 double value=rowlower[i]-rowsol[i];
00873 colsol[i+slackStart]=value;
00874 objValue+=value*cost[i+slackStart];
00875 }
00876 printf("New objective after scaling %g\n",objValue);
00877 }
00878 #if 0
00879 maybe put back - but just get feasible ?
00880
00881 int numberFixed=0;
00882 for (i=ordStart;i<ordEnd;i++) {
00883 if (colsol[i]<lower[i]+fixTolerance)
00884 numberFixed++;
00885 else if (colsol[i]>upper[i]-fixTolerance)
00886 numberFixed++;
00887 }
00888 if (numberFixed<ncols/2) {
00889 addAll=3;
00890 presolve=0;
00891 }
00892 #endif
00893 model_->createStatus();
00894
00895
00896
00897
00898
00899
00900 for (i=ordStart;i<ordEnd;i++) {
00901 if (addAll<2) {
00902 if (colsol[i]<lower[i]+fixTolerance) {
00903 upper[i]=lower[i];
00904 colsol[i]=lower[i];
00905 } else if (colsol[i]>upper[i]-fixTolerance) {
00906 lower[i]=upper[i];
00907 colsol[i]=upper[i];
00908 }
00909 }
00910 model_->setColumnStatus(i,ClpSimplex::superBasic);
00911 }
00912 double maxmin;
00913 if (model_->getObjSense()==-1.0) {
00914 maxmin=-1.0;
00915 } else {
00916 maxmin=1.0;
00917 }
00918 if (slackStart>=0) {
00919 for (i=0;i<nrows;i++) {
00920 model_->setRowStatus(i,ClpSimplex::superBasic);
00921 }
00922 for (i=slackStart;i<slackEnd;i++) {
00923 model_->setColumnStatus(i,ClpSimplex::basic);
00924 }
00925 } else {
00926
00927 int ninbas=0;
00928 for (i=0;i<nrows;i++) {
00929 model_->setRowStatus(i,ClpSimplex::basic);
00930 }
00931 for (i=0;i<ncols;i++) {
00932 if (columnLength[i]==1&&upper[i]>lower[i]+1.0e-5) {
00933 CoinBigIndex j =columnStart[i];
00934 double value=element[j];
00935 int irow=row[j];
00936 double rlo=rowlower[irow];
00937 double rup=rowupper[irow];
00938 double clo=lower[i];
00939 double cup=upper[i];
00940 double csol=colsol[i];
00941
00942 double move=0.0;
00943 if (rowsol[irow]>rup) {
00944 move=(rup-rowsol[irow])/value;
00945 if (value>0.0) {
00946
00947 if (csol+move<clo) move=min(0.0,clo-csol);
00948 } else {
00949
00950 if (csol+move>cup) move=max(0.0,cup-csol);
00951 }
00952 } else if (rowsol[irow]<rlo) {
00953 move=(rlo-rowsol[irow])/value;
00954 if (value>0.0) {
00955
00956 if (csol+move>cup) move=max(0.0,cup-csol);
00957 } else {
00958
00959 if (csol+move<clo) move=min(0.0,clo-csol);
00960 }
00961 } else {
00962
00963 if (cost[i]*maxmin>0.0) {
00964 if (value>0.0) {
00965 move=(rlo-rowsol[irow])/value;
00966
00967 if (csol+move<clo) move=min(0.0,clo-csol);
00968 } else {
00969 move=(rup-rowsol[irow])/value;
00970
00971 if (csol+move>cup) move=max(0.0,cup-csol);
00972 }
00973 } else if (cost[i]*maxmin<0.0) {
00974 if (value>0.0) {
00975 move=(rup-rowsol[irow])/value;
00976
00977 if (csol+move>cup) move=max(0.0,cup-csol);
00978 } else {
00979 move=(rlo-rowsol[irow])/value;
00980
00981 if (csol+move<clo) move=min(0.0,clo-csol);
00982 }
00983 }
00984 }
00985 rowsol[irow] +=move*value;
00986 colsol[i]+=move;
00987
00988 if (rup-rlo<1.0e-7&&model_->getRowStatus(irow)==ClpSimplex::basic) {
00989 model_->setRowStatus(irow,ClpSimplex::superBasic);
00990 model_->setColumnStatus(i,ClpSimplex::basic);
00991 ninbas++;
00992 }
00993 }
00994 }
00995
00996 }
00997 if (addAll<3) {
00998 ClpPresolve pinfo;
00999 if (presolve) {
01000 saveModel = model_;
01001 model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
01002 }
01003 if (model_) {
01004 model_->primal(1);
01005 if (presolve) {
01006 pinfo.postsolve(true);
01007 delete model_;
01008 model_ = saveModel;
01009 saveModel=NULL;
01010 }
01011 } else {
01012
01013 addAll=1;
01014 presolve=0;
01015 model_ = saveModel;
01016 saveModel=NULL;
01017 }
01018 if (addAll<2) {
01019 n=0;
01020 if (!addAll ) {
01021
01022 iteration=1;
01023 for (i=ordStart;i<ordEnd;i++) {
01024 if (whenUsed[i]>=iteration) {
01025 if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
01026 n++;
01027 upper[i]=saveUpper[i];
01028 lower[i]=saveLower[i];
01029 }
01030 }
01031 }
01032 } else {
01033 for (i=ordStart;i<ordEnd;i++) {
01034 if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
01035 n++;
01036 upper[i]=saveUpper[i];
01037 lower[i]=saveLower[i];
01038 }
01039 }
01040 }
01041 printf("Time so far %g, %d now added from previous iterations\n",
01042 CoinCpuTime()-startTime,n);
01043 if (addAll)
01044 presolve=0;
01045 if (presolve) {
01046 saveModel = model_;
01047 model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
01048 } else {
01049 presolve=0;
01050 }
01051 model_->primal(1);
01052 if (presolve) {
01053 pinfo.postsolve(true);
01054 delete model_;
01055 model_ = saveModel;
01056 saveModel=NULL;
01057 }
01058 if (!addAll) {
01059 n=0;
01060 for (i=ordStart;i<ordEnd;i++) {
01061 if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
01062 n++;
01063 upper[i]=saveUpper[i];
01064 lower[i]=saveLower[i];
01065 }
01066 }
01067 printf("Time so far %g, %d now added from previous iterations\n",
01068 CoinCpuTime()-startTime,n);
01069 }
01070 if (presolve) {
01071 saveModel = model_;
01072 model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
01073 } else {
01074 presolve=0;
01075 }
01076 model_->primal(1);
01077 if (presolve) {
01078 pinfo.postsolve(true);
01079 delete model_;
01080 model_ = saveModel;
01081 saveModel=NULL;
01082 }
01083 }
01084 printf("Total time in crossover %g\n", CoinCpuTime()-startTime);
01085 delete [] saveUpper;
01086 delete [] saveLower;
01087 }
01088 return ;
01089 }
01090 #endif
01091
01092
01093
01094 Idiot::Idiot()
01095 {
01096 model_ = NULL;
01097 maxBigIts_ = 3;
01098 maxIts_ = 5;
01099 logLevel_ = 1;
01100 logFreq_ = 100;
01101 maxIts2_ = 100;
01102 djTolerance_ = 1e-1;
01103 mu_ = 1e-4;
01104 drop_ = 5.0;
01105 exitDrop_=-1.0e20;
01106 muFactor_ = 0.3333;
01107 stopMu_ = 1e-12;
01108 smallInfeas_ = 1e-1;
01109 reasonableInfeas_ = 1e2;
01110 muAtExit_ =1.0e31;
01111 strategy_ =8;
01112 lambdaIterations_ =0;
01113 checkFrequency_ =100;
01114 whenUsed_ = NULL;
01115 majorIterations_ =30;
01116 exitFeasibility_ =-1.0;
01117 dropEnoughFeasibility_ =0.02;
01118 dropEnoughWeighted_ =0.01;
01119
01120 double nrows=10000.0;
01121 int baseIts =(int) sqrt((double)nrows);
01122 baseIts =baseIts/10;
01123 baseIts *= 10;
01124 maxIts2_ =200+baseIts+5;
01125 reasonableInfeas_ =((double) nrows)*0.05;
01126 lightWeight_=0;
01127 }
01128
01129 Idiot::Idiot(OsiSolverInterface &model)
01130 {
01131 model_ = & model;
01132 maxBigIts_ = 3;
01133 maxIts_ = 5;
01134 logLevel_ = 1;
01135 logFreq_ = 100;
01136 maxIts2_ = 100;
01137 djTolerance_ = 1e-1;
01138 mu_ = 1e-4;
01139 drop_ = 5.0;
01140 exitDrop_=-1.0e20;
01141 muFactor_ = 0.3333;
01142 stopMu_ = 1e-12;
01143 smallInfeas_ = 1e-1;
01144 reasonableInfeas_ = 1e2;
01145 muAtExit_ =1.0e31;
01146 strategy_ =8;
01147 lambdaIterations_ =0;
01148 checkFrequency_ =100;
01149 whenUsed_ = NULL;
01150 majorIterations_ =30;
01151 exitFeasibility_ =-1.0;
01152 dropEnoughFeasibility_ =0.02;
01153 dropEnoughWeighted_ =0.01;
01154
01155 double nrows;
01156 if (model_)
01157 nrows=model_->getNumRows();
01158 else
01159 nrows=10000.0;
01160 int baseIts =(int) sqrt((double)nrows);
01161 baseIts =baseIts/10;
01162 baseIts *= 10;
01163 maxIts2_ =200+baseIts+5;
01164 reasonableInfeas_ =((double) nrows)*0.05;
01165 lightWeight_=0;
01166 }
01167
01168 Idiot::Idiot(const Idiot &rhs)
01169 {
01170 model_ = rhs.model_;
01171 if (model_&&rhs.whenUsed_) {
01172 int numberColumns = model_->getNumCols();
01173 whenUsed_ = new int [numberColumns];
01174 memcpy(whenUsed_,rhs.whenUsed_,numberColumns*sizeof(int));
01175 } else {
01176 whenUsed_=NULL;
01177 }
01178 djTolerance_ = rhs.djTolerance_;
01179 mu_ = rhs.mu_;
01180 drop_ = rhs.drop_;
01181 muFactor_ = rhs.muFactor_;
01182 stopMu_ = rhs.stopMu_;
01183 smallInfeas_ = rhs.smallInfeas_;
01184 reasonableInfeas_ = rhs.reasonableInfeas_;
01185 exitDrop_ = rhs.exitDrop_;
01186 muAtExit_ = rhs.muAtExit_;
01187 exitFeasibility_ = rhs.exitFeasibility_;
01188 dropEnoughFeasibility_ = rhs.dropEnoughFeasibility_;
01189 dropEnoughWeighted_ = rhs.dropEnoughWeighted_;
01190 maxBigIts_ = rhs.maxBigIts_;
01191 maxIts_ = rhs.maxIts_;
01192 majorIterations_ = rhs.majorIterations_;
01193 logLevel_ = rhs.logLevel_;
01194 logFreq_ = rhs.logFreq_;
01195 checkFrequency_ = rhs.checkFrequency_;
01196 lambdaIterations_ = rhs.lambdaIterations_;
01197 maxIts2_ = rhs.maxIts2_;
01198 strategy_ = rhs.strategy_;
01199 lightWeight_=rhs.lightWeight_;
01200 }
01201
01202 Idiot &
01203 Idiot::operator=(const Idiot & rhs)
01204 {
01205 if (this != &rhs) {
01206 delete [] whenUsed_;
01207 model_ = rhs.model_;
01208 if (model_&&rhs.whenUsed_) {
01209 int numberColumns = model_->getNumCols();
01210 whenUsed_ = new int [numberColumns];
01211 memcpy(whenUsed_,rhs.whenUsed_,numberColumns*sizeof(int));
01212 } else {
01213 whenUsed_=NULL;
01214 }
01215 djTolerance_ = rhs.djTolerance_;
01216 mu_ = rhs.mu_;
01217 drop_ = rhs.drop_;
01218 muFactor_ = rhs.muFactor_;
01219 stopMu_ = rhs.stopMu_;
01220 smallInfeas_ = rhs.smallInfeas_;
01221 reasonableInfeas_ = rhs.reasonableInfeas_;
01222 exitDrop_ = rhs.exitDrop_;
01223 muAtExit_ = rhs.muAtExit_;
01224 exitFeasibility_ = rhs.exitFeasibility_;
01225 dropEnoughFeasibility_ = rhs.dropEnoughFeasibility_;
01226 dropEnoughWeighted_ = rhs.dropEnoughWeighted_;
01227 maxBigIts_ = rhs.maxBigIts_;
01228 maxIts_ = rhs.maxIts_;
01229 majorIterations_ = rhs.majorIterations_;
01230 logLevel_ = rhs.logLevel_;
01231 logFreq_ = rhs.logFreq_;
01232 checkFrequency_ = rhs.checkFrequency_;
01233 lambdaIterations_ = rhs.lambdaIterations_;
01234 maxIts2_ = rhs.maxIts2_;
01235 strategy_ = rhs.strategy_;
01236 lightWeight_=rhs.lightWeight_;
01237 }
01238 return *this;
01239 }
01240 Idiot::~Idiot()
01241 {
01242 delete [] whenUsed_;
01243 }