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

Last change on this file since 1480 was 1480, checked in by ladanyi, 10 years ago

exposed the idiot code through the C interface

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 53.0 KB
Line 
1/* $Id: Idiot.cpp 1480 2009-12-13 02:38:55Z ladanyi $ */
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#if 1
1321    // Array for sorting out slack values
1322    double * ratio = new double [ncols];
1323    int * which = new int [ncols];
1324    for (i=0;i<nrows;i++) {
1325      if (posSlack[i]>=0||negSlack[i]>=0) {
1326        int iCol;
1327        int nPlus=0;
1328        int nMinus=0;
1329        bool possible=true;
1330        // Get sum
1331        double sum=0.0;
1332        iCol =posSlack[i];
1333        while (iCol>=0) {
1334          double value = element[columnStart[iCol]];
1335          sum += value*colsol[iCol];
1336          if (lower[iCol]) {
1337            possible=false;
1338            break;
1339          } else {
1340            nPlus++;
1341          }
1342          iCol=nextSlack[iCol];
1343        }
1344        iCol =negSlack[i];
1345        while (iCol>=0) {
1346          double value = -element[columnStart[iCol]];
1347          sum -= value*colsol[iCol];
1348          if (lower[iCol]) {
1349            possible=false;
1350            break;
1351          } else {
1352            nMinus++;
1353          }
1354          iCol=nextSlack[iCol];
1355        }
1356        //printf("%d plus, %d minus",nPlus,nMinus);
1357        //printf("\n");
1358        if ((rowsol[i]-rowlower[i]<1.0e-7||
1359             rowupper[i]-rowsol[i]<1.0e-7)&&
1360            nPlus+nMinus<2) 
1361          possible=false;
1362        if (possible) {
1363          // Amount contributed by other varaibles
1364          sum = rowsol[i]-sum;
1365          double lo = rowlower[i];
1366          if (lo>-1.0e20)
1367            lo -=sum;
1368          double up = rowupper[i];
1369          if (up<1.0e20)
1370            up -= sum;
1371          //printf("row bounds %g %g\n",lo,up);
1372          if (0) {
1373            double sum=0.0;
1374            double x=0.0;
1375            for (int k=0;k<ncols;k++) {
1376              CoinBigIndex j;
1377              double value=colsol[k];
1378              x+=value*cost[k];
1379              for (j=columnStart[k];j<columnStart[k]+columnLength[k];j++) {
1380                int irow=row[j];
1381                if (irow==i)
1382                  sum += element[j]*value;
1383              }
1384            }
1385            printf("Before sum %g <= %g <= %g cost %.18g\n",
1386                   rowlower[i],sum,rowupper[i],x);
1387          }
1388          // set all to zero
1389          iCol =posSlack[i];
1390          while (iCol>=0) {
1391            colsol[iCol]=0.0;
1392            iCol=nextSlack[iCol];
1393          }
1394          iCol =negSlack[i];
1395          while (iCol>=0) {
1396            colsol[iCol]=0.0;
1397            iCol=nextSlack[iCol];
1398          }
1399          {
1400            int iCol;
1401            iCol =posSlack[i];
1402            while (iCol>=0) {
1403              //printf("col %d el %g sol %g bounds %g %g cost %g\n",
1404              //     iCol,element[columnStart[iCol]],
1405              //     colsol[iCol],lower[iCol],upper[iCol],cost[iCol]);
1406              iCol = nextSlack[iCol];
1407            }
1408            iCol =negSlack[i];
1409            while (iCol>=0) {
1410              //printf("col %d el %g sol %g bounds %g %g cost %g\n",
1411              //     iCol,element[columnStart[iCol]],
1412              //     colsol[iCol],lower[iCol],upper[iCol],cost[iCol]);
1413              iCol = nextSlack[iCol];
1414            }
1415          }
1416          //printf("now what?\n");
1417          int n=0;
1418          bool basic=false;
1419          if (lo>0.0) {
1420            // Add in positive
1421            iCol =posSlack[i];
1422            while (iCol>=0) {
1423              double value = element[columnStart[iCol]];
1424              ratio[n]=cost[iCol]/value;
1425              which[n++]=iCol;
1426              iCol=nextSlack[iCol];
1427            }
1428            CoinSort_2(ratio,ratio+n,which);
1429            for (int i=0;i<n;i++) {
1430              iCol=which[i];
1431              double value=element[columnStart[iCol]];
1432              if (lo>=upper[iCol]*value) {
1433                value *=upper[iCol];
1434                sum+=value;
1435                lo-=value;
1436                colsol[iCol]=upper[iCol];
1437              } else {
1438                value = lo/value;
1439                sum += lo;
1440                lo=0.0;
1441                colsol[iCol]=value;
1442                model_->setColumnStatus(iCol,ClpSimplex::basic);
1443                basic=true;
1444              }
1445              if (lo<1.0e-7)
1446                break;
1447            }
1448          } else if (up<0.0) {
1449            // Use lo so coding is more similar
1450            lo=-up;
1451            // Add in negative
1452            iCol =negSlack[i];
1453            while (iCol>=0) {
1454              double value = -element[columnStart[iCol]];
1455              ratio[n]=cost[iCol]/value;
1456              which[n++]=iCol;
1457              iCol=nextSlack[iCol];
1458            }
1459            CoinSort_2(ratio,ratio+n,which);
1460            for (int i=0;i<n;i++) {
1461              iCol=which[i];
1462              double value=-element[columnStart[iCol]];
1463              if (lo>=upper[iCol]*value) {
1464                value *=upper[iCol];
1465                sum+=value;
1466                lo-=value;
1467                colsol[iCol]=upper[iCol];
1468              } else {
1469                value = lo/value;
1470                sum += lo;
1471                lo=0.0;
1472                colsol[iCol]=value;
1473                model_->setColumnStatus(iCol,ClpSimplex::basic);
1474                basic=true;
1475              }
1476              if (lo<1.0e-7)
1477                break;
1478            }
1479          }
1480          if (0) {
1481            double sum2=0.0;
1482            double x=0.0;
1483            for (int k=0;k<ncols;k++) {
1484              CoinBigIndex j;
1485              double value=colsol[k];
1486              x+=value*cost[k];
1487              for (j=columnStart[k];j<columnStart[k]+columnLength[k];j++) {
1488                int irow=row[j];
1489                if (irow==i)
1490                  sum2 += element[j]*value;
1491              }
1492            }
1493            printf("after sum %g <= %g <= %g cost %.18g (sum = %g)\n",
1494                   rowlower[i],sum2,rowupper[i],x,sum);
1495          }
1496          rowsol[i]=sum;
1497          if (basic) {
1498            if (fabs(rowsol[i]-rowlower[i])<fabs(rowsol[i]-rowupper[i]))
1499              model_->setRowStatus(i,ClpSimplex::atLowerBound);
1500            else
1501              model_->setRowStatus(i,ClpSimplex::atUpperBound);
1502          }
1503        } else {
1504          int n=0;
1505          int iCol;
1506          iCol =posSlack[i];
1507          while (iCol>=0) {
1508            if (colsol[iCol]>lower[iCol]+1.0e-8&&
1509                colsol[iCol]<upper[iCol]-1.0e-8) {
1510              model_->setColumnStatus(iCol,ClpSimplex::basic);
1511              n++;
1512            }
1513            iCol = nextSlack[iCol];
1514          }
1515          iCol =negSlack[i];
1516          while (iCol>=0) {
1517            if (colsol[iCol]>lower[iCol]+1.0e-8&&
1518                colsol[iCol]<upper[iCol]-1.0e-8) {
1519              model_->setColumnStatus(iCol,ClpSimplex::basic);
1520              n++;
1521            }
1522            iCol = nextSlack[iCol];
1523          }
1524          if (n) {
1525            if (fabs(rowsol[i]-rowlower[i])<fabs(rowsol[i]-rowupper[i]))
1526              model_->setRowStatus(i,ClpSimplex::atLowerBound);
1527            else
1528              model_->setRowStatus(i,ClpSimplex::atUpperBound);
1529#ifdef CLP_INVESTIGATE
1530            if (n>1)
1531              printf("%d basic on row %d!\n",n,i);
1532#endif
1533          }
1534        }
1535      }
1536    }
1537    delete [] ratio;
1538    delete [] which;
1539#else
1540    for (i=0;i<nrows;i++) {
1541      int n=0;
1542      int iCol;
1543      iCol =posSlack[i];
1544      while (iCol>=0) {
1545        if (colsol[iCol]>lower[iCol]+1.0e-8&&
1546            colsol[iCol]<upper[iCol]-1.0e-8) {
1547          model_->setColumnStatus(iCol,ClpSimplex::basic);
1548          n++;
1549        }
1550        iCol = nextSlack[iCol];
1551      }
1552      iCol =negSlack[i];
1553      while (iCol>=0) {
1554        if (colsol[iCol]>lower[iCol]+1.0e-8&&
1555            colsol[iCol]<upper[iCol]-1.0e-8) {
1556          model_->setColumnStatus(iCol,ClpSimplex::basic);
1557          n++;
1558        }
1559        iCol = nextSlack[iCol];
1560      }
1561      if (n) {
1562        if (fabs(rowsol[i]-rowlower[i])<fabs(rowsol[i]-rowupper[i]))
1563          model_->setRowStatus(i,ClpSimplex::atLowerBound);
1564        else
1565          model_->setRowStatus(i,ClpSimplex::atUpperBound);
1566#ifdef CLP_INVESTIGATE
1567        if (n>1)
1568          printf("%d basic on row %d!\n",n,i);
1569#endif
1570      }
1571    }
1572#endif
1573  }
1574  double maxmin;
1575  if (model_->getObjSense()==-1.0) {
1576    maxmin=-1.0;
1577  } else {
1578    maxmin=1.0;
1579  }
1580  bool justValuesPass=majorIterations_>1000000;
1581  if (slackStart>=0) {
1582    for (i=0;i<nrows;i++) {
1583      model_->setRowStatus(i,ClpSimplex::superBasic);
1584    }
1585    for (i=slackStart;i<slackEnd;i++) {
1586      model_->setColumnStatus(i,ClpSimplex::basic);
1587    }
1588  } else {
1589    /* still try and put singletons rather than artificials in basis */
1590    int ninbas=0;
1591    for (i=0;i<nrows;i++) {
1592      model_->setRowStatus(i,ClpSimplex::basic);
1593    }
1594    for (i=0;i<ncols;i++) {
1595      if (columnLength[i]==1&&upper[i]>lower[i]+1.0e-5) {
1596        CoinBigIndex j =columnStart[i];
1597        double value=element[j];
1598        int irow=row[j];
1599        double rlo=rowlower[irow];
1600        double rup=rowupper[irow];
1601        double clo=lower[i];
1602        double cup=upper[i];
1603        double csol=colsol[i];
1604        /* adjust towards feasibility */
1605        double move=0.0;
1606        if (rowsol[irow]>rup) {
1607          move=(rup-rowsol[irow])/value;
1608          if (value>0.0) {
1609            /* reduce */
1610            if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1611          } else {
1612            /* increase */
1613            if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1614          }
1615        } else if (rowsol[irow]<rlo) {
1616          move=(rlo-rowsol[irow])/value;
1617          if (value>0.0) {
1618            /* increase */
1619            if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1620          } else {
1621            /* reduce */
1622            if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1623          }
1624        } else {
1625          /* move to improve objective */
1626          if (cost[i]*maxmin>0.0) {
1627            if (value>0.0) {
1628              move=(rlo-rowsol[irow])/value;
1629              /* reduce */
1630              if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1631            } else {
1632              move=(rup-rowsol[irow])/value;
1633              /* increase */
1634              if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1635            }
1636          } else if (cost[i]*maxmin<0.0) {
1637            if (value>0.0) {
1638              move=(rup-rowsol[irow])/value;
1639              /* increase */
1640              if (csol+move>cup) move=CoinMax(0.0,cup-csol);
1641            } else {
1642              move=(rlo-rowsol[irow])/value;
1643              /* reduce */
1644              if (csol+move<clo) move=CoinMin(0.0,clo-csol);
1645            }
1646          }
1647        }
1648        rowsol[irow] +=move*value;
1649        colsol[i]+=move;
1650        /* put in basis if row was artificial */
1651        if (rup-rlo<1.0e-7&&model_->getRowStatus(irow)==ClpSimplex::basic) {
1652          model_->setRowStatus(irow,ClpSimplex::superBasic);
1653          model_->setColumnStatus(i,ClpSimplex::basic);
1654          ninbas++;
1655        }
1656      }
1657    }
1658    /*printf("%d in basis\n",ninbas);*/
1659  }
1660  bool wantVector=false;
1661  if (dynamic_cast< ClpPackedMatrix*>(model_->clpMatrix())) {
1662    // See if original wanted vector
1663    ClpPackedMatrix * clpMatrixO = dynamic_cast< ClpPackedMatrix*>(model_->clpMatrix());
1664    wantVector = clpMatrixO->wantsSpecialColumnCopy();
1665  }
1666  if (addAll<3) {
1667    ClpPresolve pinfo;
1668    if (presolve) {
1669      if (allowInfeasible) {
1670        // fix up so will be feasible
1671        double * rhs = new double[nrows];
1672        memset(rhs,0,nrows*sizeof(double));
1673        model_->clpMatrix()->times(1.0,colsol,rhs);
1674        double * rowupper = model_->rowUpper();
1675        double * rowlower= model_->rowLower();
1676        saveRowUpper = CoinCopyOfArray(rowupper,nrows);
1677        saveRowLower = CoinCopyOfArray(rowlower,nrows);
1678        double sum = 0.0;
1679        for (i=0;i<nrows;i++) {
1680          if (rhs[i]>rowupper[i]) {
1681            sum += rhs[i]-rowupper[i];
1682            rowupper[i]=rhs[i];
1683          }
1684          if (rhs[i]<rowlower[i]) {
1685            sum += rowlower[i]-rhs[i];
1686            rowlower[i]=rhs[i];
1687          }
1688        }
1689        printf("sum of infeasibilities %g\n",sum);
1690        delete [] rhs;
1691      }
1692      saveModel = model_;
1693      pinfo.setPresolveActions(pinfo.presolveActions()|16384);
1694      model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
1695    }
1696    if (model_) {
1697      if (!wantVector) {
1698        //#define TWO_GOES
1699#ifndef TWO_GOES
1700        model_->primal(justValuesPass ? 2 : 1);
1701#else
1702        model_->primal(1+11);
1703#endif
1704      } else {
1705        ClpMatrixBase * matrix = model_->clpMatrix();
1706        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
1707        assert (clpMatrix);
1708        clpMatrix->makeSpecialColumnCopy();
1709        model_->primal(1);
1710        clpMatrix->releaseSpecialColumnCopy();
1711      }
1712      if (presolve) {
1713        pinfo.postsolve(true);
1714        delete model_;
1715        model_ = saveModel;
1716        saveModel=NULL;
1717      }
1718    } else {
1719      // not feasible
1720      addAll=1;
1721      presolve=0;
1722      model_ = saveModel;
1723      saveModel=NULL;
1724      if (justValuesPass)
1725        model_->primal(2);
1726    }
1727    if (allowInfeasible) {
1728      CoinMemcpyN(saveRowUpper,nrows,model_->rowUpper());
1729      CoinMemcpyN(saveRowLower,nrows,model_->rowLower());
1730      delete [] saveRowUpper;
1731      delete [] saveRowLower;
1732      saveRowUpper = NULL;
1733      saveRowLower = NULL;
1734    }
1735    if (addAll<2) {
1736      n=0;
1737      if (!addAll ) {
1738        /* could do scans to get a good number */
1739        iteration=1;
1740        for (i=ordStart;i<ordEnd;i++) {
1741          if (whenUsed[i]>=iteration) {
1742            if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
1743              n++;
1744              upper[i]=saveUpper[i];
1745              lower[i]=saveLower[i];
1746            }
1747          }
1748        }
1749      } else {
1750        for (i=ordStart;i<ordEnd;i++) {
1751          if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
1752            n++;
1753            upper[i]=saveUpper[i];
1754            lower[i]=saveLower[i];
1755          }
1756        }
1757        delete [] saveUpper;
1758        delete [] saveLower;
1759        saveUpper=NULL;
1760        saveLower=NULL;
1761      }
1762#ifdef COIN_DEVELOP
1763      printf("Time so far %g, %d now added from previous iterations\n",
1764             CoinCpuTime()-startTime,n);
1765#endif
1766      if (justValuesPass)
1767        return;
1768      if (addAll)
1769        presolve=0;
1770      if (presolve) {
1771        saveModel = model_;
1772        model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
1773      } else {
1774        presolve=0;
1775      }
1776      if (!wantVector) {
1777        model_->primal(1);
1778      } else {
1779        ClpMatrixBase * matrix = model_->clpMatrix();
1780        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
1781        assert (clpMatrix);
1782        clpMatrix->makeSpecialColumnCopy();
1783        model_->primal(1);
1784        clpMatrix->releaseSpecialColumnCopy();
1785      }
1786      if (presolve) {
1787        pinfo.postsolve(true);
1788        delete model_;
1789        model_ = saveModel;
1790        saveModel=NULL;
1791      }
1792      if (!addAll) {
1793        n=0;
1794        for (i=ordStart;i<ordEnd;i++) {
1795          if (upper[i]-lower[i]<1.0e-5&&saveUpper[i]-saveLower[i]>1.0e-5) {
1796            n++;
1797            upper[i]=saveUpper[i];
1798            lower[i]=saveLower[i];
1799          }
1800        }
1801        delete [] saveUpper;
1802        delete [] saveLower;
1803        saveUpper=NULL;
1804        saveLower=NULL;
1805#ifdef COIN_DEVELOP
1806        printf("Time so far %g, %d now added from previous iterations\n",
1807               CoinCpuTime()-startTime,n);
1808#endif
1809      }
1810      if (presolve) {
1811        saveModel = model_;
1812        model_ = pinfo.presolvedModel(*model_,1.0e-8,false,5);
1813      } else {
1814        presolve=0;
1815      }
1816      if (!wantVector) {
1817        model_->primal(1);
1818      } else {
1819        ClpMatrixBase * matrix = model_->clpMatrix();
1820        ClpPackedMatrix * clpMatrix = dynamic_cast< ClpPackedMatrix*>(matrix);
1821        assert (clpMatrix);
1822        clpMatrix->makeSpecialColumnCopy();
1823        model_->primal(1);
1824        clpMatrix->releaseSpecialColumnCopy();
1825      }
1826      if (presolve) {
1827        pinfo.postsolve(true);
1828        delete model_;
1829        model_ = saveModel;
1830        saveModel=NULL;
1831      }
1832    }
1833#ifdef COIN_DEVELOP
1834    printf("Total time in crossover %g\n", CoinCpuTime()-startTime);
1835#endif
1836    delete [] saveUpper;
1837    delete [] saveLower;
1838  }
1839#ifdef FEB_TRY
1840  model_->setSpecialOptions(saveOptions);
1841  model_->setPerturbation(savePerturbation);
1842#endif
1843  return ;
1844}
1845#endif
1846/*****************************************************************************/
1847
1848// Default contructor
1849Idiot::Idiot()
1850{
1851  model_ = NULL;
1852  maxBigIts_ = 3;
1853  maxIts_ = 5;
1854  logLevel_ = 1; 
1855  logFreq_ = 100;
1856  maxIts2_ = 100;
1857  djTolerance_ = 1e-1;
1858  mu_ = 1e-4;
1859  drop_ = 5.0;
1860  exitDrop_=-1.0e20;
1861  muFactor_ = 0.3333;
1862  stopMu_ = 1e-12;
1863  smallInfeas_ = 1e-1;
1864  reasonableInfeas_ = 1e2;
1865  muAtExit_ =1.0e31;
1866  strategy_ =8;
1867  lambdaIterations_ =0;
1868  checkFrequency_ =100;
1869  whenUsed_ = NULL;
1870  majorIterations_ =30;
1871  exitFeasibility_ =-1.0;
1872  dropEnoughFeasibility_ =0.02;
1873  dropEnoughWeighted_ =0.01;
1874  // adjust
1875  double nrows=10000.0;
1876  int baseIts =static_cast<int> (sqrt(static_cast<double>(nrows)));
1877  baseIts =baseIts/10;
1878  baseIts *= 10;
1879  maxIts2_ =200+baseIts+5;
1880  maxIts2_=100;
1881  reasonableInfeas_ =static_cast<double> (nrows)*0.05;
1882  lightWeight_=0;
1883}
1884// Constructor from model
1885Idiot::Idiot(OsiSolverInterface &model)
1886{
1887  model_ = & model;
1888  maxBigIts_ = 3;
1889  maxIts_ = 5;
1890  logLevel_ = 1; 
1891  logFreq_ = 100;
1892  maxIts2_ = 100;
1893  djTolerance_ = 1e-1;
1894  mu_ = 1e-4;
1895  drop_ = 5.0;
1896  exitDrop_=-1.0e20;
1897  muFactor_ = 0.3333;
1898  stopMu_ = 1e-12;
1899  smallInfeas_ = 1e-1;
1900  reasonableInfeas_ = 1e2;
1901  muAtExit_ =1.0e31;
1902  strategy_ =8;
1903  lambdaIterations_ =0;
1904  checkFrequency_ =100;
1905  whenUsed_ = NULL;
1906  majorIterations_ =30;
1907  exitFeasibility_ =-1.0;
1908  dropEnoughFeasibility_ =0.02;
1909  dropEnoughWeighted_ =0.01;
1910  // adjust
1911  double nrows;
1912  if (model_)
1913    nrows=model_->getNumRows();
1914  else
1915    nrows=10000.0;
1916  int baseIts =static_cast<int> (sqrt(static_cast<double>(nrows)));
1917  baseIts =baseIts/10;
1918  baseIts *= 10;
1919  maxIts2_ =200+baseIts+5;
1920  maxIts2_=100;
1921  reasonableInfeas_ =static_cast<double> (nrows)*0.05;
1922  lightWeight_=0;
1923}
1924// Copy constructor.
1925Idiot::Idiot(const Idiot &rhs)
1926{
1927  model_ = rhs.model_;
1928  if (model_&&rhs.whenUsed_) {
1929    int numberColumns = model_->getNumCols();
1930    whenUsed_ = new int [numberColumns];
1931    CoinMemcpyN(rhs.whenUsed_,numberColumns,whenUsed_);
1932  } else {
1933    whenUsed_=NULL;
1934  }
1935  djTolerance_ = rhs.djTolerance_;
1936  mu_ = rhs.mu_;
1937  drop_ = rhs.drop_;
1938  muFactor_ = rhs.muFactor_;
1939  stopMu_ = rhs.stopMu_;
1940  smallInfeas_ = rhs.smallInfeas_;
1941  reasonableInfeas_ = rhs.reasonableInfeas_;
1942  exitDrop_ = rhs.exitDrop_;
1943  muAtExit_ = rhs.muAtExit_;
1944  exitFeasibility_ = rhs.exitFeasibility_;
1945  dropEnoughFeasibility_ = rhs.dropEnoughFeasibility_;
1946  dropEnoughWeighted_ = rhs.dropEnoughWeighted_;
1947  maxBigIts_ = rhs.maxBigIts_;
1948  maxIts_ = rhs.maxIts_;
1949  majorIterations_ = rhs.majorIterations_;
1950  logLevel_ = rhs.logLevel_;
1951  logFreq_ = rhs.logFreq_;
1952  checkFrequency_ = rhs.checkFrequency_;
1953  lambdaIterations_ = rhs.lambdaIterations_;
1954  maxIts2_ = rhs.maxIts2_;
1955  strategy_ = rhs.strategy_;
1956  lightWeight_=rhs.lightWeight_;
1957}
1958// Assignment operator. This copies the data
1959Idiot & 
1960Idiot::operator=(const Idiot & rhs)
1961{
1962  if (this != &rhs) {
1963    delete [] whenUsed_;
1964    model_ = rhs.model_;
1965    if (model_&&rhs.whenUsed_) {
1966      int numberColumns = model_->getNumCols();
1967      whenUsed_ = new int [numberColumns];
1968      CoinMemcpyN(rhs.whenUsed_,numberColumns,whenUsed_);
1969    } else {
1970      whenUsed_=NULL;
1971    }
1972    djTolerance_ = rhs.djTolerance_;
1973    mu_ = rhs.mu_;
1974    drop_ = rhs.drop_;
1975    muFactor_ = rhs.muFactor_;
1976    stopMu_ = rhs.stopMu_;
1977    smallInfeas_ = rhs.smallInfeas_;
1978    reasonableInfeas_ = rhs.reasonableInfeas_;
1979    exitDrop_ = rhs.exitDrop_;
1980    muAtExit_ = rhs.muAtExit_;
1981    exitFeasibility_ = rhs.exitFeasibility_;
1982    dropEnoughFeasibility_ = rhs.dropEnoughFeasibility_;
1983    dropEnoughWeighted_ = rhs.dropEnoughWeighted_;
1984    maxBigIts_ = rhs.maxBigIts_;
1985    maxIts_ = rhs.maxIts_;
1986    majorIterations_ = rhs.majorIterations_;
1987    logLevel_ = rhs.logLevel_;
1988    logFreq_ = rhs.logFreq_;
1989    checkFrequency_ = rhs.checkFrequency_;
1990    lambdaIterations_ = rhs.lambdaIterations_;
1991    maxIts2_ = rhs.maxIts2_;
1992    strategy_ = rhs.strategy_;
1993    lightWeight_=rhs.lightWeight_;
1994  }
1995  return *this;
1996}
1997Idiot::~Idiot()
1998{
1999  delete [] whenUsed_;
2000}
Note: See TracBrowser for help on using the repository browser.