Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

IdiSolve.cpp

00001 // Copyright (C) 2002, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
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   /* copy */
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     /* update using all previous */
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   /* update */
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   /* adjust to make as feasible as possible */
00106   /* no */
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   /*#define NULLVECTOR*/
00159 #ifndef NULLVECTOR
00160   int nsolve=NSOLVE;
00161 #else
00162   int nsolve=NSOLVE+1;/* allow for null vector */
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; /* no acceleration at all */
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   /* check = rows */
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     /* save best solution */
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   // for two pass method
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     /* start full try */
00342     if ((iter % EVERY)==0||doFull) {
00343       // for next pass
00344       direction = - direction;
00345       // randomize. 
00346       // The cast is to avoid gcc compiler warning
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       /*if ((strategy&16)==0) {
00359         double * x=history[HISTORY-1];
00360         for (i=HISTORY-1;i>0;i--) {
00361           history[i]=history[i-1];
00362         }
00363         history[0]=x;
00364         memcpy(history[0],colsol,ncols*sizeof(double));
00365         memcpy(history[0]+ncols,solExtra,extraBlock*sizeof(double));
00366         }*/
00367       while (!good) {
00368         itry++;
00369 #define MAXTRY 5
00370         if (iter>after&&doScale<2&&itry<MAXTRY) {
00371           /* now full one */
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           // cast is to avoid gcc compiler
00415           // warning: initialization to 'int' from 'double'
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                   /* at ub */
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                 /* at lb */
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             /*printf("total %d, same sign %d, good %d %d %d %d %d\n",
00495               ntot,nsign,ngood,mgood[0],mgood[1],mgood[2],mgood[3]);*/
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; /* switch off test */
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); /* switch back on */
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         /*printf("%d %g %g %g %g\n",itry,lastObj,weightedObj,objvalue,sum1);*/
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               /*doScale++;*/
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     // go through forwards or backwards and starting at odd places
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           /*printf("xx iter %d seq %d djval %g value %g\n",
00879             iter,i,djval,value);*/
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               /*if (djval>3.55e6) {
00893                 printf("big\n");
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               /* solve */
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               /* dj but at bound */
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         /*printf("xxx iter %d extra %d djval %g value %g\n",
00985           iter,irow,djval,value);*/
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           /* solve */
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         //printf("Exiting on low dj %g after %d iterations\n",maxDj,iter);
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   /* do original costs objvalue*/
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 }

Generated on Wed Dec 3 14:37:36 2003 for CLP by doxygen 1.3.5