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 "CoinHelperFunctions.hpp"
00010 #include "Idiot.hpp"
00011 #define FIT
00012 #ifdef FIT
00013 #define HISTORY 8
00014 #else
00015 #define HISTORY 7
00016 #endif
00017 #define NSOLVE HISTORY-1
00018 static void solveSmall(int nsolve,double **aIn,double **a, double * b) {
00019 int i,j;
00020
00021 for (i=0;i<nsolve;i++) {
00022 for (j=0;j<nsolve;j++) {
00023 a[i][j]=aIn[i][j];
00024 }
00025 }
00026 for (i=0;i<nsolve;i++) {
00027
00028 double diagonal;
00029 int j;
00030 for (j=i;j<nsolve;j++) {
00031 int k;
00032 double value=a[i][j];
00033 for (k=0;k<i;k++) {
00034 value-=a[k][i]*a[k][j];
00035 }
00036 a[i][j]=value;
00037 }
00038 diagonal=a[i][i];
00039 if (diagonal<1.0e-20) {
00040 diagonal=0.0;
00041 } else {
00042 diagonal=1.0/sqrt(diagonal);
00043 }
00044 a[i][i]=diagonal;
00045 for (j=i+1;j<nsolve;j++) {
00046 a[i][j]*=diagonal;
00047 }
00048 }
00049
00050 for (i=0;i<nsolve;i++) {
00051 int j;
00052 double value=b[i];
00053 for (j=0;j<i;j++) {
00054 value-=b[j]*a[j][i];
00055 }
00056 value*=a[i][i];
00057 b[i]=value;
00058 }
00059 for (i=nsolve-1;i>=0;i--) {
00060 int j;
00061 double value=b[i];
00062 for (j=i+1;j<nsolve;j++) {
00063 value-=b[j]*a[i][j];
00064 }
00065 value*=a[i][i];
00066 b[i]=value;
00067 }
00068 }
00069 IdiotResult
00070 Idiot::objval(int nrows, int ncols, double * rowsol , double * colsol,
00071 double * pi, double * djs, const double * cost ,
00072 const double * rowlower,
00073 const double * rowupper, const double * lower,
00074 const double * upper, const double * elemnt,
00075 const int * row, const CoinBigIndex * columnStart,
00076 const int * length, int extraBlock, int * rowExtra,
00077 double * solExtra, double * elemExtra, double * upperExtra,
00078 double * costExtra,double weight)
00079 {
00080 IdiotResult result;
00081 double objvalue=0.0;
00082 double sum1=0.0,sum2=0.0;
00083 int i;
00084 for (i=0;i<nrows;i++) {
00085 rowsol[i]=-rowupper[i];
00086 }
00087 for (i=0;i<ncols;i++) {
00088 CoinBigIndex j;
00089 double value=colsol[i];
00090 if (value) {
00091 objvalue+=value*cost[i];
00092 if (elemnt) {
00093 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00094 int irow=row[j];
00095 rowsol[irow]+=elemnt[j]*value;
00096 }
00097 } else {
00098 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00099 int irow=row[j];
00100 rowsol[irow]+=value;
00101 }
00102 }
00103 }
00104 }
00105
00106
00107 if (extraBlock) {
00108 for (i=0;i<extraBlock;i++) {
00109 double element=elemExtra[i];
00110 int irow=rowExtra[i];
00111 objvalue+=solExtra[i]*costExtra[i];
00112 rowsol[irow] += solExtra[i]*element;
00113 }
00114 }
00115 for (i=0;i<nrows;i++) {
00116 double value=rowsol[i];
00117 sum1+=fabs(value);
00118 sum2+=value*value;
00119 pi[i]=-2.0*weight*value;
00120 }
00121 result.infeas=sum1;
00122 result.objval=objvalue;
00123 result.weighted=objvalue+weight*sum2;
00124 result.sumSquared=sum2;
00125 return result;
00126 }
00127 IdiotResult
00128 Idiot::IdiSolve(
00129 int nrows, int ncols, double * rowsol , double * colsol,
00130 double * pi, double * djs, const double * origcost , const double * rowlower,
00131 double * rowupper, const double * lower,
00132 const double * upper, const double * elemnt,
00133 const int * row, const CoinBigIndex * columnStart,
00134 const int * length, double * lambda,
00135 int maxIts,double mu,double drop,
00136 double maxmin, double offset,
00137 int strategy,double djTol,double djExit,double djFlag)
00138 {
00139 IdiotResult result;
00140 int i,j,k,iter;
00141 double value=0.0,objvalue=0.0,weightedObj=0.0;
00142 double tolerance=1.0e-8;
00143 double * history[HISTORY+1];
00144 int ncolx;
00145 int nChange;
00146 int extraBlock=0;
00147 int * rowExtra=NULL;
00148 double * solExtra=NULL;
00149 double * elemExtra=NULL;
00150 double * upperExtra=NULL;
00151 double * costExtra=NULL;
00152 double * useCostExtra=NULL;
00153 double * saveExtra=NULL;
00154 double * cost=NULL;
00155 double saveValue=1.0e30;
00156 double saveOffset=offset;
00157 double useOffset=offset;
00158
00159 #ifndef NULLVECTOR
00160 int nsolve=NSOLVE;
00161 #else
00162 int nsolve=NSOLVE+1;
00163 #endif
00164 int nflagged;
00165 double * thetaX;
00166 double * djX;
00167 double * bX;
00168 double * vX;
00169 double ** aX;
00170 double **aworkX;
00171 double ** allsum;
00172 double * saveSol=0;
00173 const double * useCost=cost;
00174 double bestSol=1.0e60;
00175 double weight=0.5/mu;
00176 char * statusSave=new char[2*ncols];
00177 char * statusWork=statusSave+ncols;
00178 #define DJTEST 5
00179 double djSave[DJTEST];
00180 double largestDj=0.0;
00181 double smallestDj=1.0e60;
00182 double maxDj=0.0;
00183 int doFull=0;
00184 #define SAVEHISTORY 10
00185 #define EVERY (2*SAVEHISTORY)
00186 #define AFTER SAVEHISTORY*(HISTORY+1)
00187 #define DROP 5
00188 double after=AFTER;
00189 double obj[DROP];
00190 double kbad=0,kgood=0;
00191 if (strategy&128) after=999999;
00192 for (i=0;i<DROP;i++) {
00193 obj[i]=1.0e70;
00194 }
00195 allsum=new double * [nsolve];
00196 aX=new double * [nsolve];
00197 aworkX=new double * [nsolve];
00198 thetaX=new double[nsolve];
00199 vX=new double[nsolve];
00200 bX=new double[nsolve];
00201 djX=new double[nsolve];
00202 allsum[0]=pi;
00203 for (i=0;i<nsolve;i++) {
00204 if (i) allsum[i]=new double[nrows];
00205 aX[i]=new double[nsolve];
00206 aworkX[i]=new double[nsolve];
00207 }
00208
00209 for (i=0;i<nrows;i++) {
00210 if (rowupper[i]-rowlower[i]>tolerance) {
00211 extraBlock++;
00212 }
00213 }
00214 cost=new double[ncols];
00215 memset(rowsol,0,nrows*sizeof(double));
00216 for (i=0;i<ncols;i++) {
00217 CoinBigIndex j;
00218 double value=origcost[i]*maxmin;
00219 double value2=colsol[i];
00220 if (elemnt) {
00221 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00222 int irow=row[j];
00223 value+=elemnt[j]*lambda[irow];
00224 rowsol[irow]+=elemnt[j]*value2;
00225 }
00226 } else {
00227 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00228 int irow=row[j];
00229 value+=lambda[irow];
00230 rowsol[irow]+=value2;
00231 }
00232 }
00233 cost[i]=value;
00234 }
00235 if (extraBlock) {
00236 rowExtra=new int[extraBlock];
00237 solExtra=new double[extraBlock];
00238 elemExtra=new double[extraBlock];
00239 upperExtra=new double[extraBlock];
00240 costExtra=new double[extraBlock];
00241 saveExtra=new double[extraBlock];
00242 extraBlock=0;
00243 for (i=0;i<nrows;i++) {
00244 if (rowupper[i]-rowlower[i]>tolerance) {
00245 double smaller,difference;
00246 double value;
00247 saveExtra[extraBlock]=rowupper[i];
00248 if (fabs(rowupper[i])>fabs(rowlower[i])) {
00249 smaller = rowlower[i];
00250 value=-1.0;
00251 } else {
00252 smaller = rowupper[i];
00253 value=1.0;
00254 }
00255 if (fabs(smaller)>1.0e10) {
00256 printf("Can't handle rows where both bounds >1.0e10 %d %g\n",
00257 i,smaller);
00258 abort();
00259 }
00260 difference=rowupper[i]-rowlower[i];
00261 difference = min(difference,1.0e31);
00262 rowupper[i]=smaller;
00263 elemExtra[extraBlock]=value;
00264 solExtra[extraBlock]=(rowupper[i]-rowsol[i])/value;
00265 if (solExtra[extraBlock]<0.0) solExtra[extraBlock]=0.0;
00266 if (solExtra[extraBlock]>difference) solExtra[extraBlock]=difference;
00267 costExtra[extraBlock]=lambda[i]*value;
00268 upperExtra[extraBlock]=difference;
00269 rowsol[i]+=value*solExtra[extraBlock];
00270 rowExtra[extraBlock++]=i;
00271 }
00272 }
00273 }
00274 for (i=0;i<nrows;i++) {
00275 offset+=lambda[i]*rowsol[i];
00276 }
00277 if ((strategy&256)!=0) {
00278
00279 saveSol=new double[ncols];
00280 memcpy(saveSol,colsol,ncols*sizeof(double));
00281 if (extraBlock) {
00282 useCostExtra=new double[extraBlock];
00283 memset(useCostExtra,0,extraBlock*sizeof(double));
00284 }
00285 useCost=origcost;
00286 useOffset=saveOffset;
00287 } else {
00288 useCostExtra=costExtra;
00289 useCost=cost;
00290 useOffset=offset;
00291 }
00292 ncolx=ncols+extraBlock;
00293 for (i=0;i<HISTORY+1;i++) {
00294 history[i]=new double[ncolx];
00295 }
00296 for (i=0;i<DJTEST;i++) {
00297 djSave[i]=1.0e30;
00298 }
00299 for (i=0;i<ncols;i++) {
00300 if (upper[i]-lower[i]) {
00301 statusSave[i]=0;
00302 } else {
00303 statusSave[i]=1;
00304 }
00305 }
00306
00307 int start[2];
00308 int stop[2];
00309 int direction=-1;
00310 start[0]=0;stop[0]=ncols;
00311 start[1]=0;stop[1]=0;
00312 iter=0;
00313 for (;iter<maxIts;iter++) {
00314 double sum1=0.0,sum2=0.0,djtot;
00315 double lastObj=1.0e70;
00316 int good=0,doScale=0;
00317 if (strategy&16) {
00318 int ii=iter/EVERY+1;
00319 ii=ii*EVERY;
00320 if (iter>ii-HISTORY*2&&(iter&1)==0) {
00321 double * x=history[HISTORY-1];
00322 for (i=HISTORY-1;i>0;i--) {
00323 history[i]=history[i-1];
00324 }
00325 history[0]=x;
00326 memcpy(history[0],colsol,ncols*sizeof(double));
00327 memcpy(history[0]+ncols,solExtra,extraBlock*sizeof(double));
00328 }
00329 }
00330 if ((iter % SAVEHISTORY)==0||doFull) {
00331 if ((strategy&16)==0) {
00332 double * x=history[HISTORY-1];
00333 for (i=HISTORY-1;i>0;i--) {
00334 history[i]=history[i-1];
00335 }
00336 history[0]=x;
00337 memcpy(history[0],colsol,ncols*sizeof(double));
00338 memcpy(history[0]+ncols,solExtra,extraBlock*sizeof(double));
00339 }
00340 }
00341
00342 if ((iter % EVERY)==0||doFull) {
00343
00344 direction = - direction;
00345
00346
00347 int kcol = (int)(ncols*CoinDrand48());
00348 if (kcol==ncols)
00349 kcol=ncols-1;
00350 if (direction>0) {
00351 start[0]=kcol;stop[0]=ncols;
00352 start[1]=0;stop[1]=kcol;
00353 } else {
00354 start[0]=kcol;stop[0]=-1;
00355 start[1]=ncols-1;stop[1]=kcol;
00356 }
00357 int itry=0;
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 while (!good) {
00368 itry++;
00369 #define MAXTRY 5
00370 if (iter>after&&doScale<2&&itry<MAXTRY) {
00371
00372 for (i=0;i<nrows;i++) {
00373 rowsol[i]=-rowupper[i];
00374 }
00375 sum2=0.0;
00376 objvalue=0.0;
00377 memset(pi,0,nrows*sizeof(double));
00378 djtot=0.0;
00379 {
00380 double * theta=thetaX;
00381 double * dj=djX;
00382 double * b=bX;
00383 double ** a=aX;
00384 double ** awork=aworkX;
00385 double * v=vX;
00386 double c;
00387 #ifdef FIT
00388 int ntot=0,nsign=0,ngood=0,mgood[4]={0,0,0,0};
00389 double diff1,diff2,val0,val1,val2,newValue;
00390 memcpy(history[HISTORY-1],colsol,ncols*sizeof(double));
00391 memcpy(history[HISTORY-1]+ncols,solExtra,extraBlock*sizeof(double));
00392 #endif
00393 dj[0]=0.0;
00394 for (i=1;i<nsolve;i++) {
00395 dj[i]=0.0;
00396 memset(allsum[i],0,nrows*sizeof(double));
00397 }
00398 for (i=0;i<ncols;i++) {
00399 double value2=colsol[i];
00400 if (value2>lower[i]+tolerance) {
00401 if(value2<(upper[i]-tolerance)) {
00402 int k;
00403 objvalue+=value2*cost[i];
00404 #ifdef FIT
00405 ntot++;
00406 val0=history[0][i];
00407 val1=history[1][i];
00408 val2=history[2][i];
00409 diff1=val0-val1;
00410 diff2=val1-val2;
00411 if (diff1*diff2>=0.0) {
00412 nsign++;
00413 if (fabs(diff1)<=fabs(diff2)) {
00414
00415
00416 int ii=(int)fabs(4.0*diff1/diff2);
00417 if (ii==4) ii=3;
00418 mgood[ii]++;
00419 ngood++;
00420 }
00421 if (fabs(diff1)<0.75*fabs(diff2)) {
00422 newValue=val1+(diff1*diff2)/(diff2-diff1);
00423 } else {
00424 newValue=val1+4.0*diff1;
00425 }
00426 } else {
00427 newValue=0.333333333*(val0+val1+val2);
00428 }
00429 if (newValue>upper[i]-tolerance) {
00430 newValue=upper[i];
00431 } else if (newValue<lower[i]+tolerance) {
00432 newValue=lower[i];
00433 }
00434 history[HISTORY-1][i]=newValue;
00435 #endif
00436 for (k=0;k<HISTORY-1;k++) {
00437 value=history[k][i]-history[k+1][i];
00438 dj[k] += value*cost[i];
00439 v[k]=value;
00440 }
00441 if (elemnt) {
00442 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00443 int irow=row[j];
00444 for (k=0;k<HISTORY-1;k++) {
00445 allsum[k][irow] += elemnt[j]*v[k];
00446 }
00447 rowsol[irow] += elemnt[j]*value2;
00448 }
00449 } else {
00450 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00451 int irow=row[j];
00452 for (k=0;k<HISTORY-1;k++) {
00453 allsum[k][irow] += v[k];
00454 }
00455 rowsol[irow] += value2;
00456 }
00457 }
00458 } else {
00459
00460 colsol[i]=upper[i];
00461 value2=colsol[i];
00462 objvalue+=value2*cost[i];
00463 if (elemnt) {
00464 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00465 int irow=row[j];
00466 rowsol[irow] += elemnt[j]*value2;
00467 }
00468 } else {
00469 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00470 int irow=row[j];
00471 rowsol[irow] += value2;
00472 }
00473 }
00474 }
00475 } else {
00476
00477 if (value2) {
00478 objvalue+=value2*cost[i];
00479 if (elemnt) {
00480 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00481 int irow=row[j];
00482 rowsol[irow] += elemnt[j]*value2;
00483 }
00484 } else {
00485 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00486 int irow=row[j];
00487 rowsol[irow] += value2;
00488 }
00489 }
00490 }
00491 }
00492 }
00493 #ifdef FIT
00494
00495
00496 #endif
00497 if (extraBlock) {
00498 for (i=0;i<extraBlock;i++) {
00499 double element=elemExtra[i];
00500 int irow=rowExtra[i];
00501 objvalue+=solExtra[i]*costExtra[i];
00502 if (solExtra[i]>tolerance
00503 &&solExtra[i]<(upperExtra[i]-tolerance)) {
00504 double value2=solExtra[i];
00505 int k;
00506 for (k=0;k<HISTORY-1;k++) {
00507 value=history[k][i+ncols]-history[k+1][i+ncols];
00508 dj[k] += value*costExtra[i];
00509 allsum[k][irow] += element*value;
00510 }
00511 rowsol[irow] += element*value2;
00512 } else {
00513 double value2=solExtra[i];
00514 double element=elemExtra[i];
00515 int irow=rowExtra[i];
00516 rowsol[irow] += element*value2;
00517 }
00518 }
00519 }
00520 #ifdef NULLVECTOR
00521 if ((strategy&64)) {
00522 double djVal=dj[0];
00523 for (i=0;i<ncols-nrows;i++) {
00524 double value2=colsol[i];
00525 if (value2>lower[i]+tolerance&&value2<upper[i]-tolerance) {
00526 value=history[0][i]-history[1][i];
00527 } else {
00528 value=0.0;
00529 }
00530 history[HISTORY][i]=value;
00531 }
00532 for (;i<ncols;i++) {
00533 double value2=colsol[i];
00534 double delta;
00535 int irow=i-(ncols-nrows);
00536 double oldSum=allsum[0][irow];;
00537 if (value2>lower[i]+tolerance&&value2<upper[i]-tolerance) {
00538 delta=history[0][i]-history[1][i];
00539 } else {
00540 delta=0.0;
00541 }
00542 djVal -= delta*cost[i];
00543 oldSum -= delta;
00544 delta = - oldSum;
00545 djVal += delta*cost[i];
00546 history[HISTORY][i]=delta;
00547 }
00548 dj[HISTORY-1]=djVal;
00549 djVal=0.0;
00550 for (i=0;i<ncols;i++) {
00551 double value2=colsol[i];
00552 if (value2>lower[i]+tolerance&&value2<upper[i]-tolerance||
00553 i>=ncols-nrows) {
00554 int k;
00555 value=history[HISTORY][i];
00556 djVal += value*cost[i];
00557 for (j=columnStart[i];j<columnStart[i]+length[i];j++) {
00558 int irow=row[j];
00559 allsum[nsolve-1][irow] += value;
00560 }
00561 }
00562 }
00563 printf("djs %g %g\n",dj[HISTORY-1],djVal);
00564 }
00565 #endif
00566 for (i=0;i<nsolve;i++) {
00567 int j;
00568 b[i]=0.0;
00569 for (j=0;j<nsolve;j++) {
00570 a[i][j]=0.0;
00571 }
00572 }
00573 c=0.0;
00574 for (i=0;i<nrows;i++) {
00575 double value=rowsol[i];
00576 for (k=0;k<nsolve;k++) {
00577 v[k]=allsum[k][i];
00578 b[k]+=v[k]*value;
00579 }
00580 c += value*value;
00581 for (k=0;k<nsolve;k++) {
00582 for (j=k;j<nsolve;j++) {
00583 a[k][j] += v[k]*v[j];
00584 }
00585 }
00586 }
00587 sum2=c;
00588 if (itry==1) {
00589 lastObj=objvalue+weight*sum2;
00590 }
00591 for (k=0;k<nsolve;k++) {
00592 b[k] = - (weight*b[k] + 0.5*dj[k]);
00593 for (j=k;j<nsolve;j++) {
00594 a[k][j] *= weight;
00595 a[j][k] = a[k][j];
00596 }
00597 }
00598 c*=weight;
00599 for (k=0;k<nsolve;k++) {
00600 theta[k]=b[k];
00601 }
00602 solveSmall(nsolve,a,awork,theta);
00603 if ((strategy&64)!=0) {
00604 value=10.0;
00605 for (k=0;k<nsolve;k++) {
00606 value = max (value, fabs(theta[k]));
00607 }
00608 if (value>10.0&&((logLevel_&4)!=0)) {
00609 printf("theta %g %g %g\n",theta[0],theta[1],theta[2]);
00610 }
00611 value = 10.0/value;
00612 for (k=0;k<nsolve;k++) {
00613 theta[k] *= value;
00614 }
00615 }
00616 for (i=0;i<ncolx;i++) {
00617 double valueh=0.0;
00618 for (k=0;k<HISTORY-1;k++) {
00619 value=history[k][i]-history[k+1][i];
00620 valueh+=value*theta[k];
00621 }
00622 #ifdef NULLVECTOR
00623 value=history[HISTORY][i];
00624 valueh+=value*theta[HISTORY-1];
00625 #endif
00626 history[HISTORY][i]=valueh;
00627 }
00628 }
00629 #ifdef NULLVECTOR
00630 if ((strategy&64)) {
00631 for (i=0;i<ncols-nrows;i++) {
00632 if (colsol[i]<=lower[i]+tolerance
00633 ||colsol[i]>=(upper[i]-tolerance)) {
00634 history[HISTORY][i]=0.0;;
00635 }
00636 }
00637 tolerance=-tolerance;
00638 }
00639 #endif
00640 if (!doScale) {
00641 for (i=0;i<ncols;i++) {
00642 if (colsol[i]>lower[i]+tolerance
00643 &&colsol[i]<(upper[i]-tolerance)) {
00644 value=history[HISTORY][i];
00645 colsol[i] +=value;
00646 if (colsol[i]<lower[i]+tolerance) {
00647 colsol[i]=lower[i];
00648 } else if (colsol[i]>upper[i]-tolerance) {
00649 colsol[i]=upper[i];
00650 }
00651 }
00652 }
00653 if (extraBlock) {
00654 for (i=0;i<extraBlock;i++) {
00655 if (solExtra[i]>tolerance
00656 &&solExtra[i]<(upperExtra[i]-tolerance)) {
00657 value=history[HISTORY][i+ncols];
00658 solExtra[i] +=value;
00659 if (solExtra[i]<0.0) {
00660 solExtra[i]=0.0;
00661 } else if (solExtra[i]>upperExtra[i]) {
00662 solExtra[i]=upperExtra[i];
00663 }
00664 }
00665 }
00666 }
00667 } else {
00668 double theta=1.0;
00669 double saveTheta=theta;
00670 for (i=0;i<ncols;i++) {
00671 if (colsol[i]>lower[i]+tolerance
00672 &&colsol[i]<(upper[i]-tolerance)) {
00673 value=history[HISTORY][i];
00674 if (value>0) {
00675 if (theta*value+colsol[i]>upper[i]) {
00676 theta=(upper[i]-colsol[i])/value;
00677 }
00678 } else if (value<0) {
00679 if (colsol[i]+theta*value<lower[i]) {
00680 theta = (lower[i]-colsol[i])/value;
00681 }
00682 }
00683 }
00684 }
00685 if (extraBlock) {
00686 for (i=0;i<extraBlock;i++) {
00687 if (solExtra[i]>tolerance
00688 &&solExtra[i]<(upperExtra[i]-tolerance)) {
00689 value=history[HISTORY][i+ncols];
00690 if (value>0) {
00691 if (theta*value+solExtra[i]>upperExtra[i]) {
00692 theta=(upperExtra[i]-solExtra[i])/value;
00693 }
00694 } else if (value<0) {
00695 if (solExtra[i]+theta*value<0.0) {
00696 theta = -solExtra[i]/value;
00697 }
00698 }
00699 }
00700 }
00701 }
00702 if ((iter%100==0)&&(logLevel_&8)!=0) {
00703 if (theta<saveTheta) {
00704 printf(" - modified theta %g\n",theta);
00705 }
00706 }
00707 for (i=0;i<ncols;i++) {
00708 if (colsol[i]>lower[i]+tolerance
00709 &&colsol[i]<(upper[i]-tolerance)) {
00710 value=history[HISTORY][i];
00711 colsol[i] +=value*theta;
00712 }
00713 }
00714 if (extraBlock) {
00715 for (i=0;i<extraBlock;i++) {
00716 if (solExtra[i]>tolerance
00717 &&solExtra[i]<(upperExtra[i]-tolerance)) {
00718 value=history[HISTORY][i+ncols];
00719 solExtra[i] +=value*theta;
00720 }
00721 }
00722 }
00723 }
00724 #ifdef NULLVECTOR
00725 tolerance=fabs(tolerance);
00726 #endif
00727 if ((iter %100) ==0&&(logLevel_&8)!=0) {
00728 printf("\n");
00729 }
00730 }
00731 good=1;
00732 result = objval(nrows,ncols,rowsol,colsol,pi,djs,useCost,
00733 rowlower,rowupper,lower,upper,
00734 elemnt,row,columnStart,length,extraBlock,rowExtra,
00735 solExtra,elemExtra,upperExtra,useCostExtra,
00736 weight);
00737 weightedObj=result.weighted;
00738 if (!iter) saveValue=weightedObj;
00739 objvalue=result.objval;
00740 sum1=result.infeas;
00741 if (saveSol) {
00742 if (result.weighted<bestSol) {
00743 printf("%d %g better than %g\n",iter,
00744 result.weighted*maxmin-useOffset,bestSol*maxmin-useOffset);
00745 bestSol=result.weighted;
00746 memcpy(saveSol,colsol,ncols*sizeof(double));
00747 }
00748 }
00749 #ifdef FITz
00750 if (iter>after) {
00751 IdiotResult result2;
00752 double ww,oo,ss;
00753 if (extraBlock) abort();
00754 result2= objval(nrows,ncols,row2,sol2,pi2,djs,cost,
00755 rowlower,rowupper,lower,upper,
00756 elemnt,row,columnStart,extraBlock,rowExtra,
00757 solExtra,elemExtra,upperExtra,costExtra,
00758 weight);
00759 ww=result2.weighted;
00760 oo=result2.objval;
00761 ss=result2.infeas;
00762 printf("wobj %g obj %g inf %g last %g\n",ww,oo,ss,lastObj);
00763 if (ww<weightedObj&&ww<lastObj) {
00764 printf(" taken");
00765 ntaken++;
00766 saving+=weightedObj-ww;
00767 weightedObj=ww;
00768 objvalue=oo;
00769 sum1=ss;
00770 memcpy(rowsol,row2,nrows*sizeof(double));
00771 memcpy(pi,pi2,nrows*sizeof(double));
00772 memcpy(colsol,sol2,ncols*sizeof(double));
00773 result= objval(nrows,ncols,rowsol,colsol,pi,djs,cost,
00774 rowlower,rowupper,lower,upper,
00775 elemnt,row,columnStart,extraBlock,rowExtra,
00776 solExtra,elemExtra,upperExtra,costExtra,
00777 weight);
00778 weightedObj=result.weighted;
00779 objvalue=result.objval;
00780 sum1=result.infeas;
00781 if (ww<weightedObj) abort();
00782 } else {
00783 printf(" not taken");
00784 nottaken++;
00785 }
00786 }
00787 #endif
00788
00789 if (weightedObj>lastObj+1.0e-4&&itry<MAXTRY) {
00790 if((logLevel_&16)!=0&&doScale) {
00791 printf("Weighted objective from %g to %g **** bad move\n",
00792 lastObj,weightedObj);
00793 }
00794 if (doScale) {
00795 good=1;
00796 }
00797 if ((strategy&3)==1) {
00798 good=0;
00799 if (weightedObj>lastObj+djExit) {
00800 if ((logLevel_&16)!=0) {
00801 printf("Weighted objective from %g to %g ?\n",lastObj,weightedObj);
00802 }
00803 memcpy(colsol,history[0],ncols*sizeof(double));
00804 memcpy(solExtra,history[0]+ncols,extraBlock*sizeof(double));
00805 good=1;
00806 }
00807 } else if ((strategy&3)==2) {
00808 if (weightedObj>lastObj+0.1*maxDj) {
00809 memcpy(colsol,history[0],ncols*sizeof(double));
00810 memcpy(solExtra,history[0]+ncols,extraBlock*sizeof(double));
00811 doScale++;
00812 good=0;
00813 }
00814 } else if ((strategy&3)==3) {
00815 if (weightedObj>lastObj+0.001*maxDj) {
00816
00817 good=0;
00818 }
00819 }
00820 }
00821 }
00822 if ((iter % checkFrequency_) ==0) {
00823 double best=weightedObj;
00824 double test=obj[0];
00825 for (i=1;i<DROP;i++) {
00826 obj[i-1]=obj[i];
00827 if (best>obj[i]) best=obj[i];
00828 }
00829 obj[DROP-1]=best;
00830 if (test-best<drop&&(strategy&8)==0) {
00831 if ((logLevel_&8)!=0) {
00832 printf("Exiting as drop in %d its is %g after %d iterations\n",
00833 DROP*checkFrequency_,test-best,iter);
00834 }
00835 goto RETURN;
00836 }
00837 }
00838 if ((iter % logFreq_)==0) {
00839 double piSum=0.0;
00840 for (i=0;i<nrows;i++) {
00841 piSum+=(rowsol[i]+rowupper[i])*pi[i];
00842 }
00843 if ((logLevel_&2)!=0) {
00844 printf("%d Infeas %g, obj %g - wtObj %g dual %g maxDj %g\n",
00845 iter,sum1,objvalue*maxmin-useOffset,weightedObj-useOffset,
00846 piSum*maxmin-useOffset,maxDj);
00847 }
00848 }
00849 memcpy(statusWork,statusSave,ncols*sizeof(char));
00850 nflagged=0;
00851 }
00852 nChange=0;
00853 doFull=0;
00854 maxDj=0.0;
00855
00856 int itry;
00857 for (itry=0;itry<2;itry++) {
00858 int icol=start[itry];
00859 int istop= stop[itry];
00860 for (;icol!=istop;icol += direction) {
00861 if (!statusWork[icol]) {
00862 CoinBigIndex j;
00863 double value=colsol[icol];
00864 double djval=cost[icol];
00865 double djval2,value2;
00866 double theta,a,b,c;
00867 if (elemnt) {
00868 for (j=columnStart[icol];j<columnStart[icol]+length[icol];j++) {
00869 int irow=row[j];
00870 djval -= elemnt[j]*pi[irow];
00871 }
00872 } else {
00873 for (j=columnStart[icol];j<columnStart[icol]+length[icol];j++) {
00874 int irow=row[j];
00875 djval -= pi[irow];
00876 }
00877 }
00878
00879
00880 if (djval>1.0e-5) {
00881 value2=(lower[icol]-value);
00882 } else {
00883 value2=(upper[icol]-value);
00884 }
00885 djval2 = djval*value2;
00886 djval=fabs(djval);
00887 if (djval>djTol) {
00888 if (djval2<-1.0e-4) {
00889 double valuep,thetap;
00890 nChange++;
00891 if (djval>maxDj) maxDj=djval;
00892
00893
00894
00895 a=0.0;
00896 b=0.0;
00897 c=0.0;
00898 djval2 = cost[icol];
00899 if (elemnt) {
00900 for (j=columnStart[icol];j<columnStart[icol]+length[icol];j++) {
00901 int irow=row[j];
00902 double value=rowsol[irow];
00903 c += value*value;
00904 a += elemnt[j]*elemnt[j];
00905 b += value*elemnt[j];
00906 }
00907 } else {
00908 for (j=columnStart[icol];j<columnStart[icol]+length[icol];j++) {
00909 int irow=row[j];
00910 double value=rowsol[irow];
00911 c += value*value;
00912 a += 1.0;
00913 b += value;
00914 }
00915 }
00916 a*=weight;
00917 b = b*weight+0.5*djval2;
00918 c*=weight;
00919
00920 theta = -b/a;
00921 if ((strategy&4)!=0) {
00922 value2=a*theta*theta+2.0*b*theta;
00923 thetap=2.0*theta;
00924 valuep=a*thetap*thetap+2.0*b*thetap;
00925 if (valuep<value2+djTol) {
00926 theta=thetap;
00927 kgood++;
00928 } else {
00929 kbad++;
00930 }
00931 }
00932 if (theta>0.0) {
00933 if (theta<upper[icol]-colsol[icol]) {
00934 value2=theta;
00935 } else {
00936 value2=upper[icol]-colsol[icol];
00937 }
00938 } else {
00939 if (theta>lower[icol]-colsol[icol]) {
00940 value2=theta;
00941 } else {
00942 value2=lower[icol]-colsol[icol];
00943 }
00944 }
00945 colsol[icol] += value2;
00946 objvalue += cost[icol]*value2;
00947 if (elemnt) {
00948 for (j=columnStart[icol];j<columnStart[icol]+length[icol];j++) {
00949 int irow=row[j];
00950 double value;
00951 rowsol[irow]+=elemnt[j]*value2;
00952 value=rowsol[irow];
00953 pi[irow]=-2.0*weight*value;
00954 }
00955 } else {
00956 for (j=columnStart[icol];j<columnStart[icol]+length[icol];j++) {
00957 int irow=row[j];
00958 double value;
00959 rowsol[irow]+=value2;
00960 value=rowsol[irow];
00961 pi[irow]=-2.0*weight*value;
00962 }
00963 }
00964 } else {
00965
00966 if (djval>djFlag) {
00967 statusWork[icol]=1;
00968 nflagged++;
00969 }
00970 }
00971 }
00972 }
00973 }
00974 }
00975 if (extraBlock) {
00976 for (i=0;i<extraBlock;i++) {
00977 double value=solExtra[i];
00978 double djval=costExtra[i];
00979 double djval2,value2;
00980 double element=elemExtra[i];
00981 double theta,a,b,c;
00982 int irow=rowExtra[i];
00983 djval -= element*pi[irow];
00984
00985
00986 if (djval>1.0e-5) {
00987 value2=-value;
00988 } else {
00989 value2=(upperExtra[i]-value);
00990 }
00991 djval2 = djval*value2;
00992 if (djval2<-1.0e-4&&fabs(djval)>djTol) {
00993 nChange++;
00994 a=0.0;
00995 b=0.0;
00996 c=0.0;
00997 djval2 = costExtra[i];
00998 value=rowsol[irow];
00999 c += value*value;
01000 a += element*element;
01001 b += element*value;
01002 a*=weight;
01003 b = b*weight+0.5*djval2;
01004 c*=weight;
01005
01006 theta = -b/a;
01007 if (theta>0.0) {
01008 value2=min(theta,upperExtra[i]-solExtra[i]);
01009 } else {
01010 value2=max(theta,-solExtra[i]);
01011 }
01012 solExtra[i] += value2;
01013 rowsol[irow]+=element*value2;
01014 value=rowsol[irow];
01015 pi[irow]=-2.0*weight*value;
01016 }
01017 }
01018 }
01019 if ((iter%10)==2) {
01020 for (i=DJTEST-1;i>0;i--) {
01021 djSave[i]=djSave[i-1];
01022 }
01023 djSave[0]=maxDj;
01024 largestDj=max(largestDj,maxDj);
01025 smallestDj=min(smallestDj,maxDj);
01026 for (i=DJTEST-1;i>0;i--) {
01027 maxDj+=djSave[i];
01028 }
01029 maxDj = maxDj/(double) DJTEST;
01030 if (maxDj<djExit&&iter>50) {
01031
01032 break;
01033 }
01034 if (nChange<100) {
01035 djTol*=0.5;
01036 }
01037 }
01038 }
01039 RETURN:
01040 if (kgood||kbad) {
01041 printf("%g good %g bad\n",kgood,kbad);
01042 }
01043 result = objval(nrows,ncols,rowsol,colsol,pi,djs,useCost,
01044 rowlower,rowupper,lower,upper,
01045 elemnt,row,columnStart,length,extraBlock,rowExtra,
01046 solExtra,elemExtra,upperExtra,useCostExtra,
01047 weight);
01048 result.djAtBeginning=largestDj;
01049 result.djAtEnd=smallestDj;
01050 result.dropThis=saveValue-result.weighted;
01051 if (saveSol) {
01052 if (result.weighted<bestSol) {
01053 bestSol=result.weighted;
01054 memcpy(saveSol,colsol,ncols*sizeof(double));
01055 } else {
01056 printf("restoring previous - now %g best %g\n",
01057 result.weighted*maxmin-useOffset,bestSol*maxmin-useOffset);
01058 }
01059 }
01060 if (saveSol) {
01061 if (extraBlock) {
01062 delete [] useCostExtra;
01063 }
01064 memcpy(colsol,saveSol,ncols*sizeof(double));
01065 delete [] saveSol;
01066 }
01067 for (i=0;i<nsolve;i++) {
01068 if (i) delete [] allsum[i];
01069 delete [] aX[i];
01070 delete [] aworkX[i];
01071 }
01072 delete [] thetaX;
01073 delete [] djX;
01074 delete [] bX;
01075 delete [] vX;
01076 delete [] aX;
01077 delete [] aworkX;
01078 delete [] allsum;
01079 delete [] cost;
01080 for (i=0;i<HISTORY+1;i++) {
01081 delete [] history[i];
01082 }
01083 delete [] statusSave;
01084
01085 result.objval=0.0;
01086 for (i=0;i<ncols;i++) {
01087 result.objval+=colsol[i]*origcost[i];
01088 }
01089 if (extraBlock) {
01090 for (i=0;i<extraBlock;i++) {
01091 int irow=rowExtra[i];
01092 rowupper[irow]=saveExtra[i];
01093 }
01094 delete [] rowExtra;
01095 delete [] solExtra;
01096 delete [] elemExtra;
01097 delete [] upperExtra;
01098 delete [] costExtra;
01099 delete [] saveExtra;
01100 }
01101 result.iteration=iter;
01102 result.objval-=saveOffset;
01103 result.weighted=result.objval+weight*result.sumSquared;
01104 return result;
01105 }