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

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

fix for assert

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