#include <ClpSimplexPrimalQuadratic.hpp>
Inheritance diagram for ClpSimplexPrimalQuadratic:
Public Member Functions | |
Description of algorithm | |
int | primalSLP (int numberPasses, double deltaTolerance) |
A sequential LP method. | |
int | primalQuadratic (int phase=2) |
int | primalQuadratic2 (ClpQuadraticInfo *info, int phase=2) |
ClpSimplexPrimalQuadratic * | makeQuadratic (ClpQuadraticInfo &info) |
int | endQuadratic (ClpSimplexPrimalQuadratic *quadraticModel, ClpQuadraticInfo &info) |
This moves solution back. | |
int | checkComplementarity (ClpQuadraticInfo *info, CoinIndexedVector *array1, CoinIndexedVector *array2) |
Checks complementarity and computes infeasibilities. | |
void | createDjs (ClpQuadraticInfo *info, CoinIndexedVector *array1, CoinIndexedVector *array2) |
Fills in reduced costs. | |
int | whileIterating (ClpQuadraticInfo *info) |
int | primalRow (CoinIndexedVector *rowArray, CoinIndexedVector *rhsArray, CoinIndexedVector *spareArray, CoinIndexedVector *spareArray2, ClpQuadraticInfo *info, int cleanupIteration) |
void | statusOfProblemInPrimal (int &lastCleaned, int type, ClpSimplexProgress *progress, ClpQuadraticInfo *info) |
It inherits from ClpSimplexPrimal. It has no data of its own and is never created - only cast from a ClpSimplexPrimal object at algorithm time. If needed create new class and pass around
Definition at line 26 of file ClpSimplexPrimalQuadratic.hpp.
|
This creates the large version of QP and fills in quadratic information. Returns NULL if no quadratic information Definition at line 2770 of file ClpSimplexPrimalQuadratic.cpp. References ClpSimplex::allSlackBasis(), ClpSimplex::ClpSimplex(), ClpModel::columnLower(), ClpModel::columnUpper(), ClpModel::dualColumnSolution(), ClpModel::dualRowSolution(), ClpSimplex::factorization(), ClpSimplex::loadProblem(), ClpModel::matrix(), ClpModel::messageHandler(), ClpQuadraticInfo::numberQuadraticColumns(), ClpQuadraticInfo::numberQuadraticRows(), ClpModel::numberRows(), ClpModel::objective(), ClpModel::passInMessageHandler(), ClpSimplexPrimal::primal(), ClpModel::primalColumnSolution(), ClpModel::primalRowSolution(), ClpQuadraticInfo::quadraticObjective(), ClpQuadraticObjective::quadraticObjective(), ClpModel::resize(), ClpModel::rowLower(), ClpModel::rowUpper(), ClpSimplex::setColumnStatus(), ClpModel::setLogLevel(), ClpQuadraticInfo::setOriginalObjective(), ClpSimplex::setRowStatus(), and ClpSimplex::times(). Referenced by primalQuadratic().
02771 { 02772 02773 // Get list of non linear columns 02774 ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_)); 02775 assert (quadraticObj); 02776 CoinPackedMatrix * quadratic = quadraticObj->quadraticObjective(); 02777 if (!quadratic||!quadratic->getNumElements()) { 02778 // no quadratic part 02779 return NULL; 02780 } 02781 02782 int numberColumns = this->numberColumns(); 02783 double * columnLower = this->columnLower(); 02784 double * columnUpper = this->columnUpper(); 02785 double * objective = this->objective(); 02786 double * solution = this->primalColumnSolution(); 02787 double * dj = this->dualColumnSolution(); 02788 double * pi = this->dualRowSolution(); 02789 02790 int numberRows = this->numberRows(); 02791 double * rowLower = this->rowLower(); 02792 double * rowUpper = this->rowUpper(); 02793 02794 // and elements 02795 CoinPackedMatrix * matrix = this->matrix(); 02796 const int * row = matrix->getIndices(); 02797 const int * columnStart = matrix->getVectorStarts(); 02798 const double * element = matrix->getElements(); 02799 const int * columnLength = matrix->getVectorLengths(); 02800 02801 int iColumn; 02802 const int * columnQuadratic = quadratic->getIndices(); 02803 const int * columnQuadraticStart = quadratic->getVectorStarts(); 02804 const int * columnQuadraticLength = quadratic->getVectorLengths(); 02805 const double * quadraticElement = quadratic->getElements(); 02806 #if 0 02807 // deliberate bad solution 02808 // Change to use phase 02809 //double * saveO = new double[numberColumns]; 02810 //memcpy(saveO,objective,numberColumns*sizeof(double)); 02811 //memset(objective,0,numberColumns*sizeof(double)); 02812 tempMessage messageHandler(this);; 02813 passInMessageHandler(&messageHandler); 02814 factorization()->maximumPivots(1); 02815 primal(); 02816 CoinMessageHandler handler2; 02817 passInMessageHandler(&handler2); 02818 factorization()->maximumPivots(100); 02819 setMaximumIterations(1000); 02820 #endif 02821 //memcpy(objective,saveO,numberColumns*sizeof(double)); 02822 // Get a feasible solution 02823 //printf("For testing - deliberate bad solution\n"); 02824 //columnUpper[0]=0.0; 02825 //columnLower[0]=0.0; 02826 //quadraticSLP(50,1.0e-4); 02827 //primal(1); 02828 //columnUpper[0]=COIN_DBL_MAX; 02829 02830 // Create larger problem 02831 // First workout how many rows extra 02832 info=ClpQuadraticInfo(this); 02833 quadratic = info.quadraticObjective(); 02834 int numberQuadratic = info.numberQuadraticColumns(); 02835 int newNumberRows = numberRows+numberQuadratic; 02836 int newNumberColumns = numberColumns + numberRows + numberQuadratic; 02837 int numberElements = 2*matrix->getNumElements() 02838 +2*quadratic->getNumElements() 02839 + numberQuadratic; 02840 double * elements2 = new double[numberElements]; 02841 int * start2 = new int[newNumberColumns+1]; 02842 int * row2 = new int[numberElements]; 02843 double * objective2 = new double[newNumberColumns]; 02844 double * columnLower2 = new double[newNumberColumns]; 02845 double * columnUpper2 = new double[newNumberColumns]; 02846 double * rowLower2 = new double[newNumberRows]; 02847 double * rowUpper2 = new double[newNumberRows]; 02848 memcpy(rowLower2,rowLower,numberRows*sizeof(double)); 02849 memcpy(rowUpper2,rowUpper,numberRows*sizeof(double)); 02850 int iRow; 02851 for (iRow=0;iRow<numberQuadratic;iRow++) { 02852 double cost = objective[iRow]; 02853 rowLower2[iRow+numberRows]=cost; 02854 rowUpper2[iRow+numberRows]=cost; 02855 } 02856 memset(objective2,0,newNumberColumns*sizeof(double)); 02857 // Get a row copy of quadratic objective in standard format 02858 CoinPackedMatrix copyQ; 02859 copyQ.reverseOrderedCopyOf(*quadratic); 02860 const int * columnQ = copyQ.getIndices(); 02861 const CoinBigIndex * rowStartQ = copyQ.getVectorStarts(); 02862 const int * rowLengthQ = copyQ.getVectorLengths(); 02863 const double * elementByRowQ = copyQ.getElements(); 02864 // Move solution across 02865 double * solution2 = new double[newNumberColumns]; 02866 memset(solution2,0,newNumberColumns*sizeof(double)); 02867 newNumberColumns=0; 02868 numberElements=0; 02869 start2[0]=0; 02870 // x 02871 memcpy(dj,objective,numberColumns*sizeof(double)); 02872 for (iColumn=0;iColumn<numberColumns;iColumn++) { 02873 // Original matrix 02874 columnLower2[iColumn]=columnLower[iColumn]; 02875 columnUpper2[iColumn]=columnUpper[iColumn]; 02876 solution2[iColumn]=solution[iColumn]; 02877 // Put in cost so we know it 02878 objective2[iColumn]=objective[iColumn]; 02879 int j; 02880 for (j=columnStart[iColumn]; 02881 j<columnStart[iColumn]+columnLength[iColumn]; 02882 j++) { 02883 elements2[numberElements]=element[j]; 02884 row2[numberElements++]=row[j]; 02885 } 02886 // Quadratic and modify djs 02887 for (j=columnQuadraticStart[iColumn]; 02888 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn]; 02889 j++) { 02890 int jColumn = columnQuadratic[j]; 02891 double value = quadraticElement[j]; 02892 if (iColumn!=jColumn) 02893 value *= 0.5; 02894 dj[jColumn] += solution[iColumn]*value; 02895 elements2[numberElements]=-value; 02896 row2[numberElements++]=jColumn+numberRows; 02897 } 02898 for (j=rowStartQ[iColumn]; 02899 j<rowStartQ[iColumn]+rowLengthQ[iColumn]; 02900 j++) { 02901 int jColumn = columnQ[j]; 02902 double value = elementByRowQ[j]; 02903 if (iColumn!=jColumn) { 02904 value *= 0.5; 02905 dj[jColumn] += solution[iColumn]*value; 02906 elements2[numberElements]=-value; 02907 row2[numberElements++]=jColumn+numberRows; 02908 } 02909 } 02910 start2[iColumn+1]=numberElements; 02911 } 02912 newNumberColumns=numberColumns; 02913 // pi 02914 int numberQuadraticRows = info.numberQuadraticRows(); 02915 // Get a row copy in standard format 02916 CoinPackedMatrix copy; 02917 copy.reverseOrderedCopyOf(*(this->matrix())); 02918 // get matrix data pointers 02919 const int * column = copy.getIndices(); 02920 const CoinBigIndex * rowStart = copy.getVectorStarts(); 02921 const int * rowLength = copy.getVectorLengths(); 02922 const double * elementByRow = copy.getElements(); 02923 for (iRow=0;iRow<numberRows;iRow++) { 02924 solution2[newNumberColumns]=pi[iRow]; 02925 double value = pi[iRow]; 02926 columnLower2[newNumberColumns]=-COIN_DBL_MAX; 02927 columnUpper2[newNumberColumns]=COIN_DBL_MAX; 02928 int j; 02929 for (j=rowStart[iRow]; 02930 j<rowStart[iRow]+rowLength[iRow]; 02931 j++) { 02932 double elementValue=elementByRow[j]; 02933 int jColumn = column[j]; 02934 if (jColumn>=0) { 02935 elements2[numberElements]=elementValue; 02936 row2[numberElements++]=jColumn+numberRows; 02937 } 02938 dj[jColumn]-= value*elementValue; 02939 } 02940 #ifndef CORRECT_ROW_COUNTS 02941 newNumberColumns++; 02942 start2[newNumberColumns]=numberElements; 02943 #else 02944 if (numberElements>start2[newNumberColumns]) { 02945 newNumberColumns++; 02946 start2[newNumberColumns]=numberElements; 02947 } 02948 #endif 02949 } 02950 // djs 02951 for (iColumn=0;iColumn<numberQuadratic;iColumn++) { 02952 columnLower2[newNumberColumns]=-COIN_DBL_MAX; 02953 columnUpper2[newNumberColumns]=COIN_DBL_MAX; 02954 solution2[newNumberColumns]=dj[iColumn]; 02955 elements2[numberElements]=1.0; 02956 row2[numberElements++]=iColumn+numberRows; 02957 newNumberColumns++; 02958 start2[newNumberColumns]=numberElements; 02959 } 02960 // Create model 02961 ClpSimplex * model2 = new ClpSimplex(*this); 02962 model2->resize(0,0); 02963 model2->loadProblem(newNumberColumns,newNumberRows, 02964 start2,row2, elements2, 02965 columnLower2,columnUpper2, 02966 objective2, 02967 rowLower2,rowUpper2); 02968 delete [] rowLower2; 02969 delete [] rowUpper2; 02970 delete [] columnLower2; 02971 delete [] columnUpper2; 02972 // Now create expanded quadratic objective for use in primalRow 02973 // Later pack down in some way 02974 start2[0]=0; 02975 numberElements=0; 02976 for (iColumn=0;iColumn<numberColumns;iColumn++) { 02977 // Quadratic 02978 int j; 02979 for (j=columnQuadraticStart[iColumn]; 02980 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn]; 02981 j++) { 02982 int jColumn = columnQuadratic[j]; 02983 double value = quadraticElement[j]; 02984 if (iColumn!=jColumn) 02985 value *= 0.5; 02986 elements2[numberElements]=value; 02987 row2[numberElements++]=jColumn; 02988 } 02989 for (j=rowStartQ[iColumn]; 02990 j<rowStartQ[iColumn]+rowLengthQ[iColumn]; 02991 j++) { 02992 int jColumn = columnQ[j]; 02993 double value = elementByRowQ[j]; 02994 if (iColumn!=jColumn) { 02995 value *= 0.5; 02996 elements2[numberElements]=value; 02997 row2[numberElements++]=jColumn; 02998 } 02999 } 03000 start2[iColumn+1]=numberElements; 03001 } 03002 // and pad 03003 //for (;iColumn<newNumberColumns;iColumn++) 03004 //start2[iColumn+1]=numberElements; 03005 // Load up objective with expanded linear 03006 ClpQuadraticObjective * obj = 03007 new ClpQuadraticObjective(objective2,numberColumns, 03008 start2,row2,elements2,newNumberColumns); 03009 delete [] objective2; 03010 info.setOriginalObjective(obj); 03011 //model2->loadQuadraticObjective(newNumberColumns,start2,row2,elements2); 03012 delete [] start2; 03013 delete [] row2; 03014 delete [] elements2; 03015 model2->allSlackBasis(); 03016 //model2->scaling(false); 03017 //printf("scaling off\n"); 03018 model2->setLogLevel(this->logLevel()); 03019 // Move solution across 03020 memcpy(model2->primalColumnSolution(),solution2, 03021 newNumberColumns*sizeof(double)); 03022 columnLower2 = model2->columnLower(); 03023 columnUpper2 = model2->columnUpper(); 03024 delete [] solution2; 03025 solution2 = model2->primalColumnSolution(); 03026 // Compute row activities and check feasible 03027 double * rowSolution2 = model2->primalRowSolution(); 03028 memset(rowSolution2,0,newNumberRows*sizeof(double)); 03029 model2->times(1.0,solution2,rowSolution2); 03030 rowLower2 = model2->rowLower(); 03031 rowUpper2 = model2->rowUpper(); 03032 #if 0 03033 // redo as Dantzig says 03034 for (iColumn=0;iColumn<numberColumns;iColumn++) { 03035 Status xStatus = getColumnStatus(iColumn); 03036 bool isSuperBasic; 03037 int iS = iColumn+newNumberRows; 03038 model2->setColumnStatus(iColumn,xStatus); 03039 if (xStatus==basic) { 03040 model2->setColumnStatus(iS,isFree); 03041 solution2[iS]=0.0; 03042 } else { 03043 model2->setColumnStatus(iS,basic); 03044 } 03045 // take slack out on equality rows 03046 model2->setRowBasic(iColumn+numberRows,superBasic); 03047 } 03048 for (iRow=0;iRow<numberRows;iRow++) { 03049 Status rowStatus = getRowStatus(iRow); 03050 model2->setRowStatus(iRow,rowStatus); 03051 if (rowStatus!=basic) { 03052 model2->setColumnStatus(iRow+numberColumns,basic); // make dual basic 03053 } 03054 assert (rowSolution2[iRow]>=rowLower2[iRow]-primalTolerance_); 03055 assert (rowSolution2[iRow]<=rowUpper2[iRow]+primalTolerance_); 03056 } 03057 // why ?? - take duals out and adjust 03058 for (iRow=0;iRow<numberRows;iRow++) { 03059 model2->setRowStatus(iRow,basic); 03060 model2->setColumnStatus(iRow+numberColumns,superBasic); 03061 solution2[iRow+numberColumns]=0.0; 03062 } 03063 #else 03064 for (iRow=0;iRow<numberRows;iRow++) { 03065 assert (rowSolution2[iRow]>=rowLower2[iRow]-primalTolerance_); 03066 assert (rowSolution2[iRow]<=rowUpper2[iRow]+primalTolerance_); 03067 model2->setRowStatus(iRow,basic); 03068 int jRow = iRow; 03069 model2->setColumnStatus(jRow+numberColumns,superBasic); 03070 solution2[jRow+numberColumns]=0.0; 03071 } 03072 for (iColumn=numberQuadraticRows+numberColumns;iColumn<newNumberColumns;iColumn++) { 03073 model2->setColumnStatus(iColumn,basic); 03074 model2->setRowStatus(iColumn-numberQuadraticRows-numberColumns+numberRows,isFixed); 03075 } 03076 #endif 03077 memset(rowSolution2,0,newNumberRows*sizeof(double)); 03078 model2->times(1.0,solution2,rowSolution2); 03079 for (iColumn=0;iColumn<numberQuadratic;iColumn++) { 03080 int iS = iColumn+numberColumns+numberQuadraticRows; 03081 int iRow = iColumn+numberRows; 03082 double value = rowSolution2[iRow]; 03083 if (value>rowUpper2[iRow]) { 03084 rowSolution2[iRow] = rowUpper2[iRow]; 03085 solution2[iS]-=value-rowUpper2[iRow]; 03086 } else { 03087 rowSolution2[iRow] = rowLower2[iRow]; 03088 solution2[iS]-=value-rowLower2[iRow]; 03089 } 03090 } 03091 03092 03093 // See if any s sub j have wrong sign and/or use djs from infeasibility objective 03094 double objectiveOffset; 03095 getDblParam(ClpObjOffset,objectiveOffset); 03096 double objValue = -objectiveOffset; 03097 for (iColumn=0;iColumn<numberColumns;iColumn++) 03098 objValue += objective[iColumn]*solution2[iColumn]; 03099 for (iColumn=0;iColumn<numberColumns;iColumn++) { 03100 double valueI = solution2[iColumn]; 03101 int j; 03102 for (j=columnQuadraticStart[iColumn]; 03103 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) { 03104 int jColumn = columnQuadratic[j]; 03105 double valueJ = solution2[jColumn]; 03106 double elementValue = quadraticElement[j]; 03107 objValue += 0.5*valueI*valueJ*elementValue; 03108 } 03109 } 03110 printf("Objective value %g\n",objValue); 03111 //for (iColumn=0;iColumn<newNumberColumns;iColumn++) 03112 //printf("%d %g\n",iColumn,solution2[iColumn]); 03113 return (ClpSimplexPrimalQuadratic *) model2; 03114 } |
|
Dantzig's method (actually a mixture with Jensen and King) phase - 0 normal, 1 getting complementary solution, 2 getting basic solution. Returns 0 if okay, 1 if LP infeasible. Definition at line 487 of file ClpSimplexPrimalQuadratic.cpp. References endQuadratic(), ClpModel::getColLower(), ClpModel::getColUpper(), ClpModel::getObjCoefficients(), ClpModel::getRowLower(), ClpModel::getRowUpper(), makeQuadratic(), ClpModel::matrix(), ClpModel::messageHandler(), ClpSimplex::numberPrimalInfeasibilities(), ClpSimplexPrimal::primal(), primalQuadratic2(), CoinMessageHandler::setLogLevel(), CoinMpsIO::setMpsData(), ClpSimplex::setPrimalColumnPivotAlgorithm(), and CoinMpsIO::writeMps().
00488 { 00489 // Get a feasible solution 00490 if (numberPrimalInfeasibilities()) 00491 primal(1); 00492 // still infeasible 00493 if (numberPrimalInfeasibilities()) 00494 return 1; 00495 ClpQuadraticInfo info; 00496 ClpSimplexPrimalQuadratic * model2 = makeQuadratic(info); 00497 if (!model2) { 00498 printf("** Not quadratic\n"); 00499 primal(1); 00500 return 0; 00501 } 00502 #if 0 00503 CoinMpsIO writer; 00504 writer.setMpsData(*model2->matrix(), COIN_DBL_MAX, 00505 model2->getColLower(), model2->getColUpper(), 00506 model2->getObjCoefficients(), 00507 (const char*) 0 /*integrality*/, 00508 model2->getRowLower(), model2->getRowUpper(), 00509 NULL,NULL); 00510 writer.writeMps("xx.mps"); 00511 #endif 00512 // Now do quadratic 00513 //ClpPrimalQuadraticDantzig dantzigP(model2,&info); 00514 ClpPrimalColumnDantzig dantzigP; 00515 model2->setPrimalColumnPivotAlgorithm(dantzigP); 00516 model2->messageHandler()->setLogLevel(63); 00517 model2->primalQuadratic2(&info,phase); 00518 endQuadratic(model2,info); 00519 return 0; 00520 } |
|
This is done after first pass phase - 0 normal, 1 getting complementary solution, 2 getting basic solution. Definition at line 521 of file ClpSimplexPrimalQuadratic.cpp. References checkComplementarity(), CoinIndexedVector::clear(), ClpQuadraticInfo::currentPhase(), ClpQuadraticInfo::currentSolution(), ClpQuadraticInfo::linearObjective(), ClpQuadraticInfo::numberQuadraticRows(), ClpQuadraticInfo::numberXColumns(), ClpQuadraticInfo::numberXRows(), ClpModel::objectiveAsObject(), ClpQuadraticInfo::originalObjective(), ClpPrimalColumnPivot::pivotColumn(), ClpQuadraticInfo::quadraticObjective(), ClpMatrixBase::refresh(), ClpSimplex::restoreData(), ClpSimplex::saveData(), ClpQuadraticInfo::sequenceIn(), ClpQuadraticInfo::setCrucialSj(), ClpQuadraticInfo::setCurrentPhase(), ClpQuadraticInfo::setSequenceIn(), ClpSimplex::startup(), statusOfProblemInPrimal(), and whileIterating(). Referenced by primalQuadratic().
00523 { 00524 00525 algorithm_ = +2; 00526 00527 // save data 00528 ClpDataSave data = saveData(); 00529 // Only ClpPackedMatrix at present 00530 assert ((dynamic_cast< ClpPackedMatrix*>(matrix_))); 00531 00532 // Assume problem is feasible 00533 // Stuff below will be moved into a class 00534 int numberXColumns = info->numberXColumns(); 00535 int numberXRows = info->numberXRows(); 00536 // initialize - values pass coding and algorithm_ is +1 00537 ClpObjective * saveObj = objectiveAsObject(); 00538 setObjectivePointer(info->originalObjective()); 00539 factorization_->setBiasLU(0); 00540 if (!startup(1)) { 00541 00542 //setObjectivePointer(saveObj); 00543 // Setup useful stuff 00544 info->setCurrentPhase(phase); 00545 int lastCleaned=0; // last time objective or bounds cleaned up 00546 info->setSequenceIn(-1); 00547 info->setCrucialSj(-1); 00548 bool deleteCosts=false; 00549 if (scalingFlag_>0) { 00550 // scale 00551 CoinPackedMatrix * quadratic = info->quadraticObjective(); 00552 double * objective = info->linearObjective(); 00553 // replace column by column 00554 double * newElement = new double[numberXColumns]; 00555 // scale column copy 00556 // get matrix data pointers 00557 const int * row = quadratic->getIndices(); 00558 const CoinBigIndex * columnStart = quadratic->getVectorStarts(); 00559 const int * columnLength = quadratic->getVectorLengths(); 00560 const double * elementByColumn = quadratic->getElements(); 00561 double direction = optimizationDirection_; 00562 // direction is actually scale out not scale in 00563 if (direction) 00564 direction = 1.0/direction; 00565 int iColumn; 00566 for (iColumn=0;iColumn<numberXColumns;iColumn++) { 00567 int j; 00568 double scale = columnScale_[iColumn]*direction; 00569 const double * elementsInThisColumn = elementByColumn + columnStart[iColumn]; 00570 const int * columnsInThisColumn = row + columnStart[iColumn]; 00571 int number = columnLength[iColumn]; 00572 assert (number<=numberXColumns); 00573 for (j=0;j<number;j++) { 00574 int iColumn2 = columnsInThisColumn[j]; 00575 newElement[j] = elementsInThisColumn[j]*scale*rowScale_[iColumn2+numberXRows]; 00576 } 00577 quadratic->replaceVector(iColumn,number,newElement); 00578 objective[iColumn] *= direction*columnScale_[iColumn]; 00579 } 00580 delete [] newElement; 00581 deleteCosts=true; 00582 } else if (optimizationDirection_!=1.0) { 00583 CoinPackedMatrix * quadratic = info->quadraticObjective(); 00584 double * objective = info->linearObjective(); 00585 // replace column by column 00586 double * newElement = new double[numberXColumns]; 00587 // get matrix data pointers 00588 const CoinBigIndex * columnStart = quadratic->getVectorStarts(); 00589 const int * columnLength = quadratic->getVectorLengths(); 00590 const double * elementByColumn = quadratic->getElements(); 00591 double direction = optimizationDirection_; 00592 // direction is actually scale out not scale in 00593 if (direction) 00594 direction = 1.0/direction; 00595 int iColumn; 00596 for (iColumn=0;iColumn<numberXColumns;iColumn++) { 00597 int j; 00598 const double * elementsInThisColumn = elementByColumn + columnStart[iColumn]; 00599 int number = columnLength[iColumn]; 00600 assert (number<=numberXColumns); 00601 for (j=0;j<number;j++) { 00602 newElement[j] = elementsInThisColumn[j]*direction; 00603 } 00604 quadratic->replaceVector(iColumn,number,newElement); 00605 objective[iColumn] *= direction; 00606 } 00607 delete [] newElement; 00608 deleteCosts=true; 00609 } 00610 00611 // Say no pivot has occurred (for steepest edge and updates) 00612 pivotRow_=-2; 00613 00614 // This says whether to restore things etc 00615 int factorType=0; 00616 /* 00617 Status of problem: 00618 0 - optimal 00619 1 - infeasible 00620 2 - unbounded 00621 -1 - iterating 00622 -2 - factorization wanted 00623 -3 - redo checking without factorization 00624 -4 - looks infeasible 00625 -5 - looks unbounded 00626 */ 00627 while (problemStatus_<0) { 00628 int iRow,iColumn; 00629 // clear 00630 for (iRow=0;iRow<4;iRow++) { 00631 rowArray_[iRow]->clear(); 00632 } 00633 00634 for (iColumn=0;iColumn<2;iColumn++) { 00635 columnArray_[iColumn]->clear(); 00636 } 00637 00638 // give matrix (and model costs and bounds a chance to be 00639 // refreshed (normally null) 00640 matrix_->refresh(this); 00641 // If we have done no iterations - special 00642 if (lastGoodIteration_==numberIterations_) 00643 factorType=3; 00644 // may factorize, checks if problem finished 00645 statusOfProblemInPrimal(lastCleaned,factorType,progress_,info); 00646 if (problemStatus_>=0) 00647 break; // declare victory 00648 00649 checkComplementarity (info,rowArray_[0],rowArray_[1]); 00650 00651 // Say good factorization 00652 factorType=1; 00653 00654 // Say no pivot has occurred (for steepest edge and updates) 00655 pivotRow_=-2; 00656 // Check problem phase 00657 // We assume all X are feasible 00658 if (info->currentSolution()&&info->sequenceIn()<0) { 00659 phase=0; 00660 int nextSequenceIn=-1; 00661 int numberQuadraticRows = info->numberQuadraticRows(); 00662 for (iColumn=0;iColumn<numberXColumns;iColumn++) { 00663 double value = solution_[iColumn]; 00664 double lower = lower_[iColumn]; 00665 double upper = upper_[iColumn]; 00666 if ((value>lower+primalTolerance_&&value<upper-primalTolerance_) 00667 ||getColumnStatus(iColumn)==superBasic) { 00668 if (getColumnStatus(iColumn)!=basic&&!flagged(iColumn)) { 00669 if (fabs(dj_[iColumn])>10.0*dualTolerance_|| 00670 getColumnStatus(iColumn+numberXColumns+numberQuadraticRows)==basic) { 00671 if (phase!=2) { 00672 phase=2; 00673 nextSequenceIn=iColumn; 00674 } 00675 } 00676 } 00677 } 00678 } 00679 for (iColumn=numberColumns_;iColumn<numberColumns_+numberXRows;iColumn++) { 00680 double value = solution_[iColumn]; 00681 double lower = lower_[iColumn]; 00682 double upper = upper_[iColumn]; 00683 if ((value>lower+primalTolerance_&&value<upper-primalTolerance_) 00684 ||getColumnStatus(iColumn)==superBasic) { 00685 if (getColumnStatus(iColumn)!=basic&&!flagged(iColumn)&&fabs(dj_[iColumn])>10.0*dualTolerance_) { 00686 if (phase!=2) { 00687 phase=2; 00688 nextSequenceIn=iColumn; 00689 } 00690 } 00691 } 00692 } 00693 info->setSequenceIn(nextSequenceIn); 00694 info->setCurrentPhase(phase); 00695 } 00696 00697 // exit if victory declared 00698 dualIn_=0.0; // so no updates 00699 if (!info->currentPhase()&&info->sequenceIn()<0&&primalColumnPivot_->pivotColumn(rowArray_[1], 00700 rowArray_[2],rowArray_[3], 00701 columnArray_[0], 00702 columnArray_[1]) < 0) { 00703 problemStatus_=0; 00704 break; 00705 } 00706 00707 // Iterate 00708 problemStatus_=-1; 00709 whileIterating(info); 00710 } 00711 if (deleteCosts) { 00712 // delete scaled copy of objective 00713 delete info->originalObjective(); 00714 } 00715 } 00716 setObjectivePointer(saveObj); 00717 // clean up 00718 finish(); 00719 restoreData(data); 00720 return problemStatus_; 00721 } |
|
Row array has pivot column This chooses pivot row. Rhs array is used for distance to next bound (for speed) For speed, we may need to go to a bucket approach when many variables go through bounds On exit rhsArray will have changes in costs of basic variables Initially no go thru Returns 0 - can do normal iteration 1 - losing complementarity cleanupIteration - 0 no, 1 yes, 2 restoring one of x/s in basis Definition at line 1349 of file ClpSimplexPrimalQuadratic.cpp. References ClpNonLinearCost::changeInCost(), CoinIndexedVector::clear(), ClpQuadraticInfo::crucialSj(), ClpQuadraticInfo::currentPhase(), CoinIndexedVector::denseVector(), CoinIndexedVector::getIndices(), CoinIndexedVector::getNumElements(), ClpNonLinearCost::goBack(), ClpNonLinearCost::goBackAll(), ClpNonLinearCost::goThru(), ClpQuadraticInfo::linearObjective(), CoinMessageHandler::logLevel(), CoinMessageHandler::message(), ClpNonLinearCost::nearest(), ClpQuadraticInfo::numberXColumns(), ClpQuadraticInfo::originalObjective(), ClpQuadraticObjective::quadraticObjective(), ClpQuadraticInfo::quadraticObjective(), CoinIndexedVector::setNumElements(), and ClpSimplex::solution(). Referenced by whileIterating().
01355 { 01356 int result=1; 01357 01358 // sequence stays as row number until end 01359 pivotRow_=-1; 01360 int numberSwapped=0; 01361 int numberRemaining=0; 01362 int crucialSj = info->crucialSj(); 01363 if (crucialSj<0) 01364 result=0; // linear 01365 int numberThru =0; // number gone thru a barrier 01366 int lastThru =0; // number gone thru a barrier on last time 01367 01368 double totalThru=0.0; // for when variables flip 01369 double acceptablePivot=1.0e-7; 01370 if (factorization_->pivots()) 01371 acceptablePivot=1.0e-5; // if we have iterated be more strict 01372 double bestEverPivot=acceptablePivot; 01373 int lastPivotRow = -1; 01374 double lastPivot=0.0; 01375 double lastTheta=1.0e50; 01376 int lastNumberSwapped=0; 01377 01378 // use spareArrays to put ones looked at in 01379 // First one is list of candidates 01380 // We could compress if we really know we won't need any more 01381 // Second array has current set of pivot candidates 01382 // with a backup list saved in double * part of indexed vector 01383 01384 // for zeroing out arrays after 01385 int maximumSwapped=0; 01386 // pivot elements 01387 double * spare; 01388 // indices 01389 int * index, * indexSwapped; 01390 int * saveSwapped; 01391 spareArray->clear(); 01392 spareArray2->clear(); 01393 spare = spareArray->denseVector(); 01394 index = spareArray->getIndices(); 01395 saveSwapped = (int *) spareArray2->denseVector(); 01396 indexSwapped = spareArray2->getIndices(); 01397 01398 // we also need somewhere for effective rhs 01399 double * rhs=rhsArray->denseVector(); 01400 01401 /* 01402 First we get a list of possible pivots. We can also see if the 01403 problem looks unbounded. 01404 01405 At first we increase theta and see what happens. We start 01406 theta at a reasonable guess. If in right area then we do bit by bit. 01407 We save possible pivot candidates 01408 01409 */ 01410 01411 // do first pass to get possibles 01412 // We can also see if unbounded 01413 01414 double * work=rowArray->denseVector(); 01415 int number=rowArray->getNumElements(); 01416 int * which=rowArray->getIndices(); 01417 01418 // we need to swap sign if coming in from ub 01419 double way = directionIn_; 01420 double maximumMovement; 01421 if (way>0.0) 01422 maximumMovement = min(1.0e30,upperIn_-valueIn_); 01423 else 01424 maximumMovement = min(1.0e30,valueIn_-lowerIn_); 01425 01426 int iIndex; 01427 01428 // Work out coefficients for quadratic term 01429 // This is expanded one 01430 const CoinPackedMatrix * quadratic = info->quadraticObjective(); 01431 const int * columnQuadratic = quadratic->getIndices(); 01432 const int * columnQuadraticStart = quadratic->getVectorStarts(); 01433 const int * columnQuadraticLength = quadratic->getVectorLengths(); 01434 const double * quadraticElement = quadratic->getElements(); 01435 //const double * originalCost = info->originalObjective(); 01436 // Use rhsArray 01437 rhsArray->clear(); 01438 int * index2 = rhsArray->getIndices(); 01439 int numberXColumns = info->numberXColumns(); 01440 int number2=0; 01441 //int numberOriginalRows = info->numberXRows(); 01442 // sj 01443 int iSjRow=-1; 01444 // sj for incoming 01445 int iSjRow2=-1,crucialSj2=-1; 01446 if (sequenceIn_<numberXColumns) { 01447 crucialSj2 = sequenceIn_; 01448 crucialSj2 += numberRows_; // sj2 which should go to 0.0 01449 } else if (sequenceIn_>=numberColumns_) { 01450 int iRow=sequenceIn_-numberColumns_; 01451 crucialSj2 = iRow; 01452 crucialSj2 += numberXColumns; // sj2 which should go to 0.0 01453 } 01454 double tj = 0.0; 01455 // Change in objective will be theta*coeff1 + theta*theta*coeff2 01456 double coeff1 = 0.0; 01457 double coeff2 = 0.0; 01458 double coeffSlack=0.0; 01459 for (iIndex=0;iIndex<number;iIndex++) { 01460 int iRow = which[iIndex]; 01461 double alpha = -work[iRow]*way; 01462 int iPivot=pivotVariable_[iRow]; 01463 if (numberIterations_==17) 01464 printf("row %d col %d alpha %g solution %g\n",iRow,iPivot,alpha,solution_[iPivot]); 01465 if (iPivot<numberXColumns) { 01466 index2[number2++]=iPivot; 01467 rhs[iPivot]=alpha; 01468 coeff1 += alpha*cost_[iPivot]; 01469 //printf("col %d alpha %g solution %g cost %g scale %g\n",iPivot,alpha,solution_[iPivot], 01470 // cost_[iPivot],columnScale_[iPivot]); 01471 } else { 01472 if (iPivot>=numberColumns_) { 01473 // ? do we go through column of pi 01474 assert (iPivot!=crucialSj); 01475 coeffSlack += alpha*cost_[iPivot]; 01476 } else if (iPivot<numberRows_) { 01477 // ? do we go through column of pi 01478 if (iPivot==crucialSj) { 01479 tj = alpha; 01480 iSjRow = iRow; 01481 } 01482 } else { 01483 if (iPivot==crucialSj) { 01484 tj = alpha; 01485 iSjRow = iRow; 01486 } 01487 } 01488 } 01489 if (iPivot==crucialSj2) 01490 iSjRow2=iRow; 01491 } 01492 // Incoming 01493 if (sequenceIn_<numberXColumns) { 01494 index2[number2++]=sequenceIn_; 01495 rhs[sequenceIn_]=way; 01496 //printf("incoming col %d alpha %g solution %g cost %g scale %g\n",sequenceIn_,way,valueIn_, 01497 // cost_[sequenceIn_],columnScale_[sequenceIn_]); 01498 coeff1 += way*cost_[sequenceIn_]; 01499 } else { 01500 //printf("incoming new col %d alpha %g solution %g\n",sequenceIn_,way,valueIn_); 01501 coeffSlack += way*cost_[sequenceIn_]; 01502 } 01503 printf("coeff1 now %g\n",coeff1); 01504 rhsArray->setNumElements(number2); 01505 double largestCoeff1=1.0e-20; 01506 for (iIndex=0;iIndex<number2;iIndex++) { 01507 int iColumn=index2[iIndex]; 01508 //double valueI = solution_[iColumn]; 01509 double alphaI = rhs[iColumn]; 01510 int j; 01511 for (j=columnQuadraticStart[iColumn]; 01512 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) { 01513 int jColumn = columnQuadratic[j]; 01514 double valueJ = solution_[jColumn]; 01515 double alphaJ = rhs[jColumn]; 01516 double elementValue = quadraticElement[j]; 01517 double addValue = (valueJ*alphaI)*elementValue; 01518 largestCoeff1 = max(largestCoeff1,fabs(addValue)); 01519 coeff1 += addValue; 01520 coeff2 += (alphaI*alphaJ)*elementValue; 01521 } 01522 } 01523 coeff2 *= 0.5; 01524 if (coeffSlack) 01525 printf("slack has non-zero cost - trouble?\n"); 01526 coeff1 += coeffSlack; 01527 //coeff1 = way*dualIn_; 01528 int accuracyFlag=0; 01529 if (!cleanupIteration) { 01530 if (fabs(dualIn_)<dualTolerance_&&fabs(coeff1)<dualTolerance_) { 01531 dualIn_=0.0; 01532 coeff1=0.0; 01533 } 01534 if (fabs(way*coeff1-dualIn_)>1.0e-2*(1.0+fabs(dualIn_))) 01535 printf("primal error %g, largest %g, coeff1 %g, dualin %g\n", 01536 largestPrimalError_,largestCoeff1,way*coeff1,dualIn_); 01537 assert (fabs(way*coeff1-dualIn_)<1.0e-1*(1.0+fabs(dualIn_))); 01538 assert (way*coeff1*dualIn_>=0.0); 01539 if (way*coeff1*dualIn_<0.0) { 01540 // bad 01541 accuracyFlag=2; 01542 } else if (fabs(way*coeff1-dualIn_)>1.0e-3*(1.0+fabs(dualIn_))) { 01543 // not wonderful 01544 accuracyFlag=1; 01545 } 01546 if (crucialSj>=0) { 01547 solution_[crucialSj]=way*coeff1; 01548 } 01549 } else if (dualIn_<0.0&&way*coeff1>1.0e-2) { 01550 printf("bad pair\n"); 01551 accuracyFlag=1; 01552 } else if (dualIn_>0.0&&way*coeff1<-1.0e-2) { 01553 accuracyFlag=1; 01554 printf("bad pair\n"); 01555 } 01556 // interesting places are where derivative zero or sj goes to zero 01557 double d1,d2=1.0e50; 01558 if (fabs(coeff2)>1.0e-9) 01559 d1 = - 0.5*coeff1/coeff2; 01560 else if (coeff1<=1.0e-6) 01561 d1 = maximumMovement; 01562 else 01563 d1 = 0.0; 01564 if (fabs(tj)<1.0e-7||!cleanupIteration) { 01565 //if (sequenceIn_<numberXColumns) 01566 //printf("column %d is basically linear\n",sequenceIn_); 01567 //assert(!columnQuadraticLength[sequenceIn_]); 01568 } else { 01569 d2 = -solution_[crucialSj]/tj; 01570 if (d2<0.0) { 01571 printf("d2 would be negative at %g\n",d2); 01572 d2=1.0e50; 01573 } 01574 } 01575 if (d1>1.0e10&&d2>1.0e10) { 01576 // linear variable entering 01577 // maybe we should have done dual iteration to force sj to 0.0 01578 //printf("linear variable\n"); 01579 } 01580 handler_->message(CLP_QUADRATIC_PRIMAL_DETAILS,messages_) 01581 <<coeff1<<coeff2<<coeffSlack<<dualIn_<<d1<<d2 01582 <<CoinMessageEol; 01583 // reality check 01584 { 01585 if (crucialSj2>=0) { 01586 // see if works out 01587 if (getColumnStatus(crucialSj2)==basic) { 01588 if (iSjRow2>=0) { 01589 //corresponding alpha nonzero 01590 double alpha=work[iSjRow2]; 01591 printf("Sj alpha %g sol %g ratio %g\n",alpha,solution_[crucialSj2],solution_[crucialSj2]/alpha); 01592 if (fabs(fabs(d1)-fabs(solution_[crucialSj2]/alpha))>1.0e-3*(1.0+fabs(d1))) { 01593 printf("bad test\n"); 01594 if (factorization_->pivots()) 01595 accuracyFlag=2; 01596 } 01597 d1=fabs(solution_[crucialSj2]/alpha); 01598 } else { 01599 printf("Sj basic but no alpha\n"); 01600 } 01601 } else { 01602 printf("Sj not basic\n"); 01603 } 01604 } 01605 } 01606 //if (!cleanupIteration) 01607 //dualIn_ = way*coeff1; 01608 double mind1d2=1.0e50; 01609 if (cleanupIteration) { 01610 // we are only interested in d1 if smaller than d2 01611 mind1d2 = min(maximumMovement,d2); 01612 //if (d1>1.0e-8&&d1<0.999*d2) 01613 //mind1d2=d1; 01614 } else { 01615 // There is no d2 - d1 refers to crucialSj 01616 if (d1>1.0e-5) { 01617 mind1d2 = min(maximumMovement,d1); 01618 //assert (d1>=0.0); 01619 } 01620 } 01621 maximumMovement = min(maximumMovement,mind1d2); 01622 double trueMaximumMovement; 01623 if (way>0.0) 01624 trueMaximumMovement = min(1.0e30,upperIn_-valueIn_); 01625 else 01626 trueMaximumMovement = min(1.0e30,valueIn_-lowerIn_); 01627 rhsArray->clear(); 01628 double tentativeTheta = maximumMovement; 01629 double upperTheta = maximumMovement; 01630 bool throwAway=false; 01631 if (numberIterations_==1750) { 01632 printf("Bad iteration coming up after iteration %d\n",numberIterations_); 01633 } 01634 01635 double minimumAny=1.0e50; 01636 int whichMinimum=-1; 01637 double minimumAlpha=0.0; 01638 for (iIndex=0;iIndex<number;iIndex++) { 01639 01640 int iRow = which[iIndex]; 01641 double alpha = work[iRow]; 01642 int iPivot=pivotVariable_[iRow]; 01643 alpha *= way; 01644 double oldValue = solution(iPivot); 01645 // get where in bound sequence 01646 if (alpha>0.0) { 01647 // basic variable going towards lower bound 01648 double bound = lower(iPivot); 01649 oldValue -= bound; 01650 } else if (alpha<0.0) { 01651 // basic variable going towards upper bound 01652 double bound = upper(iPivot); 01653 oldValue = bound-oldValue; 01654 } 01655 if (iPivot>=numberXColumns&&iPivot<numberColumns_) { 01656 double bound=0.0; 01657 double oldValue2 = solution(iPivot); 01658 if (alpha>0.0) { 01659 // basic variable going towards lower bound 01660 oldValue2 -= bound; 01661 } else if (alpha<0.0) { 01662 // basic variable going towards upper bound 01663 oldValue2 = bound-oldValue; 01664 } 01665 double value = oldValue2-minimumAny*fabs(alpha); 01666 if (value*oldValue2<0.0) { 01667 double ratio = fabs(oldValue2/alpha); 01668 if (ratio<minimumAny&&fabs(alpha)>1.0e2*acceptablePivot) { 01669 minimumAny = ratio; 01670 whichMinimum = iRow; 01671 minimumAlpha= fabs(alpha); 01672 } 01673 } 01674 } 01675 double value = oldValue-tentativeTheta*fabs(alpha); 01676 assert (oldValue>=-primalTolerance_*1.0001); 01677 if (value<-primalTolerance_) { 01678 // add to list 01679 spare[numberRemaining]=alpha; 01680 rhs[iRow]=oldValue; 01681 index[numberRemaining++]=iRow; 01682 double value=oldValue-upperTheta*fabs(alpha); 01683 if (value<-primalTolerance_&&fabs(alpha)>=acceptablePivot) 01684 upperTheta = (oldValue+primalTolerance_)/fabs(alpha); 01685 } 01686 } 01687 01688 // we need to keep where rhs non-zeros are 01689 int numberInRhs=numberRemaining; 01690 memcpy(rhsArray->getIndices(),index,numberInRhs*sizeof(int)); 01691 rhsArray->setNumElements(numberInRhs); 01692 01693 theta_=maximumMovement; 01694 01695 bool goBackOne = false; 01696 double fake=1.0e-2; 01697 01698 if (numberRemaining) { 01699 01700 // looks like pivoting 01701 // now try until reasonable theta 01702 tentativeTheta = max(10.0*upperTheta,1.0e-7); 01703 tentativeTheta = min(tentativeTheta,maximumMovement); 01704 01705 // loops increasing tentative theta until can't go through 01706 01707 while (tentativeTheta <= maximumMovement) { 01708 double bestPivotBeforeInteresting=0.0; 01709 double thruThis = 0.0; 01710 01711 double bestPivot=acceptablePivot; 01712 pivotRow_ = -1; 01713 01714 numberSwapped = 0; 01715 01716 upperTheta = maximumMovement; 01717 01718 for (iIndex=0;iIndex<numberRemaining;iIndex++) { 01719 01720 int iRow = index[iIndex]; 01721 double alpha = spare[iIndex]; 01722 double oldValue = rhs[iRow]; 01723 double value = oldValue-tentativeTheta*fabs(alpha); 01724 01725 if (value<-primalTolerance_) { 01726 // how much would it cost to go thru 01727 thruThis += alpha* 01728 nonLinearCost_->changeInCost(pivotVariable_[iRow],alpha); 01729 // goes on swapped list (also means candidates if too many) 01730 indexSwapped[numberSwapped++]=iRow; 01731 if (fabs(alpha)>bestPivot) { 01732 bestPivot=fabs(alpha); 01733 pivotRow_ = iRow; 01734 theta_ = oldValue/bestPivot; 01735 } 01736 } else { 01737 value = oldValue-upperTheta*fabs(alpha); 01738 if (value<-primalTolerance_ && fabs(alpha)>=acceptablePivot) 01739 upperTheta = (oldValue+primalTolerance_)/fabs(alpha); 01740 } 01741 } 01742 01743 maximumSwapped = max(maximumSwapped,numberSwapped); 01744 bestPivotBeforeInteresting=bestPivot; 01745 01746 //double dualCheck = - 2.0*coeff2*tentativeTheta - coeff1 - 0.1*infeasibilityCost_; 01747 double dualCheck = - 2.0*coeff2*tentativeTheta - coeff1; 01748 // but make a bit more pessimistic if pivot 01749 //if (bestPivot>acceptablePivot) 01750 //dualCheck=max(dualCheck-100.0*dualTolerance_,0.99*dualCheck); 01751 //dualCheck=0.0; 01752 if ((totalThru+thruThis>=dualCheck&&bestPivot>acceptablePivot)||fake*bestPivot>1.0e-3) { 01753 // We should be pivoting in this batch 01754 // so compress down to this lot 01755 01756 int saveNumber = numberRemaining; 01757 numberRemaining=0; 01758 for (iIndex=0;iIndex<numberSwapped;iIndex++) { 01759 int iRow = indexSwapped[iIndex]; 01760 spare[numberRemaining]=way*work[iRow]; 01761 index[numberRemaining++]=iRow; 01762 } 01763 memset(spare+numberRemaining,0, 01764 (saveNumber-numberRemaining)*sizeof(double)); 01765 double lastThru = totalThru; 01766 int iTry; 01767 #define MAXTRY 100 01768 // first get ratio with tolerance 01769 for (iTry=0;iTry<MAXTRY;iTry++) { 01770 01771 upperTheta=maximumMovement; 01772 numberSwapped = 0; 01773 01774 for (iIndex=0;iIndex<numberRemaining;iIndex++) { 01775 01776 int iRow = index[iIndex]; 01777 double alpha = fabs(spare[iIndex]); 01778 double oldValue = rhs[iRow]; 01779 double value = oldValue-upperTheta*alpha; 01780 01781 if (value<-primalTolerance_ && alpha>=acceptablePivot) 01782 upperTheta = (oldValue+primalTolerance_)/alpha; 01783 01784 } 01785 01786 // now look at best in this lot 01787 bestPivot=acceptablePivot; 01788 pivotRow_=-1; 01789 for (iIndex=0;iIndex<numberRemaining;iIndex++) { 01790 01791 int iRow = index[iIndex]; 01792 double alpha = spare[iIndex]; 01793 double oldValue = rhs[iRow]; 01794 double value = oldValue-upperTheta*fabs(alpha); 01795 01796 if (value<=0) { 01797 // how much would it cost to go thru 01798 totalThru += alpha* 01799 nonLinearCost_->changeInCost(pivotVariable_[iRow],alpha); 01800 // goes on swapped list (also means candidates if too many) 01801 indexSwapped[numberSwapped++]=iRow; 01802 if (fabs(alpha)>bestPivot) { 01803 bestPivot=fabs(alpha); 01804 theta_ = oldValue/bestPivot; 01805 pivotRow_=iRow; 01806 } 01807 } else { 01808 value = oldValue-upperTheta*fabs(alpha); 01809 if (value<-primalTolerance_ && fabs(alpha)>=acceptablePivot) 01810 upperTheta = (oldValue+primalTolerance_)/fabs(alpha); 01811 } 01812 } 01813 01814 maximumSwapped = max(maximumSwapped,numberSwapped); 01815 if (bestPivot<0.1*bestEverPivot&& 01816 bestEverPivot>1.0e-6&&bestPivot<1.0e-3) { 01817 // back to previous one 01818 goBackOne = true; 01819 break; 01820 } else if (pivotRow_==-1&&upperTheta>largeValue_) { 01821 if (lastPivot>acceptablePivot) { 01822 // back to previous one 01823 goBackOne = true; 01824 //break; 01825 } else { 01826 // can only get here if all pivots so far too small 01827 } 01828 break; 01829 } else { 01830 dualCheck = - 2.0*coeff2*theta_ - coeff1; 01831 if (bestPivotBeforeInteresting>1.0e-4&&bestPivot<1.0e-6) 01832 dualCheck=1.0e7; 01833 if ((totalThru>=dualCheck||fake*bestPivot>1.0e-3) 01834 &&(sequenceIn_<numberXColumns||sequenceIn_>=numberColumns_)) { 01835 if (!cleanupIteration) { 01836 // We can pivot out sj 01837 if (upperTheta==maximumMovement) { 01838 printf("figures\n"); 01839 } else if (iSjRow2>=0) { 01840 if (lastThru>=dualCheck&&theta_<trueMaximumMovement) { 01841 printf("totalThru %g, lastThru %g - taking sj to zero?\n",totalThru,lastThru); 01842 // make sure will take correct path 01843 mind1d2=1.0; 01844 maximumMovement=1.0; 01845 d2=0.0; 01846 pivotRow_=-1; 01847 } 01848 } 01849 } else { 01850 if (pivotRow_<0&&lastPivotRow<0) 01851 throwAway=true; 01852 } 01853 break; // no point trying another loop 01854 } else if (totalThru>=dualCheck||fake*bestPivot>1.0e-3||upperTheta==maximumMovement) { 01855 break; // no point trying another loop 01856 } else { 01857 // skip this lot 01858 nonLinearCost_->goThru(numberSwapped,way,indexSwapped, work,rhs); 01859 lastPivotRow=pivotRow_; 01860 lastTheta = theta_; 01861 lastThru = numberThru; 01862 numberThru += numberSwapped; 01863 lastNumberSwapped = numberSwapped; 01864 memcpy(saveSwapped,indexSwapped,lastNumberSwapped*sizeof(int)); 01865 if (bestPivot>bestEverPivot) 01866 bestEverPivot=bestPivot; 01867 lastThru = totalThru; 01868 } 01869 } 01870 } 01871 break; 01872 } else { 01873 // skip this lot 01874 nonLinearCost_->goThru(numberSwapped,way,indexSwapped, work,rhs); 01875 lastPivotRow=pivotRow_; 01876 lastTheta = theta_; 01877 lastThru = numberThru; 01878 numberThru += numberSwapped; 01879 lastNumberSwapped = numberSwapped; 01880 memcpy(saveSwapped,indexSwapped,lastNumberSwapped*sizeof(int)); 01881 if (bestPivot>bestEverPivot) 01882 bestEverPivot=bestPivot; 01883 totalThru += thruThis; 01884 tentativeTheta = 2.0*upperTheta; 01885 } 01886 } 01887 // can get here without pivotRow_ set but with lastPivotRow 01888 if (goBackOne||(pivotRow_<0&&lastPivotRow>=0)) { 01889 // back to previous one 01890 pivotRow_=lastPivotRow; 01891 theta_ = lastTheta; 01892 // undo this lot 01893 nonLinearCost_->goBack(lastNumberSwapped,saveSwapped,rhs); 01894 memcpy(indexSwapped,saveSwapped,lastNumberSwapped*sizeof(int)); 01895 numberSwapped = lastNumberSwapped; 01896 } 01897 } 01898 if (0&&minimumAny<theta_&&cleanupIteration&&bestEverPivot<1.0e-2 01899 &&minimumAlpha>bestEverPivot*1.0e2&&minimumAny>1.0e-1&&info->currentPhase()==0) { 01900 printf("Possible other pivot %d %g %g - alpha %g\n", 01901 whichMinimum,minimumAny,theta_,minimumAlpha); 01902 pivotRow_ = whichMinimum; 01903 alpha_ = work[pivotRow_]; 01904 // translate to sequence 01905 sequenceOut_ = pivotVariable_[pivotRow_]; 01906 valueOut_ = solution(sequenceOut_); 01907 lowerOut_=0.0; 01908 upperOut_=0.0; 01909 theta_= fabs(valueOut_/alpha_); 01910 01911 if (way<0.0) 01912 theta_ = - theta_; 01913 if (alpha_*way<0.0) { 01914 directionOut_=-1; // to upper bound 01915 } else { 01916 directionOut_=1; // to lower bound 01917 } 01918 dualOut_ = reducedCost(sequenceOut_); 01919 } else { 01920 01921 if (pivotRow_>=0) { 01922 if (0) { 01923 double move = coeff1*theta_+coeff2*theta_*theta_; 01924 printf("Predicted change in obj is %g %g %g\n", 01925 move,objectiveValue_-move,objectiveValue_+move); 01926 } 01927 #define MINIMUMTHETA 1.0e-12 01928 // will we need to increase tolerance 01929 #ifdef CLP_DEBUG 01930 bool found=false; 01931 #endif 01932 double largestInfeasibility = primalTolerance_; 01933 if (theta_<MINIMUMTHETA) { 01934 theta_=MINIMUMTHETA; 01935 for (iIndex=0;iIndex<numberSwapped;iIndex++) { 01936 int iRow = indexSwapped[iIndex]; 01937 #ifdef CLP_DEBUG 01938 if (iRow==pivotRow_) 01939 found=true; 01940 #endif 01941 largestInfeasibility = max (largestInfeasibility, 01942 -(rhs[iRow]-fabs(work[iRow])*theta_)); 01943 } 01944 #ifdef CLP_DEBUG 01945 assert(found); 01946 if (largestInfeasibility>primalTolerance_&&(handler_->logLevel()&32)) 01947 printf("Primal tolerance increased from %g to %g\n", 01948 primalTolerance_,largestInfeasibility); 01949 #endif 01950 primalTolerance_ = max(primalTolerance_,largestInfeasibility); 01951 } 01952 alpha_ = work[pivotRow_]; 01953 // translate to sequence 01954 sequenceOut_ = pivotVariable_[pivotRow_]; 01955 valueOut_ = solution(sequenceOut_); 01956 lowerOut_=lower_[sequenceOut_]; 01957 upperOut_=upper_[sequenceOut_]; 01958 01959 if (way<0.0) 01960 theta_ = - theta_; 01961 double newValue = valueOut_ - theta_*alpha_; 01962 if (alpha_*way<0.0) { 01963 directionOut_=-1; // to upper bound 01964 if (fabs(theta_)>1.0e-6) 01965 upperOut_ = nonLinearCost_->nearest(sequenceOut_,newValue); 01966 else 01967 upperOut_ = newValue; 01968 } else { 01969 directionOut_=1; // to lower bound 01970 if (fabs(theta_)>1.0e-6) 01971 lowerOut_ = nonLinearCost_->nearest(sequenceOut_,newValue); 01972 else 01973 lowerOut_ = newValue; 01974 } 01975 dualOut_ = reducedCost(sequenceOut_); 01976 } else { 01977 // If no pivot but bad move then throw away 01978 if (throwAway&&(sequenceIn_<numberXColumns||sequenceIn_>=numberColumns_)) { 01979 assert (pivotRow_<0); 01980 accuracyFlag=2; 01981 } 01982 if (maximumMovement<1.0e20&&maximumMovement==trueMaximumMovement) { 01983 // flip 01984 theta_ = maximumMovement; 01985 pivotRow_ = -2; // so we can tell its a flip 01986 result=0; 01987 sequenceOut_ = sequenceIn_; 01988 valueOut_ = valueIn_; 01989 dualOut_ = dualIn_; 01990 lowerOut_ = lowerIn_; 01991 upperOut_ = upperIn_; 01992 alpha_ = 0.0; 01993 if (accuracyFlag<2) 01994 accuracyFlag=0; 01995 if (way<0.0) { 01996 directionOut_=1; // to lower bound 01997 theta_ = lowerOut_ - valueOut_; 01998 } else { 01999 directionOut_=-1; // to upper bound 02000 theta_ = upperOut_ - valueOut_; 02001 } 02002 // we may still have sj to get rid of 02003 } else if (fabs(maximumMovement-mind1d2)<dualTolerance_) { 02004 // crucialSj local copy i.e. dj going to zero 02005 if (maximumMovement==d2) { 02006 // sj going to zero 02007 result=0; 02008 } else { 02009 // incoming dj going to zero 02010 if (!cleanupIteration) { 02011 result=0; 02012 iSjRow=iSjRow2; 02013 if (iSjRow>=0) 02014 crucialSj = pivotVariable_[iSjRow]; 02015 else 02016 crucialSj=-1; 02017 assert (pivotRow_<0); 02018 // If crucialSj <0 then make superbasic? 02019 if (crucialSj<0) { 02020 printf("**ouch\n"); 02021 theta_ = maximumMovement; 02022 pivotRow_ = -2; // so we can tell its a flip 02023 result=0; 02024 sequenceOut_ = sequenceIn_; 02025 valueOut_ = valueIn_; 02026 dualOut_ = dualIn_; 02027 lowerOut_ = lowerIn_; 02028 upperOut_ = upperIn_; 02029 alpha_ = 0.0; 02030 if (accuracyFlag<2) 02031 accuracyFlag=0; 02032 if (way<0.0) { 02033 directionOut_=1; // to lower bound 02034 lowerIn_ = valueOut_-theta_; 02035 theta_ = lowerIn_ - valueOut_; 02036 } else { 02037 directionOut_=-1; // to upper bound 02038 upperIn_ = valueOut_+theta_; 02039 theta_ = upperIn_ - valueOut_; 02040 } 02041 } 02042 } else { 02043 assert (fabs(dualIn_)<1.0e-3); 02044 result=1; 02045 if (minimumAlpha>0.0) { 02046 // could do this in other places if pivot looks good 02047 printf("Should take minimum\n"); 02048 pivotRow_ = whichMinimum; 02049 alpha_ = work[pivotRow_]; 02050 // translate to sequence 02051 sequenceOut_ = pivotVariable_[pivotRow_]; 02052 valueOut_ = solution(sequenceOut_); 02053 theta_ = minimumAny; 02054 if (way<0.0) 02055 theta_ = - theta_; 02056 lowerOut_=0.0; 02057 upperOut_=0.0; 02058 //???? 02059 dualOut_ = reducedCost(sequenceOut_); 02060 } 02061 } 02062 } 02063 if (!result&&crucialSj>=0) { 02064 setColumnStatus(crucialSj,isFree); 02065 pivotRow_ = iSjRow; 02066 alpha_ = work[pivotRow_]; 02067 // translate to sequence 02068 sequenceOut_ = pivotVariable_[pivotRow_]; 02069 assert (sequenceOut_==crucialSj); 02070 valueOut_ = solution(sequenceOut_); 02071 theta_ = fabs(valueOut_/alpha_); 02072 if (fabs(maximumMovement-theta_)>1.0e-3*(1.0+maximumMovement)) 02073 printf("maximumMovement %g mismatch with theta %g\n",maximumMovement,theta_);; 02074 if (way<0.0) 02075 theta_ = - theta_; 02076 lowerOut_=0.0; 02077 upperOut_=0.0; 02078 //???? 02079 dualOut_ = reducedCost(sequenceOut_); 02080 } 02081 } else { 02082 // need to do something 02083 accuracyFlag=2; 02084 } 02085 } 02086 } 02087 02088 02089 // clear arrays 02090 02091 memset(spare,0,numberRemaining*sizeof(double)); 02092 memset(saveSwapped,0,maximumSwapped*sizeof(int)); 02093 02094 // put back original bounds etc 02095 nonLinearCost_->goBackAll(rhsArray); 02096 02097 rhsArray->clear(); 02098 // Change in objective will be theta*coeff1 + theta*theta*coeff2 02099 objectiveValue_ += theta_*coeff1+theta_*theta_*coeff2; 02100 { 02101 int iColumn; 02102 objectiveValue_ =0.0; 02103 CoinPackedMatrix * quadratic = 02104 info->originalObjective()->quadraticObjective(); 02105 const int * columnQuadratic = quadratic->getIndices(); 02106 const int * columnQuadraticStart = quadratic->getVectorStarts(); 02107 const int * columnQuadraticLength = quadratic->getVectorLengths(); 02108 const double * quadraticElement = quadratic->getElements(); 02109 int numberColumns = info->numberXColumns(); 02110 const double * objective = info->linearObjective(); 02111 for (iColumn=0;iColumn<numberColumns;iColumn++) 02112 objectiveValue_ += objective[iColumn]*solution_[iColumn]; 02113 for (iColumn=0;iColumn<numberColumns;iColumn++) { 02114 double valueI = solution_[iColumn]; 02115 int j; 02116 for (j=columnQuadraticStart[iColumn]; 02117 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) { 02118 int jColumn = columnQuadratic[j]; 02119 double valueJ = solution_[jColumn]; 02120 double elementValue = quadraticElement[j]; 02121 objectiveValue_ += 0.5*valueI*valueJ*elementValue; 02122 } 02123 } 02124 } 02125 if (accuracyFlag<2) { 02126 return result+10*accuracyFlag; 02127 } else { 02128 pivotRow_=1; // make sure correct path 02129 return 20; 02130 } 02131 } |
|
A sequential LP method. Primal algorithms for quadratic At present we have two algorithms: a) Dantzig's algorithm b) Using a semi-trust region approach as for pooling problem This is in because I have it lying around Definition at line 58 of file ClpSimplexPrimalQuadratic.cpp. References ClpModel::columnLower(), ClpModel::columnUpper(), ClpModel::dualColumnSolution(), ClpModel::matrix(), ClpSimplex::numberPrimalInfeasibilities(), ClpModel::numberRows(), ClpModel::objective(), ClpModel::optimizationDirection(), ClpSimplexPrimal::primal(), ClpModel::primalColumnSolution(), ClpQuadraticObjective::quadraticObjective(), ClpSimplex::scaling(), ClpModel::setDblParam(), ClpModel::setLogLevel(), CoinMpsIO::setMpsData(), ClpModel::status(), and CoinMpsIO::writeMps().
00059 { 00060 // Are we minimizing or maximizing 00061 double whichWay=optimizationDirection(); 00062 if (whichWay<0.0) 00063 whichWay=-1.0; 00064 else if (whichWay>0.0) 00065 whichWay=1.0; 00066 00067 // This is as a user would see 00068 00069 int numberColumns = this->numberColumns(); 00070 int numberRows = this->numberRows(); 00071 double * columnLower = this->columnLower(); 00072 double * columnUpper = this->columnUpper(); 00073 double * objective = this->objective(); 00074 double * solution = this->primalColumnSolution(); 00075 00076 // Save objective 00077 00078 double * saveObjective = new double [numberColumns]; 00079 memcpy(saveObjective,objective,numberColumns*sizeof(double)); 00080 00081 // Get list of non linear columns 00082 ClpQuadraticObjective * quadraticObj = (dynamic_cast< ClpQuadraticObjective*>(objective_)); 00083 CoinPackedMatrix * quadratic = NULL; 00084 if (quadraticObj) 00085 quadratic = quadraticObj->quadraticObjective(); 00086 if (!quadratic) { 00087 // no quadratic part 00088 return primal(0); 00089 } 00090 int numberNonLinearColumns = 0; 00091 int iColumn; 00092 int * listNonLinearColumn = new int[numberColumns]; 00093 memset(listNonLinearColumn,0,numberColumns*sizeof(int)); 00094 const int * columnQuadratic = quadratic->getIndices(); 00095 const int * columnQuadraticStart = quadratic->getVectorStarts(); 00096 const int * columnQuadraticLength = quadratic->getVectorLengths(); 00097 const double * quadraticElement = quadratic->getElements(); 00098 for (iColumn=0;iColumn<numberColumns;iColumn++) { 00099 int j; 00100 for (j=columnQuadraticStart[iColumn]; 00101 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) { 00102 int jColumn = columnQuadratic[j]; 00103 listNonLinearColumn[jColumn]=1; 00104 listNonLinearColumn[iColumn]=1; 00105 } 00106 } 00107 for (iColumn=0;iColumn<numberColumns;iColumn++) { 00108 if(listNonLinearColumn[iColumn]) 00109 listNonLinearColumn[numberNonLinearColumns++]=iColumn; 00110 } 00111 00112 if (!numberNonLinearColumns) { 00113 delete [] listNonLinearColumn; 00114 // no quadratic part 00115 return primal(0); 00116 } 00117 00118 // get feasible 00119 if (!this->status()||numberPrimalInfeasibilities()) 00120 primal(1); 00121 // still infeasible 00122 if (numberPrimalInfeasibilities()) 00123 return 0; 00124 00125 int jNon; 00126 int * last[3]; 00127 00128 double * trust = new double[numberNonLinearColumns]; 00129 double * trueLower = new double[numberNonLinearColumns]; 00130 double * trueUpper = new double[numberNonLinearColumns]; 00131 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00132 iColumn=listNonLinearColumn[jNon]; 00133 trust[jNon]=0.5; 00134 trueLower[jNon]=columnLower[iColumn]; 00135 trueUpper[jNon]=columnUpper[iColumn]; 00136 if (solution[iColumn]<trueLower[jNon]) 00137 solution[iColumn]=trueLower[jNon]; 00138 else if (solution[iColumn]>trueUpper[jNon]) 00139 solution[iColumn]=trueUpper[jNon]; 00140 } 00141 int iPass; 00142 double lastObjective=1.0e31; 00143 double * saveSolution = new double [numberColumns]; 00144 double * savePi = new double [numberRows]; 00145 unsigned char * saveStatus = new unsigned char[numberRows+numberColumns]; 00146 double targetDrop=1.0e31; 00147 double objectiveOffset; 00148 getDblParam(ClpObjOffset,objectiveOffset); 00149 // 1 bound up, 2 up, -1 bound down, -2 down, 0 no change 00150 for (iPass=0;iPass<3;iPass++) { 00151 last[iPass]=new int[numberNonLinearColumns]; 00152 for (jNon=0;jNon<numberNonLinearColumns;jNon++) 00153 last[iPass][jNon]=0; 00154 } 00155 // goodMove +1 yes, 0 no, -1 last was bad - just halve gaps, -2 do nothing 00156 int goodMove=-2; 00157 char * statusCheck = new char[numberColumns]; 00158 for (iPass=0;iPass<numberPasses;iPass++) { 00159 // redo objective 00160 double offset=0.0; 00161 double objValue=-objectiveOffset; 00162 double lambda=-1.0; 00163 if (goodMove>=0) { 00164 // get best interpolation 00165 double coeff0=-objectiveOffset,coeff1=0.0,coeff2=0.0; 00166 for (iColumn=0;iColumn<numberColumns;iColumn++) { 00167 coeff0 += saveObjective[iColumn]*solution[iColumn]; 00168 coeff1 += saveObjective[iColumn]*(saveSolution[iColumn]-solution[iColumn]); 00169 } 00170 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00171 iColumn=listNonLinearColumn[jNon]; 00172 double valueI = solution[iColumn]; 00173 double valueISave = saveSolution[iColumn]; 00174 int j; 00175 for (j=columnQuadraticStart[iColumn]; 00176 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) { 00177 int jColumn = columnQuadratic[j]; 00178 double valueJ = solution[jColumn]; 00179 double valueJSave = saveSolution[jColumn]; 00180 double elementValue = 0.5*quadraticElement[j]; 00181 coeff0 += valueI*valueJ*elementValue; 00182 coeff1 += (valueI*valueJSave+valueISave*valueJ-2.0*valueI*valueJ)*elementValue; 00183 coeff2 += (valueISave*valueJSave+valueI*valueJ-valueISave*valueJ-valueI*valueJSave)*elementValue; 00184 } 00185 } 00186 double lambdaValue; 00187 if (fabs(coeff2)<1.0e-9) { 00188 if (coeff1+coeff2>=0.0) 00189 lambda = 0.0; 00190 else 00191 lambda = 1.0; 00192 } else { 00193 lambda = -(0.5*coeff1)/coeff2; 00194 if (lambda>1.0||lambda<0.0) { 00195 if (coeff1+coeff2>=0.0) 00196 lambda = 0.0; 00197 else 00198 lambda = 1.0; 00199 } 00200 } 00201 lambdaValue = lambda*lambda*coeff2+lambda*coeff1+coeff0; 00202 printf("coeffs %g %g %g - lastobj %g\n",coeff0,coeff1,coeff2,lastObjective); 00203 printf("obj at saved %g, obj now %g zero deriv at %g - value %g\n", 00204 coeff0+coeff1+coeff2,coeff0,lambda,lambdaValue); 00205 if (!iPass) lambda=0.0; 00206 if (lambda>0.0&&lambda<=1.0) { 00207 // update solution 00208 for (iColumn=0;iColumn<numberColumns;iColumn++) 00209 solution[iColumn] = lambda * saveSolution[iColumn] 00210 + (1.0-lambda) * solution[iColumn]; 00211 if (lambda>0.999) { 00212 memcpy(this->dualRowSolution(),savePi,numberRows*sizeof(double)); 00213 memcpy(status_,saveStatus,numberRows+numberColumns); 00214 } 00215 if (lambda>0.99999&&fabs(coeff1+coeff2)>1.0e-2) { 00216 // tighten all 00217 goodMove=-1; 00218 } 00219 } 00220 } 00221 memcpy(objective,saveObjective,numberColumns*sizeof(double)); 00222 for (iColumn=0;iColumn<numberColumns;iColumn++) 00223 objValue += objective[iColumn]*solution[iColumn]; 00224 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00225 iColumn=listNonLinearColumn[jNon]; 00226 if (getColumnStatus(iColumn)==basic) { 00227 if (solution[iColumn]<columnLower[iColumn]+1.0e-8) 00228 statusCheck[iColumn]='l'; 00229 else if (solution[iColumn]>columnUpper[iColumn]-1.0e-8) 00230 statusCheck[iColumn]='u'; 00231 else 00232 statusCheck[iColumn]='B'; 00233 } else { 00234 if (solution[iColumn]<columnLower[iColumn]+1.0e-8) 00235 statusCheck[iColumn]='L'; 00236 else 00237 statusCheck[iColumn]='U'; 00238 } 00239 double valueI = solution[iColumn]; 00240 int j; 00241 for (j=columnQuadraticStart[iColumn]; 00242 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) { 00243 int jColumn = columnQuadratic[j]; 00244 double valueJ = solution[jColumn]; 00245 double elementValue = quadraticElement[j]; 00246 elementValue *= 0.5; 00247 objValue += valueI*valueJ*elementValue; 00248 offset += valueI*valueJ*elementValue; 00249 double gradientI = valueJ*elementValue; 00250 double gradientJ = valueI*elementValue; 00251 offset -= gradientI*valueI; 00252 objective[iColumn] += gradientI; 00253 offset -= gradientJ*valueJ; 00254 objective[jColumn] += gradientJ; 00255 } 00256 } 00257 printf("objective %g, objective offset %g\n",objValue,offset); 00258 setDblParam(ClpObjOffset,objectiveOffset-offset); 00259 objValue *= whichWay; 00260 int * temp=last[2]; 00261 last[2]=last[1]; 00262 last[1]=last[0]; 00263 last[0]=temp; 00264 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00265 iColumn=listNonLinearColumn[jNon]; 00266 double change = solution[iColumn]-saveSolution[iColumn]; 00267 if (change<-1.0e-5) { 00268 if (fabs(change+trust[jNon])<1.0e-5) 00269 temp[jNon]=-1; 00270 else 00271 temp[jNon]=-2; 00272 } else if(change>1.0e-5) { 00273 if (fabs(change-trust[jNon])<1.0e-5) 00274 temp[jNon]=1; 00275 else 00276 temp[jNon]=2; 00277 } else { 00278 temp[jNon]=0; 00279 } 00280 } 00281 // goodMove +1 yes, 0 no, -1 last was bad - just halve gaps, -2 do nothing 00282 double maxDelta=0.0; 00283 if (goodMove>=0) { 00284 if (objValue<=lastObjective) 00285 goodMove=1; 00286 else 00287 goodMove=0; 00288 } else { 00289 maxDelta=1.0e10; 00290 } 00291 double maxGap=0.0; 00292 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00293 iColumn=listNonLinearColumn[jNon]; 00294 maxDelta = max(maxDelta, 00295 fabs(solution[iColumn]-saveSolution[iColumn])); 00296 if (goodMove>0) { 00297 if (last[0][jNon]*last[1][jNon]<0) { 00298 // halve 00299 trust[jNon] *= 0.5; 00300 } else { 00301 if (last[0][jNon]==last[1][jNon]&& 00302 last[0][jNon]==last[2][jNon]) 00303 trust[jNon] *= 1.5; 00304 } 00305 } else if (goodMove!=-2&&trust[jNon]>10.0*deltaTolerance) { 00306 trust[jNon] *= 0.2; 00307 } 00308 maxGap = max(maxGap,trust[jNon]); 00309 } 00310 std::cout<<"largest gap is "<<maxGap<<std::endl; 00311 if (iPass>10000) { 00312 for (jNon=0;jNon<numberNonLinearColumns;jNon++) 00313 trust[jNon] *=0.0001; 00314 } 00315 if (goodMove>0) { 00316 double drop = lastObjective-objValue; 00317 std::cout<<"True drop was "<<drop<<std::endl; 00318 std::cout<<"largest delta is "<<maxDelta<<std::endl; 00319 if (maxDelta<deltaTolerance&&drop<1.0e-4&&goodMove&&lambda<0.99999) { 00320 std::cout<<"Exiting"<<std::endl; 00321 break; 00322 } 00323 } 00324 if (!iPass) 00325 goodMove=1; 00326 targetDrop=0.0; 00327 double * r = this->dualColumnSolution(); 00328 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00329 iColumn=listNonLinearColumn[jNon]; 00330 columnLower[iColumn]=max(solution[iColumn] 00331 -trust[jNon], 00332 trueLower[jNon]); 00333 columnUpper[iColumn]=min(solution[iColumn] 00334 +trust[jNon], 00335 trueUpper[jNon]); 00336 } 00337 if (iPass) { 00338 // get reduced costs 00339 this->matrix()->transposeTimes(savePi, 00340 this->dualColumnSolution()); 00341 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00342 iColumn=listNonLinearColumn[jNon]; 00343 double dj = objective[iColumn]-r[iColumn]; 00344 r[iColumn]=dj; 00345 if (dj<0.0) 00346 targetDrop -= dj*(columnUpper[iColumn]-solution[iColumn]); 00347 else 00348 targetDrop -= dj*(columnLower[iColumn]-solution[iColumn]); 00349 } 00350 } else { 00351 memset(r,0,numberColumns*sizeof(double)); 00352 } 00353 #if 0 00354 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00355 iColumn=listNonLinearColumn[jNon]; 00356 if (statusCheck[iColumn]=='L'&&r[iColumn]<-1.0e-4) { 00357 columnLower[iColumn]=max(solution[iColumn], 00358 trueLower[jNon]); 00359 columnUpper[iColumn]=min(solution[iColumn] 00360 +trust[jNon], 00361 trueUpper[jNon]); 00362 } else if (statusCheck[iColumn]=='U'&&r[iColumn]>1.0e-4) { 00363 columnLower[iColumn]=max(solution[iColumn] 00364 -trust[jNon], 00365 trueLower[jNon]); 00366 columnUpper[iColumn]=min(solution[iColumn], 00367 trueUpper[jNon]); 00368 } else { 00369 columnLower[iColumn]=max(solution[iColumn] 00370 -trust[jNon], 00371 trueLower[jNon]); 00372 columnUpper[iColumn]=min(solution[iColumn] 00373 +trust[jNon], 00374 trueUpper[jNon]); 00375 } 00376 } 00377 #endif 00378 if (goodMove) { 00379 memcpy(saveSolution,solution,numberColumns*sizeof(double)); 00380 memcpy(savePi,this->dualRowSolution(),numberRows*sizeof(double)); 00381 memcpy(saveStatus,status_,numberRows+numberColumns); 00382 00383 std::cout<<"Pass - "<<iPass 00384 <<", target drop is "<<targetDrop 00385 <<std::endl; 00386 lastObjective = objValue; 00387 if (targetDrop<1.0e-5&&goodMove&&iPass) { 00388 printf("Exiting on target drop %g\n",targetDrop); 00389 break; 00390 } 00391 { 00392 double * r = this->dualColumnSolution(); 00393 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00394 iColumn=listNonLinearColumn[jNon]; 00395 printf("Trust %d %g - solution %d %g obj %g dj %g state %c - bounds %g %g\n", 00396 jNon,trust[jNon],iColumn,solution[iColumn],objective[iColumn], 00397 r[iColumn],statusCheck[iColumn],columnLower[iColumn], 00398 columnUpper[iColumn]); 00399 } 00400 } 00401 setLogLevel(63); 00402 this->scaling(false); 00403 this->primal(1); 00404 if (this->status()) { 00405 CoinMpsIO writer; 00406 writer.setMpsData(*matrix(), COIN_DBL_MAX, 00407 getColLower(), getColUpper(), 00408 getObjCoefficients(), 00409 (const char*) 0 /*integrality*/, 00410 getRowLower(), getRowUpper(), 00411 NULL,NULL); 00412 writer.writeMps("xx.mps"); 00413 } 00414 assert (!this->status()); // must be feasible 00415 goodMove=1; 00416 } else { 00417 // bad pass - restore solution 00418 printf("Backtracking\n"); 00419 memcpy(solution,saveSolution,numberColumns*sizeof(double)); 00420 memcpy(this->dualRowSolution(),savePi,numberRows*sizeof(double)); 00421 memcpy(status_,saveStatus,numberRows+numberColumns); 00422 iPass--; 00423 goodMove=-1; 00424 } 00425 } 00426 // restore solution 00427 memcpy(solution,saveSolution,numberColumns*sizeof(double)); 00428 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00429 iColumn=listNonLinearColumn[jNon]; 00430 columnLower[iColumn]=max(solution[iColumn], 00431 trueLower[jNon]); 00432 columnUpper[iColumn]=min(solution[iColumn], 00433 trueUpper[jNon]); 00434 } 00435 delete [] statusCheck; 00436 delete [] savePi; 00437 delete [] saveStatus; 00438 // redo objective 00439 double offset=0.0; 00440 double objValue=-objectiveOffset; 00441 memcpy(objective,saveObjective,numberColumns*sizeof(double)); 00442 for (iColumn=0;iColumn<numberColumns;iColumn++) 00443 objValue += objective[iColumn]*solution[iColumn]; 00444 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00445 iColumn=listNonLinearColumn[jNon]; 00446 double valueI = solution[iColumn]; 00447 int j; 00448 for (j=columnQuadraticStart[iColumn]; 00449 j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) { 00450 int jColumn = columnQuadratic[j]; 00451 double valueJ = solution[jColumn]; 00452 double elementValue = quadraticElement[j]; 00453 objValue += 0.5*valueI*valueJ*elementValue; 00454 offset += 0.5*valueI*valueJ*elementValue; 00455 double gradientI = valueJ*elementValue; 00456 double gradientJ = valueI*elementValue; 00457 offset -= gradientI*valueI; 00458 objective[iColumn] += gradientI; 00459 offset -= gradientJ*valueJ; 00460 objective[jColumn] += gradientJ; 00461 } 00462 } 00463 printf("objective %g, objective offset %g\n",objValue,offset); 00464 setDblParam(ClpObjOffset,objectiveOffset-offset); 00465 this->primal(1); 00466 // redo values 00467 setDblParam(ClpObjOffset,objectiveOffset); 00468 objectiveValue_ += whichWay*offset; 00469 for (jNon=0;jNon<numberNonLinearColumns;jNon++) { 00470 iColumn=listNonLinearColumn[jNon]; 00471 columnLower[iColumn]= trueLower[jNon]; 00472 columnUpper[iColumn]= trueUpper[jNon]; 00473 } 00474 memcpy(objective,saveObjective,numberColumns*sizeof(double)); 00475 delete [] saveSolution; 00476 for (iPass=0;iPass<3;iPass++) 00477 delete [] last[iPass]; 00478 delete [] trust; 00479 delete [] trueUpper; 00480 delete [] trueLower; 00481 delete [] saveObjective; 00482 delete [] listNonLinearColumn; 00483 return 0; 00484 } |
|
Refactorizes if necessary Checks if finished. Updates status. lastCleaned refers to iteration at which some objective/feasibility cleaning too place. type - 0 initial so set up save arrays etc
Definition at line 2134 of file ClpSimplexPrimalQuadratic.cpp. References checkComplementarity(), ClpNonLinearCost::checkInfeasibilities(), ClpSimplex::createRim(), ClpQuadraticInfo::crucialSj(), ClpQuadraticInfo::currentPhase(), ClpQuadraticInfo::currentSolution(), ClpSimplex::dualFeasible(), ClpSimplex::gutsOfSolution(), ClpSimplexProgress::lastIterationNumber(), ClpPrimalColumnPivot::looksOptimal(), ClpSimplexProgress::looping(), CoinMessageHandler::message(), ClpNonLinearCost::numberInfeasibilities(), ClpQuadraticInfo::numberXColumns(), ClpModel::objectiveValue(), ClpSimplex::primalFeasible(), CoinMessageHandler::printing(), ClpQuadraticInfo::restoreStatus(), ClpQuadraticInfo::saveStatus(), ClpPrimalColumnPivot::saveWeights(), ClpQuadraticInfo::sequenceIn(), ClpQuadraticInfo::setCurrentSolution(), ClpSimplex::setFlagged(), ClpQuadraticInfo::setSequenceIn(), ClpNonLinearCost::sumInfeasibilities(), ClpSimplexPrimal::unflag(), and ClpSimplexPrimal::unPerturb(). Referenced by primalQuadratic2().
02137 { 02138 if (info->currentPhase()) 02139 info->setCurrentSolution(solution_); 02140 //info->saveStatus(); 02141 02142 if (type==2) { 02143 // trouble - restore solution 02144 memcpy(status_ ,saveStatus_,(numberColumns_+numberRows_)*sizeof(char)); 02145 memcpy(rowActivityWork_,savedSolution_+numberColumns_ , 02146 numberRows_*sizeof(double)); 02147 memcpy(columnActivityWork_,savedSolution_ , 02148 numberColumns_*sizeof(double)); 02149 forceFactorization_=1; // a bit drastic but .. 02150 pivotRow_=-1; // say no weights update 02151 changeMade_++; // say change made 02152 info->restoreStatus(); 02153 } 02154 int saveThreshold = factorization_->sparseThreshold(); 02155 int tentativeStatus = problemStatus_; 02156 if (problemStatus_>-3||problemStatus_==-4) { 02157 // factorize 02158 // later on we will need to recover from singularities 02159 // also we could skip if first time 02160 // do weights 02161 // This may save pivotRow_ for use 02162 primalColumnPivot_->saveWeights(this,1); 02163 02164 if (type) { 02165 // is factorization okay? 02166 int numberPivots = factorization_->pivots(); 02167 if (internalFactorize(1)) { 02168 if (solveType_==2) { 02169 // say odd 02170 problemStatus_=5; 02171 return; 02172 } 02173 numberIterations_ = progress_->lastIterationNumber(0); 02174 // no - restore previous basis 02175 assert (info->crucialSj()<0); // need to work out how to unwind 02176 assert (type==1); 02177 memcpy(status_ ,saveStatus_,(numberColumns_+numberRows_)*sizeof(char)); 02178 memcpy(rowActivityWork_,savedSolution_+numberColumns_ , 02179 numberRows_*sizeof(double)); 02180 memcpy(columnActivityWork_,savedSolution_ , 02181 numberColumns_*sizeof(double)); 02182 forceFactorization_=1; // a bit drastic but .. 02183 type = 2; 02184 assert (internalFactorize(1)==0); 02185 info->restoreStatus(); 02186 // flag incoming 02187 if (numberPivots==1) { 02188 int crucialSj = info->crucialSj(); 02189 if (crucialSj<0) { 02190 setFlagged(sequenceIn_); 02191 } else { 02192 int iSequence; 02193 int numberXColumns = info->numberXColumns(); 02194 if (crucialSj<numberRows_) { 02195 // row 02196 iSequence = crucialSj-numberXColumns+numberColumns_; 02197 } else { 02198 // column 02199 iSequence = crucialSj-numberRows_; 02200 } 02201 if (getColumnStatus(iSequence)!=basic) { 02202 setFlagged(iSequence); 02203 info->setSequenceIn(-1); 02204 } else { 02205 printf("**** %d is basic ?\n",iSequence); 02206 } 02207 } 02208 } 02209 changeMade_++; // say change made 02210 } 02211 } 02212 if (problemStatus_!=-4) 02213 problemStatus_=-3; 02214 } 02215 if (info->crucialSj()<0) { 02216 // at this stage status is -3 or -5 if looks unbounded 02217 // get primal and dual solutions 02218 // put back original costs and then check 02219 createRim(4); 02220 if (info->currentPhase()) { 02221 memcpy(solution_,info->currentSolution(), 02222 (numberRows_+numberColumns_)*sizeof(double)); 02223 } 02224 gutsOfSolution(NULL,NULL); 02225 if (info->currentPhase()) { 02226 memcpy(solution_,info->currentSolution(), 02227 (numberRows_+numberColumns_)*sizeof(double)); 02228 nonLinearCost_->checkInfeasibilities(primalTolerance_); 02229 } 02230 checkComplementarity(info,rowArray_[2],rowArray_[3]); 02231 // Double check reduced costs if no action 02232 if (progress->lastIterationNumber(0)==numberIterations_) { 02233 if (primalColumnPivot_->looksOptimal()) { 02234 numberDualInfeasibilities_ = 0; 02235 sumDualInfeasibilities_ = 0.0; 02236 } 02237 } 02238 // Check if looping 02239 int loop; 02240 if (type!=2) 02241 loop = progress->looping(); // saves iteration number 02242 else 02243 loop=-1; 02244 //loop=-1; 02245 if (loop>=0) { 02246 problemStatus_ = loop; //exit if in loop 02247 return ; 02248 } else if (loop<-1) { 02249 // something may have changed 02250 gutsOfSolution(NULL,NULL); 02251 checkComplementarity(info,rowArray_[2],rowArray_[3]); 02252 } 02253 // really for free variables in 02254 //if((progressFlag_&2)!=0) 02255 //problemStatus_=-1;; 02256 progressFlag_ = 0; //reset progress flag 02257 02258 handler_->message(CLP_SIMPLEX_STATUS,messages_) 02259 <<numberIterations_<<objectiveValue(); 02260 handler_->printing(sumPrimalInfeasibilities_>0.0) 02261 <<sumPrimalInfeasibilities_<<numberPrimalInfeasibilities_; 02262 handler_->printing(sumDualInfeasibilities_>0.0) 02263 <<sumDualInfeasibilities_<<numberDualInfeasibilities_; 02264 handler_->printing(numberDualInfeasibilitiesWithoutFree_ 02265 <numberDualInfeasibilities_) 02266 <<numberDualInfeasibilitiesWithoutFree_; 02267 handler_->message()<<CoinMessageEol; 02268 assert (primalFeasible()); 02269 // we may wish to say it is optimal even if infeasible 02270 bool alwaysOptimal = (specialOptions_&1)!=0; 02271 // give code benefit of doubt 02272 if (sumOfRelaxedDualInfeasibilities_ == 0.0&& 02273 sumOfRelaxedPrimalInfeasibilities_ == 0.0&&info->sequenceIn()<0) { 02274 // say optimal (with these bounds etc) 02275 numberDualInfeasibilities_ = 0; 02276 sumDualInfeasibilities_ = 0.0; 02277 numberPrimalInfeasibilities_ = 0; 02278 sumPrimalInfeasibilities_ = 0.0; 02279 } 02280 // had ||(type==3&&problemStatus_!=-5) -- ??? why ???? 02281 if (dualFeasible()||problemStatus_==-4) { 02282 if (nonLinearCost_->numberInfeasibilities()&&!alwaysOptimal) { 02283 //may need infeasiblity cost changed 02284 // we can see if we can construct a ray 02285 // make up a new objective 02286 double saveWeight = infeasibilityCost_; 02287 // save nonlinear cost as we are going to switch off costs 02288 ClpNonLinearCost * nonLinear = nonLinearCost_; 02289 // do twice to make sure Primal solution has settled 02290 // put non-basics to bounds in case tolerance moved 02291 // put back original costs 02292 createRim(4); 02293 // put all non-basic variables to bounds 02294 int iSequence; 02295 for (iSequence=0;iSequence<numberRows_+numberColumns_;iSequence++) { 02296 Status status = getStatus(iSequence); 02297 if (status==atLowerBound||status==isFixed) 02298 solution_[iSequence]=lower_[iSequence]; 02299 else if (status==atUpperBound) 02300 solution_[iSequence]=upper_[iSequence]; 02301 } 02302 nonLinearCost_->checkInfeasibilities(primalTolerance_); 02303 gutsOfSolution(NULL,NULL); 02304 nonLinearCost_->checkInfeasibilities(primalTolerance_); 02305 checkComplementarity(info,rowArray_[2],rowArray_[3]); 02306 02307 infeasibilityCost_=1.0e100; 02308 // put back original costs 02309 createRim(4); 02310 nonLinearCost_->checkInfeasibilities(primalTolerance_); 02311 // may have fixed infeasibilities - double check 02312 if (nonLinearCost_->numberInfeasibilities()==0) { 02313 // carry on 02314 problemStatus_ = -1; 02315 infeasibilityCost_=saveWeight; 02316 nonLinearCost_->checkInfeasibilities(primalTolerance_); 02317 checkComplementarity(info,rowArray_[2],rowArray_[3]); 02318 } else { 02319 nonLinearCost_=NULL; 02320 // scale 02321 int i; 02322 for (i=0;i<numberRows_+numberColumns_;i++) 02323 cost_[i] *= 1.0e-100; 02324 gutsOfSolution(NULL,NULL); 02325 nonLinearCost_=nonLinear; 02326 infeasibilityCost_=saveWeight; 02327 if ((infeasibilityCost_>=1.0e18|| 02328 numberDualInfeasibilities_==0)&&perturbation_==101) { 02329 unPerturb(); // stop any further perturbation 02330 numberDualInfeasibilities_=1; // carry on 02331 } 02332 if (infeasibilityCost_>=1.0e20|| 02333 numberDualInfeasibilities_==0) { 02334 // we are infeasible - use as ray 02335 delete [] ray_; 02336 ray_ = new double [numberRows_]; 02337 memcpy(ray_,dual_,numberRows_*sizeof(double)); 02338 // and get feasible duals 02339 infeasibilityCost_=0.0; 02340 createRim(4); 02341 // put all non-basic variables to bounds 02342 int iSequence; 02343 for (iSequence=0;iSequence<numberRows_+numberColumns_;iSequence++) { 02344 Status status = getStatus(iSequence); 02345 if (status==atLowerBound||status==isFixed) 02346 solution_[iSequence]=lower_[iSequence]; 02347 else if (status==atUpperBound) 02348 solution_[iSequence]=upper_[iSequence]; 02349 } 02350 nonLinearCost_->checkInfeasibilities(primalTolerance_); 02351 gutsOfSolution(NULL,NULL); 02352 checkComplementarity(info,rowArray_[2],rowArray_[3]); 02353 // so will exit 02354 infeasibilityCost_=1.0e30; 02355 // reset infeasibilities 02356 sumPrimalInfeasibilities_=nonLinearCost_->sumInfeasibilities();; 02357 numberPrimalInfeasibilities_= 02358 nonLinearCost_->numberInfeasibilities(); 02359 } 02360 if (infeasibilityCost_<1.0e20) { 02361 infeasibilityCost_ *= 5.0; 02362 changeMade_++; // say change made 02363 handler_->message(CLP_PRIMAL_WEIGHT,messages_) 02364 <<infeasibilityCost_ 02365 <<CoinMessageEol; 02366 // put back original costs and then check 02367 createRim(4); 02368 nonLinearCost_->checkInfeasibilities(0.0); 02369 gutsOfSolution(NULL,NULL); 02370 checkComplementarity(info,rowArray_[2],rowArray_[3]); 02371 problemStatus_=-1; //continue 02372 } else { 02373 // say infeasible 02374 problemStatus_ = 1; 02375 } 02376 } 02377 } else { 02378 // may be optimal 02379 if (perturbation_==101) { 02380 unPerturb(); // stop any further perturbation 02381 lastCleaned=-1; // carry on 02382 } 02383 if ( lastCleaned!=numberIterations_||unflag()) { 02384 handler_->message(CLP_PRIMAL_OPTIMAL,messages_) 02385 <<primalTolerance_ 02386 <<CoinMessageEol; 02387 if (numberTimesOptimal_<4) { 02388 numberTimesOptimal_++; 02389 changeMade_++; // say change made 02390 if (numberTimesOptimal_==1) { 02391 // better to have small tolerance even if slower 02392 factorization_->zeroTolerance(1.0e-15); 02393 } 02394 lastCleaned=numberIterations_; 02395 if (primalTolerance_!=dblParam_[ClpPrimalTolerance]) 02396 handler_->message(CLP_PRIMAL_ORIGINAL,messages_) 02397 <<CoinMessageEol; 02398 double oldTolerance = primalTolerance_; 02399 primalTolerance_=dblParam_[ClpPrimalTolerance]; 02400 // put back original costs and then check 02401 createRim(4); 02402 // put all non-basic variables to bounds 02403 int iSequence; 02404 for (iSequence=0;iSequence<numberRows_+numberColumns_;iSequence++) { 02405 Status status = getStatus(iSequence); 02406 if (status==atLowerBound||status==isFixed) 02407 solution_[iSequence]=lower_[iSequence]; 02408 else if (status==atUpperBound) 02409 solution_[iSequence]=upper_[iSequence]; 02410 } 02411 nonLinearCost_->checkInfeasibilities(oldTolerance); 02412 gutsOfSolution(NULL,NULL); 02413 checkComplementarity(info,rowArray_[2],rowArray_[3]); 02414 problemStatus_ = -1; 02415 } else { 02416 problemStatus_=0; // optimal 02417 if (lastCleaned<numberIterations_) { 02418 handler_->message(CLP_SIMPLEX_GIVINGUP,messages_) 02419 <<CoinMessageEol; 02420 } 02421 } 02422 } else { 02423 problemStatus_=0; // optimal 02424 } 02425 } 02426 } else { 02427 // see if looks unbounded 02428 if (problemStatus_==-5) { 02429 if (nonLinearCost_->numberInfeasibilities()) { 02430 if (infeasibilityCost_>1.0e18&&perturbation_==101) { 02431 // back off weight 02432 infeasibilityCost_ = 1.0e13; 02433 unPerturb(); // stop any further perturbation 02434 } 02435 //we need infeasiblity cost changed 02436 if (infeasibilityCost_<1.0e20) { 02437 infeasibilityCost_ *= 5.0; 02438 changeMade_++; // say change made 02439 handler_->message(CLP_PRIMAL_WEIGHT,messages_) 02440 <<infeasibilityCost_ 02441 <<CoinMessageEol; 02442 // put back original costs and then check 02443 createRim(4); 02444 gutsOfSolution(NULL,NULL); 02445 checkComplementarity(info,rowArray_[2],rowArray_[3]); 02446 problemStatus_=-1; //continue 02447 } else { 02448 // say unbounded 02449 problemStatus_ = 2; 02450 } 02451 } else { 02452 // say unbounded 02453 problemStatus_ = 2; 02454 } 02455 } else { 02456 if(type==3&&problemStatus_!=-5) 02457 unflag(); // odd 02458 // carry on 02459 problemStatus_ = -1; 02460 } 02461 } 02462 } else { 02463 // don't update solution 02464 problemStatus_=-1; 02465 } 02466 if (type==0||type==1) { 02467 if (type!=1||!saveStatus_) { 02468 // create save arrays 02469 delete [] saveStatus_; 02470 delete [] savedSolution_; 02471 saveStatus_ = new unsigned char [numberRows_+numberColumns_]; 02472 savedSolution_ = new double [numberRows_+numberColumns_]; 02473 } 02474 // save arrays 02475 memcpy(saveStatus_,status_,(numberColumns_+numberRows_)*sizeof(char)); 02476 memcpy(savedSolution_+numberColumns_ ,rowActivityWork_, 02477 numberRows_*sizeof(double)); 02478 memcpy(savedSolution_ ,columnActivityWork_,numberColumns_*sizeof(double)); 02479 info->saveStatus(); 02480 } 02481 // restore weights (if saved) - also recompute infeasibility list 02482 if (tentativeStatus>-3) 02483 primalColumnPivot_->saveWeights(this,(type <2) ? 2 : 4); 02484 else 02485 primalColumnPivot_->saveWeights(this,3); 02486 if (problemStatus_<0&&!changeMade_) { 02487 problemStatus_=4; // unknown 02488 } 02489 if (saveThreshold) { 02490 // use default at present 02491 factorization_->sparseThreshold(0); 02492 factorization_->goSparse(); 02493 } 02494 lastGoodIteration_ = numberIterations_; 02495 } |
|
Main part. phase - 0 normal, 1 getting complementary solution, 2 getting basic solution. Definition at line 733 of file ClpSimplexPrimalQuadratic.cpp. References ClpQuadraticInfo::basicRow(), CoinIndexedVector::checkClear(), checkComplementarity(), CoinIndexedVector::clear(), createDjs(), ClpQuadraticInfo::createGradient(), ClpQuadraticInfo::crucialSj(), ClpQuadraticInfo::currentPhase(), CoinIndexedVector::denseVector(), ClpPackedMatrix::getElements(), CoinIndexedVector::getIndices(), ClpPackedMatrix::getIndices(), CoinIndexedVector::getNumElements(), ClpPackedMatrix::getVectorStarts(), ClpQuadraticInfo::gradient(), ClpSimplex::housekeeping(), ClpQuadraticInfo::impliedSj(), ClpQuadraticInfo::infeasCost(), ClpSimplex::isColumn(), CoinMessageHandler::logLevel(), CoinMessageHandler::message(), ClpNonLinearCost::numberInfeasibilities(), ClpQuadraticInfo::numberQuadraticRows(), ClpQuadraticInfo::numberXColumns(), ClpQuadraticInfo::numberXRows(), ClpSimplexPrimal::primalColumn(), ClpSimplexPrimal::primalRay(), primalRow(), ClpQuadraticInfo::sequenceIn(), ClpSimplex::sequenceWithin(), ClpQuadraticInfo::setCrucialSj(), ClpSimplex::setFlagged(), ClpNonLinearCost::setOne(), ClpNonLinearCost::setOneOutgoing(), ClpQuadraticInfo::setSequenceIn(), ClpSimplex::unpack(), ClpSimplexPrimal::updatePrimalsInPrimal(), and ClpPrimalColumnPivot::updateWeights(). Referenced by primalQuadratic2().
00735 { 00736 checkComplementarity (info,rowArray_[0],rowArray_[1]); 00737 int crucialSj = info->crucialSj(); 00738 if (info->crucialSj()>=0) { 00739 printf("after inv %d Sj value %g\n",crucialSj,solution_[info->crucialSj()]); 00740 } 00741 int returnCode=-1; 00742 int phase = info->currentPhase(); 00743 double saveObjective = objectiveValue_; 00744 int numberXColumns = info->numberXColumns(); 00745 int numberXRows = info->numberXRows(); 00746 int numberQuadraticRows = info->numberQuadraticRows(); 00747 // Make list of implied sj 00748 // And backward pointers to basic variables 00749 { 00750 int * impliedSj = info->impliedSj(); 00751 int i; 00752 for (i=numberRows_;i<numberColumns_;i++) { 00753 if (getColumnStatus(i)==basic) 00754 impliedSj[i-numberRows_]=i; 00755 else 00756 impliedSj[i-numberRows_]=-1; 00757 } 00758 int * basicRow = info->basicRow(); 00759 for (i=0;i<numberRows_+numberColumns_;i++) 00760 basicRow[i]=-1; 00761 for (i=0;i<numberRows_;i++) 00762 basicRow[pivotVariable_[i]]=i; 00763 } 00764 int nextSequenceIn=info->sequenceIn(); 00765 int oldSequenceIn=nextSequenceIn; 00766 int saveSequenceIn = sequenceIn_; 00767 // status stays at -1 while iterating, >=0 finished, -2 to invert 00768 // status -3 to go to top without an invert 00769 while (problemStatus_==-1) { 00770 if (info->crucialSj()<0&&factorization_->pivots()>=10) { 00771 returnCode =-2; // refactorize 00772 break; 00773 } 00774 #ifdef CLP_DEBUG 00775 { 00776 int i; 00777 // not [1] as has information 00778 for (i=0;i<4;i++) { 00779 if (i!=1) 00780 rowArray_[i]->checkClear(); 00781 } 00782 for (i=0;i<2;i++) { 00783 columnArray_[i]->checkClear(); 00784 } 00785 } 00786 #endif 00787 // choose column to come in 00788 // can use pivotRow_ to update weights 00789 // pass in list of cost changes so can do row updates (rowArray_[1]) 00790 // NOTE rowArray_[0] is used by computeDuals which is a 00791 // slow way of getting duals but might be used 00792 // Initially Dantzig and look at s variables 00793 // Only do if one not already chosen 00794 int cleanupIteration; 00795 if (nextSequenceIn<0) { 00796 cleanupIteration=0; 00797 if (phase==2) { 00798 // values pass 00799 // get next 00800 int iColumn; 00801 int iStart = oldSequenceIn+1; 00802 for (iColumn=iStart;iColumn<numberXColumns;iColumn++) { 00803 double value = solution_[iColumn]; 00804 double lower = lower_[iColumn]; 00805 double upper = upper_[iColumn]; 00806 if (value>lower+primalTolerance_&&value<upper-primalTolerance_) { 00807 if (getColumnStatus(iColumn)!=basic&&!flagged(iColumn)) { 00808 if (fabs(dj_[iColumn])>10.0*dualTolerance_|| 00809 getColumnStatus(iColumn+numberXColumns+numberQuadraticRows)==basic) { 00810 nextSequenceIn=iColumn; 00811 break; 00812 } 00813 } 00814 } 00815 } 00816 if (nextSequenceIn<0) { 00817 iStart=max(iStart,numberColumns_); 00818 int numberXRows = info->numberXRows(); 00819 for (iColumn=iStart;iColumn<numberColumns_+numberXRows; 00820 iColumn++) { 00821 double value = solution_[iColumn]; 00822 double lower = lower_[iColumn]; 00823 double upper = upper_[iColumn]; 00824 if (value>lower+primalTolerance_&&value<upper-primalTolerance_) { 00825 if (getColumnStatus(iColumn)!=basic&&!flagged(iColumn)&&fabs(dj_[iColumn])>10.0*dualTolerance_) { 00826 nextSequenceIn=iColumn; 00827 break; 00828 } 00829 } 00830 } 00831 } 00832 oldSequenceIn=nextSequenceIn; 00833 saveSequenceIn=sequenceIn_; 00834 sequenceIn_ = nextSequenceIn; 00835 } else { 00836 saveSequenceIn=sequenceIn_; 00837 createDjs(info,rowArray_[3],rowArray_[2]); 00838 dualIn_=0.0; // so no updates 00839 rowArray_[1]->clear(); 00840 primalColumn(rowArray_[1],rowArray_[2],rowArray_[3], 00841 columnArray_[0],columnArray_[1]); 00842 } 00843 } else { 00844 saveSequenceIn=sequenceIn_; 00845 sequenceIn_ = nextSequenceIn; 00846 if (phase==2) { 00847 if ((sequenceIn_<numberXColumns||sequenceIn_>=numberColumns_)&&info->crucialSj()<0) 00848 cleanupIteration=0; 00849 else 00850 cleanupIteration=1; 00851 } else { 00852 cleanupIteration=1; 00853 } 00854 } 00855 pivotRow_=-1; 00856 sequenceOut_=-1; 00857 rowArray_[1]->clear(); 00858 if (sequenceIn_>=0) { 00859 nextSequenceIn=-1; 00860 // we found a pivot column 00861 int chosen = sequenceIn_; 00862 // do second half of iteration 00863 while (chosen>=0) { 00864 int saveSequenceInInfo=chosen; 00865 int saveCrucialSjInfo=info->crucialSj(); 00866 rowArray_[1]->clear(); 00867 checkComplementarity (info,rowArray_[3],rowArray_[1]); 00868 printf("True objective is %g, infeas cost %g, sum %g\n", 00869 objectiveValue_,info->infeasCost(),objectiveValue_+info->infeasCost()); 00870 objectiveValue_=saveObjective; 00871 returnCode=-1; 00872 pivotRow_=-1; 00873 sequenceOut_=-1; 00874 // we found a pivot column 00875 // update the incoming column 00876 sequenceIn_=chosen; 00877 chosen=-1; 00878 unpack(rowArray_[1]); 00879 // compute dj in case linear 00880 { 00881 info->createGradient(this); 00882 double * gradient = info->gradient(); 00883 dualIn_=gradient[sequenceIn_]; 00884 int j; 00885 const double * element = rowArray_[1]->denseVector(); 00886 int numberNonZero=rowArray_[1]->getNumElements(); 00887 const int * whichRow = rowArray_[1]->getIndices(); 00888 bool packed = rowArray_[1]->packedMode(); 00889 if (packed) { 00890 for (j=0;j<numberNonZero; j++) { 00891 int iRow = whichRow[j]; 00892 dualIn_ -= element[j]*dual_[iRow]; 00893 } 00894 } else { 00895 for (j=0;j<numberNonZero; j++) { 00896 int iRow = whichRow[j]; 00897 dualIn_ -= element[iRow]*dual_[iRow]; 00898 } 00899 } 00900 } 00901 if ((!cleanupIteration&&sequenceIn_<numberXColumns)|| 00902 (cleanupIteration&&info->crucialSj()<numberColumns_&&info->crucialSj()>=numberRows_)) { 00903 int iSequence; 00904 if (!cleanupIteration) 00905 iSequence=sequenceIn_; 00906 else 00907 iSequence=info->crucialSj()-numberRows_; 00908 // may need to re-do row of basis 00909 int * impliedSj = info->impliedSj(); 00910 if (impliedSj[iSequence]>=0) { 00911 // mark as valid 00912 impliedSj[iSequence]=-1; 00913 ClpPackedMatrix* rowCopy = 00914 dynamic_cast< ClpPackedMatrix*>(rowCopy_); 00915 assert(rowCopy); 00916 const int * column = rowCopy->getIndices(); 00917 const CoinBigIndex * rowStart = rowCopy->getVectorStarts(); 00918 const double * rowElement = rowCopy->getElements(); 00919 int iRow=iSequence+numberXRows; 00920 int i; 00921 int * index = rowArray_[2]->getIndices(); 00922 double * element = rowArray_[2]->denseVector(); 00923 int n=0; 00924 int * basicRow = info->basicRow(); 00925 int * permute = factorization_->pivotColumn(); 00926 for (i=rowStart[iRow];i<rowStart[iRow+1];i++) { 00927 int iColumn = column[i]; 00928 iColumn = basicRow[iColumn]; 00929 if (iColumn>=0&&iColumn!=iRow) { 00930 index[n]=permute[iColumn]; 00931 element[n++]=rowElement[i]; 00932 } 00933 } 00934 factorization_->replaceRow(permute[iRow],n,index,element); 00935 memset(element,0,n*sizeof(double)); 00936 } 00937 } 00938 // Take out elements in implied Sj rows 00939 if (1) { 00940 int n=rowArray_[1]->getNumElements(); 00941 int * index = rowArray_[1]->getIndices(); 00942 double * element = rowArray_[1]->denseVector(); 00943 int i; 00944 int * impliedSj = info->impliedSj(); 00945 int n2=0; 00946 for (i=0;i<n;i++) { 00947 int iRow=index[i]-numberXRows; 00948 if (iRow<0||impliedSj[iRow]<0) { 00949 index[n2++]=iRow+numberXRows; 00950 } else { 00951 element[iRow+numberXRows]=0.0; 00952 } 00953 } 00954 rowArray_[1]->setNumElements(n2); 00955 } 00956 factorization_->updateColumnFT(rowArray_[2],rowArray_[1]); 00957 if (cleanupIteration) { 00958 // move back to a version of primalColumn? 00959 valueIn_=solution_[sequenceIn_]; 00960 // should keep pivot row of crucialSj as well (speed) 00961 int iSjRow=-1; 00962 if (crucialSj>=0) { 00963 double * work=rowArray_[1]->denseVector(); 00964 int number=rowArray_[1]->getNumElements(); 00965 int * which=rowArray_[1]->getIndices(); 00966 double tj = 0.0; 00967 int iIndex; 00968 for (iIndex=0;iIndex<number;iIndex++) { 00969 int iRow = which[iIndex]; 00970 double alpha = work[iRow]; 00971 int iPivot=pivotVariable_[iRow]; 00972 if (iPivot==crucialSj) { 00973 tj = alpha; 00974 iSjRow = iRow; 00975 double d2 = solution_[crucialSj]/tj; 00976 if (fabs(solution_[crucialSj])<1.0e-8) 00977 printf("zero crucialSj - pivot out - get right way\n"); 00978 // see which way to go 00979 if (d2>0) 00980 dj_[sequenceIn_]= -1.0; 00981 else 00982 dj_[sequenceIn_]= 1.0; 00983 break; 00984 } 00985 } 00986 if (!tj) { 00987 printf("trouble\n"); 00988 assert (sequenceIn_>numberXColumns&&sequenceIn_<numberColumns_); 00989 dj_[sequenceIn_]=solution_[sequenceIn_]; 00990 //assert(tj); 00991 } 00992 } 00993 00994 dualIn_=dj_[sequenceIn_]; 00995 lowerIn_=lower_[sequenceIn_]; 00996 upperIn_=upper_[sequenceIn_]; 00997 if (dualIn_>0.0) 00998 directionIn_ = -1; 00999 else 01000 directionIn_ = 1; 01001 } else { 01002 // not clean up 01003 lowerIn_=lower_[sequenceIn_]; 01004 upperIn_=upper_[sequenceIn_]; 01005 dualIn_=dj_[sequenceIn_]; 01006 valueIn_=solution_[sequenceIn_]; 01007 if (dualIn_>0.0) 01008 directionIn_ = -1; 01009 else 01010 directionIn_ = 1; 01011 if (sequenceIn_<numberColumns_) { 01012 // Set dj as value of slack 01013 crucialSj = sequenceIn_+ numberQuadraticRows+numberXColumns; // sj which should go to 0.0 01014 } else { 01015 // Set dj as value of pi 01016 int iRow = sequenceIn_-numberColumns_; 01017 crucialSj = iRow+numberXColumns; // pi which should go to 0.0 01018 } 01019 if (crucialSj>=0&&getColumnStatus(crucialSj)!=basic) 01020 crucialSj=-1; 01021 info->setCrucialSj(crucialSj); 01022 } 01023 double oldSj=1.0e30; 01024 if (info->crucialSj()>=0&&cleanupIteration) 01025 oldSj= solution_[info->crucialSj()]; 01026 // save reduced cost 01027 //double saveDj = dualIn_; 01028 // do ratio test and re-compute dj 01029 // Note second parameter long enough for columns 01030 int result=primalRow(rowArray_[1],rowArray_[3], 01031 rowArray_[2],rowArray_[0], 01032 info, 01033 cleanupIteration); 01034 if (pivotRow_==-1&&(phase==2||cleanupIteration)&&fabs(dualIn_)<1.0e-3) { 01035 // try other way 01036 dualIn_=-dualIn_; 01037 directionIn_=-directionIn_; 01038 if (info->crucialSj()>=0) 01039 setColumnStatus(info->crucialSj(),basic); 01040 result=primalRow(rowArray_[1],rowArray_[3], 01041 rowArray_[2],rowArray_[0], 01042 info, 01043 cleanupIteration); 01044 } 01045 saveObjective = objectiveValue_; 01046 if (pivotRow_>=0) { 01047 // If sj out AND not gone out since last invert then add back 01048 // if stable replace in basis 01049 int updateStatus = 0; 01050 if (result<20) { 01051 double saveCheck = factorization_->getAccuracyCheck(); 01052 if (cleanupIteration) 01053 factorization_->relaxAccuracyCheck(1.0e3*saveCheck); 01054 updateStatus=factorization_->replaceColumn(rowArray_[2], 01055 pivotRow_, 01056 alpha_); 01057 factorization_->relaxAccuracyCheck(saveCheck); 01058 } 01059 if (result>=10) { 01060 updateStatus = max(updateStatus,result/10); 01061 result = result%10; 01062 if (updateStatus>1) { 01063 alpha_=0.0; // force re-factorization 01064 info->setSequenceIn(sequenceIn_); 01065 } 01066 } 01067 // if no pivots, bad update but reasonable alpha - take and invert 01068 if (updateStatus==2&& 01069 lastGoodIteration_==numberIterations_&&fabs(alpha_)>1.0e-5) 01070 updateStatus=4; 01071 if (updateStatus==1||updateStatus==4) { 01072 // slight error 01073 if (factorization_->pivots()>5||updateStatus==4) { 01074 returnCode=-3; 01075 } 01076 } else if (updateStatus==2) { 01077 // major error 01078 // Reset sequenceIn_ 01079 // sequenceIn_=saveSequenceIn; 01080 nextSequenceIn=saveSequenceInInfo; 01081 info->setCrucialSj(saveCrucialSjInfo); 01082 if (saveCrucialSjInfo<0&&!phase) 01083 nextSequenceIn=-1; 01084 pivotRow_=-1; 01085 // better to have small tolerance even if slower 01086 factorization_->zeroTolerance(1.0e-15); 01087 int maxFactor = factorization_->maximumPivots(); 01088 if (maxFactor>10) { 01089 if (forceFactorization_<0) 01090 forceFactorization_= maxFactor; 01091 forceFactorization_ = max (1,(forceFactorization_>>1)); 01092 } 01093 // later we may need to unwind more e.g. fake bounds 01094 if(lastGoodIteration_ != numberIterations_||factorization_->pivots()) { 01095 rowArray_[1]->clear(); 01096 pivotRow_=-1; 01097 returnCode=-4; 01098 // retry on return 01099 if (info->crucialSj()>=0) 01100 nextSequenceIn = sequenceIn_; 01101 break; 01102 } else { 01103 // need to reject something 01104 char x = isColumn(sequenceIn_) ? 'C' :'R'; 01105 handler_->message(CLP_SIMPLEX_FLAG,messages_) 01106 <<x<<sequenceWithin(sequenceIn_) 01107 <<CoinMessageEol; 01108 setFlagged(sequenceIn_); 01109 lastBadIteration_ = numberIterations_; // say be more cautious 01110 rowArray_[1]->clear(); 01111 pivotRow_=-1; 01112 returnCode = -5; 01113 break; 01114 01115 } 01116 } else if (updateStatus==3) { 01117 // out of memory 01118 // increase space if not many iterations 01119 if (factorization_->pivots()< 01120 0.5*factorization_->maximumPivots()&& 01121 factorization_->pivots()<200) 01122 factorization_->areaFactor( 01123 factorization_->areaFactor() * 1.1); 01124 returnCode =-2; // factorize now 01125 } 01126 // here do part of steepest - ready for next iteration 01127 primalColumnPivot_->updateWeights(rowArray_[1]); 01128 } else { 01129 if (pivotRow_==-1) { 01130 // no outgoing row is valid 01131 rowArray_[0]->clear(); 01132 if (!factorization_->pivots()) { 01133 returnCode = 2; //say looks unbounded 01134 // do ray 01135 primalRay(rowArray_[1]); 01136 } else { 01137 returnCode = 4; //say looks unbounded but has iterated 01138 } 01139 break; 01140 } else { 01141 // flipping from bound to bound 01142 } 01143 } 01144 01145 01146 // update primal solution 01147 01148 double objectiveChange=0.0; 01149 // Cost on pivot row may change - may need to change dualIn 01150 double oldCost=0.0; 01151 if (pivotRow_>=0) 01152 oldCost = cost(pivotVariable_[pivotRow_]); 01153 // rowArray_[1] is not empty - used to update djs 01154 updatePrimalsInPrimal(rowArray_[1],theta_, objectiveChange,1); 01155 if (pivotRow_>=0) 01156 dualIn_ += (oldCost-cost(pivotVariable_[pivotRow_])); 01157 double oldValue = valueIn_; 01158 if (directionIn_==-1) { 01159 // as if from upper bound 01160 if (sequenceIn_!=sequenceOut_) { 01161 // variable becoming basic 01162 valueIn_ -= fabs(theta_); 01163 } else { 01164 valueIn_=lowerIn_; 01165 } 01166 } else { 01167 // as if from lower bound 01168 if (sequenceIn_!=sequenceOut_) { 01169 // variable becoming basic 01170 valueIn_ += fabs(theta_); 01171 } else { 01172 valueIn_=upperIn_; 01173 } 01174 } 01175 objectiveChange += dualIn_*(valueIn_-oldValue); 01176 // outgoing 01177 if (sequenceIn_!=sequenceOut_) { 01178 if (directionOut_>0) { 01179 valueOut_ = lowerOut_; 01180 } else { 01181 valueOut_ = upperOut_; 01182 } 01183 double lowerValue = lower_[sequenceOut_]; 01184 double upperValue = upper_[sequenceOut_]; 01185 if (sequenceOut_>=numberXColumns&&sequenceOut_<numberColumns_) { 01186 // really free but going to zero 01187 lowerValue=0.0; 01188 upperValue=0.0; 01189 } 01190 assert(valueOut_>=lowerValue-primalTolerance_&& 01191 valueOut_<=upperValue+primalTolerance_); 01192 // may not be exactly at bound and bounds may have changed 01193 #if 1 01194 // Make sure outgoing looks feasible 01195 double useValue=valueOut_; 01196 if (valueOut_<=lowerValue+primalTolerance_) { 01197 directionOut_=1; 01198 useValue= lower_[sequenceOut_]; 01199 } else if (valueOut_>=upperValue-primalTolerance_) { 01200 directionOut_=-1; 01201 useValue= upper_[sequenceOut_]; 01202 } else { 01203 printf("*** variable wandered off bound %g %g %g!\n", 01204 lowerValue,valueOut_,upperValue); 01205 if (valueOut_-lowerValue<=upperValue-valueOut_) { 01206 useValue= lower_[sequenceOut_]; 01207 valueOut_=lowerValue; 01208 directionOut_=1; 01209 } else { 01210 useValue= upper_[sequenceOut_]; 01211 valueOut_=upperValue; 01212 directionOut_=-1; 01213 } 01214 } 01215 solution_[sequenceOut_]=valueOut_; 01216 nonLinearCost_->setOne(sequenceOut_,useValue); 01217 #else 01218 directionOut_=nonLinearCost_->setOneOutgoing(sequenceOut_,valueOut_); 01219 solution_[sequenceOut_]=valueOut_; 01220 #endif 01221 } 01222 // change cost and bounds on incoming if primal 01223 if (sequenceIn_==sequenceOut_&&(lowerOut_!=lowerIn_||upperOut_!=upperIn_)) { 01224 // linear variable superbasic 01225 setStatus(sequenceOut_,superBasic); 01226 } 01227 nonLinearCost_->setOne(sequenceIn_,valueIn_); 01228 int whatNext=housekeeping(objectiveChange); 01229 // and again as housekeeping may have changed 01230 if (sequenceIn_==sequenceOut_&&(lowerOut_!=lowerIn_||upperOut_!=upperIn_)) { 01231 // linear variable superbasic 01232 setStatus(sequenceOut_,superBasic); 01233 } 01234 // And update backward pointers to basic variables 01235 if (sequenceIn_!=sequenceOut_) { 01236 int * basicRow = info->basicRow(); 01237 basicRow[sequenceOut_]=-1; 01238 basicRow[sequenceIn_]=pivotRow_; 01239 } 01240 if (info->crucialSj()>=0) { 01241 assert(fabs(oldSj)>= fabs(solution_[info->crucialSj()])); 01242 printf("%d Sj value went from %g to %g\n",crucialSj,oldSj,solution_[info->crucialSj()]); 01243 } 01244 checkComplementarity (info,rowArray_[2],rowArray_[3]); 01245 printf("After Housekeeping True objective is %g, infeas cost %g, sum %g\n", 01246 objectiveValue_,info->infeasCost(),objectiveValue_+info->infeasCost()); 01247 if (sequenceOut_>=numberXColumns&&sequenceOut_<numberColumns_) { 01248 // really free but going to zero 01249 setStatus(sequenceOut_,isFree); 01250 if (sequenceOut_==info->crucialSj()) 01251 info->setCrucialSj(-1); 01252 } else if (info->crucialSj()>=0) { 01253 // Just possible crucialSj still in but original out again 01254 int crucialSj=info->crucialSj(); 01255 if (crucialSj>=numberXColumns+numberQuadraticRows) { 01256 if (sequenceOut_==crucialSj-numberXColumns-numberQuadraticRows) 01257 info->setCrucialSj(-1); 01258 } else { 01259 if (sequenceOut_-numberColumns_==crucialSj-numberXColumns) 01260 info->setCrucialSj(-1); 01261 } 01262 } 01263 if (info->crucialSj()<0) 01264 result=0; 01265 if (whatNext==1) { 01266 returnCode =-2; // refactorize 01267 } else if (whatNext==2) { 01268 // maximum iterations or equivalent 01269 returnCode=3; 01270 } else if(numberIterations_ == lastGoodIteration_ 01271 + 2 * factorization_->maximumPivots()) { 01272 // done a lot of flips - be safe 01273 returnCode =-2; // refactorize 01274 } 01275 // may need to go round again 01276 cleanupIteration = 1; 01277 // may not be correct on second time 01278 if (result&&(returnCode==-1||returnCode==-2||returnCode==-3)) { 01279 int crucialSj=info->crucialSj(); 01280 if (sequenceOut_<numberXColumns) { 01281 chosen =sequenceOut_ + numberQuadraticRows + numberXColumns; // sj variable 01282 } else if (sequenceOut_>=numberColumns_) { 01283 // Does this mean we can change pi 01284 int iRow = sequenceOut_-numberColumns_; 01285 if (iRow<numberXRows) { 01286 chosen=iRow+numberXColumns; 01287 } else { 01288 printf("Row %d is in column part\n",iRow); 01289 abort(); 01290 } 01291 } else if (sequenceOut_<numberQuadraticRows+numberXColumns) { 01292 // pi out 01293 chosen = sequenceOut_-numberXColumns+numberColumns_; 01294 } else { 01295 // sj out 01296 chosen = sequenceOut_-numberQuadraticRows-numberXColumns; 01297 } 01298 // But double check as original incoming might have gone out 01299 if (chosen==crucialSj) { 01300 chosen=-1; 01301 break; // means original has gone out 01302 } 01303 rowArray_[0]->clear(); 01304 columnArray_[0]->clear(); 01305 if (returnCode==-2) { 01306 // factorization 01307 nextSequenceIn = chosen; 01308 break; 01309 } 01310 } else { 01311 break; 01312 } 01313 } 01314 if (returnCode<-1&&returnCode>-5) { 01315 problemStatus_=-2; // 01316 } else if (returnCode==-5) { 01317 // something flagged - continue; 01318 } else if (returnCode==2) { 01319 problemStatus_=-5; // looks unbounded 01320 } else if (returnCode==4) { 01321 problemStatus_=-2; // looks unbounded but has iterated 01322 } else if (returnCode!=-1) { 01323 assert(returnCode==3); 01324 problemStatus_=3; 01325 } 01326 } else { 01327 // no pivot column 01328 #ifdef CLP_DEBUG 01329 if (handler_->logLevel()&32) 01330 printf("** no column pivot\n"); 01331 #endif 01332 if (nonLinearCost_->numberInfeasibilities()) 01333 problemStatus_=-4; // might be infeasible 01334 returnCode=0; 01335 break; 01336 } 01337 } 01338 info->setSequenceIn(nextSequenceIn); 01339 return returnCode; 01340 } |