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

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

minor fix to Idiot code

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