source: trunk/Clp/src/Idiot.cpp @ 1506

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

changes for idiot code

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