// Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. #include "CoinPragma.hpp" #include #include #include #include #include "CoinHelperFunctions.hpp" #include "Idiot.hpp" #define FIT #ifdef FIT #define HISTORY 8 #else #define HISTORY 7 #endif #define NSOLVE HISTORY-1 static void solveSmall(int nsolve,double **aIn,double **a, double * b) { int i,j; /* copy */ for (i=0;i=0;i--) { int j; double value=b[i]; for (j=i+1;jtolerance) { extraBlock++; } } cost=new double[ncols]; memset(rowsol,0,nrows*sizeof(double)); for (i=0;itolerance) { double smaller,difference; double value; saveExtra[extraBlock]=rowupper[i]; if (fabs(rowupper[i])>fabs(rowlower[i])) { smaller = rowlower[i]; value=-1.0; } else { smaller = rowupper[i]; value=1.0; } if (fabs(smaller)>1.0e10) { if (!nbad) printf("Can't handle rows where both bounds >1.0e10 %d %g\n", i,smaller); nbad++; if (rowupper[i]<0.0||rowlower[i]>0.0) abort(); if (fabs(rowupper[i])>fabs(rowlower[i])) { rowlower[i]=-0.9e10; smaller = rowlower[i]; value=-1.0; } else { rowupper[i]=0.9e10; saveExtra[extraBlock]=rowupper[i]; smaller = rowupper[i]; value=1.0; } } difference=rowupper[i]-rowlower[i]; difference = CoinMin(difference,1.0e31); rowupper[i]=smaller; elemExtra[extraBlock]=value; solExtra[extraBlock]=(rowupper[i]-rowsol[i])/value; if (solExtra[extraBlock]<0.0) solExtra[extraBlock]=0.0; if (solExtra[extraBlock]>difference) solExtra[extraBlock]=difference; costExtra[extraBlock]=lambda[i]*value; upperExtra[extraBlock]=difference; rowsol[i]+=value*solExtra[extraBlock]; rowExtra[extraBlock++]=i; } } if (nbad) printf("%d bad values - results may be wrong\n",nbad); } for (i=0;iii-HISTORY*2&&(iter&1)==0) { double * x=history[HISTORY-1]; for (i=HISTORY-1;i>0;i--) { history[i]=history[i-1]; } history[0]=x; memcpy(history[0],colsol,ncols*sizeof(double)); memcpy(history[0]+ncols,solExtra,extraBlock*sizeof(double)); } } if ((iter % SAVEHISTORY)==0||doFull) { if ((strategy&16)==0) { double * x=history[HISTORY-1]; for (i=HISTORY-1;i>0;i--) { history[i]=history[i-1]; } history[0]=x; memcpy(history[0],colsol,ncols*sizeof(double)); memcpy(history[0]+ncols,solExtra,extraBlock*sizeof(double)); } } /* start full try */ if ((iter % EVERY)==0||doFull) { // for next pass direction = - direction; // randomize. // The cast is to avoid gcc compiler warning int kcol = (int)(ncols*CoinDrand48()); if (kcol==ncols) kcol=ncols-1; if (direction>0) { start[0]=kcol;stop[0]=ncols; start[1]=0;stop[1]=kcol; } else { start[0]=kcol;stop[0]=-1; start[1]=ncols-1;stop[1]=kcol; } int itry=0; /*if ((strategy&16)==0) { double * x=history[HISTORY-1]; for (i=HISTORY-1;i>0;i--) { history[i]=history[i-1]; } history[0]=x; memcpy(history[0],colsol,ncols*sizeof(double)); memcpy(history[0]+ncols,solExtra,extraBlock*sizeof(double)); }*/ while (!good) { itry++; #define MAXTRY 5 if (iter>after&&doScale<2&&itrylower[i]+tolerance) { if(value2<(upper[i]-tolerance)) { int k; objvalue+=value2*cost[i]; #ifdef FIT ntot++; val0=history[0][i]; val1=history[1][i]; val2=history[2][i]; diff1=val0-val1; diff2=val1-val2; if (diff1*diff2>=0.0) { nsign++; if (fabs(diff1)upper[i]-tolerance) { newValue=upper[i]; } else if (newValuetolerance &&solExtra[i]<(upperExtra[i]-tolerance)) { double value2=solExtra[i]; int k; for (k=0;klower[i]+tolerance&&value2lower[i]+tolerance&&value2lower[i]+tolerance&&value2=ncols-nrows) { int k; value=history[HISTORY][i]; djVal += value*cost[i]; for (j=columnStart[i];j10.0&&((logLevel_&4)!=0)) { printf("theta %g %g %g\n",theta[0],theta[1],theta[2]); } value = 10.0/value; for (k=0;k=(upper[i]-tolerance)) { history[HISTORY][i]=0.0;; } } tolerance=-tolerance; /* switch off test */ } #endif if (!doScale) { for (i=0;ilower[i]+tolerance &&colsol[i]<(upper[i]-tolerance)) { value=history[HISTORY][i]; colsol[i] +=value; if (colsol[i]upper[i]-tolerance) { colsol[i]=upper[i]; } } } if (extraBlock) { for (i=0;itolerance &&solExtra[i]<(upperExtra[i]-tolerance)) { value=history[HISTORY][i+ncols]; solExtra[i] +=value; if (solExtra[i]<0.0) { solExtra[i]=0.0; } else if (solExtra[i]>upperExtra[i]) { solExtra[i]=upperExtra[i]; } } } } } else { double theta=1.0; double saveTheta=theta; for (i=0;ilower[i]+tolerance &&colsol[i]<(upper[i]-tolerance)) { value=history[HISTORY][i]; if (value>0) { if (theta*value+colsol[i]>upper[i]) { theta=(upper[i]-colsol[i])/value; } } else if (value<0) { if (colsol[i]+theta*valuetolerance &&solExtra[i]<(upperExtra[i]-tolerance)) { value=history[HISTORY][i+ncols]; if (value>0) { if (theta*value+solExtra[i]>upperExtra[i]) { theta=(upperExtra[i]-solExtra[i])/value; } } else if (value<0) { if (solExtra[i]+theta*value<0.0) { theta = -solExtra[i]/value; } } } } } if ((iter%100==0)&&(logLevel_&8)!=0) { if (thetalower[i]+tolerance &&colsol[i]<(upper[i]-tolerance)) { value=history[HISTORY][i]; colsol[i] +=value*theta; } } if (extraBlock) { for (i=0;itolerance &&solExtra[i]<(upperExtra[i]-tolerance)) { value=history[HISTORY][i+ncols]; solExtra[i] +=value*theta; } } } } #ifdef NULLVECTOR tolerance=fabs(tolerance); /* switch back on */ #endif if ((iter %100) ==0&&(logLevel_&8)!=0) { printf("\n"); } } good=1; result = objval(nrows,ncols,rowsol,colsol,pi,djs,useCost, rowlower,rowupper,lower,upper, elemnt,row,columnStart,length,extraBlock,rowExtra, solExtra,elemExtra,upperExtra,useCostExtra, weight); weightedObj=result.weighted; if (!iter) saveValue=weightedObj; objvalue=result.objval; sum1=result.infeas; if (saveSol) { if (result.weightedafter) { IdiotResult result2; double ww,oo,ss; if (extraBlock) abort(); result2= objval(nrows,ncols,row2,sol2,pi2,djs,cost, rowlower,rowupper,lower,upper, elemnt,row,columnStart,extraBlock,rowExtra, solExtra,elemExtra,upperExtra,costExtra, weight); ww=result2.weighted; oo=result2.objval; ss=result2.infeas; printf("wobj %g obj %g inf %g last %g\n",ww,oo,ss,lastObj); if (wwlastObj+1.0e-4&&itrylastObj+djExit) { if ((logLevel_&16)!=0) { printf("Weighted objective from %g to %g ?\n",lastObj,weightedObj); } memcpy(colsol,history[0],ncols*sizeof(double)); memcpy(solExtra,history[0]+ncols,extraBlock*sizeof(double)); good=1; } } else if ((strategy&3)==2) { if (weightedObj>lastObj+0.1*maxDj) { memcpy(colsol,history[0],ncols*sizeof(double)); memcpy(solExtra,history[0]+ncols,extraBlock*sizeof(double)); doScale++; good=0; } } else if ((strategy&3)==3) { if (weightedObj>lastObj+0.001*maxDj) { /*doScale++;*/ good=0; } } } } if ((iter % checkFrequency_) ==0) { double best=weightedObj; double test=obj[0]; for (i=1;iobj[i]) best=obj[i]; } obj[DROP-1]=best; if (test-best1.0e-5) { value2=(lower[icol]-value); } else { value2=(upper[icol]-value); } djval2 = djval*value2; djval=fabs(djval); if (djval>djTol) { if (djval2<-1.0e-4) { double valuep,thetap; nChange++; if (djval>maxDj) maxDj=djval; /*if (djval>3.55e6) { printf("big\n"); }*/ a=0.0; b=0.0; c=0.0; djval2 = cost[icol]; if (elemnt) { for (j=columnStart[icol];j0.0) { if (thetalower[icol]-colsol[icol]) { value2=theta; } else { value2=lower[icol]-colsol[icol]; } } colsol[icol] += value2; objvalue += cost[icol]*value2; if (elemnt) { for (j=columnStart[icol];jdjFlag) { statusWork[icol]=1; nflagged++; } } } } } } if (extraBlock) { for (i=0;i1.0e-5) { value2=-value; } else { value2=(upperExtra[i]-value); } djval2 = djval*value2; if (djval2<-1.0e-4&&fabs(djval)>djTol) { nChange++; a=0.0; b=0.0; c=0.0; djval2 = costExtra[i]; value=rowsol[irow]; c += value*value; a += element*element; b += element*value; a*=weight; b = b*weight+0.5*djval2; c*=weight; /* solve */ theta = -b/a; if (theta>0.0) { value2=CoinMin(theta,upperExtra[i]-solExtra[i]); } else { value2=CoinMax(theta,-solExtra[i]); } solExtra[i] += value2; rowsol[irow]+=element*value2; value=rowsol[irow]; pi[irow]=-2.0*weight*value; } } } if ((iter%10)==2) { for (i=DJTEST-1;i>0;i--) { djSave[i]=djSave[i-1]; } djSave[0]=maxDj; largestDj=CoinMax(largestDj,maxDj); smallestDj=CoinMin(smallestDj,maxDj); for (i=DJTEST-1;i>0;i--) { maxDj+=djSave[i]; } maxDj = maxDj/(double) DJTEST; if (maxDj50) { //printf("Exiting on low dj %g after %d iterations\n",maxDj,iter); break; } if (nChange<100) { djTol*=0.5; } } } RETURN: if (kgood||kbad) { printf("%g good %g bad\n",kgood,kbad); } result = objval(nrows,ncols,rowsol,colsol,pi,djs,useCost, rowlower,rowupper,lower,upper, elemnt,row,columnStart,length,extraBlock,rowExtra, solExtra,elemExtra,upperExtra,useCostExtra, weight); result.djAtBeginning=largestDj; result.djAtEnd=smallestDj; result.dropThis=saveValue-result.weighted; if (saveSol) { if (result.weighted