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

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

Creating new stable branch 1.11 from trunk (rev 1457)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 52.9 KB
Line 
1/* $Id: Idiot.cpp 1458 2009-11-05 12:34:07Z 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      scaled = model_->clpMatrix()->scale(model_)==0;
652    if (scaled) {
653      const double * rowScale = model_->rowScale();
654      const double * columnScale = model_->columnScale();
655      double * oldLower = lower;
656      double * oldUpper = upper;
657      double * oldCost = cost;
658      lower = new double[ncols];
659      upper = new double[ncols];
660      cost = new double[ncols];
661      CoinMemcpyN(oldLower,ncols,lower);
662      CoinMemcpyN(oldUpper,ncols,upper);
663      CoinMemcpyN(oldCost,ncols,cost);
664      int icol,irow;
665      for (icol=0;icol<ncols;icol++) {
666        double multiplier = 1.0/columnScale[icol];
667        if (lower[icol]>-1.0e50)
668          lower[icol] *= multiplier;
669        if (upper[icol]<1.0e50)
670          upper[icol] *= multiplier;
671        colsol[icol] *= multiplier;
672        cost[icol] *= columnScale[icol];
673      }
674      CoinMemcpyN(model_->rowLower(),nrows,rowlower);
675      for (irow=0;irow<nrows;irow++) {
676        double multiplier = rowScale[irow];
677        if (rowlower[irow]>-1.0e50)
678          rowlower[irow] *= multiplier;
679        if (rowupper[irow]<1.0e50)
680          rowupper[irow] *= multiplier;
681        rowsol[irow] *= multiplier;
682      }
683      int length = columnStart[ncols-1]+columnLength[ncols-1];
684      double * elemYY = new double[length];
685      for (i=0;i<ncols;i++) {
686        CoinBigIndex j;
687        double scale = columnScale[i];
688        for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
689          int irow=row[j];
690          elemYY[j] = element[j]*scale*rowScale[irow];
691        }
692      }
693      elemXX=elemYY;
694    }
695  }
696#endif
697  for (i=0;i<ncols;i++) {
698    CoinBigIndex j;
699    double dd=columnLength[i];
700    dd=cost[i]/dd;
701    for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
702      int irow=row[j];
703      if (dd<rowsol[irow]) {
704        rowsol[irow]=dd;
705      }
706    }
707  }
708  d2=0.0;
709  for (i=0;i<nrows;i++) {
710    d2+=rowsol[i];
711  }
712  d2*=2.0; /* for luck */
713 
714  d2=d2/static_cast<double> (4*nrows+8000);
715  d2*=0.5; /* halve with more flexible method */
716  if (d2<5.0) d2=5.0;
717  if (djExit==0.0) {
718    djExit=d2;
719  }
720  if ((saveStrategy&4)!=0) {
721    /* go to relative tolerances - first small */
722    djExit=1.0e-10;
723    djFlag=1.0e-5;
724    drop=1.0e-10;
725  }
726  memset(whenUsed,0,ncols*sizeof(int));
727  strategy=strategies[strategy];
728  if ((saveStrategy&8)!=0) strategy |= 64; /* don't allow large theta */
729  CoinMemcpyN(colsol,ncols,saveSol);
730 
731  lastResult=IdiSolve(nrows,ncols,rowsol ,colsol,pi,
732                       dj,cost,rowlower,rowupper,
733                       lower,upper,elemXX,row,columnStart,columnLength,lambda,
734                       0,mu,drop,
735                      maxmin,offset,strategy,djTol,djExit,djFlag,randomNumberGenerator);
736  // update whenUsed_
737  n = cleanIteration(iteration, ordStart,ordEnd,
738                     colsol,  lower,  upper,
739                     rowlower, rowupper,
740                     cost, elemXX, fixTolerance,lastResult.objval,lastResult.infeas);
741  if ((strategy_&16384)!=0) {
742    int * posSlack = whenUsed_+ncols;
743    int * negSlack = posSlack+nrows;
744    int * nextSlack = negSlack + nrows;
745    double * rowsol2 = reinterpret_cast<double *> (nextSlack+ncols);
746    for (i=0;i<nrows;i++)
747      rowsol[i] += rowsol2[i];
748  }
749  if ((logLevel_&1)!=0) {
750#ifndef OSI_IDIOT
751    if (!handler) {
752#endif
753      printf("Iteration %d infeasibility %g, objective %g - mu %g, its %d, %d interior\n", 
754             iteration,lastResult.infeas,lastResult.objval,mu,lastResult.iteration,n);
755#ifndef OSI_IDIOT
756    } else {
757      handler->message(CLP_IDIOT_ITERATION,*messages)
758        <<iteration<<lastResult.infeas<<lastResult.objval<<mu<<lastResult.iteration<<n
759        <<CoinMessageEol;
760    }
761#endif
762  }
763  int numberBaseTrys=0; // for first time
764  int numberAway=-1;
765  iterationTotal = lastResult.iteration;
766  firstInfeas=lastResult.infeas;
767  if ((strategy_&1024)!=0) reasonableInfeas=0.5*firstInfeas;
768  if (lastResult.infeas<reasonableInfeas) lastResult.infeas=reasonableInfeas;
769  double keepinfeas=1.0e31;
770  double lastInfeas=1.0e31;
771  double bestInfeas=1.0e31;
772  while ((mu>stopMu&&lastResult.infeas>smallInfeas)||
773         (lastResult.infeas<=smallInfeas&&
774         dropping(lastResult,exitDrop,smallInfeas,&badIts))||
775         checkIteration<2||lambdaIteration<lambdaIterations_) {
776    if (lastResult.infeas<=exitFeasibility_)
777      break; 
778    iteration++;
779    checkIteration++;
780    if (lastResult.infeas<=smallInfeas&&lastResult.objval<bestFeasible) {
781      bestFeasible=lastResult.objval;
782    }
783    if (lastResult.infeas+mu*lastResult.objval<bestWeighted) {
784      bestWeighted=lastResult.objval+mu*lastResult.objval;
785    }
786    if ((saveStrategy&4096)) strategy |=256;
787    if ((saveStrategy&4)!=0&&iteration>2) {
788      /* go to relative tolerances */
789      double weighted=10.0+fabs(lastWeighted);
790      djExit=djTolerance_*weighted;
791      djFlag=2.0*djExit;
792      drop=drop_*weighted;
793      djTol=0.01*djExit;
794    }
795    CoinMemcpyN(colsol,ncols,saveSol);
796    result=IdiSolve(nrows,ncols,rowsol ,colsol,pi,dj,
797                     cost,rowlower,rowupper,
798                     lower,upper,elemXX,row,columnStart,columnLength,lambda,
799                     maxIts,mu,drop,
800                     maxmin,offset,strategy,djTol,djExit,djFlag,randomNumberGenerator);
801    n = cleanIteration(iteration, ordStart,ordEnd,
802                       colsol,  lower,  upper,
803                       rowlower, rowupper,
804                       cost, elemXX, fixTolerance,result.objval,result.infeas);
805    if ((strategy_&16384)!=0) {
806      int * posSlack = whenUsed_+ncols;
807      int * negSlack = posSlack+nrows;
808      int * nextSlack = negSlack + nrows;
809      double * rowsol2 = reinterpret_cast<double *> (nextSlack+ncols);
810      for (i=0;i<nrows;i++)
811        rowsol[i] += rowsol2[i];
812    }
813    if ((logLevel_&1)!=0) {
814#ifndef OSI_IDIOT
815      if (!handler) {
816#endif
817        printf("Iteration %d infeasibility %g, objective %g - mu %g, its %d, %d interior\n", 
818               iteration,result.infeas,result.objval,mu,result.iteration,n);
819#ifndef OSI_IDIOT
820      } else {
821        handler->message(CLP_IDIOT_ITERATION,*messages)
822          <<iteration<<result.infeas<<result.objval<<mu<<result.iteration<<n
823          <<CoinMessageEol;
824      }
825#endif
826    }
827    if (iteration>50&&n==numberAway&&result.infeas<1.0e-4) {
828      printf("infeas small %g\n",result.infeas);
829      break; // not much happening
830    }
831    if (lightWeight_==1&&iteration>10&&result.infeas>1.0&&maxIts!=7) {
832      if (lastInfeas!=bestInfeas&&CoinMin(result.infeas,lastInfeas)>0.95*bestInfeas)
833        majorIterations_ = CoinMin(majorIterations_,iteration); // not getting feasible
834    }
835    lastInfeas = result.infeas;
836    numberAway=n;
837    keepinfeas = result.infeas;
838    lastWeighted=result.weighted;
839    iterationTotal += result.iteration;
840    if (iteration==1) {
841      if ((strategy_&1024)!=0&&mu<1.0e-10) 
842        result.infeas=firstInfeas*0.8;
843      if (majorIterations_>=50||dropEnoughFeasibility_<=0.0)
844        result.infeas *= 0.8;
845      if (result.infeas>firstInfeas*0.9
846          &&result.infeas>reasonableInfeas) {
847        iteration--;
848        if (majorIterations_<50)
849          mu*=1.0e-1;
850        else
851          mu*=0.7;
852        bestFeasible=1.0e31;
853        bestWeighted=1.0e60;
854        numberBaseTrys++;
855        if (mu<1.0e-30||(numberBaseTrys>10&&lightWeight_)) {
856          // back to all slack basis
857          lightWeight_=2;
858          break;
859        }
860 CoinMemcpyN(saveSol,ncols,colsol);
861      } else {
862        maxIts=maxIts2;
863        checkIteration=0;
864        if ((strategy_&1024)!=0) mu *= 1.0e-1;
865      }
866    } else {
867    }
868    bestInfeas=CoinMin(bestInfeas,result.infeas);
869    if (iteration) {
870      /* this code is in to force it to terminate sometime */
871      double changeMu=factor;
872      if ((saveStrategy&64)!=0) {
873        keepinfeas=0.0; /* switch off ranga's increase */
874        fakeSmall=smallInfeas;
875      } else {
876        fakeSmall=-1.0;
877      }
878      saveLambdaScale=0.0;
879      if (result.infeas>reasonableInfeas||
880          (nTry+1==maxBigIts&&result.infeas>fakeSmall)) {
881        if (result.infeas>lastResult.infeas*(1.0-dropEnoughFeasibility_)||
882            nTry+1==maxBigIts||
883            (result.infeas>lastResult.infeas*0.9
884             &&result.weighted>lastResult.weighted
885             -dropEnoughWeighted_*CoinMax(fabs(lastResult.weighted),fabs(result.weighted)))) {
886          mu*=changeMu;
887          if ((saveStrategy&32)!=0&&result.infeas<reasonableInfeas&&0) {
888            reasonableInfeas=CoinMax(smallInfeas,reasonableInfeas*sqrt(changeMu));
889            printf("reasonable infeas now %g\n",reasonableInfeas);
890          }
891          result.weighted=1.0e60;
892          nTry=0;
893          bestFeasible=1.0e31;
894          bestWeighted=1.0e60;
895          checkIteration=0;
896          lambdaIteration=0;
897#define LAMBDA
898#ifdef LAMBDA
899          if ((saveStrategy&2048)==0) {
900            memset(lambda,0,nrows*sizeof(double));
901          }
902#else
903          memset(lambda,0,nrows*sizeof(double));
904#endif
905        } else {
906          nTry++;
907        }
908      } else if (lambdaIterations_>=0) {
909        /* update lambda  */
910        double scale=1.0/mu;
911        int i,nnz=0;
912        saveLambdaScale=scale;
913         lambdaIteration++;
914         if ((saveStrategy&4)==0) drop = drop_/50.0;
915         if (lambdaIteration>4 && 
916            (((lambdaIteration%10)==0 && smallInfeas<keepinfeas) ||
917             ((lambdaIteration%5)==0 && 1.5*smallInfeas<keepinfeas))) {
918           //printf(" Increasing smallInfeas from %f to %f\n",smallInfeas,1.5*smallInfeas);
919           smallInfeas *= 1.5;
920         }
921         if ((saveStrategy&2048)==0) {
922           for (i=0;i<nrows;i++) {
923             if (lambda[i]) nnz++;
924             lambda[i]+= scale*rowsol[i];
925           }
926         } else {
927           nnz=1;
928#ifdef LAMBDA
929           for (i=0;i<nrows;i++) {
930             lambda[i]+= scale*rowsol[i];
931           }
932#else
933           for (i=0;i<nrows;i++) {
934             lambda[i] = scale*rowsol[i];
935           }
936           for (i=0;i<ncols;i++) {
937             CoinBigIndex j;
938             double value=cost[i]*maxmin;
939             for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
940               int irow=row[j];
941               value+=element[j]*lambda[irow];
942             }
943             cost[i]=value*maxmin;
944           }
945           for (i=0;i<nrows;i++) {
946             offset+=lambda[i]*rowupper[i];
947             lambda[i]=0.0;
948           }
949#ifdef DEBUG
950           printf("offset %g\n",offset);
951#endif
952           model_->setDblParam(OsiObjOffset,offset);
953#endif
954         }
955        nTry++;
956        if (!nnz) {
957          bestFeasible=1.0e32;
958          bestWeighted=1.0e60;
959          checkIteration=0;
960          result.weighted=1.0e31;
961        }
962#ifdef DEBUG
963        double trueCost=0.0;
964        for (i=0;i<ncols;i++) {
965          int j;
966          trueCost+=cost[i]*colsol[i];
967        }
968        printf("True objective %g\n",trueCost-offset);
969#endif
970      } else {
971        nTry++;
972      }
973      lastResult=result;
974      if (result.infeas<reasonableInfeas&&!belowReasonable) {
975        belowReasonable=1;
976        bestFeasible=1.0e32;
977        bestWeighted=1.0e60;
978        checkIteration=0;
979        result.weighted=1.0e31;
980      }
981    }
982    if (iteration>=majorIterations_) {
983      // If not feasible and crash then dive dive dive
984      if (mu>1.0e-12&&result.infeas>1.0&&majorIterations_<40) {
985        mu=1.0e-30;
986        majorIterations_=iteration+1;
987        stopMu=0.0;
988      } else {
989        if (logLevel>2) 
990          printf("Exiting due to number of major iterations\n");
991        break;
992      }
993    }
994  }
995  majorIterations_ = saveMajorIterations;
996#ifndef OSI_IDIOT
997  if (scaled) {
998    // Scale solution and free arrays
999    const double * rowScale = model_->rowScale();
1000    const double * columnScale = model_->columnScale();
1001    int icol,irow;
1002    for (icol=0;icol<ncols;icol++) {
1003      colsol[icol] *= columnScale[icol];
1004      saveSol[icol] *= columnScale[icol];
1005      dj[icol] /= columnScale[icol];
1006    }
1007    for (irow=0;irow<nrows;irow++) {
1008      rowsol[irow] /= rowScale[irow];
1009      pi[irow] *= rowScale[irow];
1010    }
1011    // Don't know why getting Microsoft problems
1012#if defined (_MSC_VER)
1013    delete [] ( double *) elemXX;
1014#else
1015    delete [] elemXX;
1016#endif
1017    model_->setRowScale(NULL);
1018    model_->setColumnScale(NULL);
1019    delete [] lower;
1020    delete [] upper;
1021    delete [] cost;
1022    lower = model_->columnLower();
1023    upper = model_->columnUpper();
1024    cost = model_->objective();
1025    //rowlower = model_->rowLower();
1026  }
1027#endif
1028#define TRYTHIS
1029#ifdef TRYTHIS
1030  if ((saveStrategy&2048)!=0) {
1031    double offset;
1032    model_->getDblParam(OsiObjOffset,offset);
1033    for (i=0;i<ncols;i++) {
1034      CoinBigIndex j;
1035      double djval=cost[i]*maxmin;
1036      for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
1037        int irow=row[j];
1038        djval -= element[j]*lambda[irow];
1039      }
1040      cost[i]=djval;
1041    }
1042    for (i=0;i<nrows;i++) {
1043      offset+=lambda[i]*rowupper[i];
1044    }
1045    model_->setDblParam(OsiObjOffset,offset);
1046  }
1047#endif
1048  if (saveLambdaScale) {
1049    /* back off last update */
1050    for (i=0;i<nrows;i++) {
1051      lambda[i]-= saveLambdaScale*rowsol[i];
1052    }
1053  }
1054  muAtExit_=mu;
1055  // For last iteration make as feasible as possible
1056  if (oddSlacks)
1057    strategy_ |= 16384;
1058  // not scaled
1059  n = cleanIteration(iteration, ordStart,ordEnd,
1060                     colsol,  lower,  upper,
1061                     model_->rowLower(), model_->rowUpper(),
1062                     cost, element, fixTolerance,lastResult.objval,lastResult.infeas);
1063#if 0
1064  if ((logLevel&1)==0||(strategy_&16384)!=0) {
1065    printf(
1066            "%d - mu %g, infeasibility %g, objective %g, %d interior\n",
1067            iteration,mu,lastResult.infeas,lastResult.objval,n);
1068  }
1069#endif
1070#ifndef OSI_IDIOT
1071  model_->setSumPrimalInfeasibilities(lastResult.infeas);
1072#endif
1073  // Put back more feasible solution
1074  double saveInfeas[]={0.0,0.0};
1075  for (int iSol=0;iSol<3;iSol++) {
1076    const double * solution = iSol ? colsol : saveSol;
1077    if (iSol==2&&saveInfeas[0]<saveInfeas[1]) {
1078      // put back best solution
1079      CoinMemcpyN(saveSol,ncols,colsol);
1080    }
1081    double large=0.0;
1082    int i;
1083    memset(rowsol,0,nrows*sizeof(double));
1084    for (i=0;i<ncols;i++) {
1085      CoinBigIndex j;
1086      double value=solution[i];
1087      for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
1088        int irow=row[j];
1089        rowsol[irow] += element[j]*value;
1090      }
1091    }
1092    for (i=0;i<nrows;i++) {
1093      if (rowsol[i] > rowupper[i]) {
1094        double diff=rowsol[i]-rowupper[i];
1095        if (diff>large) 
1096          large=diff;
1097      } else if (rowsol[i] < rowlower[i]) {
1098        double diff=rowlower[i]-rowsol[i];
1099        if (diff>large) 
1100          large=diff;
1101      } 
1102    }
1103    if (iSol<2)
1104      saveInfeas[iSol]=large;
1105    if (logLevel>2)
1106      printf("largest infeasibility is %g\n",large);
1107  }
1108  /* subtract out lambda */
1109  for (i=0;i<nrows;i++) {
1110    pi[i]-=lambda[i];
1111  }
1112  for (i=0;i<ncols;i++) {
1113    CoinBigIndex j;
1114    double djval=cost[i]*maxmin;
1115    for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
1116      int irow=row[j];
1117      djval -= element[j]*pi[irow];
1118    }
1119    dj[i]=djval;
1120  }
1121  if ((strategy_&1024)!=0) {
1122    double ratio = static_cast<double> (ncols)/static_cast<double> (nrows);
1123    printf("col/row ratio %g infeas ratio %g\n",ratio,lastResult.infeas/firstInfeas);
1124    if (lastResult.infeas>0.01*firstInfeas*ratio) {
1125      strategy_ &= (~1024);
1126      printf(" - layer off\n");
1127    } else {
1128      printf(" - layer on\n");
1129    }
1130  }
1131  delete [] saveSol;
1132  delete [] lambda;
1133  // save solution
1134  // duals not much use - but save anyway
1135#ifndef OSI_IDIOT
1136  CoinMemcpyN(rowsol,nrows,model_->primalRowSolution());
1137  CoinMemcpyN(colsol,ncols,model_->primalColumnSolution());
1138  CoinMemcpyN(pi,nrows,model_->dualRowSolution());
1139  CoinMemcpyN(dj,ncols,model_->dualColumnSolution());
1140#else
1141  model_->setColSolution(colsol);
1142  model_->setRowPrice(pi);
1143  delete [] cost;
1144#endif
1145  delete [] rowsol;
1146  delete [] colsol;
1147  delete [] pi;
1148  delete [] dj;
1149  delete [] rowlower;
1150  delete [] rowupper;
1151  return ;
1152}
1153#ifndef OSI_IDIOT
1154void
1155Idiot::crossOver(int mode)
1156{
1157  if (lightWeight_==2) {
1158    // total failure
1159    model_->allSlackBasis();
1160    return;
1161  }
1162  double fixTolerance=IDIOT_FIX_TOLERANCE;
1163#ifdef COIN_DEVELOP
1164  double startTime = CoinCpuTime();             
1165#endif
1166  ClpSimplex * saveModel=NULL;
1167  ClpMatrixBase * matrix = model_->clpMatrix();
1168  const int * row = matrix->getIndices();
1169  const CoinBigIndex * columnStart = matrix->getVectorStarts();
1170  const int * columnLength = matrix->getVectorLengths(); 
1171  const double * element = matrix->getElements();
1172  const double * rowupper = model_->getRowUpper();
1173  int nrows=model_->getNumRows();
1174  int ncols=model_->getNumCols();
1175  double * rowsol, * colsol;
1176  // different for Osi
1177  double * lower = model_->columnLower();
1178  double * upper = model_->columnUpper();
1179  const double * rowlower= model_->getRowLower();
1180  int * whenUsed=whenUsed_;
1181  rowsol= model_->primalRowSolution();
1182  colsol= model_->primalColumnSolution();;
1183  double * cost=model_->objective();
1184
1185  int slackEnd,ordStart,ordEnd;
1186  int slackStart = countCostedSlacks(model_);
1187
1188  int addAll = mode&7;
1189  int presolve=0;
1190
1191  double djTolerance = djTolerance_;
1192  if (djTolerance>0.0&&djTolerance<1.0)
1193    djTolerance=1.0;
1194  int iteration;
1195  int i, n=0;
1196  double ratio=1.0;
1197  double objValue=0.0;
1198  if ((strategy_&128)!=0) {
1199    fixTolerance=SMALL_IDIOT_FIX_TOLERANCE;
1200  }
1201  if ((mode&16)!=0&&addAll<3) presolve=1;
1202  double * saveUpper = NULL;
1203  double * saveLower = NULL;
1204  double * saveRowUpper = NULL;
1205  double * saveRowLower = NULL;
1206  bool allowInfeasible = ((strategy_&8192)!=0)||(majorIterations_>1000000);
1207  if (addAll<3) {
1208    saveUpper = new double [ncols];
1209    saveLower = new double [ncols];
1210    CoinMemcpyN(upper,ncols,saveUpper);
1211    CoinMemcpyN(lower,ncols,saveLower);
1212    if (allowInfeasible) {
1213      saveRowUpper = new double [nrows];
1214      saveRowLower = new double [nrows];
1215      CoinMemcpyN(rowupper,nrows,saveRowUpper);
1216      CoinMemcpyN(rowlower,nrows,saveRowLower);
1217      double averageInfeas = model_->sumPrimalInfeasibilities()/static_cast<double> (model_->numberRows());
1218      fixTolerance = CoinMax(fixTolerance,1.0e-5*averageInfeas);
1219    }
1220  }
1221  if (slackStart>=0) {
1222    slackEnd=slackStart+nrows;
1223    if (slackStart) {
1224      ordStart=0;
1225      ordEnd=slackStart;
1226    } else {
1227      ordStart=nrows;
1228      ordEnd=ncols;
1229    }
1230  } else {
1231    slackEnd=slackStart;
1232    ordStart=0;
1233    ordEnd=ncols;
1234  }
1235  /* get correct rowsol (without known slacks) */
1236  memset(rowsol,0,nrows*sizeof(double));
1237  for (i=ordStart;i<ordEnd;i++) {
1238    CoinBigIndex j;
1239    double value=colsol[i];
1240    if (value<lower[i]+fixTolerance) {
1241      value=lower[i];
1242      colsol[i]=value;
1243    }
1244    for (j=columnStart[i];j<columnStart[i]+columnLength[i];j++) {
1245      int irow=row[j];
1246      rowsol[irow]+=value*element[j];
1247    }
1248  }
1249  if (slackStart>=0) {
1250    for (i=0;i<nrows;i++) {
1251      if (ratio*rowsol[i]>rowlower[i]&&rowsol[i]>1.0e-8) {
1252        ratio=rowlower[i]/rowsol[i];
1253      }
1254    }
1255    for (i=0;i<nrows;i++) {
1256      rowsol[i]*=ratio;
1257    }
1258    for (i=ordStart;i<ordEnd;i++) {
1259      double value=colsol[i]*ratio;
1260      colsol[i]=value;
1261      objValue+=value*cost[i];
1262    }
1263    for (i=0;i<nrows;i++) {
1264      double value=rowlower[i]-rowsol[i];
1265      colsol[i+slackStart]=value;
1266      objValue+=value*cost[i+slackStart];
1267    }
1268    printf("New objective after scaling %g\n",objValue);
1269  }
1270#if 0
1271   maybe put back - but just get feasible ?
1272  // If not many fixed then just exit
1273  int numberFixed=0;
1274  for (i=ordStart;i<ordEnd;i++) {
1275    if (colsol[i]<lower[i]+fixTolerance)
1276      numberFixed++;
1277    else if (colsol[i]>upper[i]-fixTolerance)
1278      numberFixed++;
1279  }
1280  if (numberFixed<ncols/2) {
1281    addAll=3;
1282    presolve=0;
1283  }
1284#endif
1285#ifdef FEB_TRY
1286  int savePerturbation = model_->perturbation();
1287  int saveOptions = model_->specialOptions();
1288  model_->setSpecialOptions(saveOptions|8192);
1289  if (savePerturbation_==50)
1290    model_->setPerturbation(56);
1291#endif
1292  model_->createStatus();
1293  /* addAll
1294     0 - chosen,all used, all
1295     1 - chosen, all
1296     2 - all
1297     3 - do not do anything  - maybe basis
1298  */
1299  for (i=ordStart;i<ordEnd;i++) {
1300    if (addAll<2) {
1301      if (colsol[i]<lower[i]+fixTolerance) {
1302        upper[i]=lower[i];
1303        colsol[i]=lower[i];
1304      } else if (colsol[i]>upper[i]-fixTolerance) {
1305        lower[i]=upper[i];
1306        colsol[i]=upper[i];
1307      }
1308    }
1309    model_->setColumnStatus(i,ClpSimplex::superBasic);
1310  }
1311  if ((strategy_&16384)!=0) {
1312    // put in basis
1313    int * posSlack = whenUsed_+ncols;
1314    int * negSlack = posSlack+nrows;
1315    int * nextSlack = negSlack + nrows;
1316#if 1
1317    // Array for sorting out slack values
1318    double * ratio = new double [ncols];
1319    int * which = new int [ncols];
1320    for (i=0;i<nrows;i++) {
1321      if (posSlack[i]>=0||negSlack[i]>=0) {
1322        int iCol;
1323        int nPlus=0;
1324        int nMinus=0;
1325        bool possible=true;
1326        // Get sum
1327        double sum=0.0;
1328        iCol =posSlack[i];
1329        while (iCol>=0) {
1330          double value = element[columnStart[iCol]];
1331          sum += value*colsol[iCol];
1332          if (lower[iCol]) {
1333            possible=false;
1334            break;
1335          } else {
1336            nPlus++;
1337          }
1338          iCol=nextSlack[iCol];
1339        }
1340        iCol =negSlack[i];
1341        while (iCol>=0) {
1342          double value = -element[columnStart[iCol]];
1343          sum -= value*colsol[iCol];
1344          if (lower[iCol]) {
1345            possible=false;
1346            break;
1347          } else {
1348            nMinus++;
1349          }
1350          iCol=nextSlack[iCol];
1351        }
1352        //printf("%d plus, %d minus",nPlus,nMinus);
1353        //printf("\n");
1354        if ((rowsol[i]-rowlower[i]<1.0e-7||
1355             rowupper[i]-rowsol[i]<1.0e-7)&&
1356            nPlus+nMinus<2) 
1357          possible=false;
1358        if (possible) {
1359          // Amount contributed by other varaibles
1360          sum = rowsol[i]-sum;
1361          double lo = rowlower[i];
1362          if (lo>-1.0e20)
1363            lo -=sum;
1364          double up = rowupper[i];
1365          if (up<1.0e20)
1366            up -= sum;
1367          //printf("row bounds %g %g\n",lo,up);
1368          if (0) {
1369            double sum=0.0;
1370            double x=0.0;
1371            for (int k=0;k<ncols;k++) {
1372              CoinBigIndex j;
1373              double value=colsol[k];
1374              x+=value*cost[k];
1375              for (j=columnStart[k];j<columnStart[k]+columnLength[k];j++) {
1376                int irow=row[j];
1377                if (irow==i)
1378                  sum += element[j]*value;
1379              }
1380            }
1381            printf("Before sum %g <= %g <= %g cost %.18g\n",
1382                   rowlower[i],sum,rowupper[i],x);
1383          }
1384          // set all to zero
1385          iCol =posSlack[i];
1386          while (iCol>=0) {
1387            colsol[iCol]=0.0;
1388            iCol=nextSlack[iCol];
1389          }
1390          iCol =negSlack[i];
1391          while (iCol>=0) {
1392            colsol[iCol]=0.0;
1393            iCol=nextSlack[iCol];
1394          }
1395          {
1396            int iCol;
1397            iCol =posSlack[i];
1398            while (iCol>=0) {
1399              //printf("col %d el %g sol %g bounds %g %g cost %g\n",
1400              //     iCol,element[columnStart[iCol]],
1401              //     colsol[iCol],lower[iCol],upper[iCol],cost[iCol]);
1402              iCol = nextSlack[iCol];
1403            }
1404            iCol =negSlack[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          }
1412          //printf("now what?\n");
1413          int n=0;
1414          bool basic=false;
1415          if (lo>0.0) {
1416            // Add in positive
1417            iCol =posSlack[i];
1418            while (iCol>=0) {
1419              double value = element[columnStart[iCol]];
1420              ratio[n]=cost[iCol]/value;
1421              which[n++]=iCol;
1422              iCol=nextSlack[iCol];
1423            }
1424            CoinSort_2(ratio,ratio+n,which);
1425            for (int i=0;i<n;i++) {
1426              iCol=which[i];
1427              double value=element[columnStart[iCol]];
1428              if (lo>=upper[iCol]*value) {
1429                value *=upper[iCol];
1430                sum+=value;
1431                lo-=value;
1432                colsol[iCol]=upper[iCol];
1433              } else {
1434                value = lo/value;
1435                sum += lo;
1436                lo=0.0;
1437                colsol[iCol]=value;
1438                model_->setColumnStatus(iCol,ClpSimplex::basic);
1439                basic=true;
1440              }
1441              if (lo<1.0e-7)
1442                break;
1443            }
1444          } else if (up<0.0) {
1445            // Use lo so coding is more similar
1446            lo=-up;
1447            // Add in negative
1448            iCol =negSlack[i];
1449            while (iCol>=0) {
1450              double value = -element[columnStart[iCol]];
1451              ratio[n]=cost[iCol]/value;
1452              which[n++]=iCol;
1453              iCol=nextSlack[iCol];
1454            }
1455            CoinSort_2(ratio,ratio+n,which);
1456            for (int i=0;i<n;i++) {
1457              iCol=which[i];
1458              double value=-element[columnStart[iCol]];
1459              if (lo>=upper[iCol]*value) {
1460                value *=upper[iCol];
1461                sum+=value;
1462                lo-=value;
1463                colsol[iCol]=upper[iCol];
1464              } else {
1465                value = lo/value;
1466                sum += lo;
1467                lo=0.0;
1468                colsol[iCol]=value;
1469                model_->setColumnStatus(iCol,ClpSimplex::basic);
1470                basic=true;
1471              }
1472              if (lo<1.0e-7)
1473                break;
1474            }
1475          }
1476          if (0) {
1477            double sum2=0.0;
1478            double x=0.0;
1479            for (int k=0;k<ncols;k++) {
1480              CoinBigIndex j;
1481              double value=colsol[k];
1482              x+=value*cost[k];
1483              for (j=columnStart[k];j<columnStart[k]+columnLength[k];j++) {
1484                int irow=row[j];
1485                if (irow==i)
1486                  sum2 += element[j]*value;
1487              }
1488            }
1489            printf("after sum %g <= %g <= %g cost %.18g (sum = %g)\n",
1490                   rowlower[i],sum2,rowupper[i],x,sum);
1491          }
1492          rowsol[i]=sum;
1493          if (basic) {
1494            if (fabs(rowsol[i]-rowlower[i])<fabs(rowsol[i]-rowupper[i]))
1495              model_->setRowStatus(i,ClpSimplex::atLowerBound);
1496            else
1497              model_->setRowStatus(i,ClpSimplex::atUpperBound);
1498          }
1499        } else {
1500          int n=0;
1501          int iCol;
1502          iCol =posSlack[i];
1503          while (iCol>=0) {
1504            if (colsol[iCol]>lower[iCol]+1.0e-8&&
1505                colsol[iCol]<upper[iCol]-1.0e-8) {
1506              model_->setColumnStatus(iCol,ClpSimplex::basic);
1507              n++;
1508            }
1509            iCol = nextSlack[iCol];
1510          }
1511          iCol =negSlack[i];
1512          while (iCol>=0) {
1513            if (colsol[iCol]>lower[iCol]+1.0e-8&&
1514                colsol[iCol]<upper[iCol]-1.0e-8) {
1515              model_->setColumnStatus(iCol,ClpSimplex::basic);
1516              n++;
1517            }
1518            iCol = nextSlack[iCol];
1519          }
1520          if (n) {
1521            if (fabs(rowsol[i]-rowlower[i])<fabs(rowsol[i]-rowupper[i]))
1522              model_->setRowStatus(i,ClpSimplex::atLowerBound);
1523            else
1524              model_->setRowStatus(i,ClpSimplex::atUpperBound);
1525#ifdef CLP_INVESTIGATE
1526            if (n>1)
1527              printf("%d basic on row %d!\n",n,i);
1528#endif
1529          }
1530        }
1531      }
1532    }
1533    delete [] ratio;
1534    delete [] which;
1535#else
1536    for (i=0;i<nrows;i++) {
1537      int n=0;
1538      int iCol;
1539      iCol =posSlack[i];
1540      while (iCol>=0) {
1541        if (colsol[iCol]>lower[iCol]+1.0e-8&&
1542            colsol[iCol]<upper[iCol]-1.0e-8) {
1543          model_->setColumnStatus(iCol,ClpSimplex::basic);
1544          n++;
1545        }
1546        iCol = nextSlack[iCol];
1547      }
1548      iCol =negSlack[i];
1549      while (iCol>=0) {
1550        if (colsol[iCol]>lower[iCol]+1.0e-8&&
1551            colsol[iCol]<upper[iCol]-1.0e-8) {
1552          model_->setColumnStatus(iCol,ClpSimplex::basic);
1553          n++;
1554        }
1555        iCol = nextSlack[iCol];
1556      }
1557      if (n) {
1558        if (fabs(rowsol[i]-rowlower[i])<fabs(rowsol[i]-rowupper[i]))
1559          model_->setRowStatus(i,ClpSimplex::atLowerBound);
1560        else
1561          model_->setRowStatus(i,ClpSimplex::atUpperBound);
1562#ifdef CLP_INVESTIGATE
1563        if (n>1)
1564          printf("%d basic on row %d!\n",n,i);
1565#endif
1566      }
1567    }
1568#endif
1569  }
1570  double maxmin;
1571  if (model_->getObjSense()==-1.0) {
1572    maxmin=-1.0;
1573  } else {
1574    maxmin=1.0;
1575  }
1576  bool justValuesPass=majorIterations_>1000000;
1577  if (slackStart>=0) {
1578    for (i=0;i<nrows;i++) {
1579      model_->setRowStatus(i,ClpSimplex::superBasic);
1580    }
1581    for (i=slackStart;i<slackEnd;i++) {
1582      model_->setColumnStatus(i,ClpSimplex::basic);
1583    }
1584  } else {
1585    /* still try and put singletons rather than artificials in basis */
1586    int ninbas=0;
1587    for (i=0;i<nrows;i++) {
1588      model_->setRowStatus(i,ClpSimplex::basic);
1589    }
1590    for (i=0;i<ncols;i++) {
1591      if (columnLength[i]==1&&upper[i]>lower[i]+1.0e-5) {
1592        CoinBigIndex j =columnStart[i];
1593        double value=element[j];
1594        int irow=row[j];
1595        double rlo=rowlower[irow];
1596        double rup=rowupper[irow];
1597        double clo=lower[i];
1598        double cup=upper[i];
1599        double csol=colsol[i];
1600        /* adjust towards feasibility */
1601        double move=0.0;
1602        if (rowsol[irow]>rup) {
1603          move=(rup-rowsol[irow])/value;
1604          if (value>0.0) {
1605            /* reduce */
1606            if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1607          } else {
1608            /* increase */
1609            if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1610          }
1611        } else if (rowsol[irow]<rlo) {
1612          move=(rlo-rowsol[irow])/value;
1613          if (value>0.0) {
1614            /* increase */
1615            if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1616          } else {
1617            /* reduce */
1618            if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1619          }
1620        } else {
1621          /* move to improve objective */
1622          if (cost[i]*maxmin>0.0) {
1623            if (value>0.0) {
1624              move=(rlo-rowsol[irow])/value;
1625              /* reduce */
1626              if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1627            } else {
1628              move=(rup-rowsol[irow])/value;
1629              /* increase */
1630              if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1631            }
1632          } else if (cost[i]*maxmin<0.0) {
1633            if (value>0.0) {
1634              move=(rup-rowsol[irow])/value;
1635              /* increase */
1636              if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1637            } else {
1638              move=(rlo-rowsol[irow])/value;
1639              /* reduce */
1640              if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1641            }
1642          }
1643        }
1644        rowsol[irow] +=move*value;
1645        colsol[i]+=move;
1646        /* put in basis if row was artificial */
1647        if (rup-rlo<1.0e-7&&model_->getRowStatus(irow)==ClpSimplex::basic) {
1648          model_->setRowStatus(irow,ClpSimplex::superBasic);
1649          model_->setColumnStatus(i,ClpSimplex::basic);
1650          ninbas++;
1651        }
1652      }
1653    }
1654    /*printf("%d in basis\n",ninbas);*/
1655  }
1656  bool wantVector=false;
1657  if (dynamic_cast< ClpPackedMatrix*>(model_->clpMatrix())) {
1658    // See if original wanted vector
1659    ClpPackedMatrix * clpMatrixO = dynamic_cast< ClpPackedMatrix*>(model_->clpMatrix());
1660    wantVector = clpMatrixO->wantsSpecialColumnCopy();
1661  }
1662  if (addAll<3) {
1663    ClpPresolve pinfo;
1664    if (presolve) {
1665      if (allowInfeasible) {
1666        // fix up so will be feasible
1667        double * rhs = new double[nrows];
1668        memset(rhs,0,nrows*sizeof(double));
1669        model_->clpMatrix()->times(1.0,colsol,rhs);
1670        double * rowupper = model_->rowUpper();
1671        double * rowlower= model_->rowLower();
1672        saveRowUpper = CoinCopyOfArray(rowupper,nrows);
1673        saveRowLower = CoinCopyOfArray(rowlower,nrows);
1674        double sum = 0.0;
1675        for (i=0;i<nrows;i++) {
1676          if (rhs[i]>rowupper[i]) {
1677            sum += rhs[i]-rowupper[i];
1678            rowupper[i]=rhs[i];
1679          }
1680          if (rhs[i]<rowlower[i]) {
1681            sum += rowlower[i]-rhs[i];
1682            rowlower[i]=rhs[i];
1683          }
1684        }
1685        printf("sum of infeasibilities %g\n",sum);
1686        delete [] rhs;
1687      }
1688      saveModel = model_;
1689      pinfo.setPresolveActions(pinfo.presolveActions()|16384);
1690      model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
1691    }
1692    if (model_) {
1693      if (!wantVector) {
1694        //#define TWO_GOES
1695#ifndef TWO_GOES
1696        model_->primal(justValuesPass ? 2 : 1);
1697#else
1698        model_->primal(1+11);
1699#endif
1700      } else {
1701        ClpMatrixBase * matrix = model_->clpMatrix();
1702        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
1703        assert (clpMatrix);
1704        clpMatrix->makeSpecialColumnCopy();
1705        model_->primal(1);
1706        clpMatrix->releaseSpecialColumnCopy();
1707      }
1708      if (presolve) {
1709        pinfo.postsolve(true);
1710        delete model_;
1711        model_ = saveModel;
1712        saveModel=NULL;
1713      }
1714    } else {
1715      // not feasible
1716      addAll=1;
1717      presolve=0;
1718      model_ = saveModel;
1719      saveModel=NULL;
1720      if (justValuesPass)
1721        model_->primal(2);
1722    }
1723    if (allowInfeasible) {
1724      CoinMemcpyN(saveRowUpper,nrows,model_->rowUpper());
1725      CoinMemcpyN(saveRowLower,nrows,model_->rowLower());
1726      delete [] saveRowUpper;
1727      delete [] saveRowLower;
1728      saveRowUpper = NULL;
1729      saveRowLower = NULL;
1730    }
1731    if (addAll<2) {
1732      n=0;
1733      if (!addAll ) {
1734        /* could do scans to get a good number */
1735        iteration=1;
1736        for (i=ordStart;i<ordEnd;i++) {
1737          if (whenUsed[i]>=iteration) {
1738            if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
1739              n++;
1740              upper[i]=saveUpper[i];
1741              lower[i]=saveLower[i];
1742            }
1743          }
1744        }
1745      } else {
1746        for (i=ordStart;i<ordEnd;i++) {
1747          if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
1748            n++;
1749            upper[i]=saveUpper[i];
1750            lower[i]=saveLower[i];
1751          }
1752        }
1753        delete [] saveUpper;
1754        delete [] saveLower;
1755        saveUpper=NULL;
1756        saveLower=NULL;
1757      }
1758#ifdef COIN_DEVELOP
1759      printf("Time so far %g, %d now added from previous iterations\n",
1760             CoinCpuTime()-startTime,n);
1761#endif
1762      if (justValuesPass)
1763        return;
1764      if (addAll)
1765        presolve=0;
1766      if (presolve) {
1767        saveModel = model_;
1768        model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
1769      } else {
1770        presolve=0;
1771      }
1772      if (!wantVector) {
1773        model_->primal(1);
1774      } else {
1775        ClpMatrixBase * matrix = model_->clpMatrix();
1776        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
1777        assert (clpMatrix);
1778        clpMatrix->makeSpecialColumnCopy();
1779        model_->primal(1);
1780        clpMatrix->releaseSpecialColumnCopy();
1781      }
1782      if (presolve) {
1783        pinfo.postsolve(true);
1784        delete model_;
1785        model_ = saveModel;
1786        saveModel=NULL;
1787      }
1788      if (!addAll) {
1789        n=0;
1790        for (i=ordStart;i<ordEnd;i++) {
1791          if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
1792            n++;
1793            upper[i]=saveUpper[i];
1794            lower[i]=saveLower[i];
1795          }
1796        }
1797        delete [] saveUpper;
1798        delete [] saveLower;
1799        saveUpper=NULL;
1800        saveLower=NULL;
1801#ifdef COIN_DEVELOP
1802        printf("Time so far %g, %d now added from previous iterations\n",
1803               CoinCpuTime()-startTime,n);
1804#endif
1805      }
1806      if (presolve) {
1807        saveModel = model_;
1808        model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
1809      } else {
1810        presolve=0;
1811      }
1812      if (!wantVector) {
1813        model_->primal(1);
1814      } else {
1815        ClpMatrixBase * matrix = model_->clpMatrix();
1816        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
1817        assert (clpMatrix);
1818        clpMatrix->makeSpecialColumnCopy();
1819        model_->primal(1);
1820        clpMatrix->releaseSpecialColumnCopy();
1821      }
1822      if (presolve) {
1823        pinfo.postsolve(true);
1824        delete model_;
1825        model_ = saveModel;
1826        saveModel=NULL;
1827      }
1828    }
1829#ifdef COIN_DEVELOP
1830    printf("Total time in crossover %g\n", CoinCpuTime()-startTime);
1831#endif
1832    delete [] saveUpper;
1833    delete [] saveLower;
1834  }
1835#ifdef FEB_TRY
1836  model_->setSpecialOptions(saveOptions);
1837  model_->setPerturbation(savePerturbation);
1838#endif
1839  return ;
1840}
1841#endif
1842/*****************************************************************************/
1843
1844// Default contructor
1845Idiot::Idiot()
1846{
1847  model_ = NULL;
1848  maxBigIts_ = 3;
1849  maxIts_ = 5;
1850  logLevel_ = 1; 
1851  logFreq_ = 100;
1852  maxIts2_ = 100;
1853  djTolerance_ = 1e-1;
1854  mu_ = 1e-4;
1855  drop_ = 5.0;
1856  exitDrop_=-1.0e20;
1857  muFactor_ = 0.3333;
1858  stopMu_ = 1e-12;
1859  smallInfeas_ = 1e-1;
1860  reasonableInfeas_ = 1e2;
1861  muAtExit_ =1.0e31;
1862  strategy_ =8;
1863  lambdaIterations_ =0;
1864  checkFrequency_ =100;
1865  whenUsed_ = NULL;
1866  majorIterations_ =30;
1867  exitFeasibility_ =-1.0;
1868  dropEnoughFeasibility_ =0.02;
1869  dropEnoughWeighted_ =0.01;
1870  // adjust
1871  double nrows=10000.0;
1872  int baseIts =static_cast<int> (sqrt(static_cast<double>(nrows)));
1873  baseIts =baseIts/10;
1874  baseIts *= 10;
1875  maxIts2_ =200+baseIts+5;
1876  maxIts2_=100;
1877  reasonableInfeas_ =static_cast<double> (nrows)*0.05;
1878  lightWeight_=0;
1879}
1880// Constructor from model
1881Idiot::Idiot(OsiSolverInterface &model)
1882{
1883  model_ = & model;
1884  maxBigIts_ = 3;
1885  maxIts_ = 5;
1886  logLevel_ = 1; 
1887  logFreq_ = 100;
1888  maxIts2_ = 100;
1889  djTolerance_ = 1e-1;
1890  mu_ = 1e-4;
1891  drop_ = 5.0;
1892  exitDrop_=-1.0e20;
1893  muFactor_ = 0.3333;
1894  stopMu_ = 1e-12;
1895  smallInfeas_ = 1e-1;
1896  reasonableInfeas_ = 1e2;
1897  muAtExit_ =1.0e31;
1898  strategy_ =8;
1899  lambdaIterations_ =0;
1900  checkFrequency_ =100;
1901  whenUsed_ = NULL;
1902  majorIterations_ =30;
1903  exitFeasibility_ =-1.0;
1904  dropEnoughFeasibility_ =0.02;
1905  dropEnoughWeighted_ =0.01;
1906  // adjust
1907  double nrows;
1908  if (model_)
1909    nrows=model_->getNumRows();
1910  else
1911    nrows=10000.0;
1912  int baseIts =static_cast<int> (sqrt(static_cast<double>(nrows)));
1913  baseIts =baseIts/10;
1914  baseIts *= 10;
1915  maxIts2_ =200+baseIts+5;
1916  maxIts2_=100;
1917  reasonableInfeas_ =static_cast<double> (nrows)*0.05;
1918  lightWeight_=0;
1919}
1920// Copy constructor.
1921Idiot::Idiot(const Idiot &rhs)
1922{
1923  model_ = rhs.model_;
1924  if (model_&&rhs.whenUsed_) {
1925    int numberColumns = model_->getNumCols();
1926    whenUsed_ = new int [numberColumns];
1927    CoinMemcpyN(rhs.whenUsed_,numberColumns,whenUsed_);
1928  } else {
1929    whenUsed_=NULL;
1930  }
1931  djTolerance_ = rhs.djTolerance_;
1932  mu_ = rhs.mu_;
1933  drop_ = rhs.drop_;
1934  muFactor_ = rhs.muFactor_;
1935  stopMu_ = rhs.stopMu_;
1936  smallInfeas_ = rhs.smallInfeas_;
1937  reasonableInfeas_ = rhs.reasonableInfeas_;
1938  exitDrop_ = rhs.exitDrop_;
1939  muAtExit_ = rhs.muAtExit_;
1940  exitFeasibility_ = rhs.exitFeasibility_;
1941  dropEnoughFeasibility_ = rhs.dropEnoughFeasibility_;
1942  dropEnoughWeighted_ = rhs.dropEnoughWeighted_;
1943  maxBigIts_ = rhs.maxBigIts_;
1944  maxIts_ = rhs.maxIts_;
1945  majorIterations_ = rhs.majorIterations_;
1946  logLevel_ = rhs.logLevel_;
1947  logFreq_ = rhs.logFreq_;
1948  checkFrequency_ = rhs.checkFrequency_;
1949  lambdaIterations_ = rhs.lambdaIterations_;
1950  maxIts2_ = rhs.maxIts2_;
1951  strategy_ = rhs.strategy_;
1952  lightWeight_=rhs.lightWeight_;
1953}
1954// Assignment operator. This copies the data
1955Idiot & 
1956Idiot::operator=(const Idiot & rhs)
1957{
1958  if (this != &rhs) {
1959    delete [] whenUsed_;
1960    model_ = rhs.model_;
1961    if (model_&&rhs.whenUsed_) {
1962      int numberColumns = model_->getNumCols();
1963      whenUsed_ = new int [numberColumns];
1964      CoinMemcpyN(rhs.whenUsed_,numberColumns,whenUsed_);
1965    } else {
1966      whenUsed_=NULL;
1967    }
1968    djTolerance_ = rhs.djTolerance_;
1969    mu_ = rhs.mu_;
1970    drop_ = rhs.drop_;
1971    muFactor_ = rhs.muFactor_;
1972    stopMu_ = rhs.stopMu_;
1973    smallInfeas_ = rhs.smallInfeas_;
1974    reasonableInfeas_ = rhs.reasonableInfeas_;
1975    exitDrop_ = rhs.exitDrop_;
1976    muAtExit_ = rhs.muAtExit_;
1977    exitFeasibility_ = rhs.exitFeasibility_;
1978    dropEnoughFeasibility_ = rhs.dropEnoughFeasibility_;
1979    dropEnoughWeighted_ = rhs.dropEnoughWeighted_;
1980    maxBigIts_ = rhs.maxBigIts_;
1981    maxIts_ = rhs.maxIts_;
1982    majorIterations_ = rhs.majorIterations_;
1983    logLevel_ = rhs.logLevel_;
1984    logFreq_ = rhs.logFreq_;
1985    checkFrequency_ = rhs.checkFrequency_;
1986    lambdaIterations_ = rhs.lambdaIterations_;
1987    maxIts2_ = rhs.maxIts2_;
1988    strategy_ = rhs.strategy_;
1989    lightWeight_=rhs.lightWeight_;
1990  }
1991  return *this;
1992}
1993Idiot::~Idiot()
1994{
1995  delete [] whenUsed_;
1996}
Note: See TracBrowser for help on using the repository browser.