source: stable/1.11/Clp/src/Idiot.cpp @ 1508

Last change on this file since 1508 was 1508, checked in by forrest, 10 years ago

out message

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 53.1 KB
Line 
1/* $Id: Idiot.cpp 1508 2010-02-04 19:14:03Z forrest $ */
2// Copyright (C) 2002, International Business Machines
3// Corporation and others.  All Rights Reserved.
4
5#include "CoinPragma.hpp"
6#include <stdio.h>
7#include <stdarg.h>
8#include <stdlib.h>
9#include <math.h>
10#include "ClpPresolve.hpp"
11#include "Idiot.hpp"
12#include "CoinTime.hpp"
13#include "CoinSort.hpp"
14#include "CoinMessageHandler.hpp"
15#include "CoinHelperFunctions.hpp"
16// Redefine stuff for Clp
17#ifndef OSI_IDIOT
18#include "ClpMessage.hpp"
19#define OsiObjOffset ClpObjOffset
20#endif
21/**** strategy 4 - drop, exitDrop and djTolerance all relative:
22For first two major iterations these are small.  Then:
23
24drop - exit a major iteration if drop over 5*checkFrequency < this is
25used as info->drop*(10.0+fabs(last weighted objective))
26
27exitDrop - exit idiot if feasible and drop < this is
28used as info->exitDrop*(10.0+fabs(last objective))
29
30djExit - exit a major iteration if largest dj (averaged over 5 checks)
31drops below this - used as info->djTolerance*(10.0+fabs(last weighted objective)
32
33djFlag - mostly skip variables with bad dj worse than this => 2*djExit
34
35djTol - only look at variables with dj better than this => 0.01*djExit
36****************/
37
38#define IDIOT_FIX_TOLERANCE 1e-6
39#define SMALL_IDIOT_FIX_TOLERANCE 1e-10
40int 
41Idiot::dropping(IdiotResult result,
42                    double tolerance,
43                    double small,
44                    int *nbad)
45{
46  if (result.infeas<=small) {
47    double value=CoinMax(fabs(result.objval),fabs(result.dropThis))+1.0;
48    if (result.dropThis>tolerance*value) {
49      *nbad=0;
50      return 1;
51    } else {
52      (*nbad)++;
53      if (*nbad>4) {
54        return 0;
55      } else {
56        return 1;
57      }
58    }
59  } else {
60    *nbad=0;
61    return 1;
62  }
63}
64// Deals with whenUsed and slacks
65int 
66Idiot::cleanIteration(int iteration, int ordinaryStart, int ordinaryEnd,
67                      double * colsol, const double * lower, const double * upper,
68                      const double * rowLower, const double * rowUpper,
69                      const double * cost, const double * element, double fixTolerance,
70                      double & objValue, double & infValue)
71{
72  int n=0;
73  if ((strategy_&16384)==0) {
74    for (int i=ordinaryStart;i<ordinaryEnd;i++) {
75      if (colsol[i]>lower[i]+fixTolerance) {
76        if (colsol[i]<upper[i]-fixTolerance) {
77          n++;
78        } else {
79          colsol[i]=upper[i];
80        }
81        whenUsed_[i]=iteration;
82      } else {
83        colsol[i]=lower[i];
84      }
85    }
86    return n;
87  } else {
88#ifdef COIN_DEVELOP
89    printf("entering inf %g, obj %g\n",infValue,objValue);
90#endif
91    int nrows=model_->getNumRows();
92    int ncols=model_->getNumCols();
93    int * posSlack = whenUsed_+ncols;
94    int * negSlack = posSlack+nrows;
95    int * nextSlack = negSlack + nrows;
96    double * rowsol = reinterpret_cast<double *> (nextSlack+ncols);
97    memset(rowsol,0,nrows*sizeof(double));
98#ifdef OSI_IDIOT
99    const CoinPackedMatrix * matrix = model_->getMatrixByCol();
100#else
101    ClpMatrixBase * matrix = model_->clpMatrix();
102#endif
103    const int * row = matrix->getIndices();
104    const CoinBigIndex * columnStart = matrix->getVectorStarts();
105    const int * columnLength = matrix->getVectorLengths(); 
106    //const double * element = matrix->getElements();
107    int i;
108    objValue=0.0;
109    infValue=0.0;
110    for ( i=0;i<ncols;i++) {
111      if (nextSlack[i]==-1) {
112        // not a slack
113        if (colsol[i]>lower[i]+fixTolerance) {
114          if (colsol[i]<upper[i]-fixTolerance) {
115            n++;
116            whenUsed_[i]=iteration;
117          } else {
118            colsol[i]=upper[i];
119          }
120          whenUsed_[i]=iteration;
121        } else {
122          colsol[i]=lower[i];
123        }
124        double value = colsol[i];
125        if (value) {
126          objValue += cost[i]*value;
127          CoinBigIndex j;
128          for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
129            int iRow = row[j];
130            rowsol[iRow] += value*element[j];
131          }
132        }
133      }
134    }
135    // temp fix for infinite lbs - just limit to -1000
136    for (i=0;i<nrows;i++) {
137      double rowSave=rowsol[i];
138      int iCol;
139      iCol =posSlack[i];
140      if (iCol>=0) {
141        // slide all slack down
142        double rowValue=rowsol[i];
143        CoinBigIndex j=columnStart[iCol];
144        double lowerValue = CoinMax(CoinMin(colsol[iCol],0.0)-1000.0,lower[iCol]);
145        rowSave += (colsol[iCol]-lowerValue)*element[j];
146        colsol[iCol]=lowerValue;
147        while (nextSlack[iCol]>=0) {
148          iCol = nextSlack[iCol];
149          double lowerValue = CoinMax(CoinMin(colsol[iCol],0.0)-1000.0,lower[iCol]);
150          j=columnStart[iCol];
151          rowSave += (colsol[iCol]-lowerValue)*element[j];
152          colsol[iCol]=lowerValue;
153        }
154        iCol =posSlack[i];
155        while (rowValue<rowLower[i]&&iCol>=0) {
156          // want to increase
157          double distance = rowLower[i]-rowValue;
158          double value = element[columnStart[iCol]];
159          double thisCost = cost[iCol];
160          if (distance<=value*(upper[iCol]-colsol[iCol])) {
161            // can get there
162            double movement = distance/value;
163            objValue += movement*thisCost;
164            rowValue = rowLower[i];
165            colsol[iCol] += movement;
166          } else {
167            // can't get there
168            double movement = upper[iCol]-colsol[iCol];
169            objValue += movement*thisCost;
170            rowValue += movement*value;
171            colsol[iCol] = upper[iCol];
172            iCol = nextSlack[iCol];
173          }
174        }
175        if (iCol>=0) {
176          // may want to carry on - because of cost?
177          while (iCol>=0&&cost[iCol]<0&&rowValue<rowUpper[i]) {
178            // want to increase
179            double distance = rowUpper[i]-rowValue;
180            double value = element[columnStart[iCol]];
181            double thisCost = cost[iCol];
182            if (distance<=value*(upper[iCol]-colsol[iCol])) {
183              // can get there
184              double movement = distance/value;
185              objValue += movement*thisCost;
186              rowValue = rowUpper[i];
187              colsol[iCol] += movement;
188              iCol=-1;
189            } else {
190              // can't get there
191              double movement = upper[iCol]-colsol[iCol];
192              objValue += movement*thisCost;
193              rowValue += movement*value;
194              colsol[iCol] = upper[iCol];
195              iCol = nextSlack[iCol];
196            }
197          }
198          if (iCol>=0&&colsol[iCol]>lower[iCol]+fixTolerance&&
199              colsol[iCol]<upper[iCol]-fixTolerance) {
200            whenUsed_[i]=iteration;
201            n++;
202          }
203        }
204        rowsol[i]=rowValue;
205      }
206      iCol =negSlack[i];
207      if (iCol>=0) {
208        // slide all slack down
209        double rowValue=rowsol[i];
210        CoinBigIndex j=columnStart[iCol];
211        rowSave += (colsol[iCol]-lower[iCol])*element[j];
212        colsol[iCol]=lower[iCol];
213        assert (lower[iCol]>-1.0e20);
214        while (nextSlack[iCol]>=0) {
215          iCol = nextSlack[iCol];
216          j=columnStart[iCol];
217          rowSave += (colsol[iCol]-lower[iCol])*element[j];
218          colsol[iCol]=lower[iCol];
219        }
220        iCol =negSlack[i];
221        while (rowValue>rowUpper[i]&&iCol>=0) {
222          // want to increase
223          double distance = -(rowUpper[i]-rowValue);
224          double value = -element[columnStart[iCol]];
225          double thisCost = cost[iCol];
226          if (distance<=value*(upper[iCol]-lower[iCol])) {
227            // can get there
228            double movement = distance/value;
229            objValue += movement*thisCost;
230            rowValue = rowUpper[i];
231            colsol[iCol] += movement;
232          } else {
233            // can't get there
234            double movement = upper[iCol]-lower[iCol];
235            objValue += movement*thisCost;
236            rowValue -= movement*value;
237            colsol[iCol] = upper[iCol];
238            iCol = nextSlack[iCol];
239          }
240        }
241        if (iCol>=0) {
242          // may want to carry on - because of cost?
243          while (iCol>=0&&cost[iCol]<0&&rowValue>rowLower[i]) {
244            // want to increase
245            double distance = -(rowLower[i]-rowValue);
246            double value = -element[columnStart[iCol]];
247            double thisCost = cost[iCol];
248            if (distance<=value*(upper[iCol]-colsol[iCol])) {
249              // can get there
250              double movement = distance/value;
251              objValue += movement*thisCost;
252              rowValue = rowLower[i];
253              colsol[iCol] += movement;
254              iCol=-1;
255            } else {
256              // can't get there
257              double movement = upper[iCol]-colsol[iCol];
258              objValue += movement*thisCost;
259              rowValue -= movement*value;
260              colsol[iCol] = upper[iCol];
261              iCol = nextSlack[iCol];
262            }
263          }
264          if (iCol>=0&&colsol[iCol]>lower[iCol]+fixTolerance&&
265              colsol[iCol]<upper[iCol]-fixTolerance) {
266            whenUsed_[i]=iteration;
267            n++;
268          }
269        }
270        rowsol[i]=rowValue;
271      }
272      infValue += CoinMax(CoinMax(0.0,rowLower[i]-rowsol[i]),rowsol[i]-rowUpper[i]);
273      // just change
274      rowsol[i] -= rowSave;
275    }
276    return n;
277  }
278}
279
280/* returns -1 if none or start of costed slacks or -2 if
281   there are costed slacks but it is messy */
282 static int countCostedSlacks(OsiSolverInterface * model)
283{
284#ifdef OSI_IDIOT
285  const CoinPackedMatrix * matrix = model->getMatrixByCol();
286#else
287  ClpMatrixBase * matrix = model->clpMatrix();
288#endif
289  const int * row = matrix->getIndices();
290  const CoinBigIndex * columnStart = matrix->getVectorStarts();
291  const int * columnLength = matrix->getVectorLengths(); 
292  const double * element = matrix->getElements();
293  const double * rowupper = model->getRowUpper();
294  int nrows=model->getNumRows();
295  int ncols=model->getNumCols();
296  int slackStart = ncols-nrows;
297  int nSlacks=nrows;
298  int i;
299 
300  if (ncols<=nrows) return -1;
301  while (1) {
302    for (i=0;i<nrows;i++) {
303      int j=i+slackStart;
304      CoinBigIndex k=columnStart[j];
305      if (columnLength[j]==1) {
306        if (row[k]!=i||element[k]!=1.0) {
307          nSlacks=0;
308          break;
309        }
310      } else {
311        nSlacks=0;
312        break;
313      }
314      if (rowupper[i]<=0.0) {
315        nSlacks=0;
316        break;
317      }
318    }
319    if (nSlacks||!slackStart) break;
320    slackStart=0;
321  }
322  if (!nSlacks) slackStart=-1;
323  return slackStart;
324}
325void
326Idiot::crash(int numberPass, CoinMessageHandler * handler,const CoinMessages *messages)
327{
328  // lightweight options
329  int numberColumns = model_->getNumCols();
330  const double * objective = model_->getObjCoefficients();
331  int nnzero=0;
332  double sum=0.0;
333  int i;
334  for (i=0;i<numberColumns;i++) {
335    if (objective[i]) {
336      sum += fabs(objective[i]);
337      nnzero++;
338    }
339  }
340  sum /= static_cast<double> (nnzero+1);
341  if (maxIts_==5)
342    maxIts_=2;
343  if (numberPass<=0)
344    majorIterations_=static_cast<int>(2+log10(static_cast<double>(numberColumns+1)));
345  else
346    majorIterations_=numberPass;
347  // If mu not changed then compute
348  if (mu_==1e-4)
349    mu_= CoinMax(1.0e-3,sum*1.0e-5);
350  if (maxIts2_==100) {
351    if (!lightWeight_) {
352      maxIts2_=105;
353    } else if (lightWeight_==1) {
354      mu_ *= 1000.0;
355      maxIts2_=23;
356    } else if (lightWeight_==2) {
357      maxIts2_=11;
358    } else {
359      maxIts2_=23;
360    }
361  }
362  //printf("setting mu to %g and doing %d passes\n",mu_,majorIterations_);
363  solve2(handler,messages);
364#ifndef OSI_IDIOT
365  double averageInfeas = model_->sumPrimalInfeasibilities()/static_cast<double> (model_->numberRows());
366  if ((averageInfeas<0.01&&(strategy_&512)!=0)||(strategy_&8192)!=0) 
367    crossOver(16+1); 
368  else
369    crossOver(majorIterations_<1000000 ? 3 : 2);
370#endif
371}
372void
373Idiot::solve()
374{
375  CoinMessages dummy;
376  solve2(NULL,&dummy);
377}
378void
379Idiot::solve2(CoinMessageHandler * handler,const CoinMessages * messages)
380{
381  int strategy=0;
382  double d2;
383  int i,n;
384  int allOnes=1;
385  int iteration=0;
386  int iterationTotal=0;
387  int nTry=0; /* number of tries at same weight */
388  double fixTolerance=IDIOT_FIX_TOLERANCE;
389  int maxBigIts=maxBigIts_;
390  int maxIts=maxIts_;
391  int logLevel=logLevel_;
392  int saveMajorIterations = majorIterations_;
393  majorIterations_ = majorIterations_%1000000;
394  if (handler) {
395    if (handler->logLevel()>0&&handler->logLevel()<3)
396      logLevel=1;
397    else if (!handler->logLevel())
398      logLevel=0;
399    else
400      logLevel=7;
401  }
402  double djExit=djTolerance_;
403  double djFlag=1.0+100.0*djExit;
404  double djTol=0.00001;
405  double mu =mu_;
406  double drop=drop_;
407  int maxIts2=maxIts2_;
408  double factor=muFactor_;
409  double smallInfeas=smallInfeas_;
410  double reasonableInfeas=reasonableInfeas_;
411  double stopMu=stopMu_;
412  double maxmin,offset;
413  double lastWeighted=1.0e50;
414  double exitDrop=exitDrop_;
415  double fakeSmall=smallInfeas;
416  double firstInfeas;
417  int badIts=0;
418  int slackStart,slackEnd,ordStart,ordEnd;
419  int checkIteration=0;
420  int lambdaIteration=0;
421  int belowReasonable=0; /* set if ever gone below reasonable infeas */
422  double bestWeighted=1.0e60;
423  double bestFeasible=1.0e60; /* best solution while feasible */
424  IdiotResult result,lastResult;
425  int saveStrategy=strategy_;
426  const int strategies[]={0,2,128};
427  double saveLambdaScale=0.0;
428  if ((saveStrategy&128)!=0) {
429    fixTolerance=SMALL_IDIOT_FIX_TOLERANCE;
430  }
431#ifdef OSI_IDIOT
432  const CoinPackedMatrix * matrix = model_->getMatrixByCol();
433#else
434  ClpMatrixBase * matrix = model_->clpMatrix();
435#endif
436  const int * row = matrix->getIndices();
437  const CoinBigIndex * columnStart = matrix->getVectorStarts();
438  const int * columnLength = matrix->getVectorLengths(); 
439  const double * element = matrix->getElements();
440  int nrows=model_->getNumRows();
441  int ncols=model_->getNumCols();
442  double * rowsol, * colsol;
443  double * pi, * dj;
444#ifndef OSI_IDIOT
445  double * cost = model_->objective();
446  double * lower = model_->columnLower();
447  double * upper = model_->columnUpper();
448#else
449  double * cost = new double [ncols];
450  CoinMemcpyN( model_->getObjCoefficients(),ncols, cost);
451  const double * lower = model_->getColLower();
452  const double * upper = model_->getColUpper();
453#endif
454  const double *elemXX;
455  double * saveSol;
456  double * rowupper= new double[nrows]; // not const as modified
457  CoinMemcpyN(model_->getRowUpper(),nrows,rowupper);
458  double * rowlower= new double[nrows]; // not const as modified
459  CoinMemcpyN(model_->getRowLower(),nrows,rowlower);
460  CoinThreadRandom * randomNumberGenerator=model_->randomNumberGenerator();
461  int * whenUsed;
462  double * lambda;
463  saveSol=new double[ncols];
464  lambda=new double [nrows];
465  rowsol= new double[nrows];
466  colsol= new double [ncols];
467  CoinMemcpyN(model_->getColSolution(),ncols,colsol);
468  pi= new double[nrows];
469  dj=new double[ncols];
470  delete [] whenUsed_;
471  bool oddSlacks=false;
472  // See if any costed slacks
473  int numberSlacks=0;
474  for (i=0;i<ncols;i++) {
475    if (columnLength[i]==1)
476      numberSlacks++;
477  }
478  if (!numberSlacks) {
479    whenUsed_=new int[ncols];
480  } else {
481#ifdef COIN_DEVELOP
482    printf("%d slacks\n",numberSlacks);
483#endif
484    oddSlacks=true;
485    int extra = static_cast<int> (nrows*sizeof(double)/sizeof(int));
486    whenUsed_=new int[2*ncols+2*nrows+extra];
487    int * posSlack = whenUsed_+ncols;
488    int * negSlack = posSlack+nrows;
489    int * nextSlack = negSlack + nrows;
490    for (i=0;i<nrows;i++) {
491      posSlack[i]=-1;
492      negSlack[i]=-1;
493    }
494    for (i=0;i<ncols;i++) 
495      nextSlack[i]=-1;
496    for (i=0;i<ncols;i++) {
497      if (columnLength[i]==1) {
498        CoinBigIndex j=columnStart[i];
499        int iRow = row[j];
500        if (element[j]>0.0) {
501          if (posSlack[iRow]==-1) {
502            posSlack[iRow]=i;
503          } else {
504            int iCol = posSlack[iRow];
505            while (nextSlack[iCol]>=0)
506              iCol = nextSlack[iCol];
507            nextSlack[iCol]=i;
508          }
509        } else {
510          if (negSlack[iRow]==-1) {
511            negSlack[iRow]=i;
512          } else {
513            int iCol = negSlack[iRow];
514            while (nextSlack[iCol]>=0)
515              iCol = nextSlack[iCol];
516            nextSlack[iCol]=i;
517          }
518        }
519      }
520    }
521    // now sort
522    for (i=0;i<nrows;i++) {
523      int iCol;
524      iCol = posSlack[i];
525      if (iCol>=0) {
526        CoinBigIndex j=columnStart[iCol];
527#ifndef NDEBUG
528        int iRow = row[j];
529#endif
530        assert (element[j]>0.0);
531        assert (iRow==i);
532        dj[0]= cost[iCol]/element[j];
533        whenUsed_[0]=iCol;
534        int n=1;
535        while (nextSlack[iCol]>=0) {
536          iCol = nextSlack[iCol];
537          CoinBigIndex j=columnStart[iCol];
538#ifndef NDEBUG
539          int iRow = row[j];
540#endif
541          assert (element[j]>0.0);
542          assert (iRow==i);
543          dj[n]= cost[iCol]/element[j];
544          whenUsed_[n++]=iCol;
545        }
546        for (j=0;j<n;j++) {
547          int jCol = whenUsed_[j];
548          nextSlack[jCol]=-2;
549        }
550        CoinSort_2(dj,dj+n,whenUsed_);
551        // put back
552        iCol = whenUsed_[0];
553        posSlack[i]=iCol;
554        for (j=1;j<n;j++) {
555          int jCol = whenUsed_[j];
556          nextSlack[iCol]=jCol;
557          iCol=jCol;
558        }
559      }
560      iCol = negSlack[i];
561      if (iCol>=0) {
562        CoinBigIndex j=columnStart[iCol];
563#ifndef NDEBUG
564        int iRow = row[j];
565#endif
566        assert (element[j]<0.0);
567        assert (iRow==i);
568        dj[0]= -cost[iCol]/element[j];
569        whenUsed_[0]=iCol;
570        int n=1;
571        while (nextSlack[iCol]>=0) {
572          iCol = nextSlack[iCol];
573          CoinBigIndex j=columnStart[iCol];
574#ifndef NDEBUG
575          int iRow = row[j];
576#endif
577          assert (element[j]<0.0);
578          assert (iRow==i);
579          dj[n]= -cost[iCol]/element[j];
580          whenUsed_[n++]=iCol;
581        }
582        for (j=0;j<n;j++) {
583          int jCol = whenUsed_[j];
584          nextSlack[jCol]=-2;
585        }
586        CoinSort_2(dj,dj+n,whenUsed_);
587        // put back
588        iCol = whenUsed_[0];
589        negSlack[i]=iCol;
590        for (j=1;j<n;j++) {
591          int jCol = whenUsed_[j];
592          nextSlack[iCol]=jCol;
593          iCol=jCol;
594        }
595      }
596    }
597  }
598  whenUsed=whenUsed_;
599  if (model_->getObjSense()==-1.0) {
600    maxmin=-1.0;
601  } else {
602    maxmin=1.0;
603  }
604  model_->getDblParam(OsiObjOffset,offset);
605  if (!maxIts2) maxIts2=maxIts;
606  strategy=strategy_;
607  strategy &= 3;
608  memset(lambda,0,nrows*sizeof(double));
609  slackStart=countCostedSlacks(model_);
610  if (slackStart>=0) {
611    printf("This model has costed slacks\n");
612    slackEnd=slackStart+nrows;
613    if (slackStart) {
614      ordStart=0;
615      ordEnd=slackStart;
616    } else {
617      ordStart=nrows;
618      ordEnd=ncols;
619    }
620  } else {
621    slackEnd=slackStart;
622    ordStart=0;
623    ordEnd=ncols;
624  }
625  if (offset&&logLevel>2) {
626    printf("** Objective offset is %g\n",offset);
627  }
628  /* compute reasonable solution cost */
629  for (i=0;i<nrows;i++) {
630    rowsol[i]=1.0e31;
631  }
632  for (i=0;i<ncols;i++) {
633    CoinBigIndex j;
634    for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
635      if (element[j]!=1.0) {
636        allOnes=0;
637        break;
638      }
639    }
640  }
641  if (allOnes) {
642    elemXX=NULL;
643  } else {
644    elemXX=element;
645  }
646  // Do scaling if wanted
647  bool scaled=false;
648#ifndef OSI_IDIOT
649  if ((strategy_&32)!=0&&!allOnes) {
650    if (model_->scalingFlag()>0) {
651      // May not be synchronized
652      int flag = model_->scalingFlag();
653      model_->scaling(0);
654      model_->scaling(flag);
655      scaled = model_->clpMatrix()->scale(model_)==0;
656    }
657    if (scaled) {
658      const double * rowScale = model_->rowScale();
659      const double * columnScale = model_->columnScale();
660      double * oldLower = lower;
661      double * oldUpper = upper;
662      double * oldCost = cost;
663      lower = new double[ncols];
664      upper = new double[ncols];
665      cost = new double[ncols];
666      CoinMemcpyN(oldLower,ncols,lower);
667      CoinMemcpyN(oldUpper,ncols,upper);
668      CoinMemcpyN(oldCost,ncols,cost);
669      int icol,irow;
670      for (icol=0;icol<ncols;icol++) {
671        double multiplier = 1.0/columnScale[icol];
672        if (lower[icol]>-1.0e50)
673          lower[icol] *= multiplier;
674        if (upper[icol]<1.0e50)
675          upper[icol] *= multiplier;
676        colsol[icol] *= multiplier;
677        cost[icol] *= columnScale[icol];
678      }
679      CoinMemcpyN(model_->rowLower(),nrows,rowlower);
680      for (irow=0;irow<nrows;irow++) {
681        double multiplier = rowScale[irow];
682        if (rowlower[irow]>-1.0e50)
683          rowlower[irow] *= multiplier;
684        if (rowupper[irow]<1.0e50)
685          rowupper[irow] *= multiplier;
686        rowsol[irow] *= multiplier;
687      }
688      int length = columnStart[ncols-1]+columnLength[ncols-1];
689      double * elemYY = new double[length];
690      for (i=0;i<ncols;i++) {
691        CoinBigIndex j;
692        double scale = columnScale[i];
693        for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
694          int irow=row[j];
695          elemYY[j] = element[j]*scale*rowScale[irow];
696        }
697      }
698      elemXX=elemYY;
699    }
700  }
701#endif
702  for (i=0;i<ncols;i++) {
703    CoinBigIndex j;
704    double dd=columnLength[i];
705    dd=cost[i]/dd;
706    for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
707      int irow=row[j];
708      if (dd<rowsol[irow]) {
709        rowsol[irow]=dd;
710      }
711    }
712  }
713  d2=0.0;
714  for (i=0;i<nrows;i++) {
715    d2+=rowsol[i];
716  }
717  d2*=2.0; /* for luck */
718 
719  d2=d2/static_cast<double> (4*nrows+8000);
720  d2*=0.5; /* halve with more flexible method */
721  if (d2<5.0) d2=5.0;
722  if (djExit==0.0) {
723    djExit=d2;
724  }
725  if ((saveStrategy&4)!=0) {
726    /* go to relative tolerances - first small */
727    djExit=1.0e-10;
728    djFlag=1.0e-5;
729    drop=1.0e-10;
730  }
731  memset(whenUsed,0,ncols*sizeof(int));
732  strategy=strategies[strategy];
733  if ((saveStrategy&8)!=0) strategy |= 64; /* don't allow large theta */
734  CoinMemcpyN(colsol,ncols,saveSol);
735 
736  lastResult=IdiSolve(nrows,ncols,rowsol ,colsol,pi,
737                       dj,cost,rowlower,rowupper,
738                       lower,upper,elemXX,row,columnStart,columnLength,lambda,
739                       0,mu,drop,
740                      maxmin,offset,strategy,djTol,djExit,djFlag,randomNumberGenerator);
741  // update whenUsed_
742  n = cleanIteration(iteration, ordStart,ordEnd,
743                     colsol,  lower,  upper,
744                     rowlower, rowupper,
745                     cost, elemXX, fixTolerance,lastResult.objval,lastResult.infeas);
746  if ((strategy_&16384)!=0) {
747    int * posSlack = whenUsed_+ncols;
748    int * negSlack = posSlack+nrows;
749    int * nextSlack = negSlack + nrows;
750    double * rowsol2 = reinterpret_cast<double *> (nextSlack+ncols);
751    for (i=0;i<nrows;i++)
752      rowsol[i] += rowsol2[i];
753  }
754  if ((logLevel_&1)!=0) {
755#ifndef OSI_IDIOT
756    if (!handler) {
757#endif
758      printf("Iteration %d infeasibility %g, objective %g - mu %g, its %d, %d interior\n", 
759             iteration,lastResult.infeas,lastResult.objval,mu,lastResult.iteration,n);
760#ifndef OSI_IDIOT
761    } else {
762      handler->message(CLP_IDIOT_ITERATION,*messages)
763        <<iteration<<lastResult.infeas<<lastResult.objval<<mu<<lastResult.iteration<<n
764        <<CoinMessageEol;
765    }
766#endif
767  }
768  int numberBaseTrys=0; // for first time
769  int numberAway=-1;
770  iterationTotal = lastResult.iteration;
771  firstInfeas=lastResult.infeas;
772  if ((strategy_&1024)!=0) reasonableInfeas=0.5*firstInfeas;
773  if (lastResult.infeas<reasonableInfeas) lastResult.infeas=reasonableInfeas;
774  double keepinfeas=1.0e31;
775  double lastInfeas=1.0e31;
776  double bestInfeas=1.0e31;
777  while ((mu>stopMu&&lastResult.infeas>smallInfeas)||
778         (lastResult.infeas<=smallInfeas&&
779         dropping(lastResult,exitDrop,smallInfeas,&badIts))||
780         checkIteration<2||lambdaIteration<lambdaIterations_) {
781    if (lastResult.infeas<=exitFeasibility_)
782      break; 
783    iteration++;
784    checkIteration++;
785    if (lastResult.infeas<=smallInfeas&&lastResult.objval<bestFeasible) {
786      bestFeasible=lastResult.objval;
787    }
788    if (lastResult.infeas+mu*lastResult.objval<bestWeighted) {
789      bestWeighted=lastResult.objval+mu*lastResult.objval;
790    }
791    if ((saveStrategy&4096)) strategy |=256;
792    if ((saveStrategy&4)!=0&&iteration>2) {
793      /* go to relative tolerances */
794      double weighted=10.0+fabs(lastWeighted);
795      djExit=djTolerance_*weighted;
796      djFlag=2.0*djExit;
797      drop=drop_*weighted;
798      djTol=0.01*djExit;
799    }
800    CoinMemcpyN(colsol,ncols,saveSol);
801    result=IdiSolve(nrows,ncols,rowsol ,colsol,pi,dj,
802                     cost,rowlower,rowupper,
803                     lower,upper,elemXX,row,columnStart,columnLength,lambda,
804                     maxIts,mu,drop,
805                     maxmin,offset,strategy,djTol,djExit,djFlag,randomNumberGenerator);
806    n = cleanIteration(iteration, ordStart,ordEnd,
807                       colsol,  lower,  upper,
808                       rowlower, rowupper,
809                       cost, elemXX, fixTolerance,result.objval,result.infeas);
810    if ((strategy_&16384)!=0) {
811      int * posSlack = whenUsed_+ncols;
812      int * negSlack = posSlack+nrows;
813      int * nextSlack = negSlack + nrows;
814      double * rowsol2 = reinterpret_cast<double *> (nextSlack+ncols);
815      for (i=0;i<nrows;i++)
816        rowsol[i] += rowsol2[i];
817    }
818    if ((logLevel_&1)!=0) {
819#ifndef OSI_IDIOT
820      if (!handler) {
821#endif
822        printf("Iteration %d infeasibility %g, objective %g - mu %g, its %d, %d interior\n", 
823               iteration,result.infeas,result.objval,mu,result.iteration,n);
824#ifndef OSI_IDIOT
825      } else {
826        handler->message(CLP_IDIOT_ITERATION,*messages)
827          <<iteration<<result.infeas<<result.objval<<mu<<result.iteration<<n
828          <<CoinMessageEol;
829      }
830#endif
831    }
832    if (iteration>50&&n==numberAway&&result.infeas<1.0e-4) {
833#ifdef CLP_INVESTIGATE
834      printf("infeas small %g\n",result.infeas);
835#endif
836      break; // not much happening
837    }
838    if (lightWeight_==1&&iteration>10&&result.infeas>1.0&&maxIts!=7) {
839      if (lastInfeas!=bestInfeas&&CoinMin(result.infeas,lastInfeas)>0.95*bestInfeas)
840        majorIterations_ = CoinMin(majorIterations_,iteration); // not getting feasible
841    }
842    lastInfeas = result.infeas;
843    numberAway=n;
844    keepinfeas = result.infeas;
845    lastWeighted=result.weighted;
846    iterationTotal += result.iteration;
847    if (iteration==1) {
848      if ((strategy_&1024)!=0&&mu<1.0e-10) 
849        result.infeas=firstInfeas*0.8;
850      if (majorIterations_>=50||dropEnoughFeasibility_<=0.0)
851        result.infeas *= 0.8;
852      if (result.infeas>firstInfeas*0.9
853          &&result.infeas>reasonableInfeas) {
854        iteration--;
855        if (majorIterations_<50)
856          mu*=1.0e-1;
857        else
858          mu*=0.7;
859        bestFeasible=1.0e31;
860        bestWeighted=1.0e60;
861        numberBaseTrys++;
862        if (mu<1.0e-30||(numberBaseTrys>10&&lightWeight_)) {
863          // back to all slack basis
864          lightWeight_=2;
865          break;
866        }
867 CoinMemcpyN(saveSol,ncols,colsol);
868      } else {
869        maxIts=maxIts2;
870        checkIteration=0;
871        if ((strategy_&1024)!=0) mu *= 1.0e-1;
872      }
873    } else {
874    }
875    bestInfeas=CoinMin(bestInfeas,result.infeas);
876    if (iteration) {
877      /* this code is in to force it to terminate sometime */
878      double changeMu=factor;
879      if ((saveStrategy&64)!=0) {
880        keepinfeas=0.0; /* switch off ranga's increase */
881        fakeSmall=smallInfeas;
882      } else {
883        fakeSmall=-1.0;
884      }
885      saveLambdaScale=0.0;
886      if (result.infeas>reasonableInfeas||
887          (nTry+1==maxBigIts&&result.infeas>fakeSmall)) {
888        if (result.infeas>lastResult.infeas*(1.0-dropEnoughFeasibility_)||
889            nTry+1==maxBigIts||
890            (result.infeas>lastResult.infeas*0.9
891             &&result.weighted>lastResult.weighted
892             -dropEnoughWeighted_*CoinMax(fabs(lastResult.weighted),fabs(result.weighted)))) {
893          mu*=changeMu;
894          if ((saveStrategy&32)!=0&&result.infeas<reasonableInfeas&&0) {
895            reasonableInfeas=CoinMax(smallInfeas,reasonableInfeas*sqrt(changeMu));
896            printf("reasonable infeas now %g\n",reasonableInfeas);
897          }
898          result.weighted=1.0e60;
899          nTry=0;
900          bestFeasible=1.0e31;
901          bestWeighted=1.0e60;
902          checkIteration=0;
903          lambdaIteration=0;
904#define LAMBDA
905#ifdef LAMBDA
906          if ((saveStrategy&2048)==0) {
907            memset(lambda,0,nrows*sizeof(double));
908          }
909#else
910          memset(lambda,0,nrows*sizeof(double));
911#endif
912        } else {
913          nTry++;
914        }
915      } else if (lambdaIterations_>=0) {
916        /* update lambda  */
917        double scale=1.0/mu;
918        int i,nnz=0;
919        saveLambdaScale=scale;
920         lambdaIteration++;
921         if ((saveStrategy&4)==0) drop = drop_/50.0;
922         if (lambdaIteration>4 && 
923            (((lambdaIteration%10)==0 && smallInfeas<keepinfeas) ||
924             ((lambdaIteration%5)==0 && 1.5*smallInfeas<keepinfeas))) {
925           //printf(" Increasing smallInfeas from %f to %f\n",smallInfeas,1.5*smallInfeas);
926           smallInfeas *= 1.5;
927         }
928         if ((saveStrategy&2048)==0) {
929           for (i=0;i<nrows;i++) {
930             if (lambda[i]) nnz++;
931             lambda[i]+= scale*rowsol[i];
932           }
933         } else {
934           nnz=1;
935#ifdef LAMBDA
936           for (i=0;i<nrows;i++) {
937             lambda[i]+= scale*rowsol[i];
938           }
939#else
940           for (i=0;i<nrows;i++) {
941             lambda[i] = scale*rowsol[i];
942           }
943           for (i=0;i<ncols;i++) {
944             CoinBigIndex j;
945             double value=cost[i]*maxmin;
946             for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
947               int irow=row[j];
948               value+=element[j]*lambda[irow];
949             }
950             cost[i]=value*maxmin;
951           }
952           for (i=0;i<nrows;i++) {
953             offset+=lambda[i]*rowupper[i];
954             lambda[i]=0.0;
955           }
956#ifdef DEBUG
957           printf("offset %g\n",offset);
958#endif
959           model_->setDblParam(OsiObjOffset,offset);
960#endif
961         }
962        nTry++;
963        if (!nnz) {
964          bestFeasible=1.0e32;
965          bestWeighted=1.0e60;
966          checkIteration=0;
967          result.weighted=1.0e31;
968        }
969#ifdef DEBUG
970        double trueCost=0.0;
971        for (i=0;i<ncols;i++) {
972          int j;
973          trueCost+=cost[i]*colsol[i];
974        }
975        printf("True objective %g\n",trueCost-offset);
976#endif
977      } else {
978        nTry++;
979      }
980      lastResult=result;
981      if (result.infeas<reasonableInfeas&&!belowReasonable) {
982        belowReasonable=1;
983        bestFeasible=1.0e32;
984        bestWeighted=1.0e60;
985        checkIteration=0;
986        result.weighted=1.0e31;
987      }
988    }
989    if (iteration>=majorIterations_) {
990      // If not feasible and crash then dive dive dive
991      if (mu>1.0e-12&&result.infeas>1.0&&majorIterations_<40) {
992        mu=1.0e-30;
993        majorIterations_=iteration+1;
994        stopMu=0.0;
995      } else {
996        if (logLevel>2) 
997          printf("Exiting due to number of major iterations\n");
998        break;
999      }
1000    }
1001  }
1002  majorIterations_ = saveMajorIterations;
1003#ifndef OSI_IDIOT
1004  if (scaled) {
1005    // Scale solution and free arrays
1006    const double * rowScale = model_->rowScale();
1007    const double * columnScale = model_->columnScale();
1008    int icol,irow;
1009    for (icol=0;icol<ncols;icol++) {
1010      colsol[icol] *= columnScale[icol];
1011      saveSol[icol] *= columnScale[icol];
1012      dj[icol] /= columnScale[icol];
1013    }
1014    for (irow=0;irow<nrows;irow++) {
1015      rowsol[irow] /= rowScale[irow];
1016      pi[irow] *= rowScale[irow];
1017    }
1018    // Don't know why getting Microsoft problems
1019#if defined (_MSC_VER)
1020    delete [] ( double *) elemXX;
1021#else
1022    delete [] elemXX;
1023#endif
1024    model_->setRowScale(NULL);
1025    model_->setColumnScale(NULL);
1026    delete [] lower;
1027    delete [] upper;
1028    delete [] cost;
1029    lower = model_->columnLower();
1030    upper = model_->columnUpper();
1031    cost = model_->objective();
1032    //rowlower = model_->rowLower();
1033  }
1034#endif
1035#define TRYTHIS
1036#ifdef TRYTHIS
1037  if ((saveStrategy&2048)!=0) {
1038    double offset;
1039    model_->getDblParam(OsiObjOffset,offset);
1040    for (i=0;i<ncols;i++) {
1041      CoinBigIndex j;
1042      double djval=cost[i]*maxmin;
1043      for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
1044        int irow=row[j];
1045        djval -= element[j]*lambda[irow];
1046      }
1047      cost[i]=djval;
1048    }
1049    for (i=0;i<nrows;i++) {
1050      offset+=lambda[i]*rowupper[i];
1051    }
1052    model_->setDblParam(OsiObjOffset,offset);
1053  }
1054#endif
1055  if (saveLambdaScale) {
1056    /* back off last update */
1057    for (i=0;i<nrows;i++) {
1058      lambda[i]-= saveLambdaScale*rowsol[i];
1059    }
1060  }
1061  muAtExit_=mu;
1062  // For last iteration make as feasible as possible
1063  if (oddSlacks)
1064    strategy_ |= 16384;
1065  // not scaled
1066  n = cleanIteration(iteration, ordStart,ordEnd,
1067                     colsol,  lower,  upper,
1068                     model_->rowLower(), model_->rowUpper(),
1069                     cost, element, fixTolerance,lastResult.objval,lastResult.infeas);
1070#if 0
1071  if ((logLevel&1)==0||(strategy_&16384)!=0) {
1072    printf(
1073            "%d - mu %g, infeasibility %g, objective %g, %d interior\n",
1074            iteration,mu,lastResult.infeas,lastResult.objval,n);
1075  }
1076#endif
1077#ifndef OSI_IDIOT
1078  model_->setSumPrimalInfeasibilities(lastResult.infeas);
1079#endif
1080  // Put back more feasible solution
1081  double saveInfeas[]={0.0,0.0};
1082  for (int iSol=0;iSol<3;iSol++) {
1083    const double * solution = iSol ? colsol : saveSol;
1084    if (iSol==2&&saveInfeas[0]<saveInfeas[1]) {
1085      // put back best solution
1086      CoinMemcpyN(saveSol,ncols,colsol);
1087    }
1088    double large=0.0;
1089    int i;
1090    memset(rowsol,0,nrows*sizeof(double));
1091    for (i=0;i<ncols;i++) {
1092      CoinBigIndex j;
1093      double value=solution[i];
1094      for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
1095        int irow=row[j];
1096        rowsol[irow] += element[j]*value;
1097      }
1098    }
1099    for (i=0;i<nrows;i++) {
1100      if (rowsol[i] > rowupper[i]) {
1101        double diff=rowsol[i]-rowupper[i];
1102        if (diff>large) 
1103          large=diff;
1104      } else if (rowsol[i] < rowlower[i]) {
1105        double diff=rowlower[i]-rowsol[i];
1106        if (diff>large) 
1107          large=diff;
1108      } 
1109    }
1110    if (iSol<2)
1111      saveInfeas[iSol]=large;
1112    if (logLevel>2)
1113      printf("largest infeasibility is %g\n",large);
1114  }
1115  /* subtract out lambda */
1116  for (i=0;i<nrows;i++) {
1117    pi[i]-=lambda[i];
1118  }
1119  for (i=0;i<ncols;i++) {
1120    CoinBigIndex j;
1121    double djval=cost[i]*maxmin;
1122    for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
1123      int irow=row[j];
1124      djval -= element[j]*pi[irow];
1125    }
1126    dj[i]=djval;
1127  }
1128  if ((strategy_&1024)!=0) {
1129    double ratio = static_cast<double> (ncols)/static_cast<double> (nrows);
1130    printf("col/row ratio %g infeas ratio %g\n",ratio,lastResult.infeas/firstInfeas);
1131    if (lastResult.infeas>0.01*firstInfeas*ratio) {
1132      strategy_ &= (~1024);
1133      printf(" - layer off\n");
1134    } else {
1135      printf(" - layer on\n");
1136    }
1137  }
1138  delete [] saveSol;
1139  delete [] lambda;
1140  // save solution
1141  // duals not much use - but save anyway
1142#ifndef OSI_IDIOT
1143  CoinMemcpyN(rowsol,nrows,model_->primalRowSolution());
1144  CoinMemcpyN(colsol,ncols,model_->primalColumnSolution());
1145  CoinMemcpyN(pi,nrows,model_->dualRowSolution());
1146  CoinMemcpyN(dj,ncols,model_->dualColumnSolution());
1147#else
1148  model_->setColSolution(colsol);
1149  model_->setRowPrice(pi);
1150  delete [] cost;
1151#endif
1152  delete [] rowsol;
1153  delete [] colsol;
1154  delete [] pi;
1155  delete [] dj;
1156  delete [] rowlower;
1157  delete [] rowupper;
1158  return ;
1159}
1160#ifndef OSI_IDIOT
1161void
1162Idiot::crossOver(int mode)
1163{
1164  if (lightWeight_==2) {
1165    // total failure
1166    model_->allSlackBasis();
1167    return;
1168  }
1169  double fixTolerance=IDIOT_FIX_TOLERANCE;
1170#ifdef COIN_DEVELOP
1171  double startTime = CoinCpuTime();             
1172#endif
1173  ClpSimplex * saveModel=NULL;
1174  ClpMatrixBase * matrix = model_->clpMatrix();
1175  const int * row = matrix->getIndices();
1176  const CoinBigIndex * columnStart = matrix->getVectorStarts();
1177  const int * columnLength = matrix->getVectorLengths(); 
1178  const double * element = matrix->getElements();
1179  const double * rowupper = model_->getRowUpper();
1180  int nrows=model_->getNumRows();
1181  int ncols=model_->getNumCols();
1182  double * rowsol, * colsol;
1183  // different for Osi
1184  double * lower = model_->columnLower();
1185  double * upper = model_->columnUpper();
1186  const double * rowlower= model_->getRowLower();
1187  int * whenUsed=whenUsed_;
1188  rowsol= model_->primalRowSolution();
1189  colsol= model_->primalColumnSolution();;
1190  double * cost=model_->objective();
1191
1192  int slackEnd,ordStart,ordEnd;
1193  int slackStart = countCostedSlacks(model_);
1194
1195  int addAll = mode&7;
1196  int presolve=0;
1197
1198  double djTolerance = djTolerance_;
1199  if (djTolerance>0.0&&djTolerance<1.0)
1200    djTolerance=1.0;
1201  int iteration;
1202  int i, n=0;
1203  double ratio=1.0;
1204  double objValue=0.0;
1205  if ((strategy_&128)!=0) {
1206    fixTolerance=SMALL_IDIOT_FIX_TOLERANCE;
1207  }
1208  if ((mode&16)!=0&&addAll<3) presolve=1;
1209  double * saveUpper = NULL;
1210  double * saveLower = NULL;
1211  double * saveRowUpper = NULL;
1212  double * saveRowLower = NULL;
1213  bool allowInfeasible = ((strategy_&8192)!=0)||(majorIterations_>1000000);
1214  if (addAll<3) {
1215    saveUpper = new double [ncols];
1216    saveLower = new double [ncols];
1217    CoinMemcpyN(upper,ncols,saveUpper);
1218    CoinMemcpyN(lower,ncols,saveLower);
1219    if (allowInfeasible) {
1220      saveRowUpper = new double [nrows];
1221      saveRowLower = new double [nrows];
1222      CoinMemcpyN(rowupper,nrows,saveRowUpper);
1223      CoinMemcpyN(rowlower,nrows,saveRowLower);
1224      double averageInfeas = model_->sumPrimalInfeasibilities()/static_cast<double> (model_->numberRows());
1225      fixTolerance = CoinMax(fixTolerance,1.0e-5*averageInfeas);
1226    }
1227  }
1228  if (slackStart>=0) {
1229    slackEnd=slackStart+nrows;
1230    if (slackStart) {
1231      ordStart=0;
1232      ordEnd=slackStart;
1233    } else {
1234      ordStart=nrows;
1235      ordEnd=ncols;
1236    }
1237  } else {
1238    slackEnd=slackStart;
1239    ordStart=0;
1240    ordEnd=ncols;
1241  }
1242  /* get correct rowsol (without known slacks) */
1243  memset(rowsol,0,nrows*sizeof(double));
1244  for (i=ordStart;i<ordEnd;i++) {
1245    CoinBigIndex j;
1246    double value=colsol[i];
1247    if (value<lower[i]+fixTolerance) {
1248      value=lower[i];
1249      colsol[i]=value;
1250    }
1251    for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
1252      int irow=row[j];
1253      rowsol[irow]+=value*element[j];
1254    }
1255  }
1256  if (slackStart>=0) {
1257    for (i=0;i<nrows;i++) {
1258      if (ratio*rowsol[i]>rowlower[i]&&rowsol[i]>1.0e-8) {
1259        ratio=rowlower[i]/rowsol[i];
1260      }
1261    }
1262    for (i=0;i<nrows;i++) {
1263      rowsol[i]*=ratio;
1264    }
1265    for (i=ordStart;i<ordEnd;i++) {
1266      double value=colsol[i]*ratio;
1267      colsol[i]=value;
1268      objValue+=value*cost[i];
1269    }
1270    for (i=0;i<nrows;i++) {
1271      double value=rowlower[i]-rowsol[i];
1272      colsol[i+slackStart]=value;
1273      objValue+=value*cost[i+slackStart];
1274    }
1275    printf("New objective after scaling %g\n",objValue);
1276  }
1277#if 0
1278   maybe put back - but just get feasible ?
1279  // If not many fixed then just exit
1280  int numberFixed=0;
1281  for (i=ordStart;i<ordEnd;i++) {
1282    if (colsol[i]<lower[i]+fixTolerance)
1283      numberFixed++;
1284    else if (colsol[i]>upper[i]-fixTolerance)
1285      numberFixed++;
1286  }
1287  if (numberFixed<ncols/2) {
1288    addAll=3;
1289    presolve=0;
1290  }
1291#endif
1292#ifdef FEB_TRY
1293  int savePerturbation = model_->perturbation();
1294  int saveOptions = model_->specialOptions();
1295  model_->setSpecialOptions(saveOptions|8192);
1296  if (savePerturbation_==50)
1297    model_->setPerturbation(56);
1298#endif
1299  model_->createStatus();
1300  /* addAll
1301     0 - chosen,all used, all
1302     1 - chosen, all
1303     2 - all
1304     3 - do not do anything  - maybe basis
1305  */
1306  for (i=ordStart;i<ordEnd;i++) {
1307    if (addAll<2) {
1308      if (colsol[i]<lower[i]+fixTolerance) {
1309        upper[i]=lower[i];
1310        colsol[i]=lower[i];
1311      } else if (colsol[i]>upper[i]-fixTolerance) {
1312        lower[i]=upper[i];
1313        colsol[i]=upper[i];
1314      }
1315    }
1316    model_->setColumnStatus(i,ClpSimplex::superBasic);
1317  }
1318  if ((strategy_&16384)!=0) {
1319    // put in basis
1320    int * posSlack = whenUsed_+ncols;
1321    int * negSlack = posSlack+nrows;
1322    int * nextSlack = negSlack + nrows;
1323#if 1
1324    // Array for sorting out slack values
1325    double * ratio = new double [ncols];
1326    int * which = new int [ncols];
1327    for (i=0;i<nrows;i++) {
1328      if (posSlack[i]>=0||negSlack[i]>=0) {
1329        int iCol;
1330        int nPlus=0;
1331        int nMinus=0;
1332        bool possible=true;
1333        // Get sum
1334        double sum=0.0;
1335        iCol =posSlack[i];
1336        while (iCol>=0) {
1337          double value = element[columnStart[iCol]];
1338          sum += value*colsol[iCol];
1339          if (lower[iCol]) {
1340            possible=false;
1341            break;
1342          } else {
1343            nPlus++;
1344          }
1345          iCol=nextSlack[iCol];
1346        }
1347        iCol =negSlack[i];
1348        while (iCol>=0) {
1349          double value = -element[columnStart[iCol]];
1350          sum -= value*colsol[iCol];
1351          if (lower[iCol]) {
1352            possible=false;
1353            break;
1354          } else {
1355            nMinus++;
1356          }
1357          iCol=nextSlack[iCol];
1358        }
1359        //printf("%d plus, %d minus",nPlus,nMinus);
1360        //printf("\n");
1361        if ((rowsol[i]-rowlower[i]<1.0e-7||
1362             rowupper[i]-rowsol[i]<1.0e-7)&&
1363            nPlus+nMinus<2) 
1364          possible=false;
1365        if (possible) {
1366          // Amount contributed by other varaibles
1367          sum = rowsol[i]-sum;
1368          double lo = rowlower[i];
1369          if (lo>-1.0e20)
1370            lo -=sum;
1371          double up = rowupper[i];
1372          if (up<1.0e20)
1373            up -= sum;
1374          //printf("row bounds %g %g\n",lo,up);
1375          if (0) {
1376            double sum=0.0;
1377            double x=0.0;
1378            for (int k=0;k<ncols;k++) {
1379              CoinBigIndex j;
1380              double value=colsol[k];
1381              x+=value*cost[k];
1382              for (j=columnStart[k];j<columnStart[k]+columnLength[k];j++) {
1383                int irow=row[j];
1384                if (irow==i)
1385                  sum += element[j]*value;
1386              }
1387            }
1388            printf("Before sum %g <= %g <= %g cost %.18g\n",
1389                   rowlower[i],sum,rowupper[i],x);
1390          }
1391          // set all to zero
1392          iCol =posSlack[i];
1393          while (iCol>=0) {
1394            colsol[iCol]=0.0;
1395            iCol=nextSlack[iCol];
1396          }
1397          iCol =negSlack[i];
1398          while (iCol>=0) {
1399            colsol[iCol]=0.0;
1400            iCol=nextSlack[iCol];
1401          }
1402          {
1403            int iCol;
1404            iCol =posSlack[i];
1405            while (iCol>=0) {
1406              //printf("col %d el %g sol %g bounds %g %g cost %g\n",
1407              //     iCol,element[columnStart[iCol]],
1408              //     colsol[iCol],lower[iCol],upper[iCol],cost[iCol]);
1409              iCol = nextSlack[iCol];
1410            }
1411            iCol =negSlack[i];
1412            while (iCol>=0) {
1413              //printf("col %d el %g sol %g bounds %g %g cost %g\n",
1414              //     iCol,element[columnStart[iCol]],
1415              //     colsol[iCol],lower[iCol],upper[iCol],cost[iCol]);
1416              iCol = nextSlack[iCol];
1417            }
1418          }
1419          //printf("now what?\n");
1420          int n=0;
1421          bool basic=false;
1422          if (lo>0.0) {
1423            // Add in positive
1424            iCol =posSlack[i];
1425            while (iCol>=0) {
1426              double value = element[columnStart[iCol]];
1427              ratio[n]=cost[iCol]/value;
1428              which[n++]=iCol;
1429              iCol=nextSlack[iCol];
1430            }
1431            CoinSort_2(ratio,ratio+n,which);
1432            for (int i=0;i<n;i++) {
1433              iCol=which[i];
1434              double value=element[columnStart[iCol]];
1435              if (lo>=upper[iCol]*value) {
1436                value *=upper[iCol];
1437                sum+=value;
1438                lo-=value;
1439                colsol[iCol]=upper[iCol];
1440              } else {
1441                value = lo/value;
1442                sum += lo;
1443                lo=0.0;
1444                colsol[iCol]=value;
1445                model_->setColumnStatus(iCol,ClpSimplex::basic);
1446                basic=true;
1447              }
1448              if (lo<1.0e-7)
1449                break;
1450            }
1451          } else if (up<0.0) {
1452            // Use lo so coding is more similar
1453            lo=-up;
1454            // Add in negative
1455            iCol =negSlack[i];
1456            while (iCol>=0) {
1457              double value = -element[columnStart[iCol]];
1458              ratio[n]=cost[iCol]/value;
1459              which[n++]=iCol;
1460              iCol=nextSlack[iCol];
1461            }
1462            CoinSort_2(ratio,ratio+n,which);
1463            for (int i=0;i<n;i++) {
1464              iCol=which[i];
1465              double value=-element[columnStart[iCol]];
1466              if (lo>=upper[iCol]*value) {
1467                value *=upper[iCol];
1468                sum+=value;
1469                lo-=value;
1470                colsol[iCol]=upper[iCol];
1471              } else {
1472                value = lo/value;
1473                sum += lo;
1474                lo=0.0;
1475                colsol[iCol]=value;
1476                model_->setColumnStatus(iCol,ClpSimplex::basic);
1477                basic=true;
1478              }
1479              if (lo<1.0e-7)
1480                break;
1481            }
1482          }
1483          if (0) {
1484            double sum2=0.0;
1485            double x=0.0;
1486            for (int k=0;k<ncols;k++) {
1487              CoinBigIndex j;
1488              double value=colsol[k];
1489              x+=value*cost[k];
1490              for (j=columnStart[k];j<columnStart[k]+columnLength[k];j++) {
1491                int irow=row[j];
1492                if (irow==i)
1493                  sum2 += element[j]*value;
1494              }
1495            }
1496            printf("after sum %g <= %g <= %g cost %.18g (sum = %g)\n",
1497                   rowlower[i],sum2,rowupper[i],x,sum);
1498          }
1499          rowsol[i]=sum;
1500          if (basic) {
1501            if (fabs(rowsol[i]-rowlower[i])<fabs(rowsol[i]-rowupper[i]))
1502              model_->setRowStatus(i,ClpSimplex::atLowerBound);
1503            else
1504              model_->setRowStatus(i,ClpSimplex::atUpperBound);
1505          }
1506        } else {
1507          int n=0;
1508          int iCol;
1509          iCol =posSlack[i];
1510          while (iCol>=0) {
1511            if (colsol[iCol]>lower[iCol]+1.0e-8&&
1512                colsol[iCol]<upper[iCol]-1.0e-8) {
1513              model_->setColumnStatus(iCol,ClpSimplex::basic);
1514              n++;
1515            }
1516            iCol = nextSlack[iCol];
1517          }
1518          iCol =negSlack[i];
1519          while (iCol>=0) {
1520            if (colsol[iCol]>lower[iCol]+1.0e-8&&
1521                colsol[iCol]<upper[iCol]-1.0e-8) {
1522              model_->setColumnStatus(iCol,ClpSimplex::basic);
1523              n++;
1524            }
1525            iCol = nextSlack[iCol];
1526          }
1527          if (n) {
1528            if (fabs(rowsol[i]-rowlower[i])<fabs(rowsol[i]-rowupper[i]))
1529              model_->setRowStatus(i,ClpSimplex::atLowerBound);
1530            else
1531              model_->setRowStatus(i,ClpSimplex::atUpperBound);
1532#ifdef CLP_INVESTIGATE
1533            if (n>1)
1534              printf("%d basic on row %d!\n",n,i);
1535#endif
1536          }
1537        }
1538      }
1539    }
1540    delete [] ratio;
1541    delete [] which;
1542#else
1543    for (i=0;i<nrows;i++) {
1544      int n=0;
1545      int iCol;
1546      iCol =posSlack[i];
1547      while (iCol>=0) {
1548        if (colsol[iCol]>lower[iCol]+1.0e-8&&
1549            colsol[iCol]<upper[iCol]-1.0e-8) {
1550          model_->setColumnStatus(iCol,ClpSimplex::basic);
1551          n++;
1552        }
1553        iCol = nextSlack[iCol];
1554      }
1555      iCol =negSlack[i];
1556      while (iCol>=0) {
1557        if (colsol[iCol]>lower[iCol]+1.0e-8&&
1558            colsol[iCol]<upper[iCol]-1.0e-8) {
1559          model_->setColumnStatus(iCol,ClpSimplex::basic);
1560          n++;
1561        }
1562        iCol = nextSlack[iCol];
1563      }
1564      if (n) {
1565        if (fabs(rowsol[i]-rowlower[i])<fabs(rowsol[i]-rowupper[i]))
1566          model_->setRowStatus(i,ClpSimplex::atLowerBound);
1567        else
1568          model_->setRowStatus(i,ClpSimplex::atUpperBound);
1569#ifdef CLP_INVESTIGATE
1570        if (n>1)
1571          printf("%d basic on row %d!\n",n,i);
1572#endif
1573      }
1574    }
1575#endif
1576  }
1577  double maxmin;
1578  if (model_->getObjSense()==-1.0) {
1579    maxmin=-1.0;
1580  } else {
1581    maxmin=1.0;
1582  }
1583  bool justValuesPass=majorIterations_>1000000;
1584  if (slackStart>=0) {
1585    for (i=0;i<nrows;i++) {
1586      model_->setRowStatus(i,ClpSimplex::superBasic);
1587    }
1588    for (i=slackStart;i<slackEnd;i++) {
1589      model_->setColumnStatus(i,ClpSimplex::basic);
1590    }
1591  } else {
1592    /* still try and put singletons rather than artificials in basis */
1593    int ninbas=0;
1594    for (i=0;i<nrows;i++) {
1595      model_->setRowStatus(i,ClpSimplex::basic);
1596    }
1597    for (i=0;i<ncols;i++) {
1598      if (columnLength[i]==1&&upper[i]>lower[i]+1.0e-5) {
1599        CoinBigIndex j =columnStart[i];
1600        double value=element[j];
1601        int irow=row[j];
1602        double rlo=rowlower[irow];
1603        double rup=rowupper[irow];
1604        double clo=lower[i];
1605        double cup=upper[i];
1606        double csol=colsol[i];
1607        /* adjust towards feasibility */
1608        double move=0.0;
1609        if (rowsol[irow]>rup) {
1610          move=(rup-rowsol[irow])/value;
1611          if (value>0.0) {
1612            /* reduce */
1613            if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1614          } else {
1615            /* increase */
1616            if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1617          }
1618        } else if (rowsol[irow]<rlo) {
1619          move=(rlo-rowsol[irow])/value;
1620          if (value>0.0) {
1621            /* increase */
1622            if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1623          } else {
1624            /* reduce */
1625            if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1626          }
1627        } else {
1628          /* move to improve objective */
1629          if (cost[i]*maxmin>0.0) {
1630            if (value>0.0) {
1631              move=(rlo-rowsol[irow])/value;
1632              /* reduce */
1633              if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1634            } else {
1635              move=(rup-rowsol[irow])/value;
1636              /* increase */
1637              if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1638            }
1639          } else if (cost[i]*maxmin<0.0) {
1640            if (value>0.0) {
1641              move=(rup-rowsol[irow])/value;
1642              /* increase */
1643              if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1644            } else {
1645              move=(rlo-rowsol[irow])/value;
1646              /* reduce */
1647              if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1648            }
1649          }
1650        }
1651        rowsol[irow] +=move*value;
1652        colsol[i]+=move;
1653        /* put in basis if row was artificial */
1654        if (rup-rlo<1.0e-7&&model_->getRowStatus(irow)==ClpSimplex::basic) {
1655          model_->setRowStatus(irow,ClpSimplex::superBasic);
1656          model_->setColumnStatus(i,ClpSimplex::basic);
1657          ninbas++;
1658        }
1659      }
1660    }
1661    /*printf("%d in basis\n",ninbas);*/
1662  }
1663  bool wantVector=false;
1664  if (dynamic_cast< ClpPackedMatrix*>(model_->clpMatrix())) {
1665    // See if original wanted vector
1666    ClpPackedMatrix * clpMatrixO = dynamic_cast< ClpPackedMatrix*>(model_->clpMatrix());
1667    wantVector = clpMatrixO->wantsSpecialColumnCopy();
1668  }
1669  if (addAll<3) {
1670    ClpPresolve pinfo;
1671    if (presolve) {
1672      if (allowInfeasible) {
1673        // fix up so will be feasible
1674        double * rhs = new double[nrows];
1675        memset(rhs,0,nrows*sizeof(double));
1676        model_->clpMatrix()->times(1.0,colsol,rhs);
1677        double * rowupper = model_->rowUpper();
1678        double * rowlower= model_->rowLower();
1679        saveRowUpper = CoinCopyOfArray(rowupper,nrows);
1680        saveRowLower = CoinCopyOfArray(rowlower,nrows);
1681        double sum = 0.0;
1682        for (i=0;i<nrows;i++) {
1683          if (rhs[i]>rowupper[i]) {
1684            sum += rhs[i]-rowupper[i];
1685            rowupper[i]=rhs[i];
1686          }
1687          if (rhs[i]<rowlower[i]) {
1688            sum += rowlower[i]-rhs[i];
1689            rowlower[i]=rhs[i];
1690          }
1691        }
1692        printf("sum of infeasibilities %g\n",sum);
1693        delete [] rhs;
1694      }
1695      saveModel = model_;
1696      pinfo.setPresolveActions(pinfo.presolveActions()|16384);
1697      model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
1698    }
1699    if (model_) {
1700      if (!wantVector) {
1701        //#define TWO_GOES
1702#ifndef TWO_GOES
1703        model_->primal(justValuesPass ? 2 : 1);
1704#else
1705        model_->primal(1+11);
1706#endif
1707      } else {
1708        ClpMatrixBase * matrix = model_->clpMatrix();
1709        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
1710        assert (clpMatrix);
1711        clpMatrix->makeSpecialColumnCopy();
1712        model_->primal(1);
1713        clpMatrix->releaseSpecialColumnCopy();
1714      }
1715      if (presolve) {
1716        pinfo.postsolve(true);
1717        delete model_;
1718        model_ = saveModel;
1719        saveModel=NULL;
1720      }
1721    } else {
1722      // not feasible
1723      addAll=1;
1724      presolve=0;
1725      model_ = saveModel;
1726      saveModel=NULL;
1727      if (justValuesPass)
1728        model_->primal(2);
1729    }
1730    if (allowInfeasible) {
1731      CoinMemcpyN(saveRowUpper,nrows,model_->rowUpper());
1732      CoinMemcpyN(saveRowLower,nrows,model_->rowLower());
1733      delete [] saveRowUpper;
1734      delete [] saveRowLower;
1735      saveRowUpper = NULL;
1736      saveRowLower = NULL;
1737    }
1738    if (addAll<2) {
1739      n=0;
1740      if (!addAll ) {
1741        /* could do scans to get a good number */
1742        iteration=1;
1743        for (i=ordStart;i<ordEnd;i++) {
1744          if (whenUsed[i]>=iteration) {
1745            if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
1746              n++;
1747              upper[i]=saveUpper[i];
1748              lower[i]=saveLower[i];
1749            }
1750          }
1751        }
1752      } else {
1753        for (i=ordStart;i<ordEnd;i++) {
1754          if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
1755            n++;
1756            upper[i]=saveUpper[i];
1757            lower[i]=saveLower[i];
1758          }
1759        }
1760        delete [] saveUpper;
1761        delete [] saveLower;
1762        saveUpper=NULL;
1763        saveLower=NULL;
1764      }
1765#ifdef COIN_DEVELOP
1766      printf("Time so far %g, %d now added from previous iterations\n",
1767             CoinCpuTime()-startTime,n);
1768#endif
1769      if (justValuesPass)
1770        return;
1771      if (addAll)
1772        presolve=0;
1773      if (presolve) {
1774        saveModel = model_;
1775        model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
1776      } else {
1777        presolve=0;
1778      }
1779      if (!wantVector) {
1780        model_->primal(1);
1781      } else {
1782        ClpMatrixBase * matrix = model_->clpMatrix();
1783        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
1784        assert (clpMatrix);
1785        clpMatrix->makeSpecialColumnCopy();
1786        model_->primal(1);
1787        clpMatrix->releaseSpecialColumnCopy();
1788      }
1789      if (presolve) {
1790        pinfo.postsolve(true);
1791        delete model_;
1792        model_ = saveModel;
1793        saveModel=NULL;
1794      }
1795      if (!addAll) {
1796        n=0;
1797        for (i=ordStart;i<ordEnd;i++) {
1798          if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
1799            n++;
1800            upper[i]=saveUpper[i];
1801            lower[i]=saveLower[i];
1802          }
1803        }
1804        delete [] saveUpper;
1805        delete [] saveLower;
1806        saveUpper=NULL;
1807        saveLower=NULL;
1808#ifdef COIN_DEVELOP
1809        printf("Time so far %g, %d now added from previous iterations\n",
1810               CoinCpuTime()-startTime,n);
1811#endif
1812      }
1813      if (presolve) {
1814        saveModel = model_;
1815        model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
1816      } else {
1817        presolve=0;
1818      }
1819      if (!wantVector) {
1820        model_->primal(1);
1821      } else {
1822        ClpMatrixBase * matrix = model_->clpMatrix();
1823        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
1824        assert (clpMatrix);
1825        clpMatrix->makeSpecialColumnCopy();
1826        model_->primal(1);
1827        clpMatrix->releaseSpecialColumnCopy();
1828      }
1829      if (presolve) {
1830        pinfo.postsolve(true);
1831        delete model_;
1832        model_ = saveModel;
1833        saveModel=NULL;
1834      }
1835    }
1836#ifdef COIN_DEVELOP
1837    printf("Total time in crossover %g\n", CoinCpuTime()-startTime);
1838#endif
1839    delete [] saveUpper;
1840    delete [] saveLower;
1841  }
1842#ifdef FEB_TRY
1843  model_->setSpecialOptions(saveOptions);
1844  model_->setPerturbation(savePerturbation);
1845#endif
1846  return ;
1847}
1848#endif
1849/*****************************************************************************/
1850
1851// Default contructor
1852Idiot::Idiot()
1853{
1854  model_ = NULL;
1855  maxBigIts_ = 3;
1856  maxIts_ = 5;
1857  logLevel_ = 1; 
1858  logFreq_ = 100;
1859  maxIts2_ = 100;
1860  djTolerance_ = 1e-1;
1861  mu_ = 1e-4;
1862  drop_ = 5.0;
1863  exitDrop_=-1.0e20;
1864  muFactor_ = 0.3333;
1865  stopMu_ = 1e-12;
1866  smallInfeas_ = 1e-1;
1867  reasonableInfeas_ = 1e2;
1868  muAtExit_ =1.0e31;
1869  strategy_ =8;
1870  lambdaIterations_ =0;
1871  checkFrequency_ =100;
1872  whenUsed_ = NULL;
1873  majorIterations_ =30;
1874  exitFeasibility_ =-1.0;
1875  dropEnoughFeasibility_ =0.02;
1876  dropEnoughWeighted_ =0.01;
1877  // adjust
1878  double nrows=10000.0;
1879  int baseIts =static_cast<int> (sqrt(static_cast<double>(nrows)));
1880  baseIts =baseIts/10;
1881  baseIts *= 10;
1882  maxIts2_ =200+baseIts+5;
1883  maxIts2_=100;
1884  reasonableInfeas_ =static_cast<double> (nrows)*0.05;
1885  lightWeight_=0;
1886}
1887// Constructor from model
1888Idiot::Idiot(OsiSolverInterface &model)
1889{
1890  model_ = & model;
1891  maxBigIts_ = 3;
1892  maxIts_ = 5;
1893  logLevel_ = 1; 
1894  logFreq_ = 100;
1895  maxIts2_ = 100;
1896  djTolerance_ = 1e-1;
1897  mu_ = 1e-4;
1898  drop_ = 5.0;
1899  exitDrop_=-1.0e20;
1900  muFactor_ = 0.3333;
1901  stopMu_ = 1e-12;
1902  smallInfeas_ = 1e-1;
1903  reasonableInfeas_ = 1e2;
1904  muAtExit_ =1.0e31;
1905  strategy_ =8;
1906  lambdaIterations_ =0;
1907  checkFrequency_ =100;
1908  whenUsed_ = NULL;
1909  majorIterations_ =30;
1910  exitFeasibility_ =-1.0;
1911  dropEnoughFeasibility_ =0.02;
1912  dropEnoughWeighted_ =0.01;
1913  // adjust
1914  double nrows;
1915  if (model_)
1916    nrows=model_->getNumRows();
1917  else
1918    nrows=10000.0;
1919  int baseIts =static_cast<int> (sqrt(static_cast<double>(nrows)));
1920  baseIts =baseIts/10;
1921  baseIts *= 10;
1922  maxIts2_ =200+baseIts+5;
1923  maxIts2_=100;
1924  reasonableInfeas_ =static_cast<double> (nrows)*0.05;
1925  lightWeight_=0;
1926}
1927// Copy constructor.
1928Idiot::Idiot(const Idiot &rhs)
1929{
1930  model_ = rhs.model_;
1931  if (model_&&rhs.whenUsed_) {
1932    int numberColumns = model_->getNumCols();
1933    whenUsed_ = new int [numberColumns];
1934    CoinMemcpyN(rhs.whenUsed_,numberColumns,whenUsed_);
1935  } else {
1936    whenUsed_=NULL;
1937  }
1938  djTolerance_ = rhs.djTolerance_;
1939  mu_ = rhs.mu_;
1940  drop_ = rhs.drop_;
1941  muFactor_ = rhs.muFactor_;
1942  stopMu_ = rhs.stopMu_;
1943  smallInfeas_ = rhs.smallInfeas_;
1944  reasonableInfeas_ = rhs.reasonableInfeas_;
1945  exitDrop_ = rhs.exitDrop_;
1946  muAtExit_ = rhs.muAtExit_;
1947  exitFeasibility_ = rhs.exitFeasibility_;
1948  dropEnoughFeasibility_ = rhs.dropEnoughFeasibility_;
1949  dropEnoughWeighted_ = rhs.dropEnoughWeighted_;
1950  maxBigIts_ = rhs.maxBigIts_;
1951  maxIts_ = rhs.maxIts_;
1952  majorIterations_ = rhs.majorIterations_;
1953  logLevel_ = rhs.logLevel_;
1954  logFreq_ = rhs.logFreq_;
1955  checkFrequency_ = rhs.checkFrequency_;
1956  lambdaIterations_ = rhs.lambdaIterations_;
1957  maxIts2_ = rhs.maxIts2_;
1958  strategy_ = rhs.strategy_;
1959  lightWeight_=rhs.lightWeight_;
1960}
1961// Assignment operator. This copies the data
1962Idiot & 
1963Idiot::operator=(const Idiot & rhs)
1964{
1965  if (this != &rhs) {
1966    delete [] whenUsed_;
1967    model_ = rhs.model_;
1968    if (model_&&rhs.whenUsed_) {
1969      int numberColumns = model_->getNumCols();
1970      whenUsed_ = new int [numberColumns];
1971      CoinMemcpyN(rhs.whenUsed_,numberColumns,whenUsed_);
1972    } else {
1973      whenUsed_=NULL;
1974    }
1975    djTolerance_ = rhs.djTolerance_;
1976    mu_ = rhs.mu_;
1977    drop_ = rhs.drop_;
1978    muFactor_ = rhs.muFactor_;
1979    stopMu_ = rhs.stopMu_;
1980    smallInfeas_ = rhs.smallInfeas_;
1981    reasonableInfeas_ = rhs.reasonableInfeas_;
1982    exitDrop_ = rhs.exitDrop_;
1983    muAtExit_ = rhs.muAtExit_;
1984    exitFeasibility_ = rhs.exitFeasibility_;
1985    dropEnoughFeasibility_ = rhs.dropEnoughFeasibility_;
1986    dropEnoughWeighted_ = rhs.dropEnoughWeighted_;
1987    maxBigIts_ = rhs.maxBigIts_;
1988    maxIts_ = rhs.maxIts_;
1989    majorIterations_ = rhs.majorIterations_;
1990    logLevel_ = rhs.logLevel_;
1991    logFreq_ = rhs.logFreq_;
1992    checkFrequency_ = rhs.checkFrequency_;
1993    lambdaIterations_ = rhs.lambdaIterations_;
1994    maxIts2_ = rhs.maxIts2_;
1995    strategy_ = rhs.strategy_;
1996    lightWeight_=rhs.lightWeight_;
1997  }
1998  return *this;
1999}
2000Idiot::~Idiot()
2001{
2002  delete [] whenUsed_;
2003}
Note: See TracBrowser for help on using the repository browser.