limp-cbc 0.3.2.0 → 0.3.2.1
raw patch · 29 files changed
+258/−20548 lines, 29 files
Files
- cbits/coin/CbcBranchAllDifferent.cpp +0/−156
- cbits/coin/CbcBranchToFixLots.cpp +0/−571
- cbits/coin/CbcCbcParam.cpp +0/−11
- cbits/coin/CbcCompareEstimate.cpp +0/−82
- cbits/coin/CbcCompareObjective.cpp +0/−80
- cbits/coin/CbcCutSubsetModifier.cpp +0/−109
- cbits/coin/CbcFathomDynamicProgramming.cpp +0/−1055
- cbits/coin/CbcLinkedUtils.cpp +0/−832
- cbits/coin/Cbc_C_Interface.cpp +0/−2553
- cbits/coin/Cbc_ampl.cpp +0/−1512
- cbits/coin/CglAllDifferent.cpp +0/−578
- cbits/coin/CglLandPTest.cpp +0/−352
- cbits/coin/CglLiftAndProject.cpp +0/−396
- cbits/coin/CglMixedIntegerRounding.cpp +0/−1717
- cbits/coin/CglSimpleRounding.cpp +0/−482
- cbits/coin/ClpDummyMatrix.cpp +0/−263
- cbits/coin/ClpDynamicExampleMatrix.cpp +0/−683
- cbits/coin/ClpGubDynamicMatrix.cpp +0/−2166
- cbits/coin/ClpGubMatrix.cpp +0/−4061
- cbits/coin/Clp_C_Interface.cpp +0/−1323
- cbits/coin/CoinAlloc.cpp +0/−176
- cbits/coin/CoinParam.cpp +0/−566
- cbits/coin/CoinParamUtils.cpp +0/−800
- examples/Base.hs +36/−0
- examples/Clustering.hs +114/−0
- examples/Infeasible.hs +21/−0
- examples/Simple.hs +59/−0
- examples/Stupid.hs +19/−0
- limp-cbc.cabal +9/−24
− cbits/coin/CbcBranchAllDifferent.cpp
@@ -1,156 +0,0 @@-// $Id: CbcBranchAllDifferent.cpp 1902 2013-04-10 16:58:16Z stefan $-// Copyright (C) 2004, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--// Edwin 11/13/2009-- carved out of CbcBranchCut--#if defined(_MSC_VER)-// Turn off compiler warning about long names-# pragma warning(disable:4786)-#endif-#include <cassert>-#include <cstdlib>-#include <cmath>-#include <cfloat>-//#define CBC_DEBUG--#include "OsiSolverInterface.hpp"-#include "CbcModel.hpp"-#include "CbcMessage.hpp"-#include "CbcBranchCut.hpp"-#include "CoinSort.hpp"-#include "CoinError.hpp"-#include "CbcBranchAllDifferent.hpp"--/** Default Constructor-*/-CbcBranchAllDifferent::CbcBranchAllDifferent ()- : CbcBranchCut(),- numberInSet_(0),- which_(NULL)-{-}--/* Useful constructor - passed set of variables-*/-CbcBranchAllDifferent::CbcBranchAllDifferent (CbcModel * model, int numberInSet,- const int * members)- : CbcBranchCut(model)-{- numberInSet_ = numberInSet;- which_ = CoinCopyOfArray(members, numberInSet_);-}-// Copy constructor-CbcBranchAllDifferent::CbcBranchAllDifferent ( const CbcBranchAllDifferent & rhs)- : CbcBranchCut(rhs)-{- numberInSet_ = rhs.numberInSet_;- which_ = CoinCopyOfArray(rhs.which_, numberInSet_);-}--// Clone-CbcObject *-CbcBranchAllDifferent::clone() const-{- return new CbcBranchAllDifferent(*this);-}--// Assignment operator-CbcBranchAllDifferent &-CbcBranchAllDifferent::operator=( const CbcBranchAllDifferent & rhs)-{- if (this != &rhs) {- CbcBranchCut::operator=(rhs);- delete [] which_;- numberInSet_ = rhs.numberInSet_;- which_ = CoinCopyOfArray(rhs.which_, numberInSet_);- }- return *this;-}--// Destructor-CbcBranchAllDifferent::~CbcBranchAllDifferent ()-{- delete [] which_;-}-CbcBranchingObject *-CbcBranchAllDifferent::createCbcBranch(OsiSolverInterface * /*solver*/- , const OsiBranchingInformation * /*info*/,- int /*way*/)-{- // by default way must be -1- //assert (way==-1);- const double * solution = model_->testSolution();- double * values = new double[numberInSet_];- int * which = new int[numberInSet_];- int i;- for (i = 0; i < numberInSet_; i++) {- int iColumn = which_[i];- values[i] = solution[iColumn];- which[i] = iColumn;- }- CoinSort_2(values, values + numberInSet_, which);- double last = -1.0;- double closest = 1.0;- int worst = -1;- for (i = 0; i < numberInSet_; i++) {- if (values[i] - last < closest) {- closest = values[i] - last;- worst = i - 1;- }- last = values[i];- }- assert (closest <= 0.99999);- OsiRowCut down;- down.setLb(-COIN_DBL_MAX);- down.setUb(-1.0);- int pair[2];- double elements[] = {1.0, -1.0};- pair[0] = which[worst];- pair[1] = which[worst+1];- delete [] values;- delete [] which;- down.setRow(2, pair, elements);- // up is same - just with rhs changed- OsiRowCut up = down;- up.setLb(1.0);- up.setUb(COIN_DBL_MAX);- // Say is not a fix type branch- CbcCutBranchingObject * newObject =- new CbcCutBranchingObject(model_, down, up, false);- if (model_->messageHandler()->logLevel() > 1)- printf("creating cut in CbcBranchCut\n");- return newObject;-}-double-CbcBranchAllDifferent::infeasibility(const OsiBranchingInformation * /*info*/,- int &preferredWay) const-{- preferredWay = -1;- //OsiSolverInterface * solver = model_->solver();- const double * solution = model_->testSolution();- //const double * lower = solver->getColLower();- //const double * upper = solver->getColUpper();- double * values = new double[numberInSet_];- int i;- for (i = 0; i < numberInSet_; i++) {- int iColumn = which_[i];- values[i] = solution[iColumn];- }- std::sort(values, values + numberInSet_);- double last = -1.0;- double closest = 1.0;- for (i = 0; i < numberInSet_; i++) {- if (values[i] - last < closest) {- closest = values[i] - last;- }- last = values[i];- }- delete [] values;- if (closest > 0.99999)- return 0.0;- else- return 0.5*(1.0 - closest);-}-
− cbits/coin/CbcBranchToFixLots.cpp
@@ -1,571 +0,0 @@-// $Id: CbcBranchToFixLots.cpp 1902 2013-04-10 16:58:16Z stefan $-// Copyright (C) 2004, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--// Edwin 11/13/2009-- carved out of CbcBranchCut--#if defined(_MSC_VER)-// Turn off compiler warning about long names-# pragma warning(disable:4786)-#endif-#include <cassert>-#include <cstdlib>-#include <cmath>-#include <cfloat>-//#define CBC_DEBUG--#include "OsiSolverInterface.hpp"-#include "CbcModel.hpp"-#include "CbcMessage.hpp"-#include "CbcBranchCut.hpp"-#include "CoinSort.hpp"-#include "CoinError.hpp"-#include "CbcBranchToFixLots.hpp"--/** Default Constructor-- Equivalent to an unspecified binary variable.-*/-CbcBranchToFixLots::CbcBranchToFixLots ()- : CbcBranchCut(),- djTolerance_(COIN_DBL_MAX),- fractionFixed_(1.0),- mark_(NULL),- depth_(-1),- numberClean_(0),- alwaysCreate_(false)-{-}--/* Useful constructor - passed reduced cost tolerance and fraction we would like fixed.- Also depth level to do at.- Also passed number of 1 rows which when clean triggers fix- Always does if all 1 rows cleaned up and number>0 or if fraction columns reached- Also whether to create branch if can't reach fraction.-*/-CbcBranchToFixLots::CbcBranchToFixLots (CbcModel * model, double djTolerance,- double fractionFixed, int depth,- int numberClean,- const char * mark, bool alwaysCreate)- : CbcBranchCut(model)-{- djTolerance_ = djTolerance;- fractionFixed_ = fractionFixed;- if (mark) {- int numberColumns = model->getNumCols();- mark_ = new char[numberColumns];- memcpy(mark_, mark, numberColumns);- } else {- mark_ = NULL;- }- depth_ = depth;- assert (model);- OsiSolverInterface * solver = model_->solver();- matrixByRow_ = *solver->getMatrixByRow();- numberClean_ = numberClean;- alwaysCreate_ = alwaysCreate;-}-// Copy constructor-CbcBranchToFixLots::CbcBranchToFixLots ( const CbcBranchToFixLots & rhs)- : CbcBranchCut(rhs)-{- djTolerance_ = rhs.djTolerance_;- fractionFixed_ = rhs.fractionFixed_;- int numberColumns = model_->getNumCols();- mark_ = CoinCopyOfArray(rhs.mark_, numberColumns);- matrixByRow_ = rhs.matrixByRow_;- depth_ = rhs.depth_;- numberClean_ = rhs.numberClean_;- alwaysCreate_ = rhs.alwaysCreate_;-}--// Clone-CbcObject *-CbcBranchToFixLots::clone() const-{- return new CbcBranchToFixLots(*this);-}--// Assignment operator-CbcBranchToFixLots &-CbcBranchToFixLots::operator=( const CbcBranchToFixLots & rhs)-{- if (this != &rhs) {- CbcBranchCut::operator=(rhs);- djTolerance_ = rhs.djTolerance_;- fractionFixed_ = rhs.fractionFixed_;- int numberColumns = model_->getNumCols();- delete [] mark_;- mark_ = CoinCopyOfArray(rhs.mark_, numberColumns);- matrixByRow_ = rhs.matrixByRow_;- depth_ = rhs.depth_;- numberClean_ = rhs.numberClean_;- alwaysCreate_ = rhs.alwaysCreate_;- }- return *this;-}--// Destructor-CbcBranchToFixLots::~CbcBranchToFixLots ()-{- delete [] mark_;-}-CbcBranchingObject *-CbcBranchToFixLots::createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * /*info*/, int /*way*/)-{- // by default way must be -1- //assert (way==-1);- //OsiSolverInterface * solver = model_->solver();- const double * solution = model_->testSolution();- const double * lower = solver->getColLower();- const double * upper = solver->getColUpper();- const double * dj = solver->getReducedCost();- int i;- int numberIntegers = model_->numberIntegers();- const int * integerVariable = model_->integerVariable();- double integerTolerance =- model_->getDblParam(CbcModel::CbcIntegerTolerance);- // make smaller ?- double tolerance = CoinMin(1.0e-8, integerTolerance);- // How many fixed are we aiming at- int wantedFixed = static_cast<int> (static_cast<double>(numberIntegers) * fractionFixed_);- int nSort = 0;- int numberFixed = 0;- int numberColumns = solver->getNumCols();- int * sort = new int[numberColumns];- double * dsort = new double[numberColumns];- if (djTolerance_ != -1.234567) {- int type = shallWe();- assert (type);- // Take clean first- if (type == 1) {- for (i = 0; i < numberIntegers; i++) {- int iColumn = integerVariable[i];- if (upper[iColumn] > lower[iColumn]) {- if (!mark_ || !mark_[iColumn]) {- if (solution[iColumn] < lower[iColumn] + tolerance) {- if (dj[iColumn] > djTolerance_) {- dsort[nSort] = -dj[iColumn];- sort[nSort++] = iColumn;- }- } else if (solution[iColumn] > upper[iColumn] - tolerance) {- if (dj[iColumn] < -djTolerance_) {- dsort[nSort] = dj[iColumn];- sort[nSort++] = iColumn;- }- }- }- } else {- numberFixed++;- }- }- // sort- CoinSort_2(dsort, dsort + nSort, sort);- nSort = CoinMin(nSort, wantedFixed - numberFixed);- } else if (type < 10) {- int i;- //const double * rowLower = solver->getRowLower();- const double * rowUpper = solver->getRowUpper();- // Row copy- const double * elementByRow = matrixByRow_.getElements();- const int * column = matrixByRow_.getIndices();- const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();- const int * rowLength = matrixByRow_.getVectorLengths();- const double * columnLower = solver->getColLower();- const double * columnUpper = solver->getColUpper();- const double * solution = solver->getColSolution();- int numberColumns = solver->getNumCols();- int numberRows = solver->getNumRows();- for (i = 0; i < numberColumns; i++) {- sort[i] = i;- if (columnLower[i] != columnUpper[i]) {- dsort[i] = 1.0e100;- } else {- dsort[i] = 1.0e50;- numberFixed++;- }- }- for (i = 0; i < numberRows; i++) {- double rhsValue = rowUpper[i];- bool oneRow = true;- // check elements- int numberUnsatisfied = 0;- for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {- int iColumn = column[j];- double value = elementByRow[j];- double solValue = solution[iColumn];- if (columnLower[iColumn] != columnUpper[iColumn]) {- if (solValue < 1.0 - integerTolerance && solValue > integerTolerance)- numberUnsatisfied++;- if (value != 1.0) {- oneRow = false;- break;- }- } else {- rhsValue -= value * floor(solValue + 0.5);- }- }- if (oneRow && rhsValue <= 1.0 + tolerance) {- if (!numberUnsatisfied) {- for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {- int iColumn = column[j];- if (dsort[iColumn] > 1.0e50) {- dsort[iColumn] = 0;- nSort++;- }- }- }- }- }- // sort- CoinSort_2(dsort, dsort + numberColumns, sort);- } else {- // new way- for (i = 0; i < numberIntegers; i++) {- int iColumn = integerVariable[i];- if (upper[iColumn] > lower[iColumn]) {- if (!mark_ || !mark_[iColumn]) {- double distanceDown = solution[iColumn] - lower[iColumn];- double distanceUp = upper[iColumn] - solution[iColumn];- double distance = CoinMin(distanceDown, distanceUp);- if (distance > 0.001 && distance < 0.5) {- dsort[nSort] = distance;- sort[nSort++] = iColumn;- }- }- }- }- // sort- CoinSort_2(dsort, dsort + nSort, sort);- int n = 0;- double sum = 0.0;- for (int k = 0; k < nSort; k++) {- sum += dsort[k];- if (sum <= djTolerance_)- n = k;- else- break;- }- nSort = CoinMin(n, numberClean_ / 1000000);- }- } else {-#define FIX_IF_LESS -0.1- // 3 in same row and sum <FIX_IF_LESS?- int numberRows = matrixByRow_.getNumRows();- const double * solution = model_->testSolution();- const int * column = matrixByRow_.getIndices();- const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();- const int * rowLength = matrixByRow_.getVectorLengths();- double bestSum = 1.0;- int nBest = -1;- int kRow = -1;- OsiSolverInterface * solver = model_->solver();- for (int i = 0; i < numberRows; i++) {- int numberUnsatisfied = 0;- double sum = 0.0;- for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {- int iColumn = column[j];- if (solver->isInteger(iColumn)) {- double solValue = solution[iColumn];- if (solValue > 1.0e-5 && solValue < FIX_IF_LESS) {- numberUnsatisfied++;- sum += solValue;- }- }- }- if (numberUnsatisfied >= 3 && sum < FIX_IF_LESS) {- // possible- if (numberUnsatisfied > nBest ||- (numberUnsatisfied == nBest && sum < bestSum)) {- nBest = numberUnsatisfied;- bestSum = sum;- kRow = i;- }- }- }- assert (nBest > 0);- for (int j = rowStart[kRow]; j < rowStart[kRow] + rowLength[kRow]; j++) {- int iColumn = column[j];- if (solver->isInteger(iColumn)) {- double solValue = solution[iColumn];- if (solValue > 1.0e-5 && solValue < FIX_IF_LESS) {- sort[nSort++] = iColumn;- }- }- }- }- OsiRowCut down;- down.setLb(-COIN_DBL_MAX);- double rhs = 0.0;- for (i = 0; i < nSort; i++) {- int iColumn = sort[i];- double distanceDown = solution[iColumn] - lower[iColumn];- double distanceUp = upper[iColumn] - solution[iColumn];- if (distanceDown < distanceUp) {- rhs += lower[iColumn];- dsort[i] = 1.0;- } else {- rhs -= upper[iColumn];- dsort[i] = -1.0;- }- }- down.setUb(rhs);- down.setRow(nSort, sort, dsort);- down.setEffectiveness(COIN_DBL_MAX); // so will persist- delete [] sort;- delete [] dsort;- // up is same - just with rhs changed- OsiRowCut up = down;- up.setLb(rhs + 1.0);- up.setUb(COIN_DBL_MAX);- // Say can fix one way- CbcCutBranchingObject * newObject =- new CbcCutBranchingObject(model_, down, up, true);- if (model_->messageHandler()->logLevel() > 1)- printf("creating cut in CbcBranchCut\n");- return newObject;-}-/* Does a lot of the work,- Returns 0 if no good, 1 if dj, 2 if clean, 3 if both- 10 if branching on ones away from bound-*/-int-CbcBranchToFixLots::shallWe() const-{- int returnCode = 0;- OsiSolverInterface * solver = model_->solver();- int numberRows = matrixByRow_.getNumRows();- //if (numberRows!=solver->getNumRows())- //return 0;- const double * solution = model_->testSolution();- const double * lower = solver->getColLower();- const double * upper = solver->getColUpper();- const double * dj = solver->getReducedCost();- int i;- int numberIntegers = model_->numberIntegers();- const int * integerVariable = model_->integerVariable();- if (numberClean_ > 1000000) {- int wanted = numberClean_ % 1000000;- int * sort = new int[numberIntegers];- double * dsort = new double[numberIntegers];- int nSort = 0;- for (i = 0; i < numberIntegers; i++) {- int iColumn = integerVariable[i];- if (upper[iColumn] > lower[iColumn]) {- if (!mark_ || !mark_[iColumn]) {- double distanceDown = solution[iColumn] - lower[iColumn];- double distanceUp = upper[iColumn] - solution[iColumn];- double distance = CoinMin(distanceDown, distanceUp);- if (distance > 0.001 && distance < 0.5) {- dsort[nSort] = distance;- sort[nSort++] = iColumn;- }- }- }- }- // sort- CoinSort_2(dsort, dsort + nSort, sort);- int n = 0;- double sum = 0.0;- for (int k = 0; k < nSort; k++) {- sum += dsort[k];- if (sum <= djTolerance_)- n = k;- else- break;- }- delete [] sort;- delete [] dsort;- return (n >= wanted) ? 10 : 0;- }- double integerTolerance =- model_->getDblParam(CbcModel::CbcIntegerTolerance);- // make smaller ?- double tolerance = CoinMin(1.0e-8, integerTolerance);- // How many fixed are we aiming at- int wantedFixed = static_cast<int> (static_cast<double>(numberIntegers) * fractionFixed_);- if (djTolerance_ < 1.0e10) {- int nSort = 0;- int numberFixed = 0;- for (i = 0; i < numberIntegers; i++) {- int iColumn = integerVariable[i];- if (upper[iColumn] > lower[iColumn]) {- if (!mark_ || !mark_[iColumn]) {- if (solution[iColumn] < lower[iColumn] + tolerance) {- if (dj[iColumn] > djTolerance_) {- nSort++;- }- } else if (solution[iColumn] > upper[iColumn] - tolerance) {- if (dj[iColumn] < -djTolerance_) {- nSort++;- }- }- }- } else {- numberFixed++;- }- }- if (numberFixed + nSort < wantedFixed && !alwaysCreate_) {- returnCode = 0;- } else if (numberFixed < wantedFixed) {- returnCode = 1;- } else {- returnCode = 0;- }- }- if (numberClean_) {- // see how many rows clean- int i;- //const double * rowLower = solver->getRowLower();- const double * rowUpper = solver->getRowUpper();- // Row copy- const double * elementByRow = matrixByRow_.getElements();- const int * column = matrixByRow_.getIndices();- const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();- const int * rowLength = matrixByRow_.getVectorLengths();- const double * columnLower = solver->getColLower();- const double * columnUpper = solver->getColUpper();- const double * solution = solver->getColSolution();- int numberClean = 0;- bool someToDoYet = false;- int numberColumns = solver->getNumCols();- char * mark = new char[numberColumns];- int numberFixed = 0;- for (i = 0; i < numberColumns; i++) {- if (columnLower[i] != columnUpper[i]) {- mark[i] = 0;- } else {- mark[i] = 1;- numberFixed++;- }- }- int numberNewFixed = 0;- for (i = 0; i < numberRows; i++) {- double rhsValue = rowUpper[i];- bool oneRow = true;- // check elements- int numberUnsatisfied = 0;- for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {- int iColumn = column[j];- double value = elementByRow[j];- double solValue = solution[iColumn];- if (columnLower[iColumn] != columnUpper[iColumn]) {- if (solValue < 1.0 - integerTolerance && solValue > integerTolerance)- numberUnsatisfied++;- if (value != 1.0) {- oneRow = false;- break;- }- } else {- rhsValue -= value * floor(solValue + 0.5);- }- }- if (oneRow && rhsValue <= 1.0 + tolerance) {- if (numberUnsatisfied) {- someToDoYet = true;- } else {- numberClean++;- for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {- int iColumn = column[j];- if (columnLower[iColumn] != columnUpper[iColumn] && !mark[iColumn]) {- mark[iColumn] = 1;- numberNewFixed++;- }- }- }- }- }- delete [] mark;- //printf("%d clean, %d old fixed, %d new fixed\n",- // numberClean,numberFixed,numberNewFixed);- if (someToDoYet && numberClean < numberClean_- && numberNewFixed + numberFixed < wantedFixed) {- } else if (numberFixed < wantedFixed) {- returnCode |= 2;- } else {- }- }- return returnCode;-}-double-CbcBranchToFixLots::infeasibility(const OsiBranchingInformation * /*info*/,- int &preferredWay) const-{- preferredWay = -1;- CbcNode * node = model_->currentNode();- int depth;- if (node)- depth = CoinMax(node->depth(), 0);- else- return 0.0;- if (depth_ < 0) {- return 0.0;- } else if (depth_ > 0) {- if ((depth % depth_) != 0)- return 0.0;- }- if (djTolerance_ != -1.234567) {- if (!shallWe())- return 0.0;- else- return 1.0e20;- } else {- // See if 3 in same row and sum <FIX_IF_LESS?- int numberRows = matrixByRow_.getNumRows();- const double * solution = model_->testSolution();- const int * column = matrixByRow_.getIndices();- const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();- const int * rowLength = matrixByRow_.getVectorLengths();- double bestSum = 1.0;- int nBest = -1;- OsiSolverInterface * solver = model_->solver();- for (int i = 0; i < numberRows; i++) {- int numberUnsatisfied = 0;- double sum = 0.0;- for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {- int iColumn = column[j];- if (solver->isInteger(iColumn)) {- double solValue = solution[iColumn];- if (solValue > 1.0e-5 && solValue < FIX_IF_LESS) {- numberUnsatisfied++;- sum += solValue;- }- }- }- if (numberUnsatisfied >= 3 && sum < FIX_IF_LESS) {- // possible- if (numberUnsatisfied > nBest ||- (numberUnsatisfied == nBest && sum < bestSum)) {- nBest = numberUnsatisfied;- bestSum = sum;- }- }- }- if (nBest > 0)- return 1.0e20;- else- return 0.0;- }-}-// Redoes data when sequence numbers change-void-CbcBranchToFixLots::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)-{- model_ = model;- if (mark_) {- OsiSolverInterface * solver = model_->solver();- int numberColumnsNow = solver->getNumCols();- char * temp = new char[numberColumnsNow];- memset(temp, 0, numberColumnsNow);- for (int i = 0; i < numberColumns; i++) {- int j = originalColumns[i];- temp[i] = mark_[j];- }- delete [] mark_;- mark_ = temp;- }- OsiSolverInterface * solver = model_->solver();- matrixByRow_ = *solver->getMatrixByRow();-}-
− cbits/coin/CbcCbcParam.cpp
@@ -1,11 +0,0 @@-/* $Id: CbcCbcParam.cpp 1902 2013-04-10 16:58:16Z stefan $ */-// Copyright (C) 2007, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#include "CbcConfig.h"-#ifndef COIN_HAS_CBC-#define COIN_HAS_CBC-#endif-#include "CbcOrClpParam.cpp"-
− cbits/coin/CbcCompareEstimate.cpp
@@ -1,82 +0,0 @@-// $Id: CbcCompareEstimate.cpp 1902 2013-04-10 16:58:16Z stefan $-// Copyright (C) 2002, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--//Edwin 11/25/09 carved out of CbcCompareActual--#if defined(_MSC_VER)-// Turn off compiler warning about long names-# pragma warning(disable:4786)-#endif-#include <cassert>-#include <cstdlib>-#include <cmath>-#include <cfloat>-//#define CBC_DEBUG--#include "CbcMessage.hpp"-#include "CbcModel.hpp"-#include "CbcTree.hpp"-#include "CbcCompareActual.hpp"-#include "CoinError.hpp"-#include "CbcCompareEstimate.hpp"-/** Default Constructor--*/-CbcCompareEstimate::CbcCompareEstimate ()- : CbcCompareBase()-{- test_ = this;-}--// Copy constructor-CbcCompareEstimate::CbcCompareEstimate ( const CbcCompareEstimate & rhs)- : CbcCompareBase(rhs)--{-}--// Clone-CbcCompareBase *-CbcCompareEstimate::clone() const-{- return new CbcCompareEstimate(*this);-}--// Assignment operator-CbcCompareEstimate &-CbcCompareEstimate::operator=( const CbcCompareEstimate & rhs)-{- if (this != &rhs) {- CbcCompareBase::operator=(rhs);- }- return *this;-}--// Destructor-CbcCompareEstimate::~CbcCompareEstimate ()-{-}--// Returns true if y better than x-bool-CbcCompareEstimate::test (CbcNode * x, CbcNode * y)-{- double testX = x->guessedObjectiveValue();- double testY = y->guessedObjectiveValue();- if (testX != testY)- return testX > testY;- else- return equalityTest(x, y); // so ties will be broken in consistent manner-}--// Create C++ lines to get to current state-void-CbcCompareEstimate::generateCpp( FILE * fp)-{- fprintf(fp, "0#include \"CbcCompareActual.hpp\"\n");- fprintf(fp, "3 CbcCompareEstimate compare;\n");- fprintf(fp, "3 cbcModel->setNodeComparison(compare);\n");-}-
− cbits/coin/CbcCompareObjective.cpp
@@ -1,80 +0,0 @@-// $Id: CbcCompareObjective.cpp 1902 2013-04-10 16:58:16Z stefan $-// Copyright (C) 2002, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--//Edwin 11/25/09 carved out of CbcCompareActual--#if defined(_MSC_VER)-// Turn off compiler warning about long names-# pragma warning(disable:4786)-#endif-#include <cassert>-#include <cstdlib>-#include <cmath>-#include <cfloat>-//#define CBC_DEBUG--#include "CbcMessage.hpp"-#include "CbcModel.hpp"-#include "CbcTree.hpp"-#include "CbcCompareActual.hpp"-#include "CoinError.hpp"-#include "CbcCompareObjective.hpp"-/** Default Constructor--*/-CbcCompareObjective::CbcCompareObjective ()- : CbcCompareBase()-{- test_ = this;-}--// Copy constructor-CbcCompareObjective::CbcCompareObjective ( const CbcCompareObjective & rhs)- : CbcCompareBase(rhs)--{-}--// Clone-CbcCompareBase *-CbcCompareObjective::clone() const-{- return new CbcCompareObjective(*this);-}--// Assignment operator-CbcCompareObjective &-CbcCompareObjective::operator=( const CbcCompareObjective & rhs)-{- if (this != &rhs) {- CbcCompareBase::operator=(rhs);- }- return *this;-}--// Destructor-CbcCompareObjective::~CbcCompareObjective ()-{-}--// Returns true if y better than x-bool-CbcCompareObjective::test (CbcNode * x, CbcNode * y)-{- double testX = x->objectiveValue();- double testY = y->objectiveValue();- if (testX != testY)- return testX > testY;- else- return equalityTest(x, y); // so ties will be broken in consistent manner-}-// Create C++ lines to get to current state-void-CbcCompareObjective::generateCpp( FILE * fp)-{- fprintf(fp, "0#include \"CbcCompareActual.hpp\"\n");- fprintf(fp, "3 CbcCompareObjective compare;\n");- fprintf(fp, "3 cbcModel->setNodeComparison(compare);\n");-}
− cbits/coin/CbcCutSubsetModifier.cpp
@@ -1,109 +0,0 @@-// $Id: CbcCutSubsetModifier.cpp 1902 2013-04-10 16:58:16Z stefan $-// Copyright (C) 2003, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--//Edwin 11/25/09 carved out of CbcCutGenerator--#if defined(_MSC_VER)-// Turn off compiler warning about long names-# pragma warning(disable:4786)-#endif-#include "CbcConfig.h"-#include <cassert>-#include <cstdlib>-#include <cmath>-#include <cfloat>--#ifdef COIN_HAS_CLP-#include "OsiClpSolverInterface.hpp"-#else-#include "OsiSolverInterface.hpp"-#endif-#include "CbcModel.hpp"-#include "CbcMessage.hpp"-#include "CbcCutGenerator.hpp"-#include "CbcBranchDynamic.hpp"-#include "CglProbing.hpp"-#include "CoinTime.hpp"-#include "CbcCutSubsetModifier.hpp"--// Default Constructor-CbcCutSubsetModifier::CbcCutSubsetModifier ()- : CbcCutModifier(),- firstOdd_(COIN_INT_MAX)-{-}--// Useful constructor-CbcCutSubsetModifier::CbcCutSubsetModifier (int firstOdd)- : CbcCutModifier()-{- firstOdd_ = firstOdd;-}--// Copy constructor-CbcCutSubsetModifier::CbcCutSubsetModifier ( const CbcCutSubsetModifier & rhs)- : CbcCutModifier(rhs)-{- firstOdd_ = rhs.firstOdd_;-}--// Clone-CbcCutModifier *-CbcCutSubsetModifier::clone() const-{- return new CbcCutSubsetModifier(*this);-}--// Assignment operator-CbcCutSubsetModifier &-CbcCutSubsetModifier::operator=( const CbcCutSubsetModifier & rhs)-{- if (this != &rhs) {- CbcCutModifier::operator=(rhs);- firstOdd_ = rhs.firstOdd_;- }- return *this;-}--// Destructor-CbcCutSubsetModifier::~CbcCutSubsetModifier ()-{-}-/* Returns- 0 unchanged- 1 strengthened- 2 weakened- 3 deleted-*/-int-CbcCutSubsetModifier::modify(const OsiSolverInterface * /*solver*/,- OsiRowCut & cut)-{- int n = cut.row().getNumElements();- if (!n)- return 0;- const int * column = cut.row().getIndices();- //const double * element = cut.row().getElements();- int returnCode = 0;- for (int i = 0; i < n; i++) {- if (column[i] >= firstOdd_) {- returnCode = 3;- break;- }- }-#ifdef COIN_DETAIL- if (!returnCode) {- const double * element = cut.row().getElements();- printf("%g <= ", cut.lb());- for (int i = 0; i < n; i++) {- printf("%g*x%d ", element[i], column[i]);- }- printf("<= %g\n", cut.ub());- }-#endif- //return 3;- return returnCode;-}-
− cbits/coin/CbcFathomDynamicProgramming.cpp
@@ -1,1055 +0,0 @@-/*- $Id: CbcFathomDynamicProgramming.cpp 1888 2013-04-06 20:52:59Z stefan $-*/-// Copyright (C) 2004, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#if defined(_MSC_VER)-// Turn off compiler warning about long names-# pragma warning(disable:4786)-#endif-#include <cassert>-#include <cstdlib>-#include <cmath>-#include <cfloat>--#include "OsiSolverInterface.hpp"-#include "CbcModel.hpp"-#include "CbcMessage.hpp"-#include "CbcFathomDynamicProgramming.hpp"-#include "CoinHelperFunctions.hpp"-#include "CoinPackedMatrix.hpp"-#include "CoinSort.hpp"-// Default Constructor-CbcFathomDynamicProgramming::CbcFathomDynamicProgramming()- : CbcFathom(),- size_(0),- type_(-1),- cost_(NULL),- back_(NULL),- lookup_(NULL),- indices_(NULL),- numberActive_(0),- maximumSizeAllowed_(1000000),- startBit_(NULL),- numberBits_(NULL),- rhs_(NULL),- coefficients_(NULL),- target_(0),- numberNonOne_(0),- bitPattern_(0),- algorithm_(-1)-{--}--// Constructor from model-CbcFathomDynamicProgramming::CbcFathomDynamicProgramming(CbcModel & model)- : CbcFathom(model),- cost_(NULL),- back_(NULL),- lookup_(NULL),- indices_(NULL),- numberActive_(0),- maximumSizeAllowed_(1000000),- startBit_(NULL),- numberBits_(NULL),- rhs_(NULL),- coefficients_(NULL),- target_(0),- numberNonOne_(0),- bitPattern_(0),- algorithm_(-1)-{- type_ = checkPossible();-}--// Destructor-CbcFathomDynamicProgramming::~CbcFathomDynamicProgramming ()-{- gutsOfDelete();-}-// Does deleteions-void-CbcFathomDynamicProgramming::gutsOfDelete()-{- delete [] cost_;- delete [] back_;- delete [] lookup_;- delete [] indices_;- delete [] startBit_;- delete [] numberBits_;- delete [] rhs_;- delete [] coefficients_;- cost_ = NULL;- back_ = NULL;- lookup_ = NULL;- indices_ = NULL;- startBit_ = NULL;- numberBits_ = NULL;- rhs_ = NULL;- coefficients_ = NULL;-}-// Clone-CbcFathom *-CbcFathomDynamicProgramming::clone() const-{- return new CbcFathomDynamicProgramming(*this);-}--// Copy constructor-CbcFathomDynamicProgramming::CbcFathomDynamicProgramming(const CbcFathomDynamicProgramming & rhs)- :- CbcFathom(rhs),- size_(rhs.size_),- type_(rhs.type_),- cost_(NULL),- back_(NULL),- lookup_(NULL),- indices_(NULL),- numberActive_(rhs.numberActive_),- maximumSizeAllowed_(rhs.maximumSizeAllowed_),- startBit_(NULL),- numberBits_(NULL),- rhs_(NULL),- coefficients_(NULL),- target_(rhs.target_),- numberNonOne_(rhs.numberNonOne_),- bitPattern_(rhs.bitPattern_),- algorithm_(rhs.algorithm_)-{- if (size_) {- cost_ = CoinCopyOfArray(rhs.cost_, size_);- back_ = CoinCopyOfArray(rhs.back_, size_);- int numberRows = model_->getNumRows();- lookup_ = CoinCopyOfArray(rhs.lookup_, numberRows);- startBit_ = CoinCopyOfArray(rhs.startBit_, numberActive_);- indices_ = CoinCopyOfArray(rhs.indices_, numberActive_);- numberBits_ = CoinCopyOfArray(rhs.numberBits_, numberActive_);- rhs_ = CoinCopyOfArray(rhs.rhs_, numberActive_);- coefficients_ = CoinCopyOfArray(rhs.coefficients_, numberActive_);- }-}-// Returns type-int-CbcFathomDynamicProgramming::checkPossible(int allowableSize)-{- algorithm_ = -1;- assert(model_->solver());- OsiSolverInterface * solver = model_->solver();- const CoinPackedMatrix * matrix = solver->getMatrixByCol();-- int numberIntegers = model_->numberIntegers();- int numberColumns = solver->getNumCols();- size_ = 0;- if (numberIntegers != numberColumns)- return -1; // can't do dynamic programming-- const double * lower = solver->getColLower();- const double * upper = solver->getColUpper();- const double * rowUpper = solver->getRowUpper();-- int numberRows = model_->getNumRows();- int i;-- // First check columns to see if possible- double * rhs = new double [numberRows];- CoinCopyN(rowUpper, numberRows, rhs);-- // Column copy- const double * element = matrix->getElements();- const int * row = matrix->getIndices();- const CoinBigIndex * columnStart = matrix->getVectorStarts();- const int * columnLength = matrix->getVectorLengths();- bool bad = false;- /* It is just possible that we could say okay as- variables may get fixed but seems unlikely */- for (i = 0; i < numberColumns; i++) {- int j;- double lowerValue = lower[i];- assert (lowerValue == floor(lowerValue));- for (j = columnStart[i];- j < columnStart[i] + columnLength[i]; j++) {- int iRow = row[j];- double value = element[j];- if (upper[i] > lowerValue && (value <= 0.0 || value != floor(value)))- bad = true;- if (lowerValue)- rhs[iRow] -= lowerValue * value;- }- }- // check possible (at present do not allow covering)- int numberActive = 0;- bool infeasible = false;- bool saveBad = bad;- for (i = 0; i < numberRows; i++) {- if (rhs[i] < 0)- infeasible = true;- else if (rhs[i] > 1.0e5 || fabs(rhs[i] - floor(rhs[i] + 0.5)) > 1.0e-7)- bad = true;- else if (rhs[i] > 0.0)- numberActive++;- }- if (bad || infeasible) {- delete [] rhs;- if (!saveBad && infeasible)- return -2;- else- return -1;- }- // check size of array needed- double size = 1.0;- double check = COIN_INT_MAX;- for (i = 0; i < numberRows; i++) {- int n = static_cast<int> (floor(rhs[i] + 0.5));- if (n) {- n++; // allow for 0,1... n- if (numberActive != 1) {- // power of 2- int iBit = 0;- int k = n;- k &= ~1;- while (k) {- iBit++;- k &= ~(1 << iBit);- }- // See if exact power- if (n != (1 << iBit)) {- // round up to next power of 2- n = 1 << (iBit + 1);- }- size *= n;- if (size >= check)- break;- } else {- size = n; // just one constraint- }- }- }- // set size needed- if (size >= check)- size_ = COIN_INT_MAX;- else- size_ = static_cast<int> (size);-- int n01 = 0;- int nbadcoeff = 0;- // See if we can tighten bounds- for (i = 0; i < numberColumns; i++) {- int j;- double lowerValue = lower[i];- double gap = upper[i] - lowerValue;- for (j = columnStart[i];- j < columnStart[i] + columnLength[i]; j++) {- int iRow = row[j];- double value = element[j];- if (value != 1.0)- nbadcoeff++;- if (gap*value > rhs[iRow] + 1.0e-8)- gap = rhs[iRow] / value;- }- gap = lowerValue + floor(gap + 1.0e-7);- if (gap < upper[i])- solver->setColUpper(i, gap);- if (gap <= 1.0)- n01++;- }- if (allowableSize && size_ <= allowableSize) {- if (n01 == numberColumns && !nbadcoeff)- algorithm_ = 0; // easiest- else- algorithm_ = 1;- }- if (allowableSize && size_ <= allowableSize) {- numberActive_ = numberActive;- indices_ = new int [numberActive_];- cost_ = new double [size_];- CoinFillN(cost_, size_, COIN_DBL_MAX);- // but do nothing is okay- cost_[0] = 0.0;- back_ = new int[size_];- CoinFillN(back_, size_, -1);- startBit_ = new int[numberActive_];- numberBits_ = new int[numberActive_];- lookup_ = new int [numberRows];- rhs_ = new int [numberActive_];- numberActive = 0;- int kBit = 0;- for (i = 0; i < numberRows; i++) {- int n = static_cast<int> (floor(rhs[i] + 0.5));- if (n) {- lookup_[i] = numberActive;- rhs_[numberActive] = n;- startBit_[numberActive] = kBit;- n++; // allow for 0,1... n- int iBit = 0;- // power of 2- int k = n;- k &= ~1;- while (k) {- iBit++;- k &= ~(1 << iBit);- }- // See if exact power- if (n != (1 << iBit)) {- // round up to next power of 2- iBit++;- }- if (numberActive != 1) {- n = 1 << iBit;- size *= n;- if (size >= check)- break;- } else {- size = n; // just one constraint- }- numberBits_[numberActive++] = iBit;- kBit += iBit;- } else {- lookup_[i] = -1;- }- }- const double * rowLower = solver->getRowLower();- if (algorithm_ == 0) {- // rhs 1 and coefficients 1- // Get first possible solution for printing- target_ = -1;- int needed = 0;- int numberActive = 0;- for (i = 0; i < numberRows; i++) {- int newRow = lookup_[i];- if (newRow >= 0) {- if (rowLower[i] == rowUpper[i]) {- needed += 1 << numberActive;- numberActive++;- }- }- }- for (i = 0; i < size_; i++) {- if ((i&needed) == needed) {- break;- }- }- target_ = i;- } else {- coefficients_ = new int[numberActive_];- // If not too many general rhs then we can be more efficient- numberNonOne_ = 0;- for (i = 0; i < numberActive_; i++) {- if (rhs_[i] != 1)- numberNonOne_++;- }- if (numberNonOne_*2 < numberActive_) {- // put rhs >1 every second- int * permute = new int[numberActive_];- int * temp = new int[numberActive_];- // try different ways- int k = 0;- for (i = 0; i < numberRows; i++) {- int newRow = lookup_[i];- if (newRow >= 0 && rhs_[newRow] > 1) {- permute[newRow] = k;- k += 2;- }- }- // adjust so k points to last- k -= 2;- // and now rest- int k1 = 1;- for (i = 0; i < numberRows; i++) {- int newRow = lookup_[i];- if (newRow >= 0 && rhs_[newRow] == 1) {- permute[newRow] = k1;- k1++;- if (k1 <= k)- k1++;- }- }- for (i = 0; i < numberActive_; i++) {- int put = permute[i];- temp[put] = rhs_[i];- }- memcpy(rhs_, temp, numberActive_*sizeof(int));- for (i = 0; i < numberActive_; i++) {- int put = permute[i];- temp[put] = numberBits_[i];- }- memcpy(numberBits_, temp, numberActive_*sizeof(int));- k = 0;- for (i = 0; i < numberActive_; i++) {- startBit_[i] = k;- k += numberBits_[i];- }- for (i = 0; i < numberRows; i++) {- int newRow = lookup_[i];- if (newRow >= 0)- lookup_[i] = permute[newRow];- }- delete [] permute;- delete [] temp;- // mark new method- algorithm_ = 2;- }- // Get first possible solution for printing- target_ = -1;- int needed = 0;- int * lower2 = new int[numberActive_];- for (i = 0; i < numberRows; i++) {- int newRow = lookup_[i];- if (newRow >= 0) {- int gap = static_cast<int> (rowUpper[i] - CoinMax(0.0, rowLower[i]));- lower2[newRow] = rhs_[newRow] - gap;- int numberBits = numberBits_[newRow];- int startBit = startBit_[newRow];- if (numberBits == 1 && !gap) {- needed |= 1 << startBit;- }- }- }- for (i = 0; i < size_; i++) {- if ((i&needed) == needed) {- // this one may do- bool good = true;- for (int kk = 0; kk < numberActive_; kk++) {- int numberBits = numberBits_[kk];- int startBit = startBit_[kk];- int size = 1 << numberBits;- int start = 1 << startBit;- int mask = start * (size - 1);- int level = (i & mask) >> startBit;- if (level < lower2[kk]) {- good = false;- break;- }- }- if (good) {- break;- }- }- }- delete [] lower2;- target_ = i;- }- }- delete [] rhs;- if (allowableSize && size_ > allowableSize) {- COIN_DETAIL_PRINT(printf("Too large - need %d entries x 8 bytes\n", size_));- return -1; // too big- } else {- return algorithm_;- }-}--// Resets stuff if model changes-void-CbcFathomDynamicProgramming::resetModel(CbcModel * model)-{- model_ = model;- type_ = checkPossible();-}-int-CbcFathomDynamicProgramming::fathom(double * & betterSolution)-{- int returnCode = 0;- int type = checkPossible(maximumSizeAllowed_);- assert (type != -1);- if (type == -2) {- // infeasible (so complete search done)- return 1;- }- if (algorithm_ >= 0) {- OsiSolverInterface * solver = model_->solver();- const double * lower = solver->getColLower();- const double * upper = solver->getColUpper();- const double * objective = solver->getObjCoefficients();- double direction = solver->getObjSense();- const CoinPackedMatrix * matrix = solver->getMatrixByCol();- // Column copy- const double * element = matrix->getElements();- const int * row = matrix->getIndices();- const CoinBigIndex * columnStart = matrix->getVectorStarts();- const int * columnLength = matrix->getVectorLengths();- const double * rowLower = solver->getRowLower();- const double * rowUpper = solver->getRowUpper();- int numberRows = model_->getNumRows();-- int numberColumns = solver->getNumCols();- double offset;- solver->getDblParam(OsiObjOffset, offset);- double fixedObj = -offset;- int i;- // may be possible- double bestAtTarget = COIN_DBL_MAX;- for (i = 0; i < numberColumns; i++) {- if (size_ > 10000000 && (i % 100) == 0)- COIN_DETAIL_PRINT(printf("column %d\n", i));- double lowerValue = lower[i];- assert (lowerValue == floor(lowerValue));- double cost = direction * objective[i];- fixedObj += lowerValue * cost;- int gap = static_cast<int> (upper[i] - lowerValue);- CoinBigIndex start = columnStart[i];- tryColumn(columnLength[i], row + start, element + start, cost, gap);- if (cost_[target_] < bestAtTarget) {- if (model_->messageHandler()->logLevel() > 1)- printf("At column %d new best objective of %g\n", i, cost_[target_]);- bestAtTarget = cost_[target_];- }- }- returnCode = 1;- int needed = 0;- double bestValue = COIN_DBL_MAX;- int iBest = -1;- if (algorithm_ == 0) {- int numberActive = 0;- for (i = 0; i < numberRows; i++) {- int newRow = lookup_[i];- if (newRow >= 0) {- if (rowLower[i] == rowUpper[i]) {- needed += 1 << numberActive;- numberActive++;- }- }- }- for (i = 0; i < size_; i++) {- if ((i&needed) == needed) {- // this one will do- if (cost_[i] < bestValue) {- bestValue = cost_[i];- iBest = i;- }- }- }- } else {- int * lower = new int[numberActive_];- for (i = 0; i < numberRows; i++) {- int newRow = lookup_[i];- if (newRow >= 0) {- int gap = static_cast<int> (rowUpper[i] - CoinMax(0.0, rowLower[i]));- lower[newRow] = rhs_[newRow] - gap;- int numberBits = numberBits_[newRow];- int startBit = startBit_[newRow];- if (numberBits == 1 && !gap) {- needed |= 1 << startBit;- }- }- }- for (i = 0; i < size_; i++) {- if ((i&needed) == needed) {- // this one may do- bool good = true;- for (int kk = 0; kk < numberActive_; kk++) {- int numberBits = numberBits_[kk];- int startBit = startBit_[kk];- int size = 1 << numberBits;- int start = 1 << startBit;- int mask = start * (size - 1);- int level = (i & mask) >> startBit;- if (level < lower[kk]) {- good = false;- break;- }- }- if (good && cost_[i] < bestValue) {- bestValue = cost_[i];- iBest = i;- }- }- }- delete [] lower;- }- if (bestValue < COIN_DBL_MAX) {- bestValue += fixedObj;- if (model_->messageHandler()->logLevel() > 1)- printf("Can get solution of %g\n", bestValue);- if (bestValue < model_->getMinimizationObjValue()) {- // set up solution- betterSolution = new double[numberColumns];- memcpy(betterSolution, lower, numberColumns*sizeof(double));- while (iBest > 0) {- int n = decodeBitPattern(iBest - back_[iBest], indices_, numberRows);- // Search for cheapest- double bestCost = COIN_DBL_MAX;- int iColumn = -1;- for (i = 0; i < numberColumns; i++) {- if (n == columnLength[i]) {- bool good = true;- for (int j = columnStart[i];- j < columnStart[i] + columnLength[i]; j++) {- int iRow = row[j];- double value = element[j];- int iValue = static_cast<int> (value);- if (iValue != indices_[iRow]) {- good = false;- break;- }- }- if (good && objective[i] < bestCost && betterSolution[i] < upper[i]) {- bestCost = objective[i];- iColumn = i;- }- }- }- assert (iColumn >= 0);- betterSolution[iColumn]++;- assert (betterSolution[iColumn] <= upper[iColumn]);- iBest = back_[iBest];- }- }- // paranoid check- double * rowActivity = new double [numberRows];- memset(rowActivity, 0, numberRows*sizeof(double));- for (i = 0; i < numberColumns; i++) {- int j;- double value = betterSolution[i];- if (value) {- for (j = columnStart[i];- j < columnStart[i] + columnLength[i]; j++) {- int iRow = row[j];- rowActivity[iRow] += value * element[j];- }- }- }- // check was feasible- bool feasible = true;- for (i = 0; i < numberRows; i++) {- if (rowActivity[i] < rowLower[i]) {- if (rowActivity[i] < rowLower[i] - 1.0e-8)- feasible = false;- } else if (rowActivity[i] > rowUpper[i]) {- if (rowActivity[i] > rowUpper[i] + 1.0e-8)- feasible = false;- }- }- if (feasible) {- if (model_->messageHandler()->logLevel() > 0)- printf("** good solution of %g by dynamic programming\n", bestValue);- }- delete [] rowActivity;- }- gutsOfDelete();- }- return returnCode;-}-/* Tries a column- returns true if was used in making any changes.-*/-bool-CbcFathomDynamicProgramming::tryColumn(int numberElements, const int * rows,- const double * coefficients, double cost,- int upper)-{- bool touched = false;- int n = 0;- if (algorithm_ == 0) {- for (int j = 0; j < numberElements; j++) {- int iRow = rows[j];- double value = coefficients[j];- int newRow = lookup_[iRow];- if (newRow < 0 || value > rhs_[newRow]) {- n = 0;- break; //can't use- } else {- indices_[n++] = newRow;- }- }- if (n && upper) {- touched = addOneColumn0(n, indices_, cost);- }- } else {- for (int j = 0; j < numberElements; j++) {- int iRow = rows[j];- double value = coefficients[j];- int iValue = static_cast<int> (value);- int newRow = lookup_[iRow];- if (newRow < 0 || iValue > rhs_[newRow]) {- n = 0;- break; //can't use- } else {- coefficients_[n] = iValue;- indices_[n++] = newRow;- if (upper*iValue > rhs_[newRow]) {- upper = rhs_[newRow] / iValue;- }- }- }- if (n) {- if (algorithm_ == 1) {- for (int k = 1; k <= upper; k++) {- bool t = addOneColumn1(n, indices_, coefficients_, cost);- if (t)- touched = true;- }- } else {- CoinSort_2(indices_, indices_ + n, coefficients_);- for (int k = 1; k <= upper; k++) {- bool t = addOneColumn1A(n, indices_, coefficients_, cost);- if (t)- touched = true;- }- }- }- }- return touched;-}-/* Adds one column if type 0,- returns true if was used in making any changes-*/-bool-CbcFathomDynamicProgramming::addOneColumn0(int numberElements, const int * rows,- double cost)-{- // build up mask- int mask = 0;- int i;- for (i = 0; i < numberElements; i++) {- int iRow = rows[i];- mask |= 1 << iRow;- }- bitPattern_ = mask;- i = size_ - 1 - mask;- bool touched = false;- while (i >= 0) {- int kMask = i & mask;- if (kMask == 0) {- double thisCost = cost_[i];- if (thisCost != COIN_DBL_MAX) {- // possible- double newCost = thisCost + cost;- int next = i + mask;- if (cost_[next] > newCost) {- cost_[next] = newCost;- back_[next] = i;- touched = true;- }- }- i--;- } else {- // we can skip some- int k = (i&~mask);-#ifdef CBC_DEBUG- for (int j = i - 1; j > k; j--) {- int jMask = j & mask;- assert (jMask != 0);- }-#endif- i = k;- }- }- return touched;-}-/* Adds one attempt of one column of type 1,- returns true if was used in making any changes.- At present the user has to call it once for each possible value-*/-bool-CbcFathomDynamicProgramming::addOneColumn1(int numberElements, const int * rows,- const int * coefficients, double cost)-{- /* build up masks.- a) mask for 1 rhs- b) mask for addition- c) mask so adding will overflow- d) individual masks- */- int mask1 = 0;- int maskAdd = 0;- int mask2 = 0;- int i;- int n2 = 0;- int mask[40];- int adjust[40];- assert (numberElements <= 40);- for (i = 0; i < numberElements; i++) {- int iRow = rows[i];- int numberBits = numberBits_[iRow];- int startBit = startBit_[iRow];- if (numberBits == 1) {- mask1 |= 1 << startBit;- maskAdd |= 1 << startBit;- mask2 |= 1 << startBit;- } else {- int value = coefficients[i];- int size = 1 << numberBits;- int start = 1 << startBit;- assert (value < size);- maskAdd |= start * value;- int gap = size - rhs_[iRow] - 1;- assert (gap >= 0);- int hi2 = rhs_[iRow] - value;- if (hi2 < size - 1)- hi2++;- adjust[n2] = start * hi2;- mask2 += start * gap;- mask[n2++] = start * (size - 1);- }- }- bitPattern_ = maskAdd;- i = size_ - 1 - maskAdd;- bool touched = false;- while (i >= 0) {- int kMask = i & mask1;- if (kMask == 0) {- bool good = true;- for (int kk = n2 - 1; kk >= 0; kk--) {- int iMask = mask[kk];- int jMask = iMask & mask2;- int kkMask = iMask & i;- kkMask += jMask;- if (kkMask > iMask) {- // we can skip some- int k = (i&~iMask);- k |= adjust[kk];-#ifdef CBC_DEBUG- for (int j = i - 1; j > k; j--) {- int jMask = j & mask1;- if (jMask == 0) {- bool good = true;- for (int kk = n2 - 1; kk >= 0; kk--) {- int iMask = mask[kk];- int jMask = iMask & mask2;- int kkMask = iMask & i;- kkMask += jMask;- if (kkMask > iMask) {- good = false;- break;- }- }- assert (!good);- }- }-#endif- i = k;- good = false;- break;- }- }- if (good) {- double thisCost = cost_[i];- if (thisCost != COIN_DBL_MAX) {- // possible- double newCost = thisCost + cost;- int next = i + maskAdd;- if (cost_[next] > newCost) {- cost_[next] = newCost;- back_[next] = i;- touched = true;- }- }- }- i--;- } else {- // we can skip some- // we can skip some- int k = (i&~mask1);-#ifdef CBC_DEBUG- for (int j = i - 1; j > k; j--) {- int jMask = j & mask1;- assert (jMask != 0);- }-#endif- i = k;- }- }- return touched;-}-/* Adds one attempt of one column of type 1,- returns true if was used in making any changes.- At present the user has to call it once for each possible value- This version is when there are enough 1 rhs to do faster-*/-bool-CbcFathomDynamicProgramming::addOneColumn1A(int numberElements, const int * rows,- const int * coefficients, double cost)-{- /* build up masks.- a) mask for 1 rhs- b) mask for addition- c) mask so adding will overflow- d) mask for non 1 rhs- */- int maskA = 0;- int maskAdd = 0;- int maskC = 0;- int maskD = 0;- int i;- for (i = 0; i < numberElements; i++) {- int iRow = rows[i];- int numberBits = numberBits_[iRow];- int startBit = startBit_[iRow];- if (numberBits == 1) {- maskA |= 1 << startBit;- maskAdd |= 1 << startBit;- } else {- int value = coefficients[i];- int size = 1 << numberBits;- int start = 1 << startBit;- assert (value < size);- maskAdd |= start * value;- int gap = size - rhs_[iRow] + value - 1;- assert (gap > 0 && gap <= size - 1);- maskC |= start * gap;- maskD |= start * (size - 1);- }- }- bitPattern_ = maskAdd;- int maskDiff = maskD - maskC;- i = size_ - 1 - maskAdd;- bool touched = false;- if (!maskD) {- // Just ones- while (i >= 0) {- int kMask = i & maskA;- if (kMask == 0) {- double thisCost = cost_[i];- if (thisCost != COIN_DBL_MAX) {- // possible- double newCost = thisCost + cost;- int next = i + maskAdd;- if (cost_[next] > newCost) {- cost_[next] = newCost;- back_[next] = i;- touched = true;- }- }- i--;- } else {- // we can skip some- int k = (i&~maskA);- i = k;- }- }- } else {- // More general- while (i >= 0) {- int kMask = i & maskA;- if (kMask == 0) {- int added = i & maskD; // just bits belonging to non 1 rhs- added += maskC; // will overflow mask if bad- added &= (~maskD);- if (added == 0) {- double thisCost = cost_[i];- if (thisCost != COIN_DBL_MAX) {- // possible- double newCost = thisCost + cost;- int next = i + maskAdd;- if (cost_[next] > newCost) {- cost_[next] = newCost;- back_[next] = i;- touched = true;- }- }- i--;- } else {- // we can skip some- int k = i & ~ maskD; // clear all- // Put back enough - but only below where we are- int kk = (numberNonOne_ << 1) - 2;- assert (rhs_[kk] > 1);- int iMask = 0;- for (; kk >= 0; kk -= 2) {- iMask = 1 << startBit_[kk+1];- if ((added&iMask) != 0) {- iMask--;- break;- }- }- assert (kk >= 0);- iMask &= maskDiff;- k |= iMask;- assert (k < i);- i = k;- }- } else {- // we can skip some- int k = (i&~maskA);- i = k;- }- }- }- return touched;-}-// update model-void CbcFathomDynamicProgramming::setModel(CbcModel * model)-{- model_ = model;- type_ = checkPossible();-}-// Gets bit pattern from original column-int CbcFathomDynamicProgramming::bitPattern(int numberElements, const int * rows,- const int * coefficients)-{- int i;- int mask = 0;- switch (algorithm_) {- // just ones- case 0:- for (i = 0; i < numberElements; i++) {- int iRow = rows[i];- iRow = lookup_[iRow];- if (iRow >= 0)- mask |= 1 << iRow;- }- break;- //- case 1:- case 2:- for (i = 0; i < numberElements; i++) {- int iRow = rows[i];- iRow = lookup_[iRow];- if (iRow >= 0) {- int startBit = startBit_[iRow];- int value = coefficients[i];- int start = 1 << startBit;- mask |= start * value;- }- }- break;- }- return mask;-}-// Fills in original column (dense) from bit pattern-int CbcFathomDynamicProgramming::decodeBitPattern(int bitPattern,- int * values,- int numberRows)-{- int i;- int n = 0;- switch (algorithm_) {- // just ones- case 0:- for (i = 0; i < numberRows; i++) {- values[i] = 0;- int iRow = lookup_[i];- if (iRow >= 0) {- if ((bitPattern&(1 << iRow)) != 0) {- values[i] = 1;- n++;- }- }- }- break;- //- case 1:- case 2:- for (i = 0; i < numberRows; i++) {- values[i] = 0;- int iRow = lookup_[i];- if (iRow >= 0) {- int startBit = startBit_[iRow];- int numberBits = numberBits_[iRow];- int iValue = bitPattern >> startBit;- iValue &= ((1 << numberBits) - 1);- if (iValue) {- values[i] = iValue;- n++;- }- }- }- break;- }- return n;-}--
− cbits/coin/CbcLinkedUtils.cpp
@@ -1,832 +0,0 @@-// Copyright (C) 2007, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--/* $Id: CbcLinkedUtils.cpp 1902 2013-04-10 16:58:16Z stefan $ */--/*! \file CbcAugmentClpSimplex.cpp- \brief Hooks to Ampl (for CbcLinked)-- This code is a condensation of ClpAmplStuff.cpp, renamed to better- reflect its current place in cbc.-- The code here had ties to NEW_STYLE_SOLVER code. During the 091209 Watson- meeting, NEW_STYLE_SOLVER code was eliminated. The code here was condensed- from ClpAmplStuff.cpp. The hook into CbcLinked is loadNonLinear. Once you- bring that in, all the rest follows. Still, we're down about 400 lines of- code. In the process, it appears that ClpAmplObjective.cpp was never needed- here; the code was hooked into ClpAmplStuff.cpp. --lh, 091209 ---*/--#include "ClpConfig.h"-#include "CbcConfig.h"-#ifdef COIN_HAS_ASL-#include "CoinPragma.hpp"-#include "CoinHelperFunctions.hpp"-#include "CoinIndexedVector.hpp"-#include "ClpFactorization.hpp"-#include "ClpSimplex.hpp"-#include "ClpAmplObjective.hpp"-#include "ClpConstraintAmpl.hpp"-#include "ClpMessage.hpp"-#include "CoinUtilsConfig.h"-#include "CoinHelperFunctions.hpp"-#include "CoinWarmStartBasis.hpp"-#include "OsiSolverInterface.hpp"-#include "Cbc_ampl.h"-#include "CoinTime.hpp"-#include "CglStored.hpp"-#include "CoinModel.hpp"-#include "CbcLinked.hpp"--extern "C" {- //# include "getstub.h"-# include "asl_pfgh.h"-}--// stolen from IPopt with changes-typedef struct {- double obj_sign_;- ASL_pfgh * asl_;- double * non_const_x_;- int * column_; // for jacobian- int * rowStart_;- double * gradient_;- double * constraintValues_;- int nz_h_full_; // number of nonzeros in hessian- int nerror_;- bool objval_called_with_current_x_;- bool conval_called_with_current_x_;- bool jacval_called_with_current_x_;-} CbcAmplInfo;--//#############################################################################-// Constructors / Destructor / Assignment-//#############################################################################--//--------------------------------------------------------------------// Default Constructor-//--------------------------------------------------------------------ClpAmplObjective::ClpAmplObjective ()- : ClpObjective()-{- type_ = 12;- objective_ = NULL;- amplObjective_ = NULL;- gradient_ = NULL;- offset_ = 0.0;-}--bool get_constraints_linearity(void * amplInfo, int n,- int * const_types)-{- CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;- ASL_pfgh* asl = info->asl_;- //check that n is good- assert(n == n_con);- // check that there are no network constraints- assert(nlnc == 0 && lnc == 0);- //the first nlc constraints are non linear the rest is linear- int i;- for (i = 0; i < nlc; i++) {- const_types[i] = 1;- }- // the rest is linear- for (i = nlc; i < n_con; i++)- const_types[i] = 0;- return true;-}-static bool internal_objval(CbcAmplInfo * info , double & obj_val)-{- ASL_pfgh* asl = info->asl_;- info->objval_called_with_current_x_ = false; // in case the call below fails-- if (n_obj == 0) {- obj_val = 0;- info->objval_called_with_current_x_ = true;- return true;- } else {- double retval = objval(0, info->non_const_x_, (fint*)&info->nerror_);- if (!info->nerror_) {- obj_val = info->obj_sign_ * retval;- info->objval_called_with_current_x_ = true;- return true;- } else {- abort();- }- }-- return false;-}--static bool internal_conval(CbcAmplInfo * info , double * g)-{- ASL_pfgh* asl = info->asl_;- info->conval_called_with_current_x_ = false; // in case the call below fails- assert (g);-- conval(info->non_const_x_, g, (fint*)&info->nerror_);-- if (!info->nerror_) {- info->conval_called_with_current_x_ = true;- return true;- } else {- abort();- }- return false;-}--static bool apply_new_x(CbcAmplInfo * info , bool new_x, int n, const double * x)-{- ASL_pfgh* asl = info->asl_;-- if (new_x) {- // update the flags so these methods are called- // before evaluating the hessian- info->conval_called_with_current_x_ = false;- info->objval_called_with_current_x_ = false;- info->jacval_called_with_current_x_ = false;-- //copy the data to the non_const_x_- if (!info->non_const_x_) {- info->non_const_x_ = new double [n];- }-- for (int i = 0; i < n; i++) {- info->non_const_x_[i] = x[i];- }-- // tell ampl that we have a new x- xknowne(info->non_const_x_, (fint*)&info->nerror_);- return info->nerror_ ? false : true;- }-- return true;-}--static bool eval_f(void * amplInfo, int n, const double * x, bool new_x, double & obj_value)-{- CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;- if (!apply_new_x(info, new_x, n, x)) {- return false;- }-- return internal_objval(info, obj_value);-}--static bool eval_grad_f(void * amplInfo, int n, const double * x, bool new_x, double * grad_f)-{- CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;- ASL_pfgh* asl = info->asl_;- if (!apply_new_x(info, new_x, n, x)) {- return false;- }- int i;-- if (n_obj == 0) {- for (i = 0; i < n; i++) {- grad_f[i] = 0.;- }- } else {- objgrd(0, info->non_const_x_, grad_f, (fint*)&info->nerror_);- if (info->nerror_) {- return false;- }-- if (info->obj_sign_ == -1) {- for (i = 0; i < n; i++) {- grad_f[i] = -grad_f[i];- }- }- }- return true;-}--static bool eval_g(void * amplInfo, int n, const double * x, bool new_x, double * g)-{- CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;-#ifndef NDEBUG- ASL_pfgh* asl = info->asl_;-#endif- // warning: n_var is a macro that assumes we have a variable called asl- assert(n == n_var);-- if (!apply_new_x(info, new_x, n, x)) {- return false;- }-- return internal_conval(info, g);-}--static bool eval_jac_g(void * amplInfo, int n, const double * x, bool new_x,- double * values)-{- CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;- ASL_pfgh* asl = info->asl_;- assert(n == n_var);-- assert (values);- if (!apply_new_x(info, new_x, n, x)) {- return false;- }-- jacval(info->non_const_x_, values, (fint*)&info->nerror_);- if (!info->nerror_) {- return true;- } else {- abort();- }- return false;-}-//--------------------------------------------------------------------// Useful Constructor-//--------------------------------------------------------------------ClpAmplObjective::ClpAmplObjective (void * amplInfo)- : ClpObjective()-{- type_ = 12;- activated_ = 1;- gradient_ = NULL;- objective_ = NULL;- offset_ = 0.0;- amplObjective_ = amplInfo;-}--//--------------------------------------------------------------------// Copy constructor-//--------------------------------------------------------------------ClpAmplObjective::ClpAmplObjective (const ClpAmplObjective & rhs)- : ClpObjective(rhs)-{- amplObjective_ = rhs.amplObjective_;- offset_ = rhs.offset_;- type_ = rhs.type_;- if (!amplObjective_) {- objective_ = NULL;- gradient_ = NULL;- } else {- CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;- ASL_pfgh* asl = info->asl_;-- int numberColumns = n_var;;- if (rhs.objective_) {- objective_ = new double [numberColumns];- memcpy(objective_, rhs.objective_, numberColumns*sizeof(double));- } else {- objective_ = NULL;- }- if (rhs.gradient_) {- gradient_ = new double [numberColumns];- memcpy(gradient_, rhs.gradient_, numberColumns*sizeof(double));- } else {- gradient_ = NULL;- }- }-}---//--------------------------------------------------------------------// Destructor-//--------------------------------------------------------------------ClpAmplObjective::~ClpAmplObjective ()-{- delete [] objective_;- delete [] gradient_;-}--//-----------------------------------------------------------------// Assignment operator-//--------------------------------------------------------------------ClpAmplObjective &-ClpAmplObjective::operator=(const ClpAmplObjective & rhs)-{- if (this != &rhs) {- delete [] objective_;- delete [] gradient_;- amplObjective_ = rhs.amplObjective_;- offset_ = rhs.offset_;- type_ = rhs.type_;- if (!amplObjective_) {- objective_ = NULL;- gradient_ = NULL;- } else {- CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;- ASL_pfgh* asl = info->asl_;-- int numberColumns = n_var;;- if (rhs.objective_) {- objective_ = new double [numberColumns];- memcpy(objective_, rhs.objective_, numberColumns*sizeof(double));- } else {- objective_ = NULL;- }- if (rhs.gradient_) {- gradient_ = new double [numberColumns];- memcpy(gradient_, rhs.gradient_, numberColumns*sizeof(double));- } else {- gradient_ = NULL;- }- }- }- return *this;-}--// Returns gradient-double *-ClpAmplObjective::gradient(const ClpSimplex * model,- const double * solution, double & offset, bool refresh,- int includeLinear)-{- if (model)- assert (model->optimizationDirection() == 1.0);-#ifndef NDEBUG- bool scaling = model && (model->rowScale() || model->objectiveScale() != 1.0 || model->optimizationDirection() != 1.0);-#endif- const double * cost = NULL;- if (model)- cost = model->costRegion();- if (!cost) {- // not in solve- cost = objective_;-#ifndef NDEBUG- scaling = false;-#endif- }- assert (!scaling);- if (!amplObjective_ || !solution || !activated_) {- offset = offset_;- return objective_;- } else {- if (refresh || !gradient_) {- CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;- ASL_pfgh* asl = info->asl_;- int numberColumns = n_var;;-- if (!gradient_)- gradient_ = new double[numberColumns];- assert (solution);- eval_grad_f(amplObjective_, numberColumns, solution, true, gradient_);- // Is this best way?- double objValue = 0.0;- eval_f(amplObjective_, numberColumns, solution, false, objValue);- double objValue2 = 0.0;- for (int i = 0; i < numberColumns; i++)- objValue2 += gradient_[i] * solution[i];- offset_ = objValue2 - objValue; // or other way???- if (model && model->optimizationDirection() != 1.0) {- offset *= model->optimizationDirection();- for (int i = 0; i < numberColumns; i++)- gradient_[i] *= -1.0;- }- }- offset = offset_;- return gradient_;- }-}--//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------ClpObjective * ClpAmplObjective::clone() const-{- return new ClpAmplObjective(*this);-}-// Resize objective-void-ClpAmplObjective::resize(int newNumberColumns)-{- CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;- ASL_pfgh* asl = info->asl_;- int numberColumns = n_var;;- if (numberColumns != newNumberColumns) {- abort();- }--}-// Delete columns in objective-void-ClpAmplObjective::deleteSome(int numberToDelete, const int * which)-{- if (numberToDelete)- abort();-}-/* Returns reduced gradient.Returns an offset (to be added to current one).- */-double-ClpAmplObjective::reducedGradient(ClpSimplex * model, double * region,- bool useFeasibleCosts)-{- int numberRows = model->numberRows();- int numberColumns = model->numberColumns();-- //work space- CoinIndexedVector * workSpace = model->rowArray(0);-- CoinIndexedVector arrayVector;- arrayVector.reserve(numberRows + 1);-- int iRow;-#ifdef CLP_DEBUG- workSpace->checkClear();-#endif- double * array = arrayVector.denseVector();- int * index = arrayVector.getIndices();- int number = 0;- const double * costNow = gradient(model, model->solutionRegion(), offset_,- true, useFeasibleCosts ? 2 : 1);- double * cost = model->costRegion();- const int * pivotVariable = model->pivotVariable();- for (iRow = 0; iRow < numberRows; iRow++) {- int iPivot = pivotVariable[iRow];- double value;- if (iPivot < numberColumns)- value = costNow[iPivot];- else if (!useFeasibleCosts)- value = cost[iPivot];- else- value = 0.0;- if (value) {- array[iRow] = value;- index[number++] = iRow;- }- }- arrayVector.setNumElements(number);-- // Btran basic costs- model->factorization()->updateColumnTranspose(workSpace, &arrayVector);- double * work = workSpace->denseVector();- ClpFillN(work, numberRows, 0.0);- // now look at dual solution- double * rowReducedCost = region + numberColumns;- double * dual = rowReducedCost;- const double * rowCost = cost + numberColumns;- for (iRow = 0; iRow < numberRows; iRow++) {- dual[iRow] = array[iRow];- }- double * dj = region;- ClpDisjointCopyN(costNow, numberColumns, dj);-- model->transposeTimes(-1.0, dual, dj);- for (iRow = 0; iRow < numberRows; iRow++) {- // slack- double value = dual[iRow];- value += rowCost[iRow];- rowReducedCost[iRow] = value;- }- return offset_;-}-/* Returns step length which gives minimum of objective for- solution + theta * change vector up to maximum theta.-- arrays are numberColumns+numberRows-*/-double-ClpAmplObjective::stepLength(ClpSimplex * model,- const double * solution,- const double * change,- double maximumTheta,- double & currentObj,- double & predictedObj,- double & thetaObj)-{- // Assume convex- CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;- ASL_pfgh* asl = info->asl_;-- int numberColumns = n_var;;- double * tempSolution = new double [numberColumns];- double * tempGradient = new double [numberColumns];- // current- eval_f(amplObjective_, numberColumns, solution, true, currentObj);- double objA = currentObj;- double thetaA = 0.0;- // at maximum- int i;- for (i = 0; i < numberColumns; i++)- tempSolution[i] = solution[i] + maximumTheta * change[i];- eval_f(amplObjective_, numberColumns, tempSolution, true, thetaObj);- double objC = thetaObj;- double thetaC = maximumTheta;- double objB = 0.5 * (objA + objC);- double thetaB = 0.5 * maximumTheta;- double gradientNorm = 1.0e6;- while (gradientNorm > 1.0e-6 && thetaC - thetaA > 1.0e-8) {- for (i = 0; i < numberColumns; i++)- tempSolution[i] = solution[i] + thetaB * change[i];- eval_grad_f(amplObjective_, numberColumns, tempSolution, true, tempGradient);- eval_f(amplObjective_, numberColumns, tempSolution, false, objB);- double changeObj = 0.0;- gradientNorm = 0.0;- for (i = 0; i < numberColumns; i++) {- changeObj += tempGradient[i] * change[i];- gradientNorm += tempGradient[i] * tempGradient[i];- }- gradientNorm = fabs(changeObj) / sqrt(gradientNorm);- // Should try and get quadratic convergence by interpolation- if (changeObj < 0.0) {- // increasing is good- thetaA = thetaB;- } else {- // decreasing is good- thetaC = thetaB;- }- thetaB = 0.5 * (thetaA + thetaC);- }- delete [] tempSolution;- delete [] tempGradient;- predictedObj = objB;- return thetaB;-}-// Return objective value (without any ClpModel offset) (model may be NULL)-double-ClpAmplObjective::objectiveValue(const ClpSimplex * model, const double * solution) const-{- CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;- ASL_pfgh* asl = info->asl_;-- int numberColumns = n_var;;- // current- double currentObj = 0.0;- eval_f(amplObjective_, numberColumns, solution, true, currentObj);- return currentObj;-}-// Scale objective-void-ClpAmplObjective::reallyScale(const double * columnScale)-{- abort();-}-/* Given a zeroed array sets nonlinear columns to 1.- Returns number of nonlinear columns-*/-int-ClpAmplObjective::markNonlinear(char * which)-{- int iColumn;- CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;- ASL_pfgh* asl = info->asl_;- int nonLinear = CoinMax(nlvc, nlvo);- for (iColumn = 0; iColumn < nonLinear; iColumn++) {- which[iColumn] = 1;- }- int numberNonLinearColumns = 0;- int numberColumns = n_var;;- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- if (which[iColumn])- numberNonLinearColumns++;- }- return numberNonLinearColumns;-}-// Say we have new primal solution - so may need to recompute-void-ClpAmplObjective::newXValues()-{- CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;- info->conval_called_with_current_x_ = false;- info->objval_called_with_current_x_ = false;- info->jacval_called_with_current_x_ = false;-}--//#############################################################################-// Constructors / Destructor / Assignment-//#############################################################################-//--------------------------------------------------------------------// Default Constructor-//--------------------------------------------------------------------ClpConstraintAmpl::ClpConstraintAmpl ()- : ClpConstraint()-{- type_ = 3;- column_ = NULL;- coefficient_ = NULL;- numberCoefficients_ = 0;- amplInfo_ = NULL;-}--//--------------------------------------------------------------------// Useful Constructor-//--------------------------------------------------------------------ClpConstraintAmpl::ClpConstraintAmpl (int row, void * amplInfo)- : ClpConstraint()-{- type_ = 3;- rowNumber_ = row;- amplInfo_ = amplInfo;- CbcAmplInfo * info = (CbcAmplInfo *) amplInfo_;-#ifndef NDEBUG- ASL_pfgh* asl = info->asl_;-#endif- // warning: nlc is a macro that assumes we have a variable called asl- assert (rowNumber_ < nlc);- numberCoefficients_ = info->rowStart_[rowNumber_+1] - info->rowStart_[rowNumber_];- column_ = CoinCopyOfArray(info->column_ + info->rowStart_[rowNumber_], numberCoefficients_);- coefficient_ = new double [numberCoefficients_];;-}--//--------------------------------------------------------------------// Copy constructor-//--------------------------------------------------------------------ClpConstraintAmpl::ClpConstraintAmpl (const ClpConstraintAmpl & rhs)- : ClpConstraint(rhs)-{- numberCoefficients_ = rhs.numberCoefficients_;- column_ = CoinCopyOfArray(rhs.column_, numberCoefficients_);- coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberCoefficients_);-}---//--------------------------------------------------------------------// Destructor-//--------------------------------------------------------------------ClpConstraintAmpl::~ClpConstraintAmpl ()-{- delete [] column_;- delete [] coefficient_;-}--//-----------------------------------------------------------------// Assignment operator-//--------------------------------------------------------------------ClpConstraintAmpl &-ClpConstraintAmpl::operator=(const ClpConstraintAmpl & rhs)-{- if (this != &rhs) {- delete [] column_;- delete [] coefficient_;- numberCoefficients_ = rhs.numberCoefficients_;- column_ = CoinCopyOfArray(rhs.column_, numberCoefficients_);- coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberCoefficients_);- }- return *this;-}-//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------ClpConstraint * ClpConstraintAmpl::clone() const-{- return new ClpConstraintAmpl(*this);-}--// Returns gradient-int-ClpConstraintAmpl::gradient(const ClpSimplex * model,- const double * solution,- double * gradient,- double & functionValue,- double & offset,- bool useScaling,- bool refresh) const-{- CbcAmplInfo * info = (CbcAmplInfo *) amplInfo_;- ASL_pfgh* asl = info->asl_;- int numberColumns = n_var;;- // If not done then do all- if (!info->jacval_called_with_current_x_) {- bool getStuff = eval_g(amplInfo_, numberColumns, solution, true, info->constraintValues_);- assert (getStuff);- getStuff = eval_jac_g(amplInfo_, numberColumns, solution, false, info->gradient_);- assert (getStuff);- info->jacval_called_with_current_x_ = getStuff;- }- if (refresh || !lastGradient_) {- functionValue_ = info->constraintValues_[rowNumber_];- offset_ = functionValue_; // sign??- if (!lastGradient_)- lastGradient_ = new double[numberColumns];- CoinZeroN(lastGradient_, numberColumns);- assert (!(model && model->rowScale() && useScaling));- int i;- int start = info->rowStart_[rowNumber_];- assert (numberCoefficients_ == info->rowStart_[rowNumber_+1] - start);- for (i = 0; i < numberCoefficients_; i++) {- int iColumn = column_[i];- double valueS = solution[iColumn];- double valueG = info->gradient_[start+i];- lastGradient_[iColumn] = valueG;- offset_ -= valueS * valueG;- }- }- functionValue = functionValue_;- offset = offset_;- memcpy(gradient, lastGradient_, numberColumns*sizeof(double));- return 0;-}-// Resize constraint-void-ClpConstraintAmpl::resize(int newNumberColumns)-{- abort();-}-// Delete columns in constraint-void-ClpConstraintAmpl::deleteSome(int numberToDelete, const int * which)-{- if (numberToDelete) {- abort();- }-}-// Scale constraint-void-ClpConstraintAmpl::reallyScale(const double * columnScale)-{- abort();-}-/* Given a zeroed array sets nonlinear columns to 1.- Returns number of nonlinear columns-*/-int-ClpConstraintAmpl::markNonlinear(char * which) const-{- CbcAmplInfo * info = (CbcAmplInfo *) amplInfo_;- ASL_pfgh* asl = info->asl_;- int iColumn;- int numberNon = 0;- int nonLinear = CoinMax(nlvc, nlvo);- for (iColumn = 0; iColumn < numberCoefficients_; iColumn++) {- int jColumn = column_[iColumn];- if (jColumn < nonLinear) {- which[jColumn] = 1;- numberNon++;- }- }- return numberNon;-}-/* Given a zeroed array sets possible nonzero coefficients to 1.- Returns number of nonzeros-*/-int-ClpConstraintAmpl::markNonzero(char * which) const-{- int iColumn;- for (iColumn = 0; iColumn < numberCoefficients_; iColumn++) {- which[column_[iColumn]] = 1;- }- return numberCoefficients_;-}-// Number of coefficients-int-ClpConstraintAmpl::numberCoefficients() const-{- return numberCoefficients_;-}-// Say we have new primal solution - so may need to recompute-void-ClpConstraintAmpl::newXValues()-{- CbcAmplInfo * info = (CbcAmplInfo *) amplInfo_;- info->conval_called_with_current_x_ = false;- info->objval_called_with_current_x_ = false;- info->jacval_called_with_current_x_ = false;-}--/* Load nonlinear part of problem from AMPL info- Returns 0 if linear- 1 if quadratic objective- 2 if quadratic constraints- 3 if nonlinear objective- 4 if nonlinear constraints- -1 on failure-*/-int-ClpSimplex::loadNonLinear(void * amplInfo, int & numberConstraints,- ClpConstraint ** & constraints)-{- numberConstraints = 0;- constraints = NULL;- CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;- ASL_pfgh* asl = info->asl_;- // For moment don't say quadratic- int type = 0;- if (nlo + nlc) {- // nonlinear- if (!nlc) {- type = 3;- delete objective_;- objective_ = new ClpAmplObjective(amplInfo);- } else {- type = 4;- numberConstraints = nlc;- constraints = new ClpConstraint * [numberConstraints];- if (nlo) {- delete objective_;- objective_ = new ClpAmplObjective(amplInfo);- }- for (int i = 0; i < numberConstraints; i++) {- constraints[i] = new ClpConstraintAmpl(i, amplInfo);- }- }- }- return type;-}-#else-#include "ClpSimplex.hpp"-#include "ClpConstraint.hpp"-int-ClpSimplex::loadNonLinear(void * , int & ,- ClpConstraint ** & )-{- abort();- return 0;-}-#endif-
− cbits/coin/Cbc_C_Interface.cpp
@@ -1,2553 +0,0 @@-// $Id: Cbc_C_Interface.cpp 1902 2013-04-10 16:58:16Z stefan $-// Copyright (C) 2004, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#include <math.h>-#include <cfloat>--#include "CoinPragma.hpp"-//#include "CoinHelperFunctions.hpp"-//#include "CoinPackedMatrix.hpp"-#include "CoinTime.hpp"--#include "CbcModel.hpp"-#include "CbcBranchActual.hpp"--#include "CoinMessageHandler.hpp"-#include "OsiClpSolverInterface.hpp"--// bobe including extras.h to get strdup()-#if defined(__MWERKS__)-// #include <extras.h> // bobe 06-02-14-#endif--// Get C stuff but with extern C-#define CBC_EXTERN_C-#include "Coin_C_defines.h"--const int VERBOSE = 0;--// To allow call backs-class Cbc_MessageHandler- : public CoinMessageHandler {--public:- /**@name Overrides */- //@{- virtual int print();- //@}- /**@name set and get */- //@{- /// Model- const Cbc_Model * model() const;- void setModel(Cbc_Model * model);- /// Call back- void setCallBack(cbc_callback callback);- //@}-- /**@name Constructors, destructor */- //@{- /** Default constructor. */- Cbc_MessageHandler();- /// Constructor with pointer to model- Cbc_MessageHandler(Cbc_Model * model,- FILE * userPointer = NULL);- /** Destructor */- virtual ~Cbc_MessageHandler();- //@}-- /**@name Copy method */- //@{- /** The copy constructor. */- Cbc_MessageHandler(const Cbc_MessageHandler&);- /** The copy constructor from an CoinSimplexMessageHandler. */- Cbc_MessageHandler(const CoinMessageHandler&);-- Cbc_MessageHandler& operator=(const Cbc_MessageHandler&);- /// Clone- virtual CoinMessageHandler * clone() const ;- //@}---protected:- /**@name Data members- The data members are protected to allow access for derived classes. */- //@{- /// Pointer back to model- Cbc_Model * model_;- /// call back- cbc_callback callback_;- //@}-};---//--------------------------------------------------------------------// Default Constructor-//--------------------------------------------------------------------Cbc_MessageHandler::Cbc_MessageHandler ()- : CoinMessageHandler(),- model_(NULL),- callback_(NULL)-{-}--//--------------------------------------------------------------------// Copy constructor-//--------------------------------------------------------------------Cbc_MessageHandler::Cbc_MessageHandler (const Cbc_MessageHandler & rhs)- : CoinMessageHandler(rhs),- model_(rhs.model_),- callback_(rhs.callback_)-{-}--Cbc_MessageHandler::Cbc_MessageHandler (const CoinMessageHandler & rhs)- : CoinMessageHandler(rhs),- model_(NULL),- callback_(NULL)-{-}--// Constructor with pointer to model-Cbc_MessageHandler::Cbc_MessageHandler(Cbc_Model * model,- FILE * /*userPointer*/)- : CoinMessageHandler(),- model_(model),- callback_(NULL)-{-}--//--------------------------------------------------------------------// Destructor-//--------------------------------------------------------------------Cbc_MessageHandler::~Cbc_MessageHandler ()-{-}--//-----------------------------------------------------------------// Assignment operator-//--------------------------------------------------------------------Cbc_MessageHandler &-Cbc_MessageHandler::operator=(const Cbc_MessageHandler & rhs)-{- if (this != &rhs) {- CoinMessageHandler::operator=(rhs);- model_ = rhs.model_;- callback_ = rhs.callback_;- }- return *this;-}-//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------CoinMessageHandler * Cbc_MessageHandler::clone() const-{- return new Cbc_MessageHandler(*this);-}-int-Cbc_MessageHandler::print()-{- if (callback_) {- int messageNumber = currentMessage().externalNumber();- if (currentSource() != "Cbc")- messageNumber += 1000000;- int i;- int nDouble = numberDoubleFields();- assert (nDouble <= 200);- double vDouble[200];- for (i = 0; i < nDouble; i++)- vDouble[i] = doubleValue(i);- int nInt = numberIntFields();- assert (nInt <= 200);- int vInt[200];- for (i = 0; i < nInt; i++)- vInt[i] = intValue(i);- int nString = numberStringFields();- assert (nString <= 200);- char * vString[200];- for (i = 0; i < nString; i++) {- std::string value = stringValue(i);- vString[i] = CoinStrdup(value.c_str());- }- callback_(model_, messageNumber,- nDouble, vDouble,- nInt, vInt,- nString, vString);- for (i = 0; i < nString; i++)- free(vString[i]);-- }- return CoinMessageHandler::print();- return 0;-}-const Cbc_Model *-Cbc_MessageHandler::model() const-{- return model_;-}-void-Cbc_MessageHandler::setModel(Cbc_Model * model)-{- model_ = model;-}-// Call back-void-Cbc_MessageHandler::setCallBack(cbc_callback callback)-{- callback_ = callback;-}-/**- *- * C Interface Routines- *- */-#include "Cbc_C_Interface.h"-#include <string>-#include <stdio.h>-#include <iostream>--#if defined(__MWERKS__)-#pragma export on-#endif--/* Version */-COINLIBAPI double COINLINKAGE Cbc_getVersion()-{- double v = 1.0;- return v;-}--/* Default Cbc_Model constructor */-COINLIBAPI Cbc_Model * COINLINKAGE-Cbc_newModel()-{- const char prefix[] = "Cbc_C_Interface::Cbc_newModel(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- Cbc_Model * model = new Cbc_Model;- OsiClpSolverInterface solver1;- model->solver_ = &solver1;- model->solver_->OsiClpSolverInterface::setHintParam(OsiDoReducePrint, true, OsiHintTry);- model->model_ = new CbcModel(solver1);- model->handler_ = NULL;- model->information_ = NULL;-- if (VERBOSE > 0) printf("%s return\n", prefix);- return model;-}-/* Cbc_Model Destructor */-COINLIBAPI void COINLINKAGE-Cbc_deleteModel(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_deleteModel(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);- fflush(stdout);-- if (VERBOSE > 1) printf("%s delete model->model_\n", prefix);- fflush(stdout);- delete model->model_;-- if (VERBOSE > 1) printf("%s delete model->handler_\n", prefix);- fflush(stdout);- delete model->handler_;-- if (VERBOSE > 1) printf("%s free model->information_\n", prefix);- fflush(stdout);- if (model->information_) free(model->information_);-- if (VERBOSE > 1) printf("%s delete model\n", prefix);- fflush(stdout);- delete model;-- if (VERBOSE > 0) printf("%s return\n", prefix);- fflush(stdout);-}--/* Loads a problem (the constraints on the- rows are given by lower and upper bounds). If a pointer is NULL then the- following values are the default:- <ul>- <li> <code>colub</code>: all columns have upper bound infinity- <li> <code>collb</code>: all columns have lower bound 0- <li> <code>rowub</code>: all rows have upper bound infinity- <li> <code>rowlb</code>: all rows have lower bound -infinity- <li> <code>obj</code>: all variables have 0 objective coefficient- </ul>-- Just like the other loadProblem() method except that the matrix is- given in a standard column major ordered format (without gaps).-*/-COINLIBAPI void COINLINKAGE-Cbc_loadProblem (Cbc_Model * model, const int numcols, const int numrows,- const CoinBigIndex * start, const int* index,- const double* value,- const double* collb, const double* colub,- const double* obj,- const double* rowlb, const double* rowub)-{- const char prefix[] = "Cbc_C_Interface::Cbc_loadProblem(): ";-// const int VERBOSE = 2;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- OsiSolverInterface * solver = model->model_->solver();-- if (VERBOSE > 1) {- printf("%s numcols = %i, numrows = %i\n",- prefix, numcols, numrows);- printf("%s model = %p, start = %p, index = %p, value = %p\n",- prefix, static_cast<void*>(model), static_cast<const void*>(start),- static_cast<const void*>(index), static_cast<const void*>(value));- printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",- prefix, static_cast<const void*>(collb),- static_cast<const void*>(colub), static_cast<const void*>(obj),- static_cast<const void*>(rowlb), static_cast<const void*>(rowub));- }-- if (VERBOSE > 1) printf("%s Calling solver->loadProblem()\n", prefix);- fflush(stdout);-- if (1) {- solver->loadProblem(numcols, numrows, start, index, value,- collb, colub, obj, rowlb, rowub);- } else {- solver->loadProblem(0, 0, NULL, NULL, NULL,- NULL, NULL, NULL, NULL, NULL);- }- if (VERBOSE > 1) printf("%s Finished solver->loadProblem()\n", prefix);- fflush(stdout);-- if (VERBOSE > 0) printf("%s return\n", prefix);-} // Cbc_loadProblem()--/* Read an mps file from the given filename */-COINLIBAPI int COINLINKAGE-Cbc_readMps(Cbc_Model * model, const char *filename)-{- const char prefix[] = "Cbc_C_Interface::Cbc_readMps(): ";-// const int VERBOSE = 2;- if (VERBOSE > 0) printf("%s begin\n", prefix);- if (VERBOSE > 1) printf("%s filename = '%s'\n", prefix, filename);-- int result = 1;- result = model->model_->solver()->readMps(filename);- assert(result == 0);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Write an mps file from the given filename */-COINLIBAPI void COINLINKAGE-Cbc_writeMps(Cbc_Model * model, const char *filename)-{- const char prefix[] = "Cbc_C_Interface::Cbc_writeMps(): ";-// const int VERBOSE = 2;- if (VERBOSE > 0) printf("%s begin\n", prefix);- if (VERBOSE > 1) printf("%s filename = '%s'\n", prefix, filename);-- model->model_->solver()->writeMps(filename, "mps", Cbc_optimizationDirection(model));-- if (VERBOSE > 0) printf("%s return\n", prefix);- return;-}-/* Integer information */-COINLIBAPI char * COINLINKAGE-Cbc_integerInformation(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_integerInformation(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int col;- int numcols = Cbc_getNumCols(model);-- // allocate model->information_ if null- // this is freed in Cbc_deleteModel() if not null- if (!model->information_)- model->information_ = (char *) malloc(numcols * sizeof(char));-- for (col = 0; col < numcols; col++)- if (model->model_->solver()->isContinuous(col))- model->information_[col] = 0;- else- model->information_[col] = 1;-- char * result = model->information_;-- if (VERBOSE > 0) printf("%s return %p\n", prefix, result);- return result;-}-/* Copy in integer information */-COINLIBAPI void COINLINKAGE-Cbc_copyInIntegerInformation(Cbc_Model * model, const char * information)-{- const char prefix[] = "Cbc_C_Interface::Cbc_copyInIntegerInformation(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int col;- int numcols = Cbc_getNumCols(model);- for (col = 0; col < numcols; col++)- if (information[col])- model->model_->solver()->setInteger(col);- else- model->model_->solver()->setContinuous(col);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Drop integer informations */-COINLIBAPI void COINLINKAGE-Cbc_deleteIntegerInformation(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_deleteIntegerInformation(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// available through-// OsiClpSolverInterface::setContinuous-//tbd model->model_->deleteIntegerInformation();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Resizes rim part of model */-COINLIBAPI void COINLINKAGE-Cbc_resize (Cbc_Model * /*model*/, int /*newNumberRows*/,- int /*newNumberColumns*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_resize(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find this in Cbc, Osi, or OsiClp-//tbd model->model_->solver()->resize(newNumberRows,newNumberColumns);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Deletes rows */-COINLIBAPI void COINLINKAGE-Cbc_deleteRows(Cbc_Model * model, int number, const int * which)-{- const char prefix[] = "Cbc_C_Interface::Cbc_deleteRows(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- OsiSolverInterface * solver = model->model_->solver();- solver->deleteRows(number, which);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Add rows */-COINLIBAPI void COINLINKAGE-Cbc_addRows(Cbc_Model * /*model*/, const int /*number*/,- const double * /*rowLower*/,- const double * /*rowUpper*/,- const int * /*rowStarts*/, const int * /*columns*/,- const double * /*elements*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_addRows(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// available through OsiClp-//tbd model->model_->addRows(number,rowLower,rowUpper,rowStarts,columns,elements);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}--/* Deletes columns */-COINLIBAPI void COINLINKAGE-Cbc_deleteColumns(Cbc_Model * model, int number, const int * which)-{- const char prefix[] = "Cbc_C_Interface::Cbc_deleteColumns(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- OsiSolverInterface * solver = model->model_->solver();- solver->deleteCols(number, which);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Add columns */-COINLIBAPI void COINLINKAGE-Cbc_addColumns(Cbc_Model * /*model*/, int /*number*/,- const double * /*columnLower*/,- const double * /*columnUpper*/,- const double * /*objective*/,- const int * /*columnStarts*/, const int * /*rows*/,- const double * /*elements*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_addColumns(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// available through OsiClp-//tbd model->model_->addColumns(number,columnLower,columnUpper,objective,-//tbd columnStarts,rows,elements);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Drops names - makes lengthnames 0 and names empty */-COINLIBAPI void COINLINKAGE-Cbc_dropNames(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_dropNames(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find names in Cbc, Osi, or OsiClp-//tbd model->model_->dropNames();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Copies in names */-COINLIBAPI void COINLINKAGE-Cbc_copyNames(Cbc_Model * /*model*/, const char * const * /*rowNamesIn*/,- const char * const * /*columnNamesIn*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_copyNames(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find names in Cbc, Osi, or OsiClp- /*clean- int iRow;- std::vector<std::string> rowNames;- int numberRows = model->model_->getNumRows();- rowNames.reserve(numberRows);- for (iRow=0;iRow<numberRows;iRow++) {- rowNames.push_back(rowNamesIn[iRow]);- }-- int iColumn;- std::vector<std::string> columnNames;- int numberColumns = model->model_->getNumCols();- columnNames.reserve(numberColumns);- for (iColumn=0;iColumn<numberColumns;iColumn++) {- columnNames.push_back(columnNamesIn[iColumn]);- }- model->model_->copyNames(rowNames,columnNames);- */-- if (VERBOSE > 0) printf("%s return\n", prefix);-}--/* Number of rows */-COINLIBAPI int COINLINKAGE-Cbc_numberRows(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_numberRows(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->getNumRows();-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Number of columns */-COINLIBAPI int COINLINKAGE-Cbc_numberColumns(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_numberColumns(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->getNumCols();-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Primal tolerance to use */-COINLIBAPI double COINLINKAGE-Cbc_primalTolerance(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_primalTolerance(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0.0;- model->model_->solver()->getDblParam(OsiPrimalTolerance, result) ;-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setPrimalTolerance(Cbc_Model * model, double value)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setPrimalTolerance(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- model->model_->solver()->setDblParam(OsiPrimalTolerance, value) ;-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Dual tolerance to use */-COINLIBAPI double COINLINKAGE-Cbc_dualTolerance(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_dualTolerance(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0.0;- model->model_->solver()->getDblParam(OsiDualTolerance, result) ;-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setDualTolerance(Cbc_Model * model, double value)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setDualTolerance(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- model->model_->solver()->setDblParam(OsiDualTolerance, value) ;-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Integer tolerance to use */-COINLIBAPI double COINLINKAGE-Cbc_integerTolerance(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_primalTolerance(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0.0;- result = model->model_->getDblParam(CbcModel::CbcIntegerTolerance) ;-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setIntegerTolerance(Cbc_Model * model, double value)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setPrimalTolerance(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- model->model_->setDblParam(CbcModel::CbcIntegerTolerance, value) ;-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Dual objective limit */-COINLIBAPI double COINLINKAGE-Cbc_dualObjectiveLimit(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_dualObjectiveLimit(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0.0;- model->model_->solver()->getDblParam(OsiDualObjectiveLimit, result) ;-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setDualObjectiveLimit(Cbc_Model * model, double value)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setDualObjectiveLimit(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- model->model_->solver()->setDblParam(OsiDualObjectiveLimit, value) ;-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Objective offset */-COINLIBAPI double COINLINKAGE-Cbc_objectiveOffset(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_objectiveOffset(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0.0;-// cannot find names in Cbc, Osi, or OsiClp-//tbd return model->model_->objectiveOffset();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setObjectiveOffset(Cbc_Model * /*model*/, double /*value*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setObjectiveOffset(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find names in Cbc, Osi, or OsiClp-//tbd model->model_->solver()->setObjectiveOffset(value);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Fills in array with problem name */-COINLIBAPI void COINLINKAGE-Cbc_problemName(Cbc_Model * model, int maxNumberCharacters, char * array)-{- const char prefix[] = "Cbc_C_Interface::Cbc_problemName(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- std::string name;- model->model_->solver()->getStrParam(OsiProbName, name);- maxNumberCharacters = CoinMin(maxNumberCharacters, (int)strlen(name.c_str()));- strncpy(array, name.c_str(), maxNumberCharacters - 1);- array[maxNumberCharacters-1] = '\0';-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Sets problem name. Must have \0 at end. */-COINLIBAPI int COINLINKAGE-Cbc_setProblemName(Cbc_Model * model, int /*maxNumberCharacters*/, char * array)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setProblemName(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- bool result = false;- result = model->model_->solver()->setStrParam(OsiProbName, array);-- if (VERBOSE > 0) printf("%s return\n", prefix);- return (result) ? 1 : 0;-}-/* Number of iterations */-COINLIBAPI int COINLINKAGE-Cbc_numberIterations(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_numberIterations(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->getIterationCount();-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setNumberIterations(Cbc_Model * /*model*/, int /*numberIterations*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setNumberIterations(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find this in Cbc, Osi, or OsiClp-//tbd model->model_->setNumberIterations(numberIterations);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);- return;-}-/* Maximum number of iterations */-COINLIBAPI int COINLINKAGE-Cbc_maximumIterations(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_maximumIterations(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// cannot find this in Cbc, Osi, or OsiClp-//tbd result = model->model_->solver()->maximumIterations();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setMaximumIterations(Cbc_Model * /*model*/, int /*value*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setMaximumIterations(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find this in Cbc, Osi, or OsiClp-//tbd model->model_->setMaximumIterations(value);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Maximum number of nodes */-COINLIBAPI int COINLINKAGE-Cbc_maxNumNode(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_maxNumNode(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->getIntParam(CbcModel::CbcMaxNumNode);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setMaxNumNode(Cbc_Model * model, int value)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setMaxNumNode(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- model->model_->setIntParam(CbcModel::CbcMaxNumNode, value);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Maximum number of solutions */-COINLIBAPI int COINLINKAGE-Cbc_maxNumSol(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::maxNumSol(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->getIntParam(CbcModel::CbcMaxNumSol);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setMaxNumSol(Cbc_Model * model, int value)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setMaxNumSol(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- model->model_->setIntParam(CbcModel::CbcMaxNumSol, value);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Maximum time in seconds (from when set called) */-COINLIBAPI double COINLINKAGE-Cbc_maximumSeconds(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_maximumSeconds(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0.0;- result = model->model_->getDblParam(CbcModel::CbcMaximumSeconds);-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setMaximumSeconds(Cbc_Model * model, double value)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setMaximumSeconds(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- model->model_->setDblParam(CbcModel::CbcMaximumSeconds, value);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Returns true if hit maximum iteratio`ns (or time) */-COINLIBAPI int COINLINKAGE-Cbc_hitMaximumIterations(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_hitMaximumIterations(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// cannot find names in Cbc, Osi, or OsiClp-//tbd result = model->model_->solver()->hitMaximumIterations() ? 1 : 0;- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Status of problem:- 0 - optimal- 1 - primal infeasible- 2 - dual infeasible- 3 - stopped on iterations etc- 4 - stopped due to errors-*/-COINLIBAPI int COINLINKAGE-Cbc_status(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_status(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->status();-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Set problem status */-COINLIBAPI void COINLINKAGE-Cbc_setProblemStatus(Cbc_Model * /*model*/, int /*problemStatus*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setProblemStatus(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find this in Cbc, Osi, or OsiClp-//tbd model->model_->setProblemStatus(problemStatus);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Secondary status of problem - may get extended- 0 - none- 1 - primal infeasible because dual limit reached- 2 - scaled problem optimal - unscaled has primal infeasibilities- 3 - scaled problem optimal - unscaled has dual infeasibilities- 4 - scaled problem optimal - unscaled has both dual and primal infeasibilities-*/-COINLIBAPI int COINLINKAGE-Cbc_secondaryStatus(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_secondaryStatus(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// cannot find this in Cbc, Osi, or OsiClp- result = model->model_->secondaryStatus();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setSecondaryStatus(Cbc_Model * /*model*/, int /*status*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setSecondaryStatus(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find this in Cbc, Osi, or OsiClp-//tbd model->model_->setSecondaryStatus(status);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */-COINLIBAPI double COINLINKAGE-Cbc_optimizationDirection(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_optimizationDirection(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0.0;- result = model->model_->getObjSense();-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setOptimizationDirection(Cbc_Model * model, double value)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setOptimizationDirection(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin, value = %g\n", prefix, value);-- model->model_->setObjSense(value);-// model->model_->solver()->setObjSense(value);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Primal row solution */-COINLIBAPI double * COINLINKAGE-Cbc_primalRowSolution(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_primalRowSolution(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;--// cannot find this in Cbc, Osi, or OsiClp-// may have to make it somehow-//tbd return model->model_->primalRowSolution();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return result;-}-/* Primal column solution */-COINLIBAPI double * COINLINKAGE-Cbc_primalColumnSolution(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_primalColumnSolution(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;-// cannot find this in Cbc, Osi, or OsiClp-// may have to make it somehow-// result = model->model_->getColSolution();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return result;-}-/* Dual row solution */-COINLIBAPI double * COINLINKAGE-Cbc_dualRowSolution(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_dualRowSolution(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;-// cannot find this in Cbc, Osi, or OsiClp-// may have to make it somehow-//tbd return model->model_->dualRowSolution();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return NULL;-}-/* Reduced costs */-COINLIBAPI double * COINLINKAGE-Cbc_dualColumnSolution(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_dualColumnSolution(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;-// cannot find this in Cbc, Osi, or OsiClp-// may have to make it somehow-//tbd return model->model_->dualColumnSolution();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return NULL;-}-/* Row lower */-COINLIBAPI double * COINLINKAGE-Cbc_rowLower(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_rowLower(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;-// cannot find this in Cbc, Osi, or OsiClp-// may have to make it somehow-//tbd return model->model_->rowLower();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return NULL;-}-/* Row upper */-COINLIBAPI double * COINLINKAGE-Cbc_rowUpper(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_rowUpper(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;-// cannot find this in Cbc, Osi, or OsiClp-// may have to make it somehow-//tbd return model->model_->rowUpper();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return NULL;-}-/* Objective Coefficients */-COINLIBAPI double * COINLINKAGE-Cbc_objective(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_objective(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;-// cannot find this in Cbc, Osi, or OsiClp-// may have to make it somehow-// result = model->model_->objective();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return NULL;-}-/* Column Lower */-COINLIBAPI double * COINLINKAGE-Cbc_columnLower(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_columnLower(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;-// cannot find this in Cbc, Osi, or OsiClp-// may have to make it somehow-//tbd return model->model_->columnLower();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return NULL;-}-/* Column Upper */-COINLIBAPI double * COINLINKAGE-Cbc_columnUpper(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_columnUpper(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;-// cannot find this in Cbc, Osi, or OsiClp-// may have to make it somehow-//tbd return model->model_->columnUpper();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return NULL;-}-/* Number of elements in matrix */-COINLIBAPI int COINLINKAGE-Cbc_getNumElements(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getNumElements(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->getNumElements();-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}--// Column starts in matrix-COINLIBAPI const CoinBigIndex * COINLINKAGE-Cbc_getVectorStarts(Cbc_Model * model)-{- const CoinPackedMatrix * matrix = NULL;- matrix = model->model_->solver()->getMatrixByCol();- return (matrix == NULL) ? NULL : matrix->getVectorStarts();-}-// Row indices in matrix-COINLIBAPI const int * COINLINKAGE-Cbc_getIndices(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getIndices(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const int * result = NULL;- const CoinPackedMatrix * matrix = NULL;- matrix = model->model_->solver()->getMatrixByCol();- result = (matrix == NULL) ? NULL : matrix->getIndices();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}--// Column vector lengths in matrix-COINLIBAPI const int * COINLINKAGE-Cbc_getVectorLengths(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getVectorLengths(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const int * result = NULL;- const CoinPackedMatrix * matrix = NULL;- matrix = model->model_->solver()->getMatrixByCol();- result = (matrix == NULL) ? NULL : matrix->getVectorLengths();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}--// Element values in matrix-COINLIBAPI const double * COINLINKAGE-Cbc_getElements(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getElements(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const double * result = NULL;- const CoinPackedMatrix * matrix = NULL;- matrix = model->model_->solver()->getMatrixByCol();- result = (matrix == NULL) ? NULL : matrix->getElements();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}-// ======================================================================--/* Objective value */-COINLIBAPI double COINLINKAGE-Cbc_objectiveValue(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_objectiveValue(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0.0;- result = model->model_->getObjValue();-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-/* Infeasibility/unbounded ray (NULL returned if none/wrong)- Up to user to use delete [] on these arrays. */-COINLIBAPI double * COINLINKAGE-Cbc_infeasibilityRay(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_infeasibilityRay(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;- // lots of rays (probably too many) are available in- // OsiClpSolverInterface::getDualRays()- //-//tbd result = model->model_->infeasibilityRay();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return result;-}-COINLIBAPI double * COINLINKAGE-Cbc_unboundedRay(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_unboundedRay(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double * result = NULL;- // lots of rays (probably too many) are available in- // OsiClpSolverInterface::getPrimalRays()- //-//tbd result = model->model_->unboundedRay();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, static_cast<void*>(result));- return result;-}-/* See if status array exists (partly for OsiClp) */-COINLIBAPI int COINLINKAGE-Cbc_statusExists(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_statusExists(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-//tbd result = model->model_->statusExists() ? 1 : 0;- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Return address of status array (char[numberRows+numberColumns]) */-COINLIBAPI void COINLINKAGE-Cbc_getBasisStatus(Cbc_Model * /*model*/, int * /*cstat*/, int * /*rstat*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getBasisStatus(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// have to figure this out-//tbd model->model_->solver()->getBasisStatus(cstat, rstat);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);- return;-}-/* Copy in status vector */-COINLIBAPI void COINLINKAGE-Cbc_setBasisStatus(Cbc_Model * /*model*/, int * /*cstat*/, int * /*rstat*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setBasisStatus(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// model->model_->solver()->setBasisStatus(cstat, rstat);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}--/* User pointer for whatever reason */-COINLIBAPI void COINLINKAGE-Cbc_setUserPointer (Cbc_Model * /*model*/, void * /*pointer*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setUserPointer(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- // not sure what this is for- //-//tbd model->model_->setUserPointer(pointer);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-COINLIBAPI void * COINLINKAGE-Cbc_getUserPointer (Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getUserPointer(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- void * result = NULL;- // not sure what this is for- //-//tbd result = model->model_->getUserPointer();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %p\n", prefix, result);- return result;-}-/* Pass in Callback function */-COINLIBAPI void COINLINKAGE-Cbc_registerCallBack(Cbc_Model * model,- cbc_callback userCallBack)-{- const char prefix[] = "Cbc_C_Interface::Cbc_registerCallBack(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- // reuse existing log level- int oldLogLevel = model->model_->messageHandler()->logLevel();- // Will be copy of users one- delete model->handler_;- model->handler_ = new Cbc_MessageHandler(*(model->model_->messageHandler()));- model->handler_->setCallBack(userCallBack);- model->handler_->setModel(model);- model->model_->passInMessageHandler(model->handler_);- model->model_->messageHandler()->setLogLevel(oldLogLevel);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Unset Callback function */-COINLIBAPI void COINLINKAGE-Cbc_clearCallBack(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_clearCallBack(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- delete model->handler_;- model->handler_ = NULL;-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Amount of print out:- 0 - none- 1 - just final- 2 - just factorizations- 3 - as 2 plus a bit more- 4 - verbose- above that 8,16,32 etc just for selective debug-*/-COINLIBAPI void COINLINKAGE-Cbc_setLogLevel(Cbc_Model * model, int value)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setLogLevel(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);- if (VERBOSE > 1) printf("%s value = %i\n", prefix, value);-- model->model_->messageHandler()->setLogLevel(value);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-COINLIBAPI int COINLINKAGE-Cbc_logLevel(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_logLevel(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->messageHandler()->logLevel();-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* length of names (0 means no names0 */-COINLIBAPI int COINLINKAGE-Cbc_lengthNames(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_lengthNames(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// cannot find names in Cbc, Osi, or OsiClp-//tbd result = model->model_->lengthNames();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Fill in array (at least lengthNames+1 long) with a row name */-COINLIBAPI void COINLINKAGE-Cbc_rowName(Cbc_Model * /*model*/, int iRow, char * name)-{- const char prefix[] = "Cbc_C_Interface::Cbc_rowName(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- sprintf(name, "ROW%5i", iRow);-// cannot find names in Cbc, Osi, or OsiClp-//tbd std::string rowName=model->model_->rowName(iRow);-//tbd strcpy(name,rowName.c_str());-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Fill in array (at least lengthNames+1 long) with a column name */-// cannot find names in Cbc, Osi, or OsiClp-COINLIBAPI void COINLINKAGE-Cbc_columnName(Cbc_Model * /*model*/, int iColumn, char * name)-{- const char prefix[] = "Cbc_C_Interface::Cbc_columnName(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- sprintf(name, "COL%5i", iColumn);-//tbd std::string columnName= model->model_->columnName(iColumn);-//tbd strcpy(name,columnName.c_str());-- if (VERBOSE > 0) printf("%s return\n", prefix);-}--/* General branch and bound solve algorithm which can do presolve.- See CbcSolve.hpp for options-*/-COINLIBAPI int COINLINKAGE-Cbc_initialSolve(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_initialSolve(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- model->model_->initialSolve();- result = model->model_->status();-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* General solve algorithm which can do presolve.- See CbcModel.hpp for options-*/-COINLIBAPI int COINLINKAGE-Cbc_branchAndBound(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_branchAndBound(): ";-// const int VERBOSE = 3;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- if (VERBOSE > 2) Cbc_printModel(model, prefix);- try {- model->model_->branchAndBound();- model->model_->solver()->resolve();- } catch (CoinError e) {- printf("%s ERROR: %s::%s, %s\n", prefix,- e.className().c_str(), e.methodName().c_str(), e.message().c_str());- }- result = model->model_->status();-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) */-COINLIBAPI void COINLINKAGE-Cbc_scaling(Cbc_Model * model, int mode)-{- const char prefix[] = "Cbc_C_Interface::Cbc_scaling(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- OsiSolverInterface * solver = model->model_->solver();- bool modeBool = (mode == 0);- solver->setHintParam(OsiDoScale, modeBool);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Gets scalingFlag */-COINLIBAPI int COINLINKAGE-Cbc_scalingFlag(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_scalingFlag(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// try to use OsiSolverInterface::getHintParam(OsiDoScale, ???)-//tbd result = model->model_->scalingFlag();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Crash - at present just aimed at dual, returns- -2 if dual preferred and crash basis created- -1 if dual preferred and all slack basis preferred- 0 if basis going in was not all slack- 1 if primal preferred and all slack basis preferred- 2 if primal preferred and crash basis created.-- if gap between bounds <="gap" variables can be flipped-- If "pivot" is- 0 No pivoting (so will just be choice of algorithm)- 1 Simple pivoting e.g. gub- 2 Mini iterations-*/-COINLIBAPI int COINLINKAGE-Cbc_crash(Cbc_Model * /*model*/, double /*gap*/, int /*pivot*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_crash(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// cannot find names in Cbc, Osi, or OsiClp-//tbd result = model->model_->crash(gap,pivot);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* If problem is primal feasible */-COINLIBAPI int COINLINKAGE-Cbc_primalFeasible(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_primalFeasible(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- OsiSolverInterface * solver = model->model_->solver();- result = solver->isProvenPrimalInfeasible() ? 0 : 1;-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* If problem is dual feasible */-COINLIBAPI int COINLINKAGE-Cbc_dualFeasible(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_dualFeasible(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- OsiSolverInterface * solver = model->model_->solver();- result = solver->isProvenDualInfeasible() ? 0 : 1;-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Dual bound */-COINLIBAPI double COINLINKAGE-Cbc_dualBound(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_dualBound(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0;-// cannot find in Cbc, Osi, or OsiClp-//tbd result = model->model_->dualBound();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setDualBound(Cbc_Model * /*model*/, double /*value*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setDualBound(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find names in Cbc, Osi, or OsiClp-//tbd model->model_->setDualBound(value);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Infeasibility cost */-COINLIBAPI double COINLINKAGE-Cbc_infeasibilityCost(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_infeasibilityCost(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0;-// cannot find names in Cbc, Osi, or OsiClp-//tbd result = model->model_->solver()->infeasibilityCost();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setInfeasibilityCost(Cbc_Model * /*model*/, double /*value*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setInfeasibilityCost(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find names in Cbc, Osi, or OsiClp-//tbd model->model_->setInfeasibilityCost(value);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Perturbation:- 50 - switch on perturbation- 100 - auto perturb if takes too long (1.0e-6 largest nonzero)- 101 - we are perturbed- 102 - don't try perturbing again- default is 100- others are for playing-*/-COINLIBAPI int COINLINKAGE-Cbc_perturbation(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_perturbation(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// cannot find names in Cbc, Osi, or OsiClp-//tbd result = model->model_->perturbation();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setPerturbation(Cbc_Model * /*model*/, int /*value*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setPerturbation(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find names in Cbc, Osi, or OsiClp-//tbd model->model_->setPerturbation(value);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Current (or last) algorithm */-COINLIBAPI int COINLINKAGE-Cbc_algorithm(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setPerturbation(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// cannot find names in Cbc, Osi, or OsiClp-//tbd result = model->model_->algorithm();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Set algorithm */-COINLIBAPI void COINLINKAGE-Cbc_setAlgorithm(Cbc_Model * /*model*/, int /*value*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setAlgorithm(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);--// cannot find names in Cbc, Osi, or OsiClp-//tbd model->model_->setAlgorithm(value);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return\n", prefix);-}-/* Sum of dual infeasibilities */-COINLIBAPI double COINLINKAGE-Cbc_sumDualInfeasibilities(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_sumDualInfeasibilities(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0;-// cannot find names in Cbc, Osi, or OsiClp-//tbd result = model->model_->sumDualInfeasibilities();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-/* Number of dual infeasibilities */-COINLIBAPI int COINLINKAGE-Cbc_numberDualInfeasibilities(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_numberDualInfeasibilities(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// cannot find names in Cbc, Osi, or OsiClp-//tbd result = model->model_->numberDualInfeasibilities();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Sum of primal infeasibilities */-COINLIBAPI double COINLINKAGE-Cbc_sumPrimalInfeasibilities(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_sumPrimalInfeasibilities(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0;-// cannot find names in Cbc, Osi, or OsiClp-//tbd result = model->model_->sumPrimalInfeasibilities();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-/* Number of primal infeasibilities */-COINLIBAPI int COINLINKAGE-Cbc_numberPrimalInfeasibilities(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_numberPrimalInfeasibilities(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-//tbd result = model->model_->getContinuousInfeasibilities();- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Save model to file, returns 0 if success. This is designed for- use outside algorithms so does not save iterating arrays etc.- It does not save any messaging information.- Does not save scaling values.- It does not know about all types of virtual functions.-*/-COINLIBAPI int COINLINKAGE-Cbc_saveModel(Cbc_Model * /*model*/, const char * /*fileName*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_saveModel(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// there is a writeMPS method in Osi-//tbd result = model->model_->saveModel(fileName);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Restore model from file, returns 0 if success,- deletes current model */-COINLIBAPI int COINLINKAGE-Cbc_restoreModel(Cbc_Model * /*model*/, const char * /*fileName*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_restoreModel(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;-// there is a readMPS method in Osi-//tbd result = model->model_->restoreModel(fileName);- if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}--/** Call this to really test if a valid solution can be feasible- Solution is number columns in size.- If fixVariables true then bounds of continuous solver updated.- Returns objective value (worse than cutoff if not feasible)-*/-COINLIBAPI void COINLINKAGE-Cbc_checkSolution(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_checkSolution(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- // see CbcModel::checkSolution(double cutoff, const double * solution,- // bool fixVariables);-// model->model_->checkSolution();-- if (VERBOSE > 0) printf("%s return\n", prefix);- return;-}-/* Number of rows */-COINLIBAPI int COINLINKAGE-Cbc_getNumRows(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getNumRows(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->getNumRows();-- if (VERBOSE > 0) printf("%s return %d\n", prefix, result);- return result;-}-/* Number of columns */-COINLIBAPI int COINLINKAGE-Cbc_getNumCols(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getNumCols(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->getNumCols();-- if (VERBOSE > 0) printf("%s return %d\n", prefix, result);- return result;-}-/* Number of iterations */-COINLIBAPI int COINLINKAGE-Cbc_getIterationCount(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getIterationCount(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->getIterationCount();-- if (VERBOSE > 0) printf("%s return %d\n", prefix, result);- return result;-}-/* Are there a numerical difficulties? */-COINLIBAPI int COINLINKAGE-Cbc_isAbandoned(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_isAbandoned(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->isAbandoned() ? 1 : 0;-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Is optimality proven? */-COINLIBAPI int COINLINKAGE-Cbc_isProvenOptimal(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_isProvenOptimal(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->isProvenOptimal() ? 1 : 0;-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Is primal infeasiblity proven? */-COINLIBAPI int COINLINKAGE-Cbc_isProvenPrimalInfeasible(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_isProvenPrimalInfeasible(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- OsiSolverInterface * solver = model->model_->solver();- result = solver->isProvenPrimalInfeasible() ? 1 : 0;-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Is dual infeasiblity proven? */-COINLIBAPI int COINLINKAGE-Cbc_isProvenDualInfeasible(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_isProvenDualInfeasible(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- OsiSolverInterface * solver = model->model_->solver();- result = solver->isProvenDualInfeasible() ? 1 : 0;-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Is the given primal objective limit reached? */-COINLIBAPI int COINLINKAGE-Cbc_isPrimalObjectiveLimitReached(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_isPrimalObjectiveLimitReached(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- OsiSolverInterface * solver = model->model_->solver();- result = solver->isPrimalObjectiveLimitReached() ? 1 : 0;-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Is the given dual objective limit reached? */-COINLIBAPI int COINLINKAGE-Cbc_isDualObjectiveLimitReached(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_isDualObjectiveLimitReached(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- OsiSolverInterface * solver = model->model_->solver();- result = solver->isDualObjectiveLimitReached() ? 1 : 0;-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Iteration limit reached? */-COINLIBAPI int COINLINKAGE-Cbc_isIterationLimitReached(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_isIterationLimitReached(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- OsiSolverInterface * solver = model->model_->solver();- result = solver->isIterationLimitReached() ? 1 : 0;-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */-COINLIBAPI double COINLINKAGE-Cbc_getObjSense(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getObjSense(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0;- result = model->model_->getObjSense();-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-/* Primal row solution */-COINLIBAPI const double * COINLINKAGE-Cbc_getRowActivity(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getRowActivity(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const double * result = NULL;- result = model->model_->getRowActivity();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}-/* Primal column solution */-COINLIBAPI const double * COINLINKAGE-Cbc_getColSolution(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getColSolution(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const double * result = NULL;- result = model->model_->getColSolution();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}-COINLIBAPI void COINLINKAGE-Cbc_setColSolution(Cbc_Model * model, const double * input)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setColSolution(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- OsiSolverInterface * solver = model->model_->solver();- solver->setColSolution(input);-- if (VERBOSE > 0) printf("%s return\n", prefix);- return;-}-/* Dual row solution */-COINLIBAPI const double * COINLINKAGE-Cbc_getRowPrice(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getRowPrice(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const double * result = NULL;- result = model->model_->getRowPrice();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}-/* Reduced costs */-COINLIBAPI const double * COINLINKAGE-Cbc_getReducedCost(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getReducedCost(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const double * result = NULL;- result = model->model_->getReducedCost();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}-/* Row lower */-COINLIBAPI const double * COINLINKAGE-Cbc_getRowLower(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getRowLower(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const double * result = NULL;- result = model->model_->getRowLower();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}-/* Row upper */-COINLIBAPI const double * COINLINKAGE-Cbc_getRowUpper(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getRowUpper(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const double * result = NULL;- result = model->model_->getRowUpper();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}-/* Objective Coefficients */-COINLIBAPI const double * COINLINKAGE-Cbc_getObjCoefficients(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getObjCoefficients(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const double * result = NULL;- result = model->model_->getObjCoefficients();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}-/* Column Lower */-COINLIBAPI const double * COINLINKAGE-Cbc_getColLower(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getColLower(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const double * result = NULL;- result = model->model_->getColLower();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}-/* Column Upper */-COINLIBAPI const double * COINLINKAGE-Cbc_getColUpper(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getColUpper(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- const double * result = NULL;- result = model->model_->getColUpper();-- if (VERBOSE > 0)- printf("%s return %p\n", prefix, static_cast<const void*>(result));- return result;-}-/* Objective value */-COINLIBAPI double COINLINKAGE-Cbc_getObjValue(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getObjValue(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0;- result = model->model_->getObjValue();-- if (VERBOSE > 0)- printf("%s return %g\n", prefix, result);- return result;-}-/* Print model */-COINLIBAPI void COINLINKAGE-Cbc_printModel(Cbc_Model * model, const char * argPrefix)-{- const char prefix[] = "Cbc_C_Interface::Cbc_printModel(): ";- const int VERBOSE = 4;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- CbcModel *cbc_model = model->model_;- int numrows = cbc_model->getNumRows();- int numcols = cbc_model->getNumCols();- int numelem = cbc_model->getNumElements();- const CoinPackedMatrix * matrix = cbc_model->solver()->getMatrixByCol();- const CoinBigIndex * start = matrix->getVectorStarts();- const int * index = matrix->getIndices();- const double * value = matrix->getElements();- const double * collb = cbc_model->getColLower();- const double * colub = cbc_model->getColUpper();- const double * obj = cbc_model->getObjCoefficients();- const double * rowlb = cbc_model->getRowLower();- const double * rowub = cbc_model->getRowUpper();-- printf("%s numcols = %i, numrows = %i, numelem = %i\n",- argPrefix, numcols, numrows, numelem);- printf("%s model = %p, start = %p, index = %p, value = %p\n",- argPrefix, static_cast<void*>(model), static_cast<const void*>(start),- static_cast<const void*>(index), static_cast<const void*>(value));- matrix->dumpMatrix(NULL);- {- int i;- for (i = 0; i <= numcols; i++)- printf("%s start[%i] = %i\n", argPrefix, i, start[i]);- for (i = 0; i < numelem; i++)- printf("%s index[%i] = %i, value[%i] = %g\n",- argPrefix, i, index[i], i, value[i]);- }-- printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",- argPrefix, static_cast<const void*>(collb),- static_cast<const void*>(colub), static_cast<const void*>(obj),- static_cast<const void*>(rowlb), static_cast<const void*>(rowub));- printf("%s optimization direction = %g\n", argPrefix, Cbc_optimizationDirection(model));- printf(" (1 - minimize, -1 - maximize, 0 - ignore)\n");- {- int i;- for (i = 0; i < numcols; i++)- printf("%s collb[%i] = %g, colub[%i] = %g, obj[%i] = %g\n",- argPrefix, i, collb[i], i, colub[i], i, obj[i]);- for (i = 0; i < numrows; i++)- printf("%s rowlb[%i] = %g, rowub[%i] = %g\n",- argPrefix, i, rowlb[i], i, rowub[i]);- }-- if (VERBOSE > 0) printf("%s return\n", prefix);-} // Cbc_printModel()--COINLIBAPI int COINLINKAGE-Cbc_isInteger(Cbc_Model * model, int i)-{- const char prefix[] = "Cbc_C_Interface::Cbc_isInteger(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- bool result = false;- result = model->model_->isInteger(i);-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return (result) ? 1 : 0;-}--COINLIBAPI double COINLINKAGE-Cbc_cpuTime(Cbc_Model * /*model*/)-{- const char prefix[] = "Cbc_C_Interface::Cbc_cpuTime(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- double result = 0;- result = CoinCpuTime() ;-- if (VERBOSE > 0) printf("%s return %g\n", prefix, result);- return result;-}-/** Number of nodes explored in B&B tree */-COINLIBAPI int COINLINKAGE-Cbc_getNodeCount(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_getNodeCount(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- int result = 0;- result = model->model_->getNodeCount() ;-- if (VERBOSE > 0) printf("%s return %i\n", prefix, result);- return result;-}-/** Return a copy of this model */-COINLIBAPI Cbc_Model * COINLINKAGE-Cbc_clone(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_clone(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- Cbc_Model * result = new Cbc_Model;- result->model_ = new CbcModel(*(model->model_));- result->solver_ = dynamic_cast< OsiClpSolverInterface*> (result->model_->solver());- result->handler_ = NULL;-- if (VERBOSE > 0) printf("%s return\n", prefix);- return model;-}-/** Set this the variable to be continuous */-COINLIBAPI Cbc_Model * COINLINKAGE-Cbc_setContinuous(Cbc_Model * model, int iColumn)-{- const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- model->model_->solver()->setContinuous(iColumn);-- if (VERBOSE > 0) printf("%s return\n", prefix);- return model;-}-/* Add an SOS constraint to the model */-COINLIBAPI void COINLINKAGE-Cbc_addSOS_Dense(Cbc_Model * model, int numObjects, const int * len,- const int * const* which, const double * weights, const int type)-{- const char prefix[] = "Cbc_C_Interface::Cbc_addSOS_Dense(): ";-// const int VERBOSE = 2;- if (VERBOSE > 0) printf("%sbegin\n", prefix);-- assert(1 > 0);// this is probably broken- int i, j;- // I think this is a different model due to overriding = operator- CbcModel m = *(model->model_);-- CbcObject ** objects = new CbcObject * [numObjects];-- if (VERBOSE > 1) printf("%s numObjects = %i\n", prefix, numObjects);- for (i = 0; i < numObjects; i++) {- if (VERBOSE > 1) {- printf("%s len[%i] = %i, identifier = %i, type = %i\n",- prefix, i, len[i], i, type);- fflush(stdout);- for (j = 0; j < len[i]; j++) {- if (VERBOSE > 2 || j == 0 || j == (len[i] - 1)) {- printf("%s which[%i][%i] = %d, weights[%i] = %g\n",- prefix, i, j, which[i][j], j, weights[j]);- fflush(stdout);- }- }- }-- // Make a CbcSOS and assign it to objects- if (VERBOSE > 1) printf("%s len[%i] = %i\n", prefix, i, len[i]);- if (VERBOSE > 1) printf("%s new CbcSOS()\n", prefix);- // ***- objects[i] = new CbcSOS(model->model_, (int)(len[i]),- (const int*)which[i], (const double*)weights, (int)i, (int)type);- // ***- if (objects[i] == NULL) {- printf("%s ERROR: objects[%i] == NULL\n", prefix, i);- fflush(stdout);- assert(objects[i] != NULL);- }- }- if (VERBOSE > 1) printf("%s calling addObjects()\n", prefix);- fflush(stdout);- model->model_->addObjects(numObjects, objects);- if (VERBOSE > 1) printf("%s finished addObjects()\n", prefix);-- for (i = 0; i < numObjects; i++) delete objects[i];- delete [] objects;-- if (VERBOSE > 0) printf("%sreturn\n", prefix);- return;-}-/** Add SOS constraints to the model using row-order matrix */-COINLIBAPI void COINLINKAGE-Cbc_addSOS_Sparse(Cbc_Model * model, const int * rowStarts,- const int * rowIndices, const double * weights, const int type)-{- const char prefix[] = "Cbc_C_Interface::Cbc_addSOS_Sparse(): ";-// const int VERBOSE = 1;- if (VERBOSE > 0) printf("%sbegin\n", prefix);-- int numRows = Cbc_numberRows(model);- if (VERBOSE > 0) printf("%s numRows = %i\n", prefix, numRows);-- // The passed sparse matrix must have the same number of rows as the model- assert(numRows == Cbc_numberRows(model));-- int row, i;- const int *colIndex;- const double *colWeight;-- // loop on rows and count number of objects according to numWeights>0- int numObjects = 0;- for (row = 0; row < numRows; row++) {- if (VERBOSE > 2) {- printf("%s row = %i\n", prefix, row);- printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);- printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row+1]);- fflush(stdout);- }- const int numWeights = rowStarts[row+1] - rowStarts[row];- if (VERBOSE > 2) printf("%s numWeights = %i\n", prefix, numWeights);- if (numWeights > 0) numObjects++;- }-- // make objects- CbcObject ** objects = new CbcObject * [numObjects];-// if (VERBOSE>1) printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);-- // loop on rows and make an object when numWeights>0- int objNum = 0;- for (row = 0; row < numRows; row++) {- if (VERBOSE > 2) {- printf("%s row = %i\n", prefix, row);- printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);- printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row+1]);- }- const int numWeights = rowStarts[row+1] - rowStarts[row];- if (VERBOSE > 2) printf("%s numWeights = %i\n", prefix, numWeights);- colIndex = rowIndices + rowStarts[row];- colWeight = weights + rowStarts[row];- if (numWeights > 0) {- // Make a CbcSOS and assign it to objects- if (VERBOSE > 3) {- for (i = 0; i < numWeights; i++) {- printf("%s colIndex [%i] = %i\n", prefix, i, colIndex[i]);- printf("%s colWeight[%i] = %f\n", prefix, i, colWeight[i]);- }- fflush(stdout);- }- objects[objNum] = new CbcSOS(model->model_, (int)(numWeights),- (const int*)colIndex, (const double*)colWeight, (int)objNum, (int)type);-// if (VERBOSE>2) printf("%s objects[%i] = %X\n",prefix,objNum,objects[objNum]);- if (objects[objNum] == NULL) {- printf("%s ERROR: objects[%i] == NULL\n", prefix, objNum);- fflush(stdout);- assert(objects[objNum] != NULL);- }- objNum++;- }- }- if (VERBOSE > 2) {- printf("%s calling addObjects()\n", prefix);- /*- printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);- for (row=0; row<numObjects; row++)- printf("%s objects[%i] = %X\n",prefix,row,objects[row]);- */- }- fflush(stdout);- model->model_->addObjects(numObjects, objects);- if (VERBOSE > 1) printf("%s finished addObjects()\n", prefix);-- for (objNum = 0; objNum < numObjects; objNum++) delete objects[objNum];- delete [] objects;-- if (VERBOSE > 0) printf("%sreturn\n", prefix);- return;-}--/** Delete all object information */-COINLIBAPI void COINLINKAGE-Cbc_deleteObjects(Cbc_Model * model)-{- const char prefix[] = "Cbc_C_Interface::Cbc_deleteObjects(): ";-// const int VERBOSE = 2;- if (VERBOSE > 0) printf("%s begin\n", prefix);-- model->model_->deleteObjects();-- if (VERBOSE > 0) printf("%s return\n", prefix);- return;-}--/** Print the solution */-COINLIBAPI void COINLINKAGE-Cbc_printSolution(Cbc_Model * model)-{- {- //- // Now to print out row solution. The methods used return const- // pointers - which is of course much more virtuous.- //- // This version just does non-zero columns- //-- // * Rows-- int numberRows = Cbc_getNumRows(model);- int iRow;--- const double * rowPrimal = Cbc_getRowActivity(model);- // * Alternatively getReducedCost(model)- const double * rowDual = Cbc_getRowPrice(model);- // * Alternatively getColLower(model)- const double * rowLower = Cbc_getRowLower(model);- // * Alternatively getColUpper(model)- const double * rowUpper = Cbc_getRowUpper(model);- printf("--------------------------------------\n");-- // * If we have not kept names (parameter to readMps) this will be 0- // assert(Cbc_lengthNames(model));-- printf(" Primal Dual Lower Upper\n");- for (iRow = 0; iRow < numberRows; iRow++) {- double value;- value = rowPrimal[iRow];- if (value > 1.0e-8 || value < -1.0e-8) {- char name[20];- // Cbc_columnName(model,iColumn,name);- sprintf(name, "ROW%5i", iRow);- printf("%6d %8s", iRow, name);- printf(" %13g", rowPrimal[iRow]);- printf(" %13g", rowDual[iRow]);- printf(" %13g", rowLower[iRow]);- printf(" %13g", rowUpper[iRow]);- printf("\n");- }- }- printf("--------------------------------------\n");- }- {- //- // Now to print out column solution. The methods used return const- // pointers - which is of course much more virtuous.- //- // This version just does non-zero columns- //- //-- // * Columns-- int numberColumns = Cbc_numberColumns(model);- int iColumn;--- // * Alternatively getColSolution(model)- const double * columnPrimal = Cbc_getColSolution(model);- // * Alternatively getReducedCost(model)- const double * columnDual = Cbc_getReducedCost(model);- // * Alternatively getColLower(model)- const double * columnLower = Cbc_getColLower(model);- // * Alternatively getColUpper(model)- const double * columnUpper = Cbc_getColUpper(model);- // * Alternatively getObjCoefficients(model)- const double * columnObjective = Cbc_getObjCoefficients(model);-- const char * isInteger = Cbc_integerInformation(model);-- printf("--------------------------------------\n");-- // * If we have not kept names (parameter to readMps) this will be 0-// assert(Cbc_lengthNames(model));-- printf(" Primal Dual Lower Upper Cost isInteger\n");- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- double value;- value = columnPrimal[iColumn];- if (value > 1.0e-8 || value < -1.0e-8) {- char name[20];-// Cbc_columnName(model,iColumn,name);- sprintf(name, "COL%5i", iColumn);- printf("%6d %8s", iColumn, name);- printf(" %13g", columnPrimal[iColumn]);- printf(" %13g", columnDual[iColumn]);- printf(" %13g", columnLower[iColumn]);- printf(" %13g", columnUpper[iColumn]);- printf(" %13g", columnObjective[iColumn]);- printf(" %13i", isInteger[iColumn]);- printf("\n");- }- }- printf("--------------------------------------\n");- }- if (0) Cbc_printModel(model, "cbc::main(): ");- return;-}-/** Dual initial solve */-COINLIBAPI int COINLINKAGE-Cbc_initialDualSolve(Cbc_Model * /*model*/)-{- return 0;-}-/** Primal initial solve */-COINLIBAPI int COINLINKAGE-Cbc_initialPrimalSolve(Cbc_Model * /*model*/)-{- return 0;-}-/** Dual algorithm - see ClpSimplexDual.hpp for method */-COINLIBAPI int COINLINKAGE-Cbc_dual(Cbc_Model * /*model*/, int /*ifValuesPass*/)-{- return 0;-}-/** Primal algorithm - see ClpSimplexPrimal.hpp for method */-COINLIBAPI int COINLINKAGE-Cbc_primal(Cbc_Model * /*model*/, int /*ifValuesPass*/)-{- return 0;-}-#if defined(__MWERKS__)-#pragma export off-#endif-
− cbits/coin/Cbc_ampl.cpp
@@ -1,1512 +0,0 @@-/* $Id: Cbc_ampl.cpp 1926 2013-05-24 10:19:49Z stefan $ */-/****************************************************************-Copyright (C) 1997-2000 Lucent Technologies-Modifications for Coin - Copyright (C) 2006, International Business Machines Corporation and others.-All Rights Reserved--Permission to use, copy, modify, and distribute this software and-its documentation for any purpose and without fee is hereby-granted, provided that the above copyright notice appear in all-copies and that both that the copyright notice and this-permission notice and warranty disclaimer appear in supporting-documentation, and that the name of Lucent or any of its entities-not be used in advertising or publicity pertaining to-distribution of the software without specific, written prior-permission.--LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.-IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY-SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER-IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF-THIS SOFTWARE.-****************************************************************/--/*! \file Cbc_ampl.cpp-- Interface routines for AMPL.-*/--#include "CbcConfig.h"--#ifdef COIN_HAS_ASL--#ifdef HAVE_UNISTD_H-# include "unistd.h"-#endif-#include "CoinUtilsConfig.h"-#include "CoinHelperFunctions.hpp"-#include "CoinModel.hpp"-#include "CoinSort.hpp"-#include "CoinPackedMatrix.hpp"-#include "CoinMpsIO.hpp"-#include "CoinFloatEqual.hpp"-#ifdef COIN_HAS_CLP-#include "OsiClpSolverInterface.hpp"-#endif-#include "Cbc_ampl.h"-extern "C" {-# include "getstub.h"-# include "asl_pfgh.h"-}--#include <string>-#include <cassert>-/* so decodePhrase and clpCheck can access */-static ampl_info * saveInfo = NULL;-// Set to 1 if algorithm found-static char algFound[20] = "";-static char*-checkPhrase(Option_Info *oi, keyword *kw, char *v)-{- if (strlen(v))- printf("string %s\n", v);- // Say algorithm found- strcpy(algFound, kw->desc);- return v;-}-static char*-checkPhrase2(Option_Info *oi, keyword *kw, char *v)-{- if (strlen(v))- printf("string %s\n", v);- // put out keyword- saveInfo->arguments = (char **) realloc(saveInfo->arguments, (saveInfo->numberArguments + 1) * sizeof(char *));- saveInfo->arguments[saveInfo->numberArguments++] = strdup(kw->desc);- return v;-}-static fint-decodePhrase(char * phrase, ftnlen length)-{- char * blank = strchr(phrase, ' ');- if (blank) {- /* split arguments */- *blank = '\0';- saveInfo->arguments = (char **) realloc(saveInfo->arguments, (saveInfo->numberArguments + 2) * sizeof(char *));- saveInfo->arguments[saveInfo->numberArguments++] = strdup(phrase);- *blank = ' ';- phrase = blank + 1; /* move on */- if (strlen(phrase))- saveInfo->arguments[saveInfo->numberArguments++] = strdup(phrase);- } else if (strlen(phrase)) {- saveInfo->arguments = (char **) realloc(saveInfo->arguments, (saveInfo->numberArguments + 1) * sizeof(char *));- saveInfo->arguments[saveInfo->numberArguments++] = strdup(phrase);- }- return 0;-}-static void-sos_kludge(int nsos, int *sosbeg, double *sosref, int * sosind)-{- // Adjust sosref if necessary to make monotonic increasing- int i, j, k;- // first sort- for (i = 0; i < nsos; i++) {- k = sosbeg[i];- int end = sosbeg[i+1];- CoinSort_2(sosref + k, sosref + end, sosind + k);- }- double t, t1;- for (i = j = 0; i++ < nsos; ) {- k = sosbeg[i];- t = sosref[j];- while (++j < k) {- t1 = sosref[j];- t += 1e-10;- if (t1 <= t)- sosref[j] = t1 = t + 1e-10;- t = t1;- }- }-}-static char xxxxxx[20];-#define VP (char*)-static keyword keywds[] = { /* must be sorted */- { const_cast<char*>("barrier"), checkPhrase, (char *) xxxxxx ,- const_cast<char*>("-barrier")},- { const_cast<char*>("dual"), checkPhrase, (char *) xxxxxx ,- const_cast<char*>("-dualsimplex")},- { const_cast<char*>("help"), checkPhrase2, (char *) xxxxxx ,- const_cast<char*>("-?")},- { const_cast<char*>("initial"), checkPhrase, (char *) xxxxxx ,- const_cast<char*>("-initialsolve")},- { const_cast<char*>("max"), checkPhrase2, (char *) xxxxxx ,- const_cast<char*>("-maximize")},- { const_cast<char*>("maximize"), checkPhrase2, (char *) xxxxxx ,- const_cast<char*>("-maximize")},- { const_cast<char*>("primal"), checkPhrase, (char *) xxxxxx ,- const_cast<char*>("-primalsimplex")},- { const_cast<char*>("quit"), checkPhrase2, (char *) xxxxxx ,- const_cast<char*>("-quit")},- { const_cast<char*>("wantsol"), WS_val, NULL,- const_cast<char*>("write .sol file (without -AMPL)")}-};-static Option_Info Oinfo = {- const_cast<char*>("cbc"),- const_cast<char*>("CBC " CBC_VERSION),- const_cast<char*>("cbc_options"),- keywds,- nkeywds,- 0,- 0,- 0,- decodePhrase,- 0,- 0,- 0,- 20130502-};-// strdup used to avoid g++ compiler warning-static SufDecl suftab[] = {-#ifdef JJF_ZERO- { const_cast<char*>("current"), 0, ASL_Sufkind_con | ASL_Sufkind_outonly },- { const_cast<char*>("current"), 0, ASL_Sufkind_var | ASL_Sufkind_outonly },- { const_cast<char*>("direction"), 0, ASL_Sufkind_var },- { const_cast<char*>("down"), 0, ASL_Sufkind_con | ASL_Sufkind_outonly },- { const_cast<char*>("down"), 0, ASL_Sufkind_var | ASL_Sufkind_outonly },- { const_cast<char*>("priority"), 0, ASL_Sufkind_var },-#endif- { const_cast<char*>("cut"), 0, ASL_Sufkind_con },- { const_cast<char*>("direction"), 0, ASL_Sufkind_var },- { const_cast<char*>("downPseudocost"), 0, ASL_Sufkind_var | ASL_Sufkind_real },- { const_cast<char*>("priority"), 0, ASL_Sufkind_var },- { const_cast<char*>("ref"), 0, ASL_Sufkind_var | ASL_Sufkind_real },- { const_cast<char*>("sos"), 0, ASL_Sufkind_var },- { const_cast<char*>("sos"), 0, ASL_Sufkind_con },- { const_cast<char*>("sosno"), 0, ASL_Sufkind_var | ASL_Sufkind_real },- { const_cast<char*>("sosref"), 0, ASL_Sufkind_var | ASL_Sufkind_real },- { const_cast<char*>("special"), 0, ASL_Sufkind_var },- { const_cast<char*>("special"), 0, ASL_Sufkind_con },- /*{ const_cast<char*>("special"), 0, ASL_Sufkind_con },*/- { const_cast<char*>("sstatus"), 0, ASL_Sufkind_var, 0 },- { const_cast<char*>("sstatus"), 0, ASL_Sufkind_con, 0 },- { const_cast<char*>("upPseudocost"), 0, ASL_Sufkind_var | ASL_Sufkind_real }-#ifdef JJF_ZERO- { const_cast<char*>("unbdd"), 0, ASL_Sufkind_var | ASL_Sufkind_outonly},- { const_cast<char*>("up"), 0, ASL_Sufkind_con | ASL_Sufkind_outonly },- { const_cast<char*>("up"), 0, ASL_Sufkind_var | ASL_Sufkind_outonly }-#endif-};-#include "float.h"-#include "limits.h"-static ASL *asl = NULL;-static FILE *nl = NULL;--static void-mip_stuff(void)-{- int i;- double *pseudoUp, *pseudoDown;- int *priority, *direction;- // To label cuts (there will be other uses for special)- int *cut;- // To label special variables - at present 1= must be >= 1 or <= -1- int * special;- SufDesc *dpup, *dpdown, *dpri, *ddir, *dcut, *dspecial;-- ddir = suf_get("direction", ASL_Sufkind_var);- direction = ddir->u.i;- dpri = suf_get("priority", ASL_Sufkind_var);- priority = dpri->u.i;- dspecial = suf_get("special", ASL_Sufkind_con);- dcut = suf_get("cut", ASL_Sufkind_con);- cut = dcut->u.i;- if (!cut) {- // try special- dcut = suf_get("special", ASL_Sufkind_con);- cut = dcut->u.i;- }- dspecial = suf_get("special", ASL_Sufkind_var);- special = dspecial->u.i;- dpdown = suf_get("downPseudocost", ASL_Sufkind_var);- pseudoDown = dpdown->u.r;- dpup = suf_get("upPseudocost", ASL_Sufkind_var);- pseudoUp = dpup->u.r;- assert(saveInfo);- int numberColumns = saveInfo->numberColumns;- if (direction) {- int baddir = 0;- saveInfo->branchDirection = (int *) malloc(numberColumns * sizeof(int));- for (i = 0; i < numberColumns; i++) {- int value = direction[i];- if (value < -1 || value > 1) {- baddir++;- value = 0;- }- saveInfo->branchDirection[i] = value;- }- if (baddir)- fprintf(Stderr,- "Treating %d .direction values outside [-1, 1] as 0.\n",- baddir);- }- if (priority) {- int badpri = 0;- saveInfo->priorities = (int *) malloc(numberColumns * sizeof(int));- for (i = 0; i < numberColumns; i++) {- int value = priority[i];- if (value < 0) {- badpri++;- value = 0;- }- saveInfo->priorities[i] = value;- }- if (badpri)- fprintf(Stderr,- "Treating %d negative .priority values as 0\n",- badpri);- }- if (special) {- int badspecial = 0;- saveInfo->special = (int *) malloc(numberColumns * sizeof(int));- for (i = 0; i < numberColumns; i++) {- int value = special[i];- if (value < 0) {- badspecial++;- value = 0;- }- saveInfo->special[i] = value;- }- if (badspecial)- fprintf(Stderr,- "Treating %d negative special values as 0\n",- badspecial);- }- int numberRows = saveInfo->numberRows;- if (cut) {- int badcut = 0;- saveInfo->cut = (int *) malloc(numberRows * sizeof(int));- for (i = 0; i < numberRows; i++) {- int value = cut[i];- if (value < 0) {- badcut++;- value = 0;- }- saveInfo->cut[i] = value;- }- if (badcut)- fprintf(Stderr,- "Treating %d negative cut values as 0\n",- badcut);- }- if (pseudoDown || pseudoUp) {- int badpseudo = 0;- if (!pseudoDown || !pseudoUp)- fprintf(Stderr,- "Only one set of pseudocosts - assumed same\n");- saveInfo->pseudoDown = (double *) malloc(numberColumns * sizeof(double));- saveInfo->pseudoUp = (double *) malloc(numberColumns * sizeof(double));- for (i = 0; i < numberColumns; i++) {- double valueD = 0.0, valueU = 0.0;- if (pseudoDown) {- valueD = pseudoDown[i];- if (valueD < 0) {- badpseudo++;- valueD = 0.0;- }- }- if (pseudoUp) {- valueU = pseudoUp[i];- if (valueU < 0) {- badpseudo++;- valueU = 0.0;- }- }- if (!valueD)- valueD = valueU;- if (!valueU)- valueU = valueD;- saveInfo->pseudoDown[i] = valueD;- saveInfo->pseudoUp[i] = valueU;- }- if (badpseudo)- fprintf(Stderr,- "Treating %d negative pseudoCosts as 0.0\n", badpseudo);- }-}-static void-stat_map(int *stat, int n, int *map, int mx, const char *what)-{- int bad, i, i1 = 0, j, j1 = 0;- static char badfmt[] = "Coin driver: %s[%d] = %d\n";-- for (i = bad = 0; i < n; i++) {- if ((j = stat[i]) >= 0 && j <= mx)- stat[i] = map[j];- else {- stat[i] = 0;- i1 = i;- j1 = j;- if (!bad++)- fprintf(Stderr, badfmt, what, i, j);- }- }- if (bad > 1) {- if (bad == 2)- fprintf(Stderr, badfmt, what, i1, j1);- else- fprintf(Stderr,- "Coin driver: %d messages about bad %s values suppressed.\n",- bad - 1, what);- }-}--int-readAmpl(ampl_info * info, int argc, char **argv, void ** coinModel)-{- char *stub;- ograd *og;- int i;- SufDesc *csd;- SufDesc *rsd;- /*bool *basis, *lower;*/- /*double *LU, *c, lb, objadj, *rshift, *shift, t, ub, *x, *x0, *x1;*/- char * environment = getenv("cbc_options");- char tempBuffer[20];- double * obj;- double * columnLower;- double * columnUpper;- double * rowLower;- double * rowUpper;- char ** saveArgv = argv;- char fileName[1000];- if (argc > 1)- strcpy(fileName, argv[1]);- else- fileName[0] = '\0';- int nonLinearType = -1;- // testosi parameter - if >= 10 then go in through coinModel- for (i = 1; i < argc; i++) {- if (!strncmp(argv[i], "testosi", 7)) {- char * equals = strchr(argv[i], '=');- if (equals && atoi(equals + 1) >= 10 && atoi(equals + 1) <= 20) {- nonLinearType = atoi(equals + 1);- break;- }- }- }- int saveArgc = argc;- if (info->numberRows != -1234567)- memset(info, 0, sizeof(ampl_info)); // overwrite unless magic number set- /* save so can be accessed by decodePhrase */- saveInfo = info;- info->numberArguments = 0;- info->arguments = (char **) malloc(2 * sizeof(char *));- info->arguments[info->numberArguments++] = strdup("ampl");- info->arguments[info->numberArguments++] = strdup("cbc");- asl = ASL_alloc(ASL_read_f);- stub = getstub(&argv, &Oinfo);- if (!stub)- usage_ASL(&Oinfo, 1);- nl = jac0dim(stub, 0);- suf_declare(suftab, sizeof(suftab) / sizeof(SufDecl));-- /* set A_vals to get the constraints column-wise (malloc so can be freed) */- A_vals = (double *) malloc(nzc * sizeof(double));- if (!A_vals) {- printf("no memory\n");- return 1;- }- /* say we want primal solution */- want_xpi0 = 1;- /* for basis info */- info->columnStatus = (int *) malloc(n_var * sizeof(int));- info->rowStatus = (int *) malloc(n_con * sizeof(int));- csd = suf_iput("sstatus", ASL_Sufkind_var, info->columnStatus);- rsd = suf_iput("sstatus", ASL_Sufkind_con, info->rowStatus);- if (!(nlvc + nlvo) && nonLinearType < 10) {- /* read linear model*/- f_read(nl, 0);- // see if any sos- if (true) {- char *sostype;- int nsosnz, *sosbeg, *sosind, * sospri;- double *sosref;- int nsos;- int i = ASL_suf_sos_explict_free;- int copri[2], **p_sospri;- copri[0] = 0;- copri[1] = 0;- p_sospri = &sospri;- nsos = suf_sos(i, &nsosnz, &sostype, p_sospri, copri,- &sosbeg, &sosind, &sosref);- if (nsos) {- info->numberSos = nsos;- info->sosType = (char *) malloc(nsos);- info->sosPriority = (int *) malloc(nsos * sizeof(int));- info->sosStart = (int *) malloc((nsos + 1) * sizeof(int));- info->sosIndices = (int *) malloc(nsosnz * sizeof(int));- info->sosReference = (double *) malloc(nsosnz * sizeof(double));- sos_kludge(nsos, sosbeg, sosref, sosind);- for (int i = 0; i < nsos; i++) {- char ichar = sostype[i];- assert (ichar == '1' || ichar == '2');- info->sosType[i] = static_cast<char>(ichar - '0');- }- memcpy(info->sosPriority, sospri, nsos*sizeof(int));- memcpy(info->sosStart, sosbeg, (nsos + 1)*sizeof(int));- memcpy(info->sosIndices, sosind, nsosnz*sizeof(int));- memcpy(info->sosReference, sosref, nsosnz*sizeof(double));- }- }-- /*sos_finish(&specialOrderedInfo, 0, &j, 0, 0, 0, 0, 0);*/- Oinfo.uinfo = tempBuffer;- if (getopts(argv, &Oinfo))- return 1;- /* objective*/- obj = (double *) malloc(n_var * sizeof(double));- for (i = 0; i < n_var; i++)- obj[i] = 0.0;- if (n_obj) {- for (og = Ograd[0]; og; og = og->next)- obj[og->varno] = og->coef;- }- if (objtype[0])- info->direction = -1.0;- else- info->direction = 1.0;- info->offset = objconst(0);- /* Column bounds*/- columnLower = (double *) malloc(n_var * sizeof(double));- columnUpper = (double *) malloc(n_var * sizeof(double));- for (i = 0; i < n_var; i++) {- columnLower[i] = LUv[2*i];- if (columnLower[i] <= negInfinity)- columnLower[i] = -COIN_DBL_MAX;- columnUpper[i] = LUv[2*i+1];- if (columnUpper[i] >= Infinity)- columnUpper[i] = COIN_DBL_MAX;- }- /* Row bounds*/- rowLower = (double *) malloc(n_con * sizeof(double));- rowUpper = (double *) malloc(n_con * sizeof(double));- for (i = 0; i < n_con; i++) {- rowLower[i] = LUrhs[2*i];- if (rowLower[i] <= negInfinity)- rowLower[i] = -COIN_DBL_MAX;- rowUpper[i] = LUrhs[2*i+1];- if (rowUpper[i] >= Infinity)- rowUpper[i] = COIN_DBL_MAX;- }- info->numberRows = n_con;- info->numberColumns = n_var;- info->numberElements = nzc;- info->numberBinary = nbv;- info->numberIntegers = niv + nbv;- info->objective = obj;- info->rowLower = rowLower;- info->rowUpper = rowUpper;- info->columnLower = columnLower;- info->columnUpper = columnUpper;- info->starts = A_colstarts;- /*A_colstarts=NULL;*/- info->rows = A_rownos;- /*A_rownos=NULL;*/- info->elements = A_vals;- /*A_vals=NULL;*/- info->primalSolution = NULL;- /* put in primalSolution if exists */- if (X0) {- info->primalSolution = (double *) malloc(n_var * sizeof(double));- memcpy(info->primalSolution, X0, n_var*sizeof(double));- }- info->dualSolution = NULL;- if (niv + nbv > 0)- mip_stuff(); // get any extra info- if ((!(niv + nbv) && (csd->kind & ASL_Sufkind_input))- || (rsd->kind & ASL_Sufkind_input)) {- /* convert status - need info on map */- static int map[] = {1, 3, 1, 1, 2, 1, 1};- stat_map(info->columnStatus, n_var, map, 6, "incoming columnStatus");- stat_map(info->rowStatus, n_con, map, 6, "incoming rowStatus");- } else {- /* all slack basis */- // leave status for output */-#ifdef JJF_ZERO- free(info->rowStatus);- info->rowStatus = NULL;- free(info->columnStatus);- info->columnStatus = NULL;-#endif- }- } else {- // QP- // Add .nl if not there- if (!strstr(fileName, ".nl"))- strcat(fileName, ".nl");- CoinModel * model = new CoinModel((nonLinearType > 10) ? 2 : 1, fileName, info);- if (model->numberRows() > 0 || model->numberColumns() > 0)- *coinModel = (void *) model;- Oinfo.uinfo = tempBuffer;- if (getopts(argv, &Oinfo))- return 1;- Oinfo.wantsol = 1;- if (objtype[0])- info->direction = -1.0;- else- info->direction = 1.0;- model->setOptimizationDirection(info->direction);- info->offset = objconst(0);- info->numberRows = n_con;- info->numberColumns = n_var;- info->numberElements = nzc;- info->numberBinary = nbv;- int numberIntegers = niv + nlvci + nlvoi + nbv;- if (nlvci + nlvoi + nlvc + nlvo) {- // Non linear- // No idea if there are overlaps so compute- int numberIntegers = 0;- for ( i = 0; i < n_var; i++) {- if (model->columnIsInteger(i))- numberIntegers++;- }- }- info->numberIntegers = numberIntegers;- // Say nonlinear if it is- info->nonLinear = nlvc + nlvo;- if (numberIntegers > 0) {- mip_stuff(); // get any extra info- if (info->cut)- model->setCutMarker(info->numberRows, info->cut);- if (info->priorities)- model->setPriorities(info->numberColumns, info->priorities);- }- }- /* add -solve - unless something there already- - also check for sleep=yes */- {- int found = 0;- int foundLog = 0;- int foundSleep = 0;- const char * something[] = {"solve", "branch", "duals", "primals", "user"};- for (i = 0; i < info->numberArguments; i++) {- unsigned int j;- const char * argument = info->arguments[i];- for (j = 0; j < sizeof(something) / sizeof(char *); j++) {- const char * check = something[j];- if (!strncmp(argument, check, sizeof(check))) {- found = (int)(j + 1);- } else if (!strncmp(argument, "log", 3)) {- foundLog = 1;- } else if (!strncmp(argument, "sleep", 5)) {- foundSleep = 1;- }- }- }- if (foundLog) {- /* print options etc */- for (i = 0; i < saveArgc; i++)- printf("%s ", saveArgv[i]);- printf("\n");- if (environment)- printf("env %s\n", environment);- /*printf("%d rows %d columns %d elements\n",n_con,n_var,nzc);*/- }- if (!found) {- if (!strlen(algFound)) {- info->arguments = (char **) realloc(info->arguments, (info->numberArguments + 1) * sizeof(char *));- info->arguments[info->numberArguments++] = strdup("-solve");- } else {- // use algorithm from keyword- info->arguments = (char **) realloc(info->arguments, (info->numberArguments + 1) * sizeof(char *));- info->arguments[info->numberArguments++] = strdup(algFound);- }- }- if (foundSleep) {- /* let user copy .nl file */- fprintf(stderr, "You can copy .nl file %s for debug purposes or attach debugger\n", saveArgv[1]);- fprintf(stderr, "Type q to quit, anything else to continue\n");- int getChar = getc(stdin);- if (getChar == 'q' || getChar == 'Q')- exit(1);- }- }- /* add -quit */- info->arguments = (char **) realloc(info->arguments, (info->numberArguments + 1) * sizeof(char *));- info->arguments[info->numberArguments++] = strdup("-quit");- return 0;-}-void freeArrays1(ampl_info * info)-{- free(info->objective);- info->objective = NULL;- free(info->rowLower);- info->rowLower = NULL;- free(info->rowUpper);- info->rowUpper = NULL;- free(info->columnLower);- info->columnLower = NULL;- free(info->columnUpper);- info->columnUpper = NULL;- /* this one not freed by ASL_free */- free(info->elements);- info->elements = NULL;- free(info->primalSolution);- info->primalSolution = NULL;- free(info->dualSolution);- info->dualSolution = NULL;- /*free(info->rowStatus);- info->rowStatus=NULL;- free(info->columnStatus);- info->columnStatus=NULL;*/-}-void freeArrays2(ampl_info * info)-{- free(info->primalSolution);- info->primalSolution = NULL;- free(info->dualSolution);- info->dualSolution = NULL;- free(info->rowStatus);- info->rowStatus = NULL;- free(info->columnStatus);- info->columnStatus = NULL;- free(info->priorities);- info->priorities = NULL;- free(info->branchDirection);- info->branchDirection = NULL;- free(info->pseudoDown);- info->pseudoDown = NULL;- free(info->pseudoUp);- info->pseudoUp = NULL;- free(info->sosType);- info->sosType = NULL;- free(info->sosPriority);- info->sosPriority = NULL;- free(info->sosStart);- info->sosStart = NULL;- free(info->sosIndices);- info->sosIndices = NULL;- free(info->sosReference);- info->sosReference = NULL;- free(info->cut);- info->cut = NULL;- ASL_free(&asl);-}-void freeArgs(ampl_info * info)-{- int i;- for ( i = 0; i < info->numberArguments; i++)- free(info->arguments[i]);- free(info->arguments);-}-int ampl_obj_prec()-{- return obj_prec();-}-void writeAmpl(ampl_info * info)-{- char buf[1000];- typedef struct {- const char *msg;- int code;- int wantObj;- } Sol_info;- static Sol_info solinfo[] = {- { "optimal solution", 000, 1 },- { "infeasible", 200, 1 },- { "unbounded", 300, 0 },- { "iteration limit etc", 400, 1 },- { "solution limit", 401, 1 },- { "ran out of space", 500, 0 },- { "status unknown", 501, 1 },- { "bug!", 502, 0 },- { "best MIP solution so far restored", 101, 1 },- { "failed to restore best MIP solution", 503, 1 },- { "optimal (?) solution", 100, 1 }- };- /* convert status - need info on map */- static int map[] = {0, 3, 4, 1};- sprintf(buf, "%s %s", Oinfo.bsname, info->buffer);- solve_result_num = solinfo[info->problemStatus].code;- if (info->columnStatus) {- stat_map(info->columnStatus, n_var, map, 4, "outgoing columnStatus");- stat_map(info->rowStatus, n_con, map, 4, "outgoing rowStatus");- suf_iput("sstatus", ASL_Sufkind_var, info->columnStatus);- suf_iput("sstatus", ASL_Sufkind_con, info->rowStatus);- }- write_sol(buf, info->primalSolution, info->dualSolution, &Oinfo);-}-/* Read a problem from AMPL nl file- */-CoinModel::CoinModel( int nonLinear, const char * fileName, const void * info)- : CoinBaseModel(),- maximumRows_(0),- maximumColumns_(0),- numberElements_(0),- maximumElements_(0),- numberQuadraticElements_(0),- maximumQuadraticElements_(0),- rowLower_(NULL),- rowUpper_(NULL),- rowType_(NULL),- objective_(NULL),- columnLower_(NULL),- columnUpper_(NULL),- integerType_(NULL),- columnType_(NULL),- start_(NULL),- elements_(NULL),- packedMatrix_(NULL),- quadraticElements_(NULL),- sortIndices_(NULL),- sortElements_(NULL),- sortSize_(0),- sizeAssociated_(0),- associated_(NULL),- numberSOS_(0),- startSOS_(NULL),- memberSOS_(NULL),- typeSOS_(NULL),- prioritySOS_(NULL),- referenceSOS_(NULL),- priority_(NULL),- cut_(NULL),- moreInfo_(NULL),- type_(-1),- noNames_(false),- links_(0)-{- problemName_ = "";- int status = 0;- if (!strcmp(fileName, "-") || !strcmp(fileName, "stdin")) {- // stdin- } else {- std::string name = fileName;- bool readable = fileCoinReadable(name);- if (!readable) {- std::cerr << "Unable to open file "- << fileName << std::endl;- status = -1;- }- }- if (!status) {- gdb(nonLinear, fileName, info);- }-}-#ifdef JJF_ZERO-static real-qterm(ASL *asl, fint *colq, fint *rowq, real *delsq)-{- double t, t1, *x, *x0, *xe;- fint *rq0, *rqe;-- t = 0.;- x0 = x = X0;- xe = x + n_var;- rq0 = rowq;- while (x < xe) {- t1 = *x++;- rqe = rq0 + *++colq;- while (rowq < rqe)- t += t1 * x0[*rowq++]**delsq++;- }- return 0.5 * t;-}-#endif-// stolen from IPopt with changes-typedef struct {- double obj_sign_;- ASL_pfgh * asl_;- double * non_const_x_;- int * column_; // for jacobian- int * rowStart_;- double * gradient_;- double * constraintValues_;- int nz_h_full_; // number of nonzeros in hessian- int nerror_;- bool objval_called_with_current_x_;- bool conval_called_with_current_x_;- bool jacval_called_with_current_x_;-} CbcAmplInfo;--void-CoinModel::gdb( int nonLinear, const char * fileName, const void * info)-{- const ampl_info * amplInfo = (const ampl_info *) info;- ograd *og = NULL;- int i;- SufDesc *csd = NULL;- SufDesc *rsd = NULL;- /*bool *basis, *lower;*/- /*double *LU, *c, lb, objadj, *rshift, *shift, t, ub, *x, *x0, *x1;*/- //char tempBuffer[20];- double * objective = NULL;- double * columnLower = NULL;- double * columnUpper = NULL;- double * rowLower = NULL;- double * rowUpper = NULL;- int * columnStatus = NULL;- int * rowStatus = NULL;- int numberRows = -1;- int numberColumns = -1;- int numberElements = -1;- int numberBinary = -1;- int numberIntegers = -1;- int numberAllNonLinearBoth = 0;- int numberIntegerNonLinearBoth = 0;- int numberAllNonLinearConstraints = 0;- int numberIntegerNonLinearConstraints = 0;- int numberAllNonLinearObjective = 0;- int numberIntegerNonLinearObjective = 0;- double * primalSolution = NULL;- double direction = 1.0;- char * stub = strdup(fileName);- CoinPackedMatrix matrixByRow;- fint ** colqp = NULL;- int *z = NULL;- if (nonLinear == 0) {- // linear- asl = ASL_alloc(ASL_read_f);- nl = jac0dim(stub, 0);- free(stub);- suf_declare(suftab, sizeof(suftab) / sizeof(SufDecl));-- /* set A_vals to get the constraints column-wise (malloc so can be freed) */- A_vals = (double *) malloc(nzc * sizeof(double));- if (!A_vals) {- printf("no memory\n");- return ;- }- /* say we want primal solution */- want_xpi0 = 1;- /* for basis info */- columnStatus = (int *) malloc(n_var * sizeof(int));- rowStatus = (int *) malloc(n_con * sizeof(int));- csd = suf_iput("sstatus", ASL_Sufkind_var, columnStatus);- rsd = suf_iput("sstatus", ASL_Sufkind_con, rowStatus);- /* read linear model*/- f_read(nl, 0);- // see if any sos- if (true) {- char *sostype;- int nsosnz, *sosbeg, *sosind, * sospri;- double *sosref;- int nsos;- int i = ASL_suf_sos_explict_free;- int copri[2], **p_sospri;- copri[0] = 0;- copri[1] = 0;- p_sospri = &sospri;- nsos = suf_sos(i, &nsosnz, &sostype, p_sospri, copri,- &sosbeg, &sosind, &sosref);- if (nsos) {- abort();-#ifdef JJF_ZERO- info->numberSos = nsos;- info->sosType = (char *) malloc(nsos);- info->sosPriority = (int *) malloc(nsos * sizeof(int));- info->sosStart = (int *) malloc((nsos + 1) * sizeof(int));- info->sosIndices = (int *) malloc(nsosnz * sizeof(int));- info->sosReference = (double *) malloc(nsosnz * sizeof(double));- sos_kludge(nsos, sosbeg, sosref, sosind);- for (int i = 0; i < nsos; i++) {- int ichar = sostype[i];- assert (ichar == '1' || ichar == '2');- info->sosType[i] = ichar - '0';- }- memcpy(info->sosPriority, sospri, nsos*sizeof(int));- memcpy(info->sosStart, sosbeg, (nsos + 1)*sizeof(int));- memcpy(info->sosIndices, sosind, nsosnz*sizeof(int));- memcpy(info->sosReference, sosref, nsosnz*sizeof(double));-#endif- }- }-- /*sos_finish(&specialOrderedInfo, 0, &j, 0, 0, 0, 0, 0);*/- //Oinfo.uinfo = tempBuffer;- //if (getopts(argv, &Oinfo))- //return 1;- /* objective*/- objective = (double *) malloc(n_var * sizeof(double));- for (i = 0; i < n_var; i++)- objective[i] = 0.0;- if (n_obj) {- for (og = Ograd[0]; og; og = og->next)- objective[og->varno] = og->coef;- }- if (objtype[0])- direction = -1.0;- else- direction = 1.0;- objectiveOffset_ = objconst(0);- /* Column bounds*/- columnLower = (double *) malloc(n_var * sizeof(double));- columnUpper = (double *) malloc(n_var * sizeof(double));- for (i = 0; i < n_var; i++) {- columnLower[i] = LUv[2*i];- if (columnLower[i] <= negInfinity)- columnLower[i] = -COIN_DBL_MAX;- columnUpper[i] = LUv[2*i+1];- if (columnUpper[i] >= Infinity)- columnUpper[i] = COIN_DBL_MAX;- }- /* Row bounds*/- rowLower = (double *) malloc(n_con * sizeof(double));- rowUpper = (double *) malloc(n_con * sizeof(double));- for (i = 0; i < n_con; i++) {- rowLower[i] = LUrhs[2*i];- if (rowLower[i] <= negInfinity)- rowLower[i] = -COIN_DBL_MAX;- rowUpper[i] = LUrhs[2*i+1];- if (rowUpper[i] >= Infinity)- rowUpper[i] = COIN_DBL_MAX;- }- numberRows = n_con;- numberColumns = n_var;- numberElements = nzc;- numberBinary = nbv;- numberIntegers = niv;- /* put in primalSolution if exists */- if (X0) {- primalSolution = (double *) malloc(n_var * sizeof(double));- memcpy( primalSolution, X0, n_var*sizeof(double));- }- //double * dualSolution=NULL;- if (niv + nbv > 0)- mip_stuff(); // get any extra info- if ((!(niv + nbv) && (csd->kind & ASL_Sufkind_input))- || (rsd->kind & ASL_Sufkind_input)) {- /* convert status - need info on map */- static int map[] = {1, 3, 1, 1, 2, 1, 1};- stat_map(columnStatus, n_var, map, 6, "incoming columnStatus");- stat_map(rowStatus, n_con, map, 6, "incoming rowStatus");- } else {- /* all slack basis */- // leave status for output */-#ifdef JJF_ZERO- free(rowStatus);- rowStatus = NULL;- free(columnStatus);- columnStatus = NULL;-#endif- }- CoinPackedMatrix columnCopy(true, numberRows, numberColumns, numberElements,- A_vals, A_rownos, A_colstarts, NULL);- matrixByRow.reverseOrderedCopyOf(columnCopy);- } else if (nonLinear == 1) {- // quadratic- asl = ASL_alloc(ASL_read_fg);- nl = jac0dim(stub, (ftnlen) strlen(stub));- free(stub);- suf_declare(suftab, sizeof(suftab) / sizeof(SufDecl));- /* read model*/- X0 = (double*) malloc(n_var * sizeof(double));- CoinZeroN(X0, n_var);- qp_read(nl, 0);- assert (n_obj == 1);- int nz = 1 + n_con;- colqp = (fint**) malloc(nz * (2 * sizeof(int*)- + sizeof(double*)));- fint ** rowqp = colqp + nz;- double ** delsqp = (double **)(rowqp + nz);- z = (int*) malloc(nz * sizeof(int));- for (i = 0; i <= n_con; i++) {- z[i] = nqpcheck(-i, rowqp + i, colqp + i, delsqp + i);- }- qp_opify();- /* objective*/- objective = (double *) malloc(n_var * sizeof(double));- for (i = 0; i < n_var; i++)- objective[i] = 0.0;- if (n_obj) {- for (og = Ograd[0]; og; og = og->next)- objective[og->varno] = og->coef;- }- if (objtype[0])- direction = -1.0;- else- direction = 1.0;- objectiveOffset_ = objconst(0);- /* Column bounds*/- columnLower = (double *) malloc(n_var * sizeof(double));- columnUpper = (double *) malloc(n_var * sizeof(double));- for (i = 0; i < n_var; i++) {- columnLower[i] = LUv[2*i];- if (columnLower[i] <= negInfinity)- columnLower[i] = -COIN_DBL_MAX;- columnUpper[i] = LUv[2*i+1];- if (columnUpper[i] >= Infinity)- columnUpper[i] = COIN_DBL_MAX;- }- // Build by row from scratch- //matrixByRow.reserve(n_var,nzc,true);- // say row orderded- matrixByRow.transpose();- /* Row bounds*/- rowLower = (double *) malloc(n_con * sizeof(double));- rowUpper = (double *) malloc(n_con * sizeof(double));- CoinBigIndex * rowStart = new CoinBigIndex [n_con+1];- int * column = new int [nzc];- double * element = new double [nzc];- rowStart[0] = 0;- numberElements = 0;- for (i = 0; i < n_con; i++) {- rowLower[i] = LUrhs[2*i];- if (rowLower[i] <= negInfinity)- rowLower[i] = -COIN_DBL_MAX;- rowUpper[i] = LUrhs[2*i+1];- if (rowUpper[i] >= Infinity)- rowUpper[i] = COIN_DBL_MAX;- for (cgrad * cg = Cgrad[i]; cg; cg = cg->next) {- column[numberElements] = cg->varno;- element[numberElements++] = cg->coef;- }- rowStart[i+1] = numberElements;- }- assert (numberElements == nzc);- matrixByRow.appendRows(n_con, rowStart, column, element);- delete [] rowStart;- delete [] column;- delete [] element;- numberRows = n_con;- numberColumns = n_var;- //numberElements=nzc;- numberBinary = nbv;- numberIntegers = niv;- numberAllNonLinearBoth = nlvb;- numberIntegerNonLinearBoth = nlvbi;- numberAllNonLinearConstraints = nlvc;- numberIntegerNonLinearConstraints = nlvci;- numberAllNonLinearObjective = nlvo;- numberIntegerNonLinearObjective = nlvoi;- /* say we want primal solution */- want_xpi0 = 1;- //double * dualSolution=NULL;- // save asl- // Fix memory leak one day- CbcAmplInfo * info = new CbcAmplInfo;- //amplGamsData_ = info;- info->asl_ = NULL; // as wrong form asl;- info->nz_h_full_ = -1; // number of nonzeros in hessian- info->objval_called_with_current_x_ = false;- info->nerror_ = 0;- info->obj_sign_ = direction;- info->conval_called_with_current_x_ = false;- info->non_const_x_ = NULL;- info->jacval_called_with_current_x_ = false;- info->rowStart_ = NULL;- info->column_ = NULL;- info->gradient_ = NULL;- info->constraintValues_ = NULL;- } else if (nonLinear == 2) {- // General nonlinear!- //ASL_pfgh* asl = (ASL_pfgh*)ASL_alloc(ASL_read_pfgh);- asl = ASL_alloc(ASL_read_pfgh);- nl = jac0dim(stub, (ftnlen) strlen(stub));- free(stub);- suf_declare(suftab, sizeof(suftab) / sizeof(SufDecl));- /* read model*/- X0 = (double*) malloc(n_var * sizeof(double));- CoinZeroN(X0, n_var);- // code stolen from Ipopt- int retcode = pfgh_read(nl, ASL_return_read_err | ASL_findgroups);-- switch (retcode) {- case ASL_readerr_none : {}- break;- case ASL_readerr_nofile : {- printf( "Cannot open .nl file\n");- exit(-1);- }- break;- case ASL_readerr_nonlin : {- assert(false); // this better not be an error!- printf( "model involves nonlinearities (ed0read)\n");- exit(-1);- }- break;- case ASL_readerr_argerr : {- printf( "user-defined function with bad args\n");- exit(-1);- }- break;- case ASL_readerr_unavail : {- printf( "user-defined function not available\n");- exit(-1);- }- break;- case ASL_readerr_corrupt : {- printf( "corrupt .nl file\n");- exit(-1);- }- break;- case ASL_readerr_bug : {- printf( "bug in .nl reader\n");- exit(-1);- }- break;- case ASL_readerr_CLP : {- printf( "ASL error message: \"solver cannot handle CLP extensions\"\n");- exit(-1);- }- break;- default: {- printf( "Unknown error in stub file read. retcode = %d\n", retcode);- exit(-1);- }- break;- }-- // see "changes" in solvers directory of ampl code...- hesset(1, 0, 1, 0, nlc);-- assert (n_obj == 1);- // find the nonzero structure for the hessian- // parameters to sphsetup:- int coeff_obj = 1; // coefficient of the objective fn ???- int mult_supplied = 1; // multipliers will be supplied- int uptri = 1; // only need the upper triangular part- // save asl- // Fix memory leak one day- CbcAmplInfo * info = new CbcAmplInfo;- moreInfo_ = (void *) info;- //amplGamsData_ = info;- info->asl_ = (ASL_pfgh *) asl;- // This is not easy to get from ampl so save- info->nz_h_full_ = sphsetup(-1, coeff_obj, mult_supplied, uptri);- info->objval_called_with_current_x_ = false;- info->nerror_ = 0;- info->obj_sign_ = direction;- info->conval_called_with_current_x_ = false;- info->non_const_x_ = NULL;- info->jacval_called_with_current_x_ = false;- // Look at nonlinear- if (nzc) {- n_conjac[1] = nlc; // just nonlinear- int * rowStart = new int [nlc+1];- info->rowStart_ = rowStart;- // See how many- int current_nz = 0;- for (int i = 0; i < nlc; i++) {- for (cgrad* cg = Cgrad[i]; cg; cg = cg->next) {- current_nz++;- }- }- // setup the structure- int * column = new int [current_nz];- info->column_ = column;- current_nz = 0;- rowStart[0] = 0;- for (int i = 0; i < nlc; i++) {- for (cgrad* cg = Cgrad[i]; cg; cg = cg->next) {- cg->goff = current_nz;- //iRow[cg->goff] = i ;- //jCol[cg->goff] = cg->varno + 1;- column[cg->goff] = cg->varno ;- current_nz++;- }- rowStart[i+1] = current_nz;- }- info->gradient_ = new double [nzc];- info->constraintValues_ = new double [nlc];- }- /* objective*/- objective = (double *) malloc(n_var * sizeof(double));- for (i = 0; i < n_var; i++)- objective[i] = 0.0;- if (n_obj) {- for (og = Ograd[0]; og; og = og->next)- objective[og->varno] = og->coef;- }- if (objtype[0])- direction = -1.0;- else- direction = 1.0;- objectiveOffset_ = objconst(0);- /* Column bounds*/- columnLower = (double *) malloc(n_var * sizeof(double));- columnUpper = (double *) malloc(n_var * sizeof(double));- for (i = 0; i < n_var; i++) {- columnLower[i] = LUv[2*i];- if (columnLower[i] <= negInfinity)- columnLower[i] = -COIN_DBL_MAX;- columnUpper[i] = LUv[2*i+1];- if (columnUpper[i] >= Infinity)- columnUpper[i] = COIN_DBL_MAX;- }- // Build by row from scratch- //matrixByRow.reserve(n_var,nzc,true);- // say row orderded- matrixByRow.transpose();- CoinBigIndex * rowStart = new CoinBigIndex [n_con+1];- int * column = new int [nzc];- double * element = new double [nzc];- rowStart[0] = 0;- numberElements = 0;- /* Row bounds*/- rowLower = (double *) malloc(n_con * sizeof(double));- rowUpper = (double *) malloc(n_con * sizeof(double));- for (i = 0; i < n_con; i++) {- rowLower[i] = LUrhs[2*i];- if (rowLower[i] <= negInfinity)- rowLower[i] = -COIN_DBL_MAX;- rowUpper[i] = LUrhs[2*i+1];- if (rowUpper[i] >= Infinity)- rowUpper[i] = COIN_DBL_MAX;- for (cgrad * cg = Cgrad[i]; cg; cg = cg->next) {- column[numberElements] = cg->varno;- double value = cg->coef;- if (!value)- value = -1.2345e-29;- element[numberElements++] = value;- }- rowStart[i+1] = numberElements;- }- assert (numberElements == nzc);- matrixByRow.appendRows(n_con, rowStart, column, element);- delete [] rowStart;- delete [] column;- delete [] element;- numberRows = n_con;- numberColumns = n_var;- numberElements = nzc;- numberBinary = nbv;- numberIntegers = niv;- numberAllNonLinearBoth = nlvb;- numberIntegerNonLinearBoth = nlvbi;- numberAllNonLinearConstraints = nlvc;- numberIntegerNonLinearConstraints = nlvci;- numberAllNonLinearObjective = nlvo;- numberIntegerNonLinearObjective = nlvoi;- /* say we want primal solution */- want_xpi0 = 1;- //double * dualSolution=NULL;- } else {- abort();- }- // set problem name- problemName_ = "???";-- // Build by row from scratch- const double * element = matrixByRow.getElements();- const int * column = matrixByRow.getIndices();- const CoinBigIndex * rowStart = matrixByRow.getVectorStarts();- const int * rowLength = matrixByRow.getVectorLengths();- for (i = 0; i < numberRows; i++) {- addRow(rowLength[i], column + rowStart[i],- element + rowStart[i], rowLower[i], rowUpper[i]);- }- // Now do column part- for (i = 0; i < numberColumns; i++) {- setColumnBounds(i, columnLower[i], columnUpper[i]);- setColumnObjective(i, objective[i]);- }- for ( i = numberColumns - numberBinary - numberIntegers;- i < numberColumns; i++) {- setColumnIsInteger(i, true);- }- // and non linear- for (i = numberAllNonLinearBoth - numberIntegerNonLinearBoth;- i < numberAllNonLinearBoth; i++) {- setColumnIsInteger(i, true);- }- for (i = numberAllNonLinearConstraints - numberIntegerNonLinearConstraints;- i < numberAllNonLinearConstraints; i++) {- setColumnIsInteger(i, true);- }- for (i = numberAllNonLinearObjective - numberIntegerNonLinearObjective;- i < numberAllNonLinearObjective; i++) {- setColumnIsInteger(i, true);- }- free(columnLower);- free(columnUpper);- free(rowLower);- free(rowUpper);- free(objective);- // do names- int iRow;- for (iRow = 0; iRow < numberRows_; iRow++) {- char name[9];- sprintf(name, "r%7.7d", iRow);- setRowName(iRow, name);- }- int iColumn;- for (iColumn = 0; iColumn < numberColumns_; iColumn++) {- char name[9];- sprintf(name, "c%7.7d", iColumn);- setColumnName(iColumn, name);- }- if (colqp) {- // add in quadratic- int nz = 1 + n_con;- int nOdd = 0;- fint ** rowqp = colqp + nz;- double ** delsqp = (double **)(rowqp + nz);- for (i = 0; i <= n_con; i++) {- int nels = z[i];- if (nels) {- double * element = delsqp[i];- int * start = (int *) colqp[i];- int * row = (int *) rowqp[i];- if (!element) {- // odd row - probably not quadratic- nOdd++;- continue;- }-#ifdef JJF_ZERO- printf("%d quadratic els\n", nels);- for (int j = 0; j < n_var; j++) {- for (int k = start[j]; k < start[j+1]; k++)- printf("%d %d %g\n", j, row[k], element[k]);- }-#endif- if (i) {- int iRow = i - 1;- for (int j = 0; j < n_var; j++) {- for (int k = start[j]; k < start[j+1]; k++) {- int kColumn = row[k];- double value = element[k];- // ampl gives twice with assumed 0.5- if (kColumn < j)- continue;- else if (kColumn == j)- value *= 0.5;- const char * expr = getElementAsString(iRow, j);- double constant = 0.0;- bool linear;- if (expr && strcmp(expr, "Numeric")) {- linear = false;- } else {- constant = getElement(iRow, j);- linear = true;- }- char temp[1000];- char temp2[30];- if (value == 1.0)- sprintf(temp2, "c%7.7d", kColumn);- else- sprintf(temp2, "%g*c%7.7d", value, kColumn);- if (linear) {- if (!constant)- strcpy(temp, temp2);- else if (value > 0.0)- sprintf(temp, "%g+%s", constant, temp2);- else- sprintf(temp, "%g%s", constant, temp2);- } else {- if (value > 0.0)- sprintf(temp, "%s+%s", expr, temp2);- else- sprintf(temp, "%s%s", expr, temp2);- }- assert (strlen(temp) < 1000);- setElement(iRow, j, temp);- if (amplInfo->logLevel > 1)- printf("el for row %d column c%7.7d is %s\n", iRow, j, temp);- }- }- } else {- // objective- for (int j = 0; j < n_var; j++) {- for (int k = start[j]; k < start[j+1]; k++) {- int kColumn = row[k];- double value = element[k];- // ampl gives twice with assumed 0.5- if (kColumn < j)- continue;- else if (kColumn == j)- value *= 0.5;- const char * expr = getColumnObjectiveAsString(j);- double constant = 0.0;- bool linear;- if (expr && strcmp(expr, "Numeric")) {- linear = false;- } else {- constant = getColumnObjective(j);- linear = true;- }- char temp[1000];- char temp2[30];- if (value == 1.0)- sprintf(temp2, "c%7.7d", kColumn);- else- sprintf(temp2, "%g*c%7.7d", value, kColumn);- if (linear) {- if (!constant)- strcpy(temp, temp2);- else if (value > 0.0)- sprintf(temp, "%g+%s", constant, temp2);- else- sprintf(temp, "%g%s", constant, temp2);- } else {- if (value > 0.0)- sprintf(temp, "%s+%s", expr, temp2);- else- sprintf(temp, "%s%s", expr, temp2);- }- assert (strlen(temp) < 1000);- setObjective(j, temp);- if (amplInfo->logLevel > 1)- printf("el for objective column c%7.7d is %s\n", j, temp);- }- }- }- }- }- if (nOdd) {- printf("%d non-linear constraints could not be converted to quadratic\n", nOdd);- exit(77);- }- }- free(colqp);- free(z);- // see if any sos- {- char *sostype;- int nsosnz, *sosbeg, *sosind, * sospri;- double *sosref;- int nsos;- int i = ASL_suf_sos_explict_free;- int copri[2], **p_sospri;- copri[0] = 0;- copri[1] = 0;- p_sospri = &sospri;- nsos = suf_sos(i, &nsosnz, &sostype, p_sospri, copri,- &sosbeg, &sosind, &sosref);- if (nsos) {- numberSOS_ = nsos;- typeSOS_ = new int [numberSOS_];- prioritySOS_ = new int [numberSOS_];- startSOS_ = new int [numberSOS_+1];- memberSOS_ = new int[nsosnz];- referenceSOS_ = new double [nsosnz];- sos_kludge(nsos, sosbeg, sosref, sosind);- for (int i = 0; i < nsos; i++) {- int ichar = sostype[i];- assert (ichar == '1' || ichar == '2');- typeSOS_[i] = ichar - '0';- }- memcpy(prioritySOS_, sospri, nsos*sizeof(int));- memcpy(startSOS_, sosbeg, (nsos + 1)*sizeof(int));- memcpy(memberSOS_, sosind, nsosnz*sizeof(int));- memcpy(referenceSOS_, sosref, nsosnz*sizeof(double));- }- }-}-#else-#include "Cbc_ampl.h"-int-readAmpl(ampl_info * , int , char **, void ** )-{- return 0;-}-void freeArrays1(ampl_info *)-{-}-void freeArrays2(ampl_info *)-{-}-void freeArgs(ampl_info * )-{-}-int ampl_obj_prec()-{- return 0;-}-void writeAmpl(ampl_info * )-{-}-#endif-
− cbits/coin/CglAllDifferent.cpp
@@ -1,578 +0,0 @@-// Copyright (C) 2005, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#include <cstdlib>-#include <cstdio>-#include <cmath>-#include <cfloat>-#include <cassert>-#include <iostream>-//#define PRINT_DEBUG-//#define CGL_DEBUG 1-//#undef NDEBUG-#include "CoinPragma.hpp"-#include "CoinHelperFunctions.hpp"-#include "CoinPackedVector.hpp"-#include "CoinPackedMatrix.hpp"-#include "CoinFinite.hpp"-#include "OsiRowCutDebugger.hpp"-#include "CglAllDifferent.hpp"--#ifdef CGL_DEBUG-// A declaration is required somewhere, eh? I'm assuming static so the value-// carries over between calls to generateCuts.-namespace { int nPath = 0 ; }-#endif-//--------------------------------------------------------------------// Generate cuts-//------------------------------------------------------------------- -void CglAllDifferent::generateCuts(const OsiSolverInterface & si, OsiCuts & cs,- const CglTreeInfo )-{-#ifndef NDEBUG- int nCols=si.getNumCols();-#endif- int i;- const double * lower = si.getColLower();- const double * upper = si.getColUpper();-#ifdef CGL_DEBUG- const OsiRowCutDebugger * debugger = si.getRowCutDebugger();- if (debugger&&debugger->onOptimalPath(si)) {- printf("On optimal path %d\n",nPath);- nPath++;- int nCols=si.getNumCols();- const double * solution = si.getColSolution();- const double * optimal = debugger->optimalSolution();- const double * objective = si.getObjCoefficients();- double objval1=0.0,objval2=0.0;- for (i=0;i<nCols;i++) {-#if CGL_DEBUG>1- printf("%d %g %g %g %g\n",i,lower[i],solution[i],upper[i],optimal[i]);-#endif- objval1 += solution[i]*objective[i];- objval2 += optimal[i]*objective[i];- assert(optimal[i]>=lower[i]&&optimal[i]<=upper[i]);- }- printf("current obj %g, integer %g\n",objval1,objval2);- }-#endif- int * lo = new int[numberDifferent_];- int * up = new int[numberDifferent_];- for (i=0;i<numberDifferent_;i++) {- int iColumn = originalWhich_[i];- assert (iColumn<nCols);- lo[i] = static_cast<int> (lower[iColumn]);- assert (floor(lower[iColumn]+0.5)==lower[iColumn]);- up[i] = static_cast<int> (upper[iColumn]);- assert (floor(upper[iColumn]+0.5)==upper[iColumn]);- assert (up[i]>=lo[i]);- }- // We are going to assume we can just have one big 2d array!- // Could save by going to bits- // also could skip sets where all are fixed- // could do some of above by separate first pass- // once a variable fixed - can take out of list- // so need to redo complete stuff (including temp which_) every big pass- int offset = COIN_INT_MAX;- int maxValue = -COIN_INT_MAX;- int numberLook=0;- // copies- //int * which = new int [numberTotal];- //int * start = new int [numberSets_+1];- for (i=0;i<numberSets_;i++) {- for (int j=start_[i];j<start_[i+1];j++) {- int k=which_[j];- offset = CoinMin(offset,lo[k]);- maxValue = CoinMax(maxValue,up[k]);- }- numberLook++;- int gap = maxValue-offset+1;- double size = static_cast<double> (gap) * numberDifferent_;- if (size>1.0e7) {- if (logLevel_)- printf("Only looking at %d sets\n",numberLook);- break;- }- }- // Which sets a variable is in- int * back = new int [start_[numberSets_]];- int * backStart = new int[numberDifferent_+1];- memset(backStart,0,(numberDifferent_+1)*sizeof(int));- int numberTotal = start_[numberLook];- for (i=0;i<numberTotal;i++) {- int k=which_[i];- // note +1 - backStart[k+1]++;- }- int n=0;- for (i=0;i<numberDifferent_;i++) {- int nThis = backStart[i+1];- backStart[i+1]=n;- n+= nThis;- }- // at end all backStart correct!- for (i=0;i<numberLook;i++) {- for (int j=start_[i];j<start_[i+1];j++) {- int k=which_[j];- // note +1 - int iPut = backStart[k+1];- back[iPut]=i;- backStart[k+1]=iPut+1;- }- }- // value is possible for variable k if possible[k*gap+value] is nonzero- int gap = maxValue-offset+1;- char * possible = new char[gap*numberDifferent_];- memset(possible,0,gap*numberDifferent_);- // initialize- int numberFixed=0;- int * alreadyFixed = new int[numberDifferent_];- for (i=0;i<numberDifferent_;i++) {- alreadyFixed[i]=-1;- int startV = i*gap + lo[i] - offset;- int n = up[i]-lo[i]+1;- memset(possible+startV,1,n);- }- for (i=0;i<numberDifferent_;i++) {- int n = up[i]-lo[i]+1;- if (n==1) {- int fixedAt = lo[i]-offset;- numberFixed++;- alreadyFixed[i]=fixedAt;- // take out of all others- for (int j=backStart[i];j<backStart[i+1];j++) {- int iSet = back[j];- for (int jj=start_[iSet];jj<start_[iSet+1];jj++) {- int k=which_[jj];- if (k!=i) {- // impossible- possible[k*gap+fixedAt]=0;- }- }- }- }- }- bool finished=false;- //int numberTightened=0;- bool infeasible=false;- // space to see which values possible- int * check = new int[gap];- unsigned int * bitmap = new unsigned int[numberDifferent_];- int * stack = new int[numberDifferent_+1];- int * first = new int[numberDifferent_+1];- // just for valgrind etc- memset(stack,0,(numberDifferent_+1)*sizeof(int));- memset(first,0,(numberDifferent_+1)*sizeof(int));- // do one set at a time- while (!finished) {- finished=true;- int fixed=numberFixed;- for (i=0;i<numberLook;i++) {- memset(check,0,gap*sizeof(int));- for (int j=start_[i];j<start_[i+1];j++) {- int k=which_[j];- if (alreadyFixed[k]>=0) {- if (check[alreadyFixed[k]]==0) {- check[alreadyFixed[k]]=1;- continue;- } else {- // infeasible- infeasible=true;- i=numberLook;- break;- }- }- char * allowed = possible + k*gap;- int n=0;- for (int jj=0;jj<gap;jj++) {- if (allowed[jj]) {- n++;- check[jj]++;- }- }- if (n<2) {- if (n==1) {- // fix- int fixedAt = -1;- for (int jj=0;jj<gap;jj++) {- if (allowed[jj]) {- fixedAt=jj;- break;- }- }- numberFixed++;- alreadyFixed[k]=fixedAt;- check[fixedAt]=1;- // take out of all others- for (int j=backStart[k];j<backStart[k+1];j++) {- int iSet = back[j];- for (int jj=start_[iSet];jj<start_[iSet+1];jj++) {- int kk=which_[jj];- if (kk!=k) {- // impossible- possible[kk*gap+fixedAt]=0;- }- }- }- } else {- // infeasible- infeasible=true;- j=numberTotal;- i=numberLook;- break;- }- }- }- // now check set- // If number covered < number in set infeasible- if (gap<30&&!infeasible) {- int n=start_[i+1]-start_[i];- memset(bitmap,0,n*sizeof(unsigned int));- int j;- int * which = which_+start_[i];- unsigned int covered=0;- bool good=true;- for (j=0;j<n;j++) {- int k=which[j];- char * allowed = possible + k*gap;- int jj;- for (jj=0;jj<gap;jj++) - if (allowed[jj]) - break;- assert (jj<gap);- first[j]=jj;- unsigned int iBit = 1<<jj;- if ((covered&iBit)==0) {- stack[j]=jj;- covered |= iBit;- } else {- // can't- jj++;- for (;jj<gap;jj++) {- iBit = iBit << 1;- if (allowed[jj]&&(covered&iBit)==0) - break;- }- if (jj<gap) {- stack[j]=jj;- covered |= iBit;- } else {- good = false;- break;- }- }- }- int nStack=j;- // just do first for rest- for (;j<n;j++) {- int k=which[j];- char * allowed = possible + k*gap;- int jj;- for (jj=0;jj<gap;jj++) - if (allowed[jj]) - break;- assert (jj<gap);- first[j]=jj;- }- int kLook=0;- while (nStack) {- nStack--;- if (good) {-#if 0- printf("con %d = ",i);- for (j=0;j<n;j++) - printf("%d ",stack[j]+1);- printf("\n");-#endif- // bug - kLook >= 0- kLook=0;- for (j=kLook;j<n;j++) {- int iBit = 1 << stack[j];- bitmap[j] |= iBit;- }- }- kLook=nStack;- int jj=stack[nStack];- unsigned int iBit = 1<<jj;- covered &= ~iBit;- {- unsigned int kBit=0;- for (int k=0;k<nStack;k++) {- int kk=stack[k];- kBit |= 1<<kk;- }- assert (covered==kBit);- }- jj++;- stack[nStack]=jj;- while (nStack<n) {- int k=which[nStack];- char * allowed = possible + k*gap;- for (;jj<gap;jj++) {- iBit = 1 << jj;- if (allowed[jj]&&(covered&iBit)==0) - break;- }- if (jj<gap) {- stack[nStack]=jj;- covered |= iBit;- nStack++;- stack[nStack]=first[nStack];- jj = first[nStack];- good=true;- } else {- good = false;- break;- }- }- }- int nnFix=0;- // Now see if we can fix any- for (j=0;j<n;j++) {- int k=which[j];- unsigned int mapped = bitmap[j];- char * allowed = possible + k*gap;- unsigned int iBit=1;- for (int jj=0;jj<gap;jj++) {- if ((mapped&iBit)==0) {- if (allowed[jj]) {- if (!nnFix)- printf("for con %d x ",i);- nnFix++;- printf("%d not %d ",j,jj+1);- allowed[jj]=0;- finished=false;- }- }- iBit = iBit << 1;- }- }- if (nnFix)- printf("\n");- }- }- if (numberFixed>fixed)- finished=false; // try again- }- // Could try two sets- if (infeasible) {- // create infeasible cut- OsiRowCut rc;- rc.setLb(COIN_DBL_MAX);- rc.setUb(0.0); - cs.insert(rc);- } else {- // check to see if can tighten bounds- CoinPackedVector lbs;- CoinPackedVector ubs;- int nTightened=0;- for (i=0;i<numberDifferent_;i++) {- int iColumn = originalWhich_[i];- char * allowed = possible+i*gap;- int firstLo=-1;- int lastUp=-1;- for (int jj=0;jj<gap;jj++) {- if (allowed[jj]) {- if (firstLo<0)- firstLo=jj;- lastUp = jj;- }- }- if (firstLo+offset>lo[i]) {- lbs.insert(iColumn,static_cast<double> (firstLo+offset));- nTightened++;- }- if (lastUp+offset<up[i]) {- ubs.insert(iColumn,static_cast<double> (lastUp+offset));- nTightened++;- }- }- if (nTightened) {- OsiColCut cc;- cc.setUbs(ubs);- cc.setLbs(lbs);- cc.setEffectiveness(100.0);- cs.insert(cc);- }- }- //delete [] which;- //delete [] start;- delete [] first;- delete [] stack;- delete [] bitmap;- delete [] check;- delete [] alreadyFixed;- delete [] back;- delete [] backStart;- delete [] possible;- delete [] lo;- delete [] up;-}--//--------------------------------------------------------------------// Default Constructor -//--------------------------------------------------------------------CglAllDifferent::CglAllDifferent ()-:-CglCutGenerator(),-numberSets_(0),-numberDifferent_(0),-maxLook_(2),-logLevel_(0),-start_(NULL),-which_(NULL),-originalWhich_(NULL)-{-}--//--------------------------------------------------------------------// Useful Constructor -//--------------------------------------------------------------------CglAllDifferent::CglAllDifferent (int numberSets,- const int * starts, const int * which)-:-CglCutGenerator(),-numberSets_(numberSets),-maxLook_(2),-logLevel_(0),-start_(NULL),-which_(NULL),-originalWhich_(NULL)-{- if (numberSets_>0) {- int n = starts[numberSets_];- start_ = CoinCopyOfArray(starts,numberSets_+1);- originalWhich_ = CoinCopyOfArray(which,n);- which_ = new int[n];- int i;- int maxValue=-1;- for (i=0;i<n;i++) {- int iColumn = which[i];- assert (iColumn>=0);- maxValue = CoinMax(iColumn,maxValue);- }- maxValue++;- int * translate = new int[maxValue];- for (i=0;i<maxValue;i++)- translate[i]=-1;- for (i=0;i<n;i++) {- int iColumn = which[i];- translate[iColumn]=0;- }- numberDifferent_=0;- for (i=0;i<maxValue;i++) {- if (!translate[i]) - translate[i]=numberDifferent_++;- }- // Now translate- for (i=0;i<n;i++) {- int iColumn = which[i];- iColumn = translate[iColumn];- assert (iColumn>=0);- which_[i]=iColumn;- }- delete [] translate;- }-}--//--------------------------------------------------------------------// Copy constructor -//--------------------------------------------------------------------CglAllDifferent::CglAllDifferent ( const CglAllDifferent & rhs)- :- CglCutGenerator(rhs),- numberSets_(rhs.numberSets_),- numberDifferent_(rhs.numberDifferent_),- maxLook_(rhs.maxLook_),- logLevel_(rhs.logLevel_)-{ - if (numberSets_) {- int n = rhs.start_[numberSets_];- start_ = CoinCopyOfArray(rhs.start_,numberSets_+1);- which_ = CoinCopyOfArray(rhs.which_,n);- originalWhich_ = CoinCopyOfArray(rhs.originalWhich_,n);- } else {- start_=NULL;- which_=NULL;- originalWhich_=NULL;- }-}--//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------CglCutGenerator *-CglAllDifferent::clone() const-{- return new CglAllDifferent(*this);-}--//--------------------------------------------------------------------// Destructor -//--------------------------------------------------------------------CglAllDifferent::~CglAllDifferent ()-{- // free memory- delete [] start_;- delete [] which_;- delete [] originalWhich_;-}--//-----------------------------------------------------------------// Assignment operator -//--------------------------------------------------------------------CglAllDifferent &-CglAllDifferent::operator=(- const CglAllDifferent& rhs)-{- if (this != &rhs) {- CglCutGenerator::operator=(rhs);- // free memory- delete [] start_;- delete [] which_;- delete [] originalWhich_;- numberSets_ = rhs.numberSets_;- numberDifferent_ = rhs.numberDifferent_;- maxLook_ = rhs.maxLook_;- logLevel_ = rhs.logLevel_;- if (numberSets_) {- int n = rhs.start_[numberSets_];- start_ = CoinCopyOfArray(rhs.start_,numberSets_+1);- which_ = CoinCopyOfArray(rhs.which_,n);- originalWhich_ = CoinCopyOfArray(rhs.originalWhich_,n);- } else {- start_=NULL;- which_=NULL;- originalWhich_=NULL;- }- }- return *this;-}--/// This can be used to refresh any inforamtion-void -CglAllDifferent::refreshSolver(OsiSolverInterface * )-{-}-// Create C++ lines to get to current state-std::string-CglAllDifferent::generateCpp( FILE * fp) -{- CglAllDifferent other;- fprintf(fp,"0#include \"CglAllDifferent.hpp\"\n");- fprintf(fp,"3 CglAllDifferent allDifferent;\n");- if (logLevel_!=other.logLevel_)- fprintf(fp,"3 allDifferent.setLogLevel(%d);\n",logLevel_);- else- fprintf(fp,"4 allDifferent.setLogLevel(%d);\n",logLevel_);- if (maxLook_!=other.maxLook_)- fprintf(fp,"3 allDifferent.setMaxLook(%d);\n",maxLook_);- else- fprintf(fp,"4 allDifferent.setMaxLook(%d);\n",maxLook_);- if (getAggressiveness()!=other.getAggressiveness())- fprintf(fp,"3 allDifferent.setAggressiveness(%d);\n",getAggressiveness());- else- fprintf(fp,"4 allDifferent.setAggressiveness(%d);\n",getAggressiveness());- return "allDifferent";-}
− cbits/coin/CglLandPTest.cpp
@@ -1,352 +0,0 @@-// $Id: CglLandPTest.cpp 1123 2013-04-06 20:47:24Z stefan $-// Copyright (C) 2000-2009, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--// UnitTest for CglGomory adapted for lift-and-project--#include <cstdio>--#ifdef NDEBUG-#undef NDEBUG-#endif--#include <cassert>--#include "CoinPragma.hpp"-#include "CoinPackedMatrix.hpp"-#include "OsiCuts.hpp"-#include "CoinWarmStartBasis.hpp"-#include "CglLandP.hpp"--void-CglLandPUnitTest(- OsiSolverInterface * si,- const std::string &mpsDir)-{- CoinRelFltEq eq(1e-05);- // Test default constructor- {- CglLandP aGenerator;- assert(aGenerator.parameter().pivotLimit==20);- assert(aGenerator.parameter().maxCutPerRound==5000);- assert(aGenerator.parameter().failedPivotLimit==1);- assert(aGenerator.parameter().degeneratePivotLimit==0);- assert(eq(aGenerator.parameter().pivotTol, 1e-04));- assert(eq(aGenerator.parameter().away, 5e-04));- assert(eq(aGenerator.parameter().timeLimit, COIN_DBL_MAX));- assert(eq(aGenerator.parameter().singleCutTimeLimit, COIN_DBL_MAX));- assert(aGenerator.parameter().useTableauRow==true);- assert(aGenerator.parameter().modularize==false);- assert(aGenerator.parameter().strengthen==true);- assert(aGenerator.parameter().perturb==true);- assert(aGenerator.parameter().pivotSelection==CglLandP::mostNegativeRc);- }--- // Test copy constructor- {- CglLandP a;- {- CglLandP b;- b.parameter().pivotLimit = 100;- b.parameter().maxCutPerRound = 100;- b.parameter().failedPivotLimit = 10;- b.parameter().degeneratePivotLimit = 10;- b.parameter().pivotTol = 1e-07;- b.parameter().away = 1e-10;- b.parameter().timeLimit = 120;- b.parameter().singleCutTimeLimit = 15;- b.parameter().useTableauRow = true;- b.parameter().modularize = true;- b.parameter().strengthen = false;- b.parameter().perturb = false;- b.parameter().pivotSelection=CglLandP::bestPivot;- //Test Copy- CglLandP c(b);- assert(c.parameter().pivotLimit == 100);- assert(c.parameter().maxCutPerRound == 100);- assert(c.parameter().failedPivotLimit == 10);- assert(c.parameter().degeneratePivotLimit == 10);- assert(c.parameter().pivotTol == 1e-07);- assert(c.parameter().away == 1e-10);- assert(c.parameter().timeLimit == 120);- assert(c.parameter().singleCutTimeLimit == 15);- assert(c.parameter().useTableauRow == true);- assert(c.parameter().modularize == true);- assert(c.parameter().strengthen == false);- assert(c.parameter().perturb == false);- assert(c.parameter().pivotSelection == CglLandP::bestPivot);- a=b;- assert(a.parameter().pivotLimit == 100);- assert(a.parameter().maxCutPerRound == 100);- assert(a.parameter().failedPivotLimit == 10);- assert(a.parameter().degeneratePivotLimit == 10);- assert(a.parameter().pivotTol == 1e-07);- assert(a.parameter().away == 1e-10);- assert(a.parameter().timeLimit == 120);- assert(a.parameter().singleCutTimeLimit == 15);- assert(a.parameter().useTableauRow == true);- assert(a.parameter().modularize == true);- assert(a.parameter().strengthen == false);- assert(a.parameter().perturb == false);- assert(a.parameter().pivotSelection == CglLandP::bestPivot);- }- }-- {- // Maximize 2 x2- // s.t.- // 2x1 + 2x2 <= 3- // -2x1 + 2x2 <= 1- // 7x1 + 4x2 <= 8- // -7x1 + 4x2 <= 1- // x1, x2 >= 0 and x1, x2 integer- // Slacks are s1, s2, s3, s4---- //Test that problem is correct- // Optimal Basis is x1, x2, s3, s4 with tableau- // x1 0.25 s1 -0.25 s2 = 0.5- // x2 0.25 s1 0.25 s2 = 1- // -2.75 s1 0.75 s2 s3 = 0.5- // 0.75 s1 -2.75 s2 s4 = 0.5- // z= -0.25 s1 -0.25 s2 = -1- // Gomory cut from variable x1 is x2 <= 0.5- // Can be improved by first pivoting s2 in and s4 out, then s1 in and s3 out- // to x2 <= 0.25- {- int start[2] = {0,4};- int length[2] = {4,4};- int rows[8] = {0,1,2,3,0,1,2,3};- double elements[8] = {2.0,-2.0,7.0,-7.0,2.0,2.0,4.0,4.0};- CoinPackedMatrix columnCopy(true,4,2,8,elements,rows,start,length);-- double rowLower[4]={-COIN_DBL_MAX,-COIN_DBL_MAX,- -COIN_DBL_MAX,-COIN_DBL_MAX};- double rowUpper[4]={3.,1.,8.,1.};- double colLower[2]={0.0,0.0};- double colUpper[2]={1.0,1.0};- double obj[2]={-1,-1};- int intVar[2]={0,1};-- OsiSolverInterface * siP = si->clone();- siP->loadProblem(columnCopy, colLower, colUpper, obj, rowLower, rowUpper);- siP->setInteger(intVar,2);- CglLandP test;- test.setLogLevel(2);- test.parameter().sepSpace = CglLandP::Full;- siP->resolve();- // Test generateCuts method- {- OsiCuts cuts;- test.generateCuts(*siP,cuts);- cuts.printCuts();- assert(cuts.sizeRowCuts()==1);- OsiRowCut aCut = cuts.rowCut(0);- assert(eq(aCut.lb(), -.0714286));- CoinPackedVector row = aCut.row();- if (row.getNumElements() == 1)- {- assert(row.getIndices()[0]==1);- assert(eq(row.getElements()[0], -4*.0714286));- }- else if (row.getNumElements() == 2)- {- assert(row.getIndices()[0]==0);- assert(eq(row.getElements()[0], 0.));- assert(row.getIndices()[1]==1);- assert(eq(row.getElements()[1], -1));- }- OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts);-- siP->resolve();- }- if (0)- {- OsiCuts cuts;- test.generateCuts(*siP,cuts);- cuts.printCuts();- assert(cuts.sizeRowCuts()==1);- OsiRowCut aCut = cuts.rowCut(0);- CoinPackedVector row = aCut.row();- if (row.getNumElements() == 1)- {- assert(row.getIndices()[0]==1);- assert(eq(row.getElements()[0], -1));- }- else if (row.getNumElements() == 2)- {- assert(row.getIndices()[0]==0);- assert(eq(row.getElements()[0], 0.));- assert(row.getIndices()[1]==1);- assert(eq(row.getElements()[1], -1));- }- assert(eq(aCut.lb(), 0.));- OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts);-- siP->resolve();- }- delete siP;- }- }-- if (1) //Test on p0033- {- // Setup- OsiSolverInterface * siP = si->clone();- std::string fn(mpsDir+"p0033");- siP->readMps(fn.c_str(),"mps");- siP->activateRowCutDebugger("p0033");- CglLandP test;-- // Solve the LP relaxation of the model and- // print out ofv for sake of comparison- siP->initialSolve();- double lpRelaxBefore=siP->getObjValue();- assert( eq(lpRelaxBefore, 2520.5717391304347) );-#ifdef CGL_DEBUG- printf("\n\nOrig LP min=%f\n",lpRelaxBefore);-#endif-- OsiCuts cuts;-- // Test generateCuts method- test.generateCuts(*siP,cuts);- OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts);-- siP->resolve();- double lpRelaxAfter=siP->getObjValue();- //assert( eq(lpRelaxAfter, 2592.1908295194507) );-- std::cout<<"Relaxation after "<<lpRelaxAfter<<std::endl;- assert( lpRelaxAfter> 2840. );-#ifdef CGL_DEBUG- printf("\n\nOrig LP min=%f\n",lpRelaxBefore);- printf("\n\nFinal LP min=%f\n",lpRelaxAfter);-#endif- assert( lpRelaxBefore < lpRelaxAfter );-- delete siP;- }- if (1) //test again with modularization- {- // Setup- OsiSolverInterface * siP = si->clone();- std::string fn(mpsDir+"p0033");- siP->readMps(fn.c_str(),"mps");- siP->activateRowCutDebugger("p0033");- CglLandP test;- test.parameter().modularize = true;- // Solve the LP relaxation of the model and- // print out ofv for sake of comparison- siP->initialSolve();- double lpRelaxBefore=siP->getObjValue();- assert( eq(lpRelaxBefore, 2520.5717391304347) );-#ifdef CGL_DEBUG- printf("\n\nOrig LP min=%f\n",lpRelaxBefore);-#endif-- OsiCuts cuts;-- // Test generateCuts method- test.generateCuts(*siP,cuts);- OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts);-- siP->resolve();- double lpRelaxAfter=siP->getObjValue();- //assert( eq(lpRelaxAfter, 2592.1908295194507) );-- std::cout<<"Relaxation after "<<lpRelaxAfter<<std::endl;- assert( lpRelaxAfter> 2840. );-#ifdef CGL_DEBUG- printf("\n\nOrig LP min=%f\n",lpRelaxBefore);- printf("\n\nFinal LP min=%f\n",lpRelaxAfter);-#endif- assert( lpRelaxBefore < lpRelaxAfter );-- delete siP;- }- if (1) //test again with alternate pivoting rule- {- // Setup- OsiSolverInterface * siP = si->clone();- std::string fn(mpsDir+"p0033");- siP->readMps(fn.c_str(),"mps");- siP->activateRowCutDebugger("p0033");- CglLandP test;- test.parameter().pivotSelection = CglLandP::bestPivot;- // Solve the LP relaxation of the model and- // print out ofv for sake of comparison- siP->initialSolve();- double lpRelaxBefore=siP->getObjValue();- assert( eq(lpRelaxBefore, 2520.5717391304347) );-#ifdef CGL_DEBUG- printf("\n\nOrig LP min=%f\n",lpRelaxBefore);-#endif-- OsiCuts cuts;-- // Test generateCuts method- test.generateCuts(*siP,cuts);- OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts);-- siP->resolve();- double lpRelaxAfter=siP->getObjValue();- //assert( eq(lpRelaxAfter, 2592.1908295194507) );-- std::cout<<"Relaxation after "<<lpRelaxAfter<<std::endl;- assert( lpRelaxAfter> 2840. );-#ifdef CGL_DEBUG- printf("\n\nOrig LP min=%f\n",lpRelaxBefore);- printf("\n\nFinal LP min=%f\n",lpRelaxAfter);-#endif- assert( lpRelaxBefore < lpRelaxAfter );-- delete siP;- }-- if (1) //Finally test code in documentation- {- // Setup- OsiSolverInterface * siP = si->clone();- std::string fn(mpsDir+"p0033");- siP->readMps(fn.c_str(),"mps");- siP->activateRowCutDebugger("p0033");- CglLandP landpGen;-- landpGen.parameter().timeLimit = 10.;- landpGen.parameter().pivotLimit = 2;--- // Solve the LP relaxation of the model and- // print out ofv for sake of comparison- siP->initialSolve();- double lpRelaxBefore=siP->getObjValue();- assert( eq(lpRelaxBefore, 2520.5717391304347) );-#ifdef CGL_DEBUG- printf("\n\nOrig LP min=%f\n",lpRelaxBefore);-#endif-- OsiCuts cuts;-- // Test generateCuts method- landpGen.generateCuts(*siP, cuts);- OsiSolverInterface::ApplyCutsReturnCode rc = siP->applyCuts(cuts);-- siP->resolve();- double lpRelaxAfter=siP->getObjValue();- //assert( eq(lpRelaxAfter, 2592.1908295194507) );-- std::cout<<"Relaxation after "<<lpRelaxAfter<<std::endl;- assert( lpRelaxAfter> 2840. );-#ifdef CGL_DEBUG- printf("\n\nOrig LP min=%f\n",lpRelaxBefore);- printf("\n\nFinal LP min=%f\n",lpRelaxAfter);-#endif- assert( lpRelaxBefore < lpRelaxAfter );-- delete siP;- }-}
− cbits/coin/CglLiftAndProject.cpp
@@ -1,396 +0,0 @@-// Copyright (C) 2000, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#include <cstdlib>-#include <cstdio>-#include <cmath>-#include <cassert>-#include <cfloat>-#include <iostream>--#include "CoinPragma.hpp"-#include "CoinHelperFunctions.hpp"-#include "CglLiftAndProject.hpp"-#include "CoinPackedVector.hpp"-#include "CoinSort.hpp"-#include "CoinPackedMatrix.hpp"--//------------------------------------------------------------------------------// Generate Lift-and-Project cuts-//------------------------------------------------------------------- -void CglLiftAndProject::generateCuts(const OsiSolverInterface& si, OsiCuts& cs,- const CglTreeInfo /*info*/)-{- // Assumes the mixed 0-1 problem - //- // min {cx: <Atilde,x> >= btilde} - //- // is in canonical form with all bounds,- // including x_t>=0, -x_t>=-1 for x_t binary,- // explicitly stated in the constraint matrix. - // See ~/COIN/Examples/Cgl2/cgl2.cpp - // for a general purpose "convert" function. -- // Reference [BCC]: Balas, Ceria, and Corneujols,- // "A lift-and-project cutting plane algorithm- // for mixed 0-1 program", Math Prog 58, (1993) - // 295-324.-- // This implementation uses Normalization 1.-- // Given canonical problem and- // the lp-relaxation solution, x,- // the LAP cut generator attempts to construct- // a cut for every x_j such that 0<x_j<1- // [BCC:307]- -- // x_j is the strictly fractional binary variable- // the cut is generated from- int j = 0; -- // Get basic problem information- // let Atilde be an m by n matrix- const int m = si.getNumRows(); - const int n = si.getNumCols(); - const double * x = si.getColSolution();-- // Remember - Atildes may have gaps..- const CoinPackedMatrix * Atilde = si.getMatrixByRow();- const double * AtildeElements = Atilde->getElements();- const int * AtildeIndices = Atilde->getIndices();- const CoinBigIndex * AtildeStarts = Atilde->getVectorStarts();- const int * AtildeLengths = Atilde->getVectorLengths(); - const int AtildeFullSize = AtildeStarts[m];- const double * btilde = si.getRowLower();-- // Set up memory for system (10) [BCC:307]- // (the problem over the norm intersected - // with the polar cone)- // - // min <<x^T,Atilde^T>,u> + x_ju_0- // s.t.- // <B,w> = (0,...,0,beta_,beta)^T- // w is nonneg for all but the- // last two entries, which are free.- // where - // w = (u,v,v_0,u_0)in BCC notation - // u and v are m-vectors; u,v >=0- // v_0 and u_0 are free-scalars, and- // - // B = Atilde^T -Atilde^T -e_j e_j- // btilde^T e_0^T 0 0- // e_0^T btilde^T 1 0-- // ^T indicates Transpose- // e_0 is a (AtildeNCols x 1) vector of all zeros - // e_j is e_0 with a 1 in the jth position-- // Storing B in column order. B is a (n+2 x 2m+2) matrix - // But need to allow for possible gaps in Atilde.- // At each iteration, only need to change 2 cols and objfunc- // Sane design of OsiSolverInterface does not permit mucking- // with matrix.- // Because we must delete and add cols to alter matrix,- // and we can only add columns on the end of the matrix- // put the v_0 and u_0 columns on the end.- // rather than as described in [BCC]- - // Initially allocating B with space for v_0 and u_O cols- // but not populating, for efficiency.-- // B without u_0 and v_0 is a (n+2 x 2m) size matrix.-- int twoM = 2*m;- int BNumRows = n+2;- int BNumCols = twoM+2;- int BFullSize = 2*AtildeFullSize+twoM+3;- double * BElements = new double[BFullSize];- int * BIndices = new int[BFullSize];- CoinBigIndex * BStarts = new CoinBigIndex [BNumCols+1];- int * BLengths = new int[BNumCols];--- int i, ij, k=0;- int nPlus1=n+1;- int offset = AtildeStarts[m]+m;- for (i=0; i<m; i++){- for (ij=AtildeStarts[i];ij<AtildeStarts[i]+AtildeLengths[i];ij++){- BElements[k]=AtildeElements[ij];- BElements[k+offset]=-AtildeElements[ij];- BIndices[k]= AtildeIndices[ij];- BIndices[k+offset]= AtildeIndices[ij];-- k++;- }- BElements[k]=btilde[i];- BElements[k+offset]=btilde[i];- BIndices[k]=n;- BIndices[k+offset]=nPlus1;- BStarts[i]= AtildeStarts[i]+i;- BStarts[i+m]=offset+BStarts[i];// = AtildeStarts[m]+m+AtildeStarts[i]+i- BLengths[i]= AtildeLengths[i]+1;- BLengths[i+m]= AtildeLengths[i]+1;- k++;- }-- BStarts[twoM]=BStarts[twoM-1]+BLengths[twoM-1];-- // Cols that will be deleted each iteration- int BNumColsLessOne=BNumCols-1;- int BNumColsLessTwo=BNumCols-2;- const int delCols[2] = {BNumColsLessOne, BNumColsLessTwo};-- // Set lower bound on u and v- // u_0, v_0 will be reset as free- const double solverINFINITY = si.getInfinity();- double * BColLowers = new double[BNumCols];- double * BColUppers = new double[BNumCols];- CoinFillN(BColLowers,BNumCols,0.0); - CoinFillN(BColUppers,BNumCols,solverINFINITY); -- // Set row lowers and uppers.- // The rhs is zero, for but the last two rows.- // For these the rhs is beta_- double * BRowLowers = new double[BNumRows];- double * BRowUppers = new double[BNumRows];- CoinFillN(BRowLowers,BNumRows,0.0); - CoinFillN(BRowUppers,BNumRows,0.0);- BRowLowers[BNumRows-2]=beta_;- BRowUppers[BNumRows-2]=beta_;- BRowLowers[BNumRows-1]=beta_;- BRowUppers[BNumRows-1]=beta_;--- // Calculate base objective <<x^T,Atilde^T>,u>- // Note: at each iteration coefficient u_0- // changes to <x^T,e_j>- // w=(u,v,beta,v_0,u_0) size 2m+3- // So, BOjective[2m+2]=x[j]- double * BObjective= new double[BNumCols];- double * Atildex = new double[m];- CoinFillN(BObjective,BNumCols,0.0);- Atilde->times(x,Atildex); // Atildex is size m, x is size n- CoinDisjointCopyN(Atildex,m,BObjective); -- // Number of cols and size of Elements vector- // in B without the v_0 and u_0 cols- int BFullSizeLessThree = BFullSize-3;-- // Load B matrix into a column orders CoinPackedMatrix- CoinPackedMatrix * BMatrix = new CoinPackedMatrix(true, BNumRows,- BNumColsLessTwo, - BFullSizeLessThree,- BElements,BIndices, - BStarts,BLengths);- // Assign problem into a solver interface - // Note: coneSi will cleanup the memory itself- OsiSolverInterface * coneSi = si.clone(false);- coneSi->assignProblem (BMatrix, BColLowers, BColUppers, - BObjective,- BRowLowers, BRowUppers);-- // Problem sense should default to "min" by default, - // but just to be virtuous...- coneSi->setObjSense(1.0);-- // The plot outline from here on down:- // coneSi has been assigned B without the u_0 and v_0 columns- // Calculate base objective <<x^T,Atilde^T>,u>- // bool haveWarmStart = false;- // For (j=0; j<n, j++)- // if (!isBinary(x_j) || x_j<=0 || x_j>=1) continue;- // // IMPROVEME: if(haveWarmStart) check if j attractive- // add {-e_j,0,-1} matrix column for v_0- // add {e_j,0,0} matrix column for u_0- // objective coefficient for u_0 is x_j - // if (haveWarmStart) - // set warmstart info- // solve min{objw:Bw=0; w>=0,except v_0, u_0 free}- // if (bounded)- // get warmstart info- // haveWarmStart=true;- // ustar = optimal u solution- // ustar_0 = optimal u_0 solution- // alpha^T= <ustar^T,Atilde> -ustar_0e_j^T- // (double check <alpha^T,x> >= beta_ should be violated)- // add <alpha^T,x> >= beta_ to cutset - // endif- // delete column for u_0 // this deletes all column info.- // delete column for v_0- // endFor- // clean up memory- // return 0;-- int * nVectorIndices = new int[n];- CoinIotaN(nVectorIndices, n, 0);-- bool haveWarmStart = false;- bool equalObj1, equalObj2;- CoinRelFltEq eq;-- double v_0Elements[2] = {-1,1};- double u_0Elements[1] = {1};-- CoinWarmStart * warmStart = 0;-- double * ustar = new double[m];- CoinFillN(ustar, m, 0.0);-- double* alpha = new double[n];- CoinFillN(alpha, n, 0.0);-- for (j=0;j<n;j++){- if (!si.isBinary(j)) continue; // Better to ask coneSi? No! - // coneSi has no binInfo.- equalObj1=eq(x[j],0);- equalObj2=eq(x[j],1);- if (equalObj1 || equalObj2) continue;- // IMPROVEME: if (haveWarmStart) check if j attractive;-- // AskLL:wanted to declare u_0 and v_0 packedVec outside loop- // and setIndices, but didn't see a method to do that(?)- // (Could "insert". Seems inefficient)- int v_0Indices[2]={j,nPlus1};- int u_0Indices[1]={j};- // - CoinPackedVector v_0(2,v_0Indices,v_0Elements,false);- CoinPackedVector u_0(1,u_0Indices,u_0Elements,false);--#if CGL_DEBUG- const CoinPackedMatrix *see1 = coneSi->getMatrixByRow();-#endif-- coneSi->addCol(v_0,-solverINFINITY,solverINFINITY,0);- coneSi->addCol(u_0,-solverINFINITY,solverINFINITY,x[j]);- if(haveWarmStart) {- coneSi->setWarmStart(warmStart);- coneSi->resolve();- }- else {--#if CGL_DEBUG- const CoinPackedMatrix *see2 = coneSi->getMatrixByRow();-#endif-- coneSi->initialSolve();- }- if(coneSi->isProvenOptimal()){- warmStart = coneSi->getWarmStart();- haveWarmStart=true;- const double * wstar = coneSi->getColSolution();- CoinDisjointCopyN(wstar, m, ustar);- Atilde->transposeTimes(ustar,alpha);- alpha[j]+=wstar[BNumCols-1]; - -#if debug- int p;- double sum;- for(p=0;p<n;p++)sum+=alpha[p]*x[p];- if (sum<=beta_){- throw CoinError("Cut not violated",- "cutGeneration",- "CglLiftAndProject");- }-#endif-- // add <alpha^T,x> >= beta_ to cutset- OsiRowCut rc;- rc.setRow(n,nVectorIndices,alpha);- rc.setLb(beta_);- rc.setUb(solverINFINITY);- cs.insert(rc);- }- // delete col for u_o and v_0- coneSi->deleteCols(2,delCols);-- // clean up memory- }- // clean up- delete [] alpha;- delete [] ustar;- delete [] nVectorIndices;- // BMatrix, BColLowers,BColUppers, BObjective, BRowLowers, BRowUppers- // are all freed by OsiSolverInterface destructor (?)- delete [] BLengths;- delete [] BStarts;- delete [] BIndices;- delete [] BElements;-}--//--------------------------------------------------------------------// Default Constructor -//--------------------------------------------------------------------CglLiftAndProject::CglLiftAndProject ()-:-CglCutGenerator(),-beta_(1),-epsilon_(1.0e-08),-onetol_(1-epsilon_)-{- // nothing to do here-}--//--------------------------------------------------------------------// Copy constructor -//--------------------------------------------------------------------CglLiftAndProject::CglLiftAndProject (const CglLiftAndProject & source) :- CglCutGenerator(source),- beta_(source.beta_),- epsilon_(source.epsilon_),- onetol_(source.onetol_)-{- // Nothing to do here-}--//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------CglCutGenerator *-CglLiftAndProject::clone() const-{- return new CglLiftAndProject(*this);-}--//--------------------------------------------------------------------// Destructor -//--------------------------------------------------------------------CglLiftAndProject::~CglLiftAndProject ()-{- // Nothing to do here-}--//-----------------------------------------------------------------// Assignment operator -//--------------------------------------------------------------------CglLiftAndProject &-CglLiftAndProject::operator=(- const CglLiftAndProject& rhs)-{- if (this != &rhs) {- CglCutGenerator::operator=(rhs);- beta_=rhs.beta_;- epsilon_=rhs.epsilon_;- onetol_=rhs.onetol_;- }- return *this;-}-// Create C++ lines to get to current state-std::string-CglLiftAndProject::generateCpp( FILE * fp) -{- CglLiftAndProject other;- fprintf(fp,"0#include \"CglLiftAndProject.hpp\"\n");- fprintf(fp,"3 CglLiftAndProject liftAndProject;\n");- if (beta_!=other.beta_)- fprintf(fp,"3 liftAndProject.setBeta(%d);\n",static_cast<int> (beta_));- else- fprintf(fp,"4 liftAndProject.setBeta(%d);\n",static_cast<int> (beta_));- fprintf(fp,"3 liftAndProject.setAggressiveness(%d);\n",getAggressiveness());- if (getAggressiveness()!=other.getAggressiveness())- fprintf(fp,"3 liftAndProject.setAggressiveness(%d);\n",getAggressiveness());- else- fprintf(fp,"4 liftAndProject.setAggressiveness(%d);\n",getAggressiveness());- return "liftAndProject";-}
− cbits/coin/CglMixedIntegerRounding.cpp
@@ -1,1717 +0,0 @@-// LAST EDIT: -//------------------------------------------------------------------------------// name: Mixed Integer Rounding Cut Generator-// authors: Joao Goncalves (jog7@lehigh.edu) -// Laszlo Ladanyi (ladanyi@us.ibm.com) -// date: August 11, 2004 -//------------------------------------------------------------------------------// Copyright (C) 2004, International Business Machines Corporation and others. -// All Rights Reserved.-// This code is published under the Eclipse Public License.--//#include <cmath>-//#include <cstdlib>-#include <cassert>--#include "CoinPragma.hpp"-#include "CoinHelperFunctions.hpp"-#include "CoinPackedMatrix.hpp"-#include "CoinPackedVector.hpp"--#include "CglMixedIntegerRounding.hpp"-//#define CGL_DEBUG 1-//------------------------------------------------------------------------------// Generate Mixed Integer Rounding inequality-//------------------------------------------------------------------- -void-CglMixedIntegerRounding::generateCuts(const OsiSolverInterface& si,- OsiCuts& cs,- const CglTreeInfo )-{-- // If the LP or integer presolve is used, then need to redo preprocessing- // everytime this function is called. Otherwise, just do once.- bool preInit = false;- bool preReso = false;- si.getHintParam(OsiDoPresolveInInitial, preInit);- si.getHintParam(OsiDoPresolveInResolve, preReso);- if (preInit == false && preReso == false && doPreproc_ == -1 ) { // Do once- if (doneInitPre_ == false) { - mixIntRoundPreprocess(si);- doneInitPre_ = true;- }- }- else {- if(doPreproc_ == 1){ // Do everytime - mixIntRoundPreprocess(si);- doneInitPre_ = true;- } - else {- if (doneInitPre_ == false) { - mixIntRoundPreprocess(si);- doneInitPre_ = true;- } - }- }-- const double* xlp = si.getColSolution(); // LP solution- const double* colUpperBound = si.getColUpper(); // vector of upper bounds- const double* colLowerBound = si.getColLower(); // vector of lower bounds-- // get matrix by row- const CoinPackedMatrix & tempMatrixByRow = *si.getMatrixByRow();- CoinPackedMatrix matrixByRow;- matrixByRow.submatrixOf(tempMatrixByRow, numRows_, indRows_);- CoinPackedMatrix matrixByCol = matrixByRow;- matrixByCol.reverseOrdering();- //const CoinPackedMatrix & matrixByRow = *si.getMatrixByRow();- const double* LHS = si.getRowActivity();- const double* coefByRow = matrixByRow.getElements();- const int* colInds = matrixByRow.getIndices();- const int* rowStarts = matrixByRow.getVectorStarts();- const int* rowLengths = matrixByRow.getVectorLengths();-- // get matrix by column- //const CoinPackedMatrix & matrixByCol = *si.getMatrixByCol();- const double* coefByCol = matrixByCol.getElements();- const int* rowInds = matrixByCol.getIndices();- const int* colStarts = matrixByCol.getVectorStarts();- const int* colLengths = matrixByCol.getVectorLengths();--- generateMirCuts(si, xlp, colUpperBound, colLowerBound,- matrixByRow, LHS, coefByRow,- colInds, rowStarts, rowLengths, //matrixByCol,- coefByCol, rowInds, colStarts, colLengths,- cs);-}--//--------------------------------------------------------------------// Default Constructor -//--------------------------------------------------------------------CglMixedIntegerRounding::CglMixedIntegerRounding ()- :- CglCutGenerator()-{ - gutsOfConstruct(1, true, 1, -1);-}---//--------------------------------------------------------------------// Alternate Constructor -//--------------------------------------------------------------------CglMixedIntegerRounding::CglMixedIntegerRounding (const int maxaggr,- const bool multiply,- const int criterion,- const int preproc)- :- CglCutGenerator()-{ - gutsOfConstruct(maxaggr, multiply, criterion, preproc);-}---//--------------------------------------------------------------------// Copy constructor -//--------------------------------------------------------------------CglMixedIntegerRounding::CglMixedIntegerRounding ( - const CglMixedIntegerRounding & rhs)- :- CglCutGenerator(rhs)-{ - gutsOfCopy(rhs);-}---//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------CglCutGenerator *-CglMixedIntegerRounding::clone() const-{- return new CglMixedIntegerRounding(*this);-}--//-------------------------------------------------------------------// Assignment operator -//--------------------------------------------------------------------CglMixedIntegerRounding &-CglMixedIntegerRounding::operator=(const CglMixedIntegerRounding& rhs)-{- if (this != &rhs) {- gutsOfDelete();- CglCutGenerator::operator=(rhs);- gutsOfCopy(rhs);- }- return *this;-}---//--------------------------------------------------------------------// Destructor -//------------------------------------------------------------------- -CglMixedIntegerRounding::~CglMixedIntegerRounding ()-{- gutsOfDelete();-}--//--------------------------------------------------------------------// Construct-//------------------------------------------------------------------- -void-CglMixedIntegerRounding::gutsOfConstruct (const int maxaggr,- const bool multiply,- const int criterion,- const int preproc)-{- if (maxaggr > 0) {- MAXAGGR_ = maxaggr;- }- else {- throw CoinError("Unallowable value. maxaggr must be > 0",- "gutsOfConstruct","CglMixedIntegerRounding");- }- MULTIPLY_ = multiply;- if ((criterion >= 1) && (criterion <= 3)) {- CRITERION_ = criterion;- }- else {- throw CoinError("Unallowable value. criterion must be 1, 2 or 3",- "gutsOfConstruct","CglMixedIntegerRounding");- }- if ((preproc >= -1) && (preproc <= 2)) {- doPreproc_ = preproc;- }- else {- throw CoinError("Unallowable value. preproc must be -1, 0 or 1",- "gutsOfConstruct","CglMixedIntegerRounding");- }- EPSILON_ = 1.0e-6;- UNDEFINED_ = -1;- TOLERANCE_ = 1.0e-4;- numRows_ = 0;- numCols_ = 0;- doneInitPre_ = false;- vubs_ = 0;- vlbs_ = 0;- rowTypes_ = 0;- indRows_ = 0;- numRowMix_ = 0;- indRowMix_ = 0;- numRowCont_ = 0;- indRowCont_ = 0;- numRowInt_ = 0;- indRowInt_ = 0;- numRowContVB_ = 0;- indRowContVB_ = 0;- sense_=NULL;- RHS_=NULL;-}--//--------------------------------------------------------------------// Delete-//------------------------------------------------------------------- -void-CglMixedIntegerRounding::gutsOfDelete ()-{- if (vubs_ != 0) { delete [] vubs_; vubs_ = 0; }- if (vlbs_ != 0) { delete [] vlbs_; vlbs_ = 0; }- if (rowTypes_ != 0) { delete [] rowTypes_; rowTypes_ = 0; } - if (indRows_ != 0) { delete [] indRows_; indRows_ = 0; }- if (indRowMix_ != 0) { delete [] indRowMix_; indRowMix_ = 0; }- if (indRowCont_ != 0) { delete [] indRowCont_; indRowCont_ = 0; }- if (indRowInt_ != 0) { delete [] indRowInt_; indRowInt_ = 0; }- if (indRowContVB_ != 0) { delete [] indRowContVB_; indRowContVB_ = 0; }- if (sense_ !=NULL) { delete [] sense_; sense_=NULL;}- if (RHS_ !=NULL) { delete [] RHS_; RHS_=NULL;}-}--//--------------------------------------------------------------------// Copy-//------------------------------------------------------------------- -void-CglMixedIntegerRounding::gutsOfCopy (const CglMixedIntegerRounding& rhs)-{- MAXAGGR_ = rhs.MAXAGGR_;- MULTIPLY_ = rhs.MULTIPLY_;- CRITERION_ = rhs.CRITERION_;- EPSILON_ = rhs.EPSILON_;- UNDEFINED_ = rhs.UNDEFINED_;- TOLERANCE_ = rhs.TOLERANCE_;- doPreproc_ = rhs.doPreproc_;- numRows_ = rhs.numRows_;- numCols_ = rhs.numCols_;- doneInitPre_ = rhs.doneInitPre_;- numRowMix_ = rhs.numRowMix_;- numRowCont_ = rhs.numRowCont_;- numRowInt_ = rhs.numRowInt_;- numRowContVB_ = rhs.numRowContVB_;-- if (numCols_ > 0) {- vubs_ = new CglMixIntRoundVUB [numCols_];- vlbs_ = new CglMixIntRoundVLB [numCols_];- CoinDisjointCopyN(rhs.vubs_, numCols_, vubs_);- CoinDisjointCopyN(rhs.vlbs_, numCols_, vlbs_);- }- else {- vubs_ = 0;- vlbs_ = 0;- }-- if (numRows_ > 0) {- rowTypes_ = new RowType [numRows_];- CoinDisjointCopyN(rhs.rowTypes_, numRows_, rowTypes_);- indRows_ = new int [numRows_];- CoinDisjointCopyN(rhs.indRows_, numRows_, indRows_);- sense_ = CoinCopyOfArray(rhs.sense_,numRows_);- RHS_ = CoinCopyOfArray(rhs.RHS_,numRows_);- }- else {- rowTypes_ = 0;- indRows_ = 0;- sense_=NULL;- RHS_=NULL;- }-- if (numRowMix_ > 0) {- indRowMix_ = new int [numRowMix_];- CoinDisjointCopyN(rhs.indRowMix_, numRowMix_, indRowMix_);- }- else {- indRowMix_ = 0;- }-- if (numRowCont_ > 0) {- indRowCont_ = new int [numRowCont_];- CoinDisjointCopyN(rhs.indRowCont_, numRowCont_, indRowCont_);- indRowContVB_ = new int [numRowCont_];- CoinDisjointCopyN(rhs.indRowContVB_, numRowCont_, indRowContVB_);- }- else {- indRowCont_ = 0;- indRowContVB_ = 0;- }-- if (numRowInt_ > 0) {- indRowInt_ = new int [numRowInt_];- CoinDisjointCopyN(rhs.indRowInt_, numRowInt_, indRowInt_);- }- else {- indRowInt_ = 0;- }--}--//--------------------------------------------------------------------// Do preprocessing-// It determines the type of each row. It also identifies the variable-// upper bounds and variable lower bounds.-//------------------------------------------------------------------- -void -CglMixedIntegerRounding::-mixIntRoundPreprocess(const OsiSolverInterface& si)-{- // get matrix stored by row- const CoinPackedMatrix & matrixByRow = *si.getMatrixByRow();- numRows_ = si.getNumRows();- numCols_ = si.getNumCols();- const double* coefByRow = matrixByRow.getElements();- const int* colInds = matrixByRow.getIndices();- const int* rowStarts = matrixByRow.getVectorStarts();- const int* rowLengths = matrixByRow.getVectorLengths();- // Get copies of sense and RHS so we can modify if ranges- if (sense_) {- delete [] sense_;- delete [] RHS_;- }- sense_ = CoinCopyOfArray(si.getRowSense(),numRows_);- RHS_ = CoinCopyOfArray(si.getRightHandSide(),numRows_);-- if (rowTypes_ != 0) {- delete [] rowTypes_; rowTypes_ = 0;- }- rowTypes_ = new RowType [numRows_]; // Destructor will free memory-- // Summarize the row type infomation.- int numUNDEFINED = 0;- int numVARUB = 0;- int numVARLB = 0;- int numVAREQ = 0;- int numMIX = 0;- int numCONT = 0;- int numINT = 0;- int numOTHER = 0;-- int iRow;- const double* rowActivity = si.getRowActivity();- const double* rowLower = si.getRowLower();- const double* rowUpper = si.getRowUpper();- for (iRow = 0; iRow < numRows_; ++iRow) {- // If range then choose which to use- if (sense_[iRow]=='R') {- if (rowActivity[iRow]-rowLower[iRow]<- rowUpper[iRow]-rowActivity[iRow]) {- // treat as G row- RHS_[iRow]=rowLower[iRow];- sense_[iRow]='G';- } else {- // treat as L row- RHS_[iRow]=rowUpper[iRow];- sense_[iRow]='L';- }- }- // get the type of a row- const RowType rowType = - determineRowType(si, rowLengths[iRow], colInds+rowStarts[iRow],- coefByRow+rowStarts[iRow], sense_[iRow], RHS_[iRow]);- // store the type of the current row- rowTypes_[iRow] = rowType;-- // Summarize information about row types- switch(rowType) {- case ROW_UNDEFINED:- ++numUNDEFINED; - break;- case ROW_VARUB:- ++numVARUB; - break;- case ROW_VARLB:- ++numVARLB; - break;- case ROW_VAREQ:- ++numVAREQ; - break;- case ROW_MIX:- ++numMIX; - break;- case ROW_CONT:- ++numCONT; - break;- case ROW_INT:- ++numINT; - break;- case ROW_OTHER:- ++numOTHER; - break;- default:- throw CoinError("Unknown row type", "MixIntRoundPreprocess",- "CglMixedIntegerRounding");- }- }-- // allocate memory for vector of indices of all rows- if (indRows_ != 0) { delete [] indRows_; indRows_ = 0; }- if (numRows_ > 0)- indRows_ = new int [numRows_]; // Destructor will free memory- // allocate memory for vector of indices of rows of type ROW_MIX- numRowMix_ = numMIX;- if (indRowMix_ != 0) { delete [] indRowMix_; indRowMix_ = 0; }- if (numRowMix_ > 0)- indRowMix_ = new int [numRowMix_]; // Destructor will free memory- // allocate memory for vector of indices of rows of type ROW_CONT- numRowCont_ = numCONT;- if (indRowCont_ != 0) { delete [] indRowCont_; indRowCont_ = 0; }- if (numRowCont_ > 0)- indRowCont_ = new int [numRowCont_]; // Destructor will free memory- // allocate memory for vector of indices of rows of type ROW_INT- numRowInt_ = numINT;- if (indRowInt_ != 0) { delete [] indRowInt_; indRowInt_ = 0; }- if (numRowInt_ > 0)- indRowInt_ = new int [numRowInt_]; // Destructor will free memory--#if CGL_DEBUG- std::cout << "The num of rows = " << numRows_ << std::endl;- std::cout << "Summary of Row Type" << std::endl;- std::cout << "numUNDEFINED = " << numUNDEFINED << std::endl;- std::cout << "numVARUB = " << numVARUB << std::endl;- std::cout << "numVARLB = " << numVARLB << std::endl;- std::cout << "numVAREQ = " << numVAREQ << std::endl;- std::cout << "numMIX = " << numMIX << std::endl;- std::cout << "numCONT = " << numCONT << std::endl;- std::cout << "numINT = " << numINT << std::endl;- std::cout << "numOTHER = " << numOTHER << std::endl;-#endif-- //---------------------------------------------------------------------------- // Setup vubs_ and vlbs_- if (vubs_ != 0) { delete [] vubs_; vubs_ = 0; }- vubs_ = new CglMixIntRoundVUB [numCols_]; // Destructor will free- if (vlbs_ != 0) { delete [] vlbs_; vlbs_ = 0; }- vlbs_ = new CglMixIntRoundVLB [numCols_]; // Destructor will free-- // Initialization. Altough this has been done in constructor, it is needed- // for the case where the mixIntRoundPreprocess is called more than once- for (int iCol = 0; iCol < numCols_; ++iCol) {- vubs_[iCol].setVar(UNDEFINED_);- vlbs_[iCol].setVar(UNDEFINED_);- }- - int countM = 0;- int countC = 0;- int countI = 0;- for ( iRow = 0; iRow < numRows_; ++iRow) {-- RowType rowType = rowTypes_[iRow];-- // fill the vector indRows_ with the indices of all rows- indRows_[iRow] = iRow;-- // fill the vector indRowMix_ with the indices of the rows of type ROW_MIX- if (rowType == ROW_MIX) {- indRowMix_[countM] = iRow;- countM++;- }- // fill the vector indRowCont_ with the indices of rows of type ROW_CONT- else if (rowType == ROW_CONT) {- indRowCont_[countC] = iRow;- countC++;- }- // fill the vector indRowInt_ with the indices of the rows of type ROW_INT- else if (rowType == ROW_INT) {- indRowInt_[countI] = iRow;- countI++;- }- // create vectors with variable lower and upper bounds- else if ( (rowType == ROW_VARUB) || - (rowType == ROW_VARLB) || - (rowType == ROW_VAREQ) ) { - - int startPos = rowStarts[iRow];- int stopPos = startPos + rowLengths[iRow];- int xInd = 0, yInd = 0; // x is continuous, y is integer- double xCoef = 0.0, yCoef = 0.0;-- for (int i = startPos; i < stopPos; ++i) {- if ( fabs(coefByRow[i]) > EPSILON_ ) {- if( si.isInteger(colInds[i]) ) {- yInd = colInds[i];- yCoef = coefByRow[i];- }- else {- xInd = colInds[i];- xCoef = coefByRow[i];- }- }- }-- switch (rowType) {- case ROW_VARUB: // Inequality: x <= ? * y- vubs_[xInd].setVar(yInd);- vubs_[xInd].setVal(-yCoef / xCoef);- break;- case ROW_VARLB: // Inequality: x >= ? * y- vlbs_[xInd].setVar(yInd);- vlbs_[xInd].setVal(-yCoef / xCoef);- break;- case ROW_VAREQ: // Inequality: x >= AND <= ? * y- vubs_[xInd].setVar(yInd);- vubs_[xInd].setVal(-yCoef / xCoef);- vlbs_[xInd].setVar(yInd);- vlbs_[xInd].setVal(-yCoef / xCoef);- break;- default:- // I am getting compiler bug which gets here - I am disabling - JJF- //throw CoinError("Unknown row type: impossible", - // "MixIntRoundPreprocess",- // "CglMixedIntegerRounding");- break;- }- }- }-- // allocate memory for vector of indices of rows of type ROW_CONT- // that have at least one variable with variable upper or lower bound- if (indRowContVB_ != 0) { delete [] indRowContVB_; indRowContVB_ = 0; }- if (numRowCont_ > 0)- indRowContVB_ = new int [numRowCont_]; // Destructor will free memory- // create vector with rows of type ROW_CONT that have at least- // one variable with variable upper or lower bound- countC = 0;- for (int i = 0; i < numRowCont_; ++i) {- int indRow = indRowCont_[i];- int jStart = rowStarts[indRow];- int jStop = jStart + rowLengths[indRow];- for (int j = jStart; j < jStop; ++j) {- int indCol = colInds[j];- CglMixIntRoundVLB VLB = vlbs_[indCol];- CglMixIntRoundVUB VUB = vubs_[indCol];- if (( VLB.getVar() != UNDEFINED_ ) || ( VUB.getVar() != UNDEFINED_ ) ){- indRowContVB_[countC] = indRow;- countC++;- break;- }- }- }- numRowContVB_ = countC;--}--//--------------------------------------------------------------------// Determine the type of a given row -//--------------------------------------------------------------------CglMixedIntegerRounding::RowType-CglMixedIntegerRounding::determineRowType(const OsiSolverInterface& si,- const int rowLen, const int* ind, - const double* coef, const char sense, - const double rhs) const-{- if (rowLen == 0) - return ROW_UNDEFINED;-- if (sense == 'N' || rhs == si.getInfinity() || rhs == -si.getInfinity())- return ROW_OTHER;-- RowType rowType = ROW_UNDEFINED;-- int numPosInt = 0; // num of positive integer variables- int numNegInt = 0; // num of negative integer variables- int numInt = 0; // num of integer variables- int numPosCon = 0; // num of positive continuous variables- int numNegCon = 0; // num of negative continuous variables- int numCon = 0; // num of continuous variables--- // Summarize the variable types of the given row.- for ( int i = 0; i < rowLen; ++i ) {- if ( coef[i] < -EPSILON_ ) {- if( si.isInteger(ind[i]) )- ++numNegInt;- else- ++numNegCon;- }- else if ( coef[i] > EPSILON_ ) {- if( si.isInteger(ind[i]) )- ++numPosInt;- else- ++numPosCon;- }- }- numInt = numNegInt + numPosInt;- numCon = numNegCon + numPosCon;--#if CGL_DEBUG- std::cout << "numNegInt = " << numNegInt << std::endl;- std::cout << "numPosInt = " << numPosInt << std::endl;- std::cout << "numInt = " << numInt << std::endl;- std::cout << "numNegCon = " << numNegCon << std::endl;- std::cout << "numPosCon = " << numPosCon << std::endl;- std::cout << "numCon = " << numCon << std::endl;- std::cout << "rowLen = " << rowLen << std::endl;-#endif--- //-------------------------------------------------------------------------- // Classify row type based on the types of variables.- - if ((numInt > 0) && (numCon > 0)) {- if ((numInt == 1) && (numCon == 1) && (fabs(rhs) <= EPSILON_)) {- // It's a variable bound constraint- switch (sense) {- case 'L':- rowType = numPosCon == 1 ? ROW_VARUB : ROW_VARLB;- break;- case 'G':- rowType = numPosCon == 1 ? ROW_VARLB : ROW_VARUB;- break;- case 'E':- rowType = ROW_VAREQ;- break;- default:- break;- }- }- else {- // It's a constraint with continuous and integer variables;- // The total number of variables is at least 2- rowType = ROW_MIX;- }- }- else if (numInt == 0) {- // It's a constraint with only continuous variables- rowType = ROW_CONT;- }- else if ((numCon == 0) && ((sense == 'L') || (sense == 'G'))) {- // It's a <= or >= constraint with only integer variables - rowType = ROW_INT;- }- else- // It's a constraint that does not fit the above categories- rowType = ROW_OTHER;--- return rowType;-}--//--------------------------------------------------------------------// Generate MIR cuts-//--------------------------------------------------------------------void-CglMixedIntegerRounding::generateMirCuts( - const OsiSolverInterface& si,- const double* xlp,- const double* colUpperBound,- const double* colLowerBound,- const CoinPackedMatrix& matrixByRow,- const double* LHS,- const double* /*coefByRow*/,- const int* /*colInds*/,- const int* /*rowStarts*/,- const int* /*rowLengths*/,- //const CoinPackedMatrix& matrixByCol,- const double* coefByCol,- const int* rowInds,- const int* colStarts,- const int* colLengths,- OsiCuts& cs ) const-{--#if CGL_DEBUG- // Open debug data file; incorporate solver name so we get separate files- // when running unit test.- std::string dbgFname ;- si.getStrParam(OsiSolverName,dbgFname) ;- dbgFname = "mir_"+dbgFname+"_stats.dat" ;- std::ofstream fout(dbgFname.c_str()) ;-#endif-- // Define upper limit for the loop where the cMIRs are constructed- int upperLimit;- if (MULTIPLY_)- upperLimit = 2;- else- upperLimit = 1;- - // create a vector with the columns that were used in the aggregation- int* listColsSelected = new int[MAXAGGR_];- // create a vector with the rows that were aggregated- int* listRowsAggregated = new int[MAXAGGR_];- // create a vector with the LP solutions of the slack variables- double* xlpExtra = new double[MAXAGGR_];-- // loop until maximum number of aggregated rows is reached or a - // violated cut is found- int numRowMixAndRowContVB = numRowMix_ + numRowContVB_;- int numRowMixAndRowContVBAndRowInt = numRowMixAndRowContVB + numRowInt_;- for (int iRow = 0; iRow < numRowMixAndRowContVBAndRowInt; ++iRow) {-- int rowSelected; // row selected to be aggregated next- int colSelected; // column selected for pivot in aggregation- CoinPackedVector rowAggregated;- double rhsAggregated;- // create a set with the indices of rows selected- std::set<int> setRowsAggregated;-- // loop until the maximum number of aggregated rows is reached- for (int iAggregate = 0; iAggregate < MAXAGGR_; ++iAggregate) {-- if (iAggregate == 0) {-- // select row- if (iRow < numRowMix_) {- rowSelected = indRowMix_[iRow];- }- else if (iRow < numRowMixAndRowContVB) {- rowSelected = indRowContVB_[iRow - numRowMix_];- }- else {- rowSelected = indRowInt_[iRow - numRowMixAndRowContVB];- }-- copyRowSelected(iAggregate, rowSelected, setRowsAggregated,- listRowsAggregated, xlpExtra, sense_[rowSelected], - RHS_[rowSelected], LHS[rowSelected], - matrixByRow, rowAggregated, rhsAggregated);-- } - else {-- // search for a row to aggregate- bool foundRowToAggregate = selectRowToAggregate(- si, rowAggregated,- colUpperBound, colLowerBound, - setRowsAggregated, xlp, - coefByCol, rowInds, colStarts,- colLengths, - rowSelected, colSelected);-- // if finds row to aggregate, compute aggregated row- if (foundRowToAggregate) {-- CoinPackedVector rowToAggregate;- double rhsToAggregate;-- listColsSelected[iAggregate] = colSelected;-- copyRowSelected(iAggregate, rowSelected, setRowsAggregated,- listRowsAggregated, xlpExtra, sense_[rowSelected], - RHS_[rowSelected], LHS[rowSelected], - matrixByRow, rowToAggregate, rhsToAggregate);-- // call aggregate row heuristic- aggregateRow(colSelected, rowToAggregate, rhsToAggregate, - rowAggregated, rhsAggregated);-- }- else- break;- }--- // construct cMIR with current rowAggregated- // and, if upperLimit=2 construct also a cMIR with - // the current rowAggregated multiplied by -1- for (int i = 0; i < upperLimit; ++i) {- - // create vector for mixed knapsack constraint- CoinPackedVector rowToUse = rowAggregated;- double rhsMixedKnapsack = rhsAggregated;- if (i == 1) {- rowToUse *= (-1.0);- rhsMixedKnapsack *= (-1.0);- } - CoinPackedVector mixedKnapsack;- double sStar = 0.0;-- // create vector for the continuous variables in s- CoinPackedVector contVariablesInS;-- // call bound substitution heuristic- bool foundMixedKnapsack = boundSubstitution(- si, rowToUse, - xlp, xlpExtra, - colUpperBound, colLowerBound,- mixedKnapsack, rhsMixedKnapsack, - sStar, contVariablesInS);- // may want some limit?- if (mixedKnapsack.getNumElements()>25000) {-#if CGL_DEBUG - std::cout << "mixed knapsack has " - <<mixedKnapsack.getNumElements()<<" elements - rhs is "- <<rhsMixedKnapsack- << std::endl;-#endif- continue;- }- - // if it did not find a mixed knapsack it is because there is at- // least one integer variable with lower bound different than zero- // or there are no integer or continuous variables.- // In this case, we continue without trying to generate a c-MIR- if (!foundMixedKnapsack) {-#if CGL_DEBUG - std::cout << "couldn't create mixed knapsack" << std::endl;-#endif- continue;- }-- OsiRowCut cMirCut;-- // Find a c-MIR cut with the current mixed knapsack constraint- bool hasCut = cMirSeparation(si, matrixByRow, rowToUse,- listRowsAggregated, sense_, RHS_,- //coefByRow, colInds, rowStarts, rowLengths,- xlp, sStar, colUpperBound, colLowerBound, - mixedKnapsack,- rhsMixedKnapsack, contVariablesInS,- cMirCut);--#if CGL_DEBUG- // PRINT STATISTICS- printStats(fout, hasCut, si, rowAggregated, rhsAggregated, xlp,- xlpExtra, listRowsAggregated, listColsSelected, - iAggregate+1, colUpperBound, colLowerBound );-#endif-- // if a cut was found, insert it into cs- if (hasCut) {-#if CGL_DEBUG- std::cout << "MIR cut generated " << std::endl;-#endif- cs.insert(cMirCut);- }-- }- - }-- }-- // free memory- delete [] listColsSelected; listColsSelected = 0;- delete [] listRowsAggregated; listRowsAggregated = 0;- delete [] xlpExtra; xlpExtra = 0;- -#if CGL_DEBUG- // CLOSE FILE- fout.close();-#endif-- return;--}--//--------------------------------------------------------------------// Copy row selected to CoinPackedVector-//--------------------------------------------------------------------void-CglMixedIntegerRounding::copyRowSelected(- const int iAggregate,- const int rowSelected,- std::set<int>& setRowsAggregated,- int* listRowsAggregated,- double* xlpExtra,- const char sen,- const double rhs,- const double lhs,- const CoinPackedMatrix& matrixByRow,- CoinPackedVector& rowToAggregate,- double& rhsToAggregate) const-{-- // copy the row selected to a vector of type CoinPackedVector- const CoinShallowPackedVector reqdBySunCC = matrixByRow.getVector(rowSelected);- rowToAggregate = reqdBySunCC ;- rhsToAggregate = rhs;-- // update list of indices of rows selected- setRowsAggregated.insert(rowSelected);- listRowsAggregated[iAggregate] = rowSelected;-- // Add a slack variable if needed and compute its current value- if (sen == 'L') {- rowToAggregate.insert(numCols_ + iAggregate, 1);- xlpExtra[iAggregate] = rhs - lhs;- }- else if (sen == 'G') {- rowToAggregate.insert(numCols_ + iAggregate, -1);- xlpExtra[iAggregate] = lhs - rhs;- }--}--//--------------------------------------------------------------------// Construct the set P* and select a row to aggregate-//--------------------------------------------------------------------bool-CglMixedIntegerRounding::selectRowToAggregate( - const OsiSolverInterface& si,- const CoinPackedVector& rowAggregated,- const double* colUpperBound,- const double* colLowerBound,- const std::set<int>& setRowsAggregated,- const double* xlp, const double* coefByCol,- const int* rowInds, const int* colStarts,- const int* colLengths,- int& rowSelected,- int& colSelected ) const-{-- bool foundRowToAggregate = false;-- double deltaMax = 0.0; // maximum delta- const int numColsAggregated = rowAggregated.getNumElements();- const int *rowAggregatedIndices = rowAggregated.getIndices();- const double *rowAggregatedElements = rowAggregated.getElements(); -- for (int j = 0; j < numColsAggregated; ++j) {-- // store the index and coefficient of column j- int indCol = rowAggregatedIndices[j];- if (indCol >= numCols_) continue;- double coefCol = rowAggregatedElements[j];-- // Consider only continuous variables- if ( (!si.isContinuous(indCol)) || (fabs(coefCol) < EPSILON_)) continue;-- // Compute current lower bound- CglMixIntRoundVLB VLB = vlbs_[indCol];- double LB = ( VLB.getVar() != UNDEFINED_ ) ? - VLB.getVal() * xlp[VLB.getVar()] : colLowerBound[indCol];- - // Compute current upper bound- CglMixIntRoundVUB VUB = vubs_[indCol];- double UB = ( VUB.getVar() != UNDEFINED_ ) ? - VUB.getVal() * xlp[VUB.getVar()] : colUpperBound[indCol];-- // Compute distances from current solution to upper and lower bounds- double delta = CoinMin(xlp[indCol] - LB, UB - xlp[indCol]);-- // In case this variable is acceptable look for possible rows- if (delta > deltaMax) {-- int iStart = colStarts[indCol];- int iStop = iStart + colLengths[indCol];- // int count = 0;-- // std::vector<int> rowPossible;-- // find a row to use in aggregation- for (int i = iStart; i < iStop; ++i) {- int rowInd = rowInds[i];- if (setRowsAggregated.find(rowInd) == setRowsAggregated.end()) {- // if the row was not already selected, select it- RowType rType = rowTypes_[rowInd];- if ( ((rType == ROW_MIX) || (rType == ROW_CONT)) - && (fabs(coefByCol[i]) > EPSILON_) ) {- // rowPossible.push_back(rowInd);- rowSelected = rowInd;- deltaMax = delta;- colSelected = indCol;- foundRowToAggregate = true;- //count++;- break;- }- }- }-- // if (count > 0)- // rowSelected = rowPossible[rand() % count];- // std::cout << count << std::endl;- }- - }-- return foundRowToAggregate;--}- -//--------------------------------------------------------------------// Aggregate the selected row with the current aggregated row-//--------------------------------------------------------------------void-CglMixedIntegerRounding::aggregateRow( - const int colSelected,- CoinPackedVector& rowToAggregate, double rhs,- CoinPackedVector& rowAggregated, - double& rhsAggregated ) const-{-- // quantity to multiply by the coefficients of the row to aggregate- double multiCoef = rowAggregated[colSelected] / rowToAggregate[colSelected];-- rowToAggregate *= multiCoef; - rhs *= multiCoef;-- rowAggregated = rowAggregated - rowToAggregate;- rhsAggregated -= rhs;--}--//--------------------------------------------------------------------// Choose the bound substitution based on the criteria defined by the user-//--------------------------------------------------------------------inline bool-CglMixedIntegerRounding::isLowerSubst(const double inf, - const double aj,- const double xlp, - const double LB, - const double UB) const-{- if (CRITERION_ == 1) {- // criterion 1 (the same as criterion (a) in the paper)- return xlp - LB < UB - xlp;- }- else {- if (UB == inf || xlp == LB) - return true;- if (LB == -inf || xlp == UB)- return false;- if (CRITERION_ == 2) - // criterion 2 (the same as criterion (b) in the paper)- return aj < 0;- else- // criterion 3 (the same as criterion (c) in the paper)- return aj > 0;- }-}----//--------------------------------------------------------------------// Bound substitution heuristic-//--------------------------------------------------------------------bool-CglMixedIntegerRounding::boundSubstitution( - const OsiSolverInterface& si,- const CoinPackedVector& rowAggregated,- const double* xlp,- const double* xlpExtra,- const double* colUpperBound,- const double* colLowerBound,- CoinPackedVector& mixedKnapsack,- double& rhsMixedKnapsack, double& sStar,- CoinPackedVector& contVariablesInS ) const-{-- bool generated = false;- const int numColsAggregated = rowAggregated.getNumElements();- const int *rowAggregatedIndices = rowAggregated.getIndices();- const double *rowAggregatedElements = rowAggregated.getElements(); -- // go through all the variables and if it is continuous and delta is - // negative, store variable in the vector contVariablesInS.- // If it is integer, store variable in the vector mixedKnapsack- int numCont = 0;- int j;- for ( j = 0; j < numColsAggregated; ++j) {-- // get index and coefficient of column j in the aggregated row- const int indCol = rowAggregatedIndices[j];- const double coefCol = rowAggregatedElements[j];-- // if the lower bound is equal to the upper bound, remove variable- if ( (indCol < numCols_) &&- (colLowerBound[indCol] == colUpperBound[indCol]) ) {- rhsMixedKnapsack -= coefCol * colLowerBound[indCol];- continue;- }-- if (fabs(coefCol) < EPSILON_) continue;- // set the coefficients of the integer variables- if ( (indCol < numCols_) && (!si.isContinuous(indCol)) ) {- // Copy the integer variable to the vector mixedKnapsack- if (mixedKnapsack.isExistingIndex(indCol)) {- const int index = mixedKnapsack.findIndex(indCol);- mixedKnapsack.setElement(index, mixedKnapsack[indCol] + coefCol);- }- else- mixedKnapsack.insert(indCol, coefCol);- continue;- }-- // Select the continuous variables and copy the ones in s to - // the vector contVariablesInS- if (indCol < numCols_) { // variable is model variable-- // Compute lower bound for variable indCol- const CglMixIntRoundVLB VLB = vlbs_[indCol];- const double LB = ( VLB.getVar() != UNDEFINED_ ) ? - VLB.getVal() * xlp[VLB.getVar()] : colLowerBound[indCol];- - // Compute upper bound for variable indCol- const CglMixIntRoundVUB VUB = vubs_[indCol];- const double UB = ( VUB.getVar() != UNDEFINED_ ) ? - VUB.getVal() * xlp[VUB.getVar()] : colUpperBound[indCol];-- // if both bounds are infinite, then we cannot form a mixed knapsack- if ( (LB == -1.0 * si.getInfinity()) &&- (UB == si.getInfinity()) ) {-#if CGL_DEBUG- std::cout << "continuous var with infinite bounds. " <<- "Cannot form mixed Knapsack = " << std::endl;-#endif- return generated;- }-- // Select the bound substitution- if (isLowerSubst(si.getInfinity(), rowAggregatedElements[j],- xlp[indCol], LB, UB)) {- if (VLB.getVar() != UNDEFINED_ ) {- const int indVLB = VLB.getVar();- if (mixedKnapsack.isExistingIndex(indVLB)) {- const int index = mixedKnapsack.findIndex(indVLB);- mixedKnapsack.setElement(index, mixedKnapsack[indVLB] + - coefCol * VLB.getVal());- }- else- mixedKnapsack.insert(indVLB, coefCol * VLB.getVal());- }- else {- rhsMixedKnapsack -= coefCol * LB;- }- // Update sStar- if (coefCol < -EPSILON_) {- contVariablesInS.insert(indCol, coefCol);- sStar -= coefCol * (xlp[indCol] - LB);- numCont++;- }- }- else {- if (VUB.getVar() != UNDEFINED_ ) {- const int indVUB = VUB.getVar();- if (mixedKnapsack.isExistingIndex(indVUB)) {- const int index = mixedKnapsack.findIndex(indVUB);- mixedKnapsack.setElement(index, mixedKnapsack[indVUB] + - coefCol * VUB.getVal());- }- else- mixedKnapsack.insert(indVUB, coefCol * VUB.getVal());- }- else {- rhsMixedKnapsack -= coefCol * UB;- }- // Update sStar- if (coefCol > EPSILON_) {- contVariablesInS.insert(indCol, - coefCol);- sStar += coefCol * (UB - xlp[indCol]);- numCont++;- }- }- }- else { // variable is slack variable- // in this case the LB = 0 and the UB = infinity- // Update sStar- const double tLB = xlpExtra[indCol - numCols_];- if (coefCol < -EPSILON_) {- contVariablesInS.insert(indCol, coefCol);- sStar -= coefCol * tLB;- numCont++;- }- }-- }-- // if there are no continuous variables to form s, then we stop-#if CGL_DEBUG- std::cout << "# of continuous var in mixedKnapsack = " << numCont <<- std::endl;-#endif- if (numCont == 0) return generated;-- // check that the integer variables have lower bound equal to zero- const int numInt = mixedKnapsack.getNumElements();- // if there are not integer variables in mixedKnapsack, then we stop- // CAUTION: all the coefficients could be zero-#if CGL_DEBUG- std::cout << "# of integer var in mixedKnapsack = " << numInt <<- std::endl;-#endif- if (numInt == 0) return generated;- const int *knapsackIndices = mixedKnapsack.getIndices();- const double *knapsackElements = mixedKnapsack.getElements(); -- for ( j = 0; j < numInt; ++j) {- // if the coefficient is zero, disregard- if (fabs(knapsackElements[j]) < EPSILON_) continue;- // if the lower bound is not zero, then we stop- if (fabs(colLowerBound[knapsackIndices[j]]) > EPSILON_) return generated;- }- // if the lower bounds of all integer variables are zero, proceed- generated = true;- return generated;--}--//--------------------------------------------------------------------// c-MIR separation heuristic-//--------------------------------------------------------------------bool-CglMixedIntegerRounding::cMirSeparation( - const OsiSolverInterface& si,- const CoinPackedMatrix& matrixByRow,- const CoinPackedVector& rowAggregated,- const int* listRowsAggregated,- const char* sense, const double* RHS,- //const double* coefByRow,- //const int* colInds, const int* rowStarts,- //const int* rowLengths,- const double* xlp, const double sStar,- const double* colUpperBound,- const double* colLowerBound,- const CoinPackedVector& mixedKnapsack,- const double& rhsMixedKnapsack,- const CoinPackedVector& contVariablesInS,- OsiRowCut& cMirCut) const-{-- bool generated = false;- double numeratorBeta = rhsMixedKnapsack;- CoinPackedVector cMIR = mixedKnapsack;- double rhscMIR;- double maxViolation = 0.0;- double bestDelta = 0.0;- CoinPackedVector bestCut;- double rhsBestCut = 0.0;- double sCoefBestCut = 0.0;- const int numInt = mixedKnapsack.getNumElements(); - const int *knapsackIndices = mixedKnapsack.getIndices();- const double *knapsackElements = mixedKnapsack.getElements(); - const int *contVarInSIndices = contVariablesInS.getIndices();- const double *contVarInSElements = contVariablesInS.getElements();-- // Construct set C, T will be the rest.- // Also, for T we construct a CoinPackedVector named complT which- // contains the vars in T that are strictly between their bounds- std::set<int> setC;- CoinPackedVector complT;- int j;- for ( j = 0; j < numInt; ++j) {- const int indCol = knapsackIndices[j];- // if the upper bound is infinity, then indCol is in T and cannot- // be in complT- if (colUpperBound[indCol] != si.getInfinity()) {- if (xlp[indCol] >= colUpperBound[indCol] / 2.0) {- setC.insert(j);- numeratorBeta -= knapsackElements[j] * colUpperBound[indCol];- } else {- if ( (xlp[indCol] <= EPSILON_) || - (xlp[indCol] >= colUpperBound[indCol] - EPSILON_))- continue;- complT.insert(j, fabs(xlp[indCol] - colUpperBound[indCol]/2));- }- }- }-- // Sort the indices in complT by nondecreasing values - // (which are $|y^*_j-u_j/2|$)- if (complT.getNumElements() > 0) {- complT.sortIncrElement();- }-- // Construct c-MIR inequalities and take the one with the largest violation- for ( j = 0; j < numInt; ++j) {- int indCol = knapsackIndices[j];- if ( (xlp[indCol] <= EPSILON_) || - (xlp[indCol] >= colUpperBound[indCol] - EPSILON_))- continue;- double delta = knapsackElements[j];- // delta has to be positive- if (delta <= EPSILON_) continue;-- double violation = 0.0;- double sCoef = 0.0;-- // form a cMIR inequality- cMirInequality(numInt, delta, numeratorBeta, knapsackIndices, - knapsackElements, xlp, sStar, colUpperBound, setC, cMIR,- rhscMIR, sCoef, violation);-- // store cut if it is the best found so far- if (violation > maxViolation + EPSILON_) {- bestCut = cMIR;- rhsBestCut = rhscMIR;- sCoefBestCut = sCoef;- maxViolation = violation;- bestDelta = delta;- }- }-- // if no violated inequality has been found, exit now- if (maxViolation == 0.0) return generated;-- // improve the best violated inequality.- // try to divide delta by 2, 4 or 8 and see if increases the violation- double deltaBase = bestDelta;- for (int multFactor = 2; multFactor <= 8; multFactor *= 2) {- double delta = deltaBase / multFactor;- double violation = 0.0;- double sCoef = 0.0;-- // form a cMIR inequality- cMirInequality(numInt, delta, numeratorBeta, knapsackIndices, - knapsackElements, xlp, sStar, colUpperBound, setC, cMIR,- rhscMIR, sCoef, violation);-- // store cut if it is the best found so far- if (violation > maxViolation + EPSILON_) {- bestCut = cMIR;- rhsBestCut = rhscMIR;- sCoefBestCut = sCoef;- maxViolation = violation;- bestDelta = delta;- }- }-- // improve cMIR for the best delta- // complT contains indices into mixedKnapsack for the variables- // which may be complemented and they are already appropriately- // sorted.- const int complTSize = complT.getNumElements();- if (complTSize > 0) {- const int *complTIndices = complT.getIndices();- for (int j = 0; j < complTSize; ++j) {- // move variable in set complT from set T to set C- int jIndex = complTIndices[j];- int indCol = knapsackIndices[jIndex];- // do nothing if upper bound is infinity- if (colUpperBound[indCol] >= si.getInfinity()) continue;- setC.insert(jIndex);- double violation = 0.0;- double sCoef = 0.0;- double localNumeratorBeta = numeratorBeta -- mixedKnapsack[indCol] * colUpperBound[indCol];-- // form a cMIR inequality- cMirInequality(numInt, bestDelta, localNumeratorBeta, knapsackIndices, - knapsackElements, xlp, sStar, colUpperBound, setC, cMIR,- rhscMIR, sCoef, violation);-- // store cut if it is the best found so far; otherwise, move the variable- // that was added to set C back to set T- if (violation > maxViolation + EPSILON_) {- bestCut = cMIR;- rhsBestCut = rhscMIR;- sCoefBestCut = sCoef;- maxViolation = violation;- numeratorBeta = localNumeratorBeta;- }- else- setC.erase(jIndex);- }- }-- // write the best cut found with the model variables- int numCont = contVariablesInS.getNumElements();- for ( j = 0; j < numCont; ++j) {- int indCol = contVarInSIndices[j];- double coefCol = contVarInSElements[j];- - if (indCol < numCols_) { // variable is model variable-- // Compute lower bound for variable indCol- CglMixIntRoundVLB VLB = vlbs_[indCol];- double LB = ( VLB.getVar() != UNDEFINED_ ) ? - VLB.getVal() * xlp[VLB.getVar()] : colLowerBound[indCol];- - // Compute upper bound for variable indCol- CglMixIntRoundVUB VUB = vubs_[indCol];- double UB = ( VUB.getVar() != UNDEFINED_ ) ? - VUB.getVal() * xlp[VUB.getVar()] : colUpperBound[indCol];-- // Select the bound substitution- if (isLowerSubst(si.getInfinity(), rowAggregated[indCol],- xlp[indCol], LB, UB)) { - if (VLB.getVar() != UNDEFINED_ ) {- int indVLB = VLB.getVar();- if (bestCut.isExistingIndex(indVLB)){- int index = bestCut.findIndex(indVLB);- bestCut.setElement(index, bestCut[indVLB] - - sCoefBestCut * coefCol * VLB.getVal());- }- else- bestCut.insert(indVLB, - sCoefBestCut * coefCol * VLB.getVal());- bestCut.insert(indCol, sCoefBestCut * coefCol);- }- else {- rhsBestCut += sCoefBestCut * coefCol * colLowerBound[indCol];- bestCut.insert(indCol, sCoefBestCut * coefCol);- }- }- else {- if (VUB.getVar() != UNDEFINED_ ) {- int indVUB = VUB.getVar();- if (bestCut.isExistingIndex(indVUB)){- int index = bestCut.findIndex(indVUB);- bestCut.setElement(index, bestCut[indVUB] + - sCoefBestCut * coefCol * VUB.getVal());- }- else- bestCut.insert(indVUB, sCoefBestCut * coefCol * VUB.getVal());- bestCut.insert(indCol, - sCoefBestCut * coefCol);- }- else {- rhsBestCut -= sCoefBestCut * coefCol * colUpperBound[indCol];- bestCut.insert(indCol, - sCoefBestCut * coefCol);- }- }- }- else { // variable is slack variable- // in this case the LB = 0 and the UB = infinity- // copy the row selected to a vector of type CoinPackedVector- const int iRow = listRowsAggregated[indCol - numCols_];- const CoinShallowPackedVector reqdBySunCC = matrixByRow.getVector(iRow);- CoinPackedVector row = reqdBySunCC ;- double rhs = RHS[iRow];-- if (sense[iRow] == 'L') {- // if it is a <= inequality, the coefficient of the slack is 1- row *= (- sCoefBestCut * coefCol);- rhs *= (- sCoefBestCut * coefCol);- }- else {- assert (sense[iRow]=='G');- // if it is a <= inequality, the coefficient of the slack is -1- row *= (sCoefBestCut * coefCol);- rhs *= (sCoefBestCut * coefCol);- }-- rhsBestCut += rhs;- bestCut = bestCut + row;- }- }-- // Check the violation of the cut after it is written with the original- // variables.- int cutLen = bestCut.getNumElements();- int* cutInd = bestCut.getIndices();- double* cutCoef = bestCut.getElements();- double cutRHS = rhsBestCut;- double violation = 0.0;- double normCut = 0.0;- // Also weaken by small coefficients- int n=0;- for ( j = 0; j < cutLen; ++j) {- double value = cutCoef[j];- int column = cutInd[j];- if (fabs(value)>1.0e-12) {- violation += cutCoef[j] * xlp[column];- normCut += cutCoef[j] * cutCoef[j];- cutCoef[n]=value;- cutInd[n++]=column;- } else if (value) {- // Weaken- if (value>0.0) {- // Allow for at lower bound- cutRHS -= value*colLowerBound[column];- } else {- // Allow for at upper bound- cutRHS -= value*colUpperBound[column];- }- }- }- cutLen=n;- violation -= cutRHS;- violation /= sqrt(normCut);-- if ( violation > TOLERANCE_ ) {- cMirCut.setRow(cutLen, cutInd, cutCoef);- cMirCut.setLb(-1.0 * si.getInfinity());- cMirCut.setUb(cutRHS);- cMirCut.setEffectiveness(violation);-#ifdef CGL_DEBUG- {- for (int k=0; k<cutLen; k++){- assert(cutInd[k]>=0);- assert(cutCoef[k]);- assert (fabs(cutCoef[k])>1.0e-12);- }- }-#endif- generated = true;- }-- return generated;--}--//--------------------------------------------------------------------// construct a c-MIR inequality-//--------------------------------------------------------------------void-CglMixedIntegerRounding::cMirInequality(- const int numInt, - const double delta,- const double numeratorBeta,- const int *knapsackIndices,- const double* knapsackElements,- const double* xlp, - const double sStar, - const double* colUpperBound,- const std::set<int>& setC,- CoinPackedVector& cMIR,- double& rhscMIR,- double& sCoef,- double& violation) const-{-- // form a cMIR inequality- double beta = numeratorBeta / delta;- double f = beta - floor(beta);- rhscMIR = floor(beta);- double normCut = 0.0;- // coefficients of variables in set T- for (int i = 0; i < numInt; ++i) {- const int iIndex = knapsackIndices[i];- double G = 0.0;- if (setC.find(i) == setC.end()) {- // i is not in setC, i.e., it is in T- G = functionG(knapsackElements[i] / delta, f);- violation += (G * xlp[iIndex]);- normCut += G * G;- cMIR.setElement(i, G);- } else {- G = functionG( - knapsackElements[i] / delta, f);- violation -= (G * xlp[iIndex]);- normCut += G * G;- rhscMIR -= G * colUpperBound[iIndex];- cMIR.setElement(i, -G); - }- }- sCoef = 1.0 / (delta * (1.0 - f));- violation -= (rhscMIR + sCoef * sStar);- normCut += sCoef * sCoef;- violation /= sqrt(normCut);--}---//--------------------------------------------------------------------// function G for computing coefficients in cMIR inequality-//--------------------------------------------------------------------inline double-CglMixedIntegerRounding::functionG( const double d, const double f ) const-{- double delta = d - floor(d) - f;- if (delta > EPSILON_)- return floor(d) + delta / (1 - f);- else- return floor(d);-}--//--------------------------------------------------------------------// Printing statistics-//--------------------------------------------------------------------void-CglMixedIntegerRounding::printStats(- std::ofstream & fout,- const bool hasCut,- const OsiSolverInterface& si,- const CoinPackedVector& rowAggregated,- const double& rhsAggregated, const double* xlp,- const double* xlpExtra,- const int* listRowsAggregated,- const int* listColsSelected,- const int level,- const double* colUpperBound,- const double* colLowerBound ) const-{--- const int numColsAggregated = rowAggregated.getNumElements();- const int *rowAggregatedIndices = rowAggregated.getIndices();- const double *rowAggregatedElements = rowAggregated.getElements(); -- fout << "Rows ";- for (int i = 0; i < level; ++i) {- fout << listRowsAggregated[i] << " ";- }- fout << std::endl;-- int numColsBack = 0;-- // go through all the variables - for (int j = 0; j < numColsAggregated; ++j) {-- // get index and coefficient of column j in the aggregated row- int indCol = rowAggregatedIndices[j];- double coefCol = rowAggregatedElements[j];-- // check if a column used in aggregation is back into the aggregated row- for (int i = 0; i < level-1; ++i) {- if ( (listColsSelected[i] == indCol) && (coefCol != 0) ) {- numColsBack++;- break;- }- }---- if (fabs(coefCol) < EPSILON_) {- // print variable number and coefficient- fout << indCol << " " << 0.0 << std::endl;- continue;- }- else {- // print variable number and coefficient- fout << indCol << " " << coefCol << " ";- }-- // integer variables- if ( (indCol < numCols_) && (!si.isContinuous(indCol)) ) {-- // print - fout << "I " << xlp[indCol] << " " << colLowerBound[indCol] <<- " " << colUpperBound[indCol] << std::endl;-- continue;- }-- // continuous variables - if (indCol < numCols_) { // variable is model variable-- // print- fout << "C " << xlp[indCol] << " " << colLowerBound[indCol] <<- " " << colUpperBound[indCol] << " ";-- // variable lower bound?- CglMixIntRoundVLB VLB = vlbs_[indCol];- if (VLB.getVar() != UNDEFINED_) {- fout << VLB.getVal() << " " << xlp[VLB.getVar()] << " " <<- colLowerBound[VLB.getVar()] << " " <<- colUpperBound[VLB.getVar()] << " ";- }- else {- fout << "-1 -1 -1 -1 ";- }-- // variable upper bound?- CglMixIntRoundVUB VUB = vubs_[indCol];- if (VUB.getVar() != UNDEFINED_) {- fout << VUB.getVal() << " " << xlp[VUB.getVar()] << " " <<- colLowerBound[VUB.getVar()] << " " <<- colUpperBound[VUB.getVar()] << " ";- }- else {- fout << "-1 -1 -1 -1 ";- }-- } - else { // variable is slack variable- // in this case the LB = 0 and the UB = infinity- // print- fout << "C " << xlpExtra[indCol-numCols_] << " " << 0.0 <<- " " << si.getInfinity() << " ";- }-- fout << std::endl;-- }-- fout << "rhs " << rhsAggregated << std::endl;-- fout << "numColsBack " << numColsBack << std::endl;-- if (hasCut) {- fout << "CUT: YES" << std::endl;- }- else {- fout << "CUT: NO" << std::endl;- }--}-// This can be used to refresh any inforamtion-void -CglMixedIntegerRounding::refreshSolver(OsiSolverInterface * )-{- doneInitPre_ = false;-}-// Create C++ lines to get to current state-std::string-CglMixedIntegerRounding::generateCpp( FILE * fp) -{- CglMixedIntegerRounding other;- fprintf(fp,"0#include \"CglMixedIntegerRounding.hpp\"\n");- fprintf(fp,"3 CglMixedIntegerRounding mixedIntegerRounding;\n");- if (MAXAGGR_!=other.MAXAGGR_)- fprintf(fp,"3 mixedIntegerRounding.setMAXAGGR_(%d);\n",MAXAGGR_);- else- fprintf(fp,"4 mixedIntegerRounding.setMAXAGGR_(%d);\n",MAXAGGR_);- if (MULTIPLY_!=other.MULTIPLY_)- fprintf(fp,"3 mixedIntegerRounding.setMULTIPLY_(%d);\n",MULTIPLY_);- else- fprintf(fp,"4 mixedIntegerRounding.setMULTIPLY_(%d);\n",MULTIPLY_);- if (CRITERION_!=other.CRITERION_)- fprintf(fp,"3 mixedIntegerRounding.setCRITERION_(%d);\n",CRITERION_);- if (doPreproc_!=other.doPreproc_)- fprintf(fp,"3 mixedIntegerRounding.setDoPreproc_(%d);\n", doPreproc_);- if (getAggressiveness()!=other.getAggressiveness())- fprintf(fp,"3 mixedIntegerRounding.setAggressiveness(%d);\n",getAggressiveness());- else- fprintf(fp,"4 mixedIntegerRounding.setAggressiveness(%d);\n",getAggressiveness());- return "mixedIntegerRounding";-}-void CglMixedIntegerRounding::setDoPreproc(int value)-{- if (value != -1 && value != 0 && value != 1) {- throw CoinError("setDoPrepoc", "invalid value",- "CglMixedIntegerRounding2");- }- else {- doPreproc_ = value;- } -}--bool CglMixedIntegerRounding::getDoPreproc() const-{- return (doPreproc_!=0);-}
− cbits/coin/CglSimpleRounding.cpp
@@ -1,482 +0,0 @@-// $Id: CglSimpleRounding.cpp 1123 2013-04-06 20:47:24Z stefan $-// Copyright (C) 2000, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#include <cstdlib>-#include <cmath>-#include <cstdio>-#include <cfloat> -#include <cassert>--#include "CoinPragma.hpp"-#include "CglSimpleRounding.hpp" -#include "CoinPackedVector.hpp"-#include "CoinSort.hpp"-#include "CoinPackedMatrix.hpp"--//--------------------------------------------------------------void-CglSimpleRounding::generateCuts(const OsiSolverInterface & si, OsiCuts & cs,- const CglTreeInfo /*info*/)-{- int nRows=si.getNumRows(); // number of rows in the coefficient matrix- int nCols=si.getNumCols(); // number of columns in the coefficient matrix- int rowIndex; // index into the constraint matrix stored in row- // order - CoinPackedVector irow; // "integer row": working space to hold the integer- // <= inequality derived from the rowIndex-th- // constraint - double b=0; // working space for the rhs of integer <= inequality- bool * negative= new bool[nCols]; // negative[i]= true if coefficient of the - // ith variable is negative and false- // otherwise - int k; // dummy iterator variable - for ( k=0; k<nCols; k++ ) negative[k] = false;- - const CoinPackedMatrix * rowCopy = - si.getMatrixByRow(); // row copy: matrix stored in row order-- /////////////////////////////////////////////////////////////////////////////- // Main loop: //- // For every row in the matrix, //- // if we can derive a valid <= inequality in integer variables, then //- // try to construct a simple rounding cut from the integer inequality. //- // Add the resulting cut to the set of cuts. //- /////////////////////////////////////////////////////////////////////////////-- for (rowIndex=0; rowIndex<nRows; rowIndex++){-- // Only look at tight rows- // double * pi=ekk_rowduals(model); - // if (fabs(pi[row]) < epsilon_){- // continue;- // }-- // Try to derive an <= inequality in integer variables from the row - // by netting out the continuous variables.- // Store the value and the sign of the coefficients separately:- // irow.getElements() contains the absolute values of the coefficients.- // negative is a boolean vector indicating the sign of the coeffcients.- // b is the rhs of the <= integer inequality-- if (!deriveAnIntegerRow( si, - rowIndex, - rowCopy->getVector(rowIndex),- irow, b, negative))- {-- // Reset local data for the next iteration of the rowIndex-loop- for(k=0; k<irow.getNumElements(); k++) negative[irow.getIndices()[k]]=false;- irow.setVector(0,NULL,NULL);- continue;- } - - // Euclid's greatest common divisor (gcd) algorithm applies to positive- // INTEGERS. - // Determine the power of 10 needed, so that multipylying the integer- // inequality through by 10**power makes all coefficients essentially- // integral. - int power = power10ToMakeDoubleAnInt(irow.getNumElements(),irow.getElements(),epsilon_*1.0e-4);-- // Now a vector to store the integer-ized values. For instance, - // if x[i] is .66 and power is 1000 then xInt[i] will be 660- int * xInt = NULL;- if (power >=0) {-- xInt = new int[irow.getNumElements()]; - double dxInt; // a double version of xInt for error trapping- - -#ifdef CGL_DEBUG - printf("The (double) coefficients and their integer-ized counterparts:\n");-#endif-- for (k=0; k<irow.getNumElements(); k++){- dxInt = irow.getElements()[k]*pow(10.0,power);- xInt[k]= static_cast<int> (dxInt+0.5); // Need to add the 0.5 - // so that a dxInt=9.999 will give a xInt=1--#ifdef CGL_DEBUG- printf("%g %g \n",irow.getElements()[k],dxInt);-#endif-- }-- } else {-- // If overflow is detected, one warning message is printed and - // the row is skipped.-#ifdef CGL_DEBUG- printf("SimpleRounding: Warning: Overflow detected \n");- printf(" on %i of vars in processing row %i. Row skipped.\n",- -power, rowIndex);-#endif- // reset local data for next iteration- for(k=0; k<irow.getNumElements(); k++) negative[irow.getIndices()[k]]=false;- irow.setVector(0,NULL,NULL);- continue;- }-- // find greatest common divisor of the irow.elements- int gcd = gcdv(irow.getNumElements(), xInt);--#ifdef CGL_DEBUG- printf("The gcd of xInt is %i\n",gcd); -#endif-- // construct new cut by dividing through by gcd and - // rounding down rhs and accounting for negatives- CoinPackedVector cut;- for (k=0; k<irow.getNumElements(); k++){- cut.insert(irow.getIndices()[k],xInt[k]/gcd);- }- double cutRhs = floor((b*pow(10.0,power))/gcd);-- // un-negate the negated variables in the cut- {- const int s = cut.getNumElements();- const int * indices = cut.getIndices();- double* elements = cut.getElements();- for (k=0; k<s; k++){- int column=indices[k];- if (negative[column]) {- elements[k] *= -1;- }- }- }-- // Create the row cut and add it to the set of cuts- // It may not be violated- if (fabs(cutRhs*gcd-b)> epsilon_){ // if the cut and row are different. - OsiRowCut rc;- rc.setRow(cut.getNumElements(),cut.getIndices(),cut.getElements());- rc.setLb(-COIN_DBL_MAX);- rc.setUb(cutRhs); - cs.insert(rc);--#ifdef CGL_DEBUG- printf("Row %i had a simple rounding cut:\n",rowIndex);- printf("Cut size: %i Cut rhs: %g Index Element \n",- cut.getNumElements(), cutRhs);- for (k=0; k<cut.getNumElements(); k++){- printf("%i %g\n",cut.getIndices()[k], cut.getElements()[k]);- }- printf("\n");-#endif- }-- // Reset local data for the next iteration of the rowIndex-loop- for(k=0; k<irow.getNumElements(); k++) negative[irow.getIndices()[k]]=false;- irow.setVector(0,NULL,NULL);- delete [] xInt;--- }-- delete [] negative;-}---//--------------------------------------------------------------------// deriveAnIntegerRow: dervies a <= inequality-// in integer variables of the form ax<=b -// from a row in the model, if possible by-// netting out the continuous variables-//--------------------------------------------------------------------bool-CglSimpleRounding::deriveAnIntegerRow(- const OsiSolverInterface & si, - int rowIndex,- const CoinShallowPackedVector & matrixRow,- CoinPackedVector & irow, - double & b,- bool * negative) const-{- irow.clear();- int i; // dummy iterator variable- double sign=1.0; // +1 if le row, -1 if ge row -- // number of columns in the row- int sizeOfRow=matrixRow.getNumElements();-- // Get the sense of the row constraint- const char rowsense = si.getRowSense()[rowIndex];-- // Skip equality rows - if (rowsense=='E' || rowsense=='N') {- return 0; - }- // le row - if (rowsense=='L'){- b=si.getRightHandSide()[rowIndex];- }- // ge row- // Multiply through by -1 to convert it to a le row - if (rowsense=='G'){- b=-si.getRightHandSide()[rowIndex];- sign=-1.0;- }- - // Finite, but unequal row bounds - // Could derive an simple rounding inequality from either - // (or from both!) but for expediency, - // use the le relationship as the default for now - if (rowsense=='R') {- b=si.getRightHandSide()[rowIndex];- }- - // Try to net out the continuous variables from the constraint.- // Multipy through by sign to convert the inequality to a le inequality - // If the coefficient on a continuous variable is positive, replace- // the continous variable with its lower bound - // If the coefficient on a continuous variable is negative, replace- // the continuous variable with its upper bound.- // example:- // 2.5 <= 3x0-2.8x1+4x2, 0<=x0<=0.2, 0.4<=x1, x2 integer- // -3x0+2.8x1-4x2 <= -2.5- // -3(0.2)+2.8(0.4)-4x3 <= -3x0+2.8x1-4x2 <= -2.5- // gives the (weaker, valid) integer inequality- // -4x2 <= -2.5+3(0.2)-2.8(0.4)- // sign = -1- // irow.elements = 4- // irow.indices = 2- // negative = (true, true, false)- // b=-2.5+3(0.2)-2.8(0.4)= -3.02-- const double * colupper = si.getColUpper();- const double * collower = si.getColLower();-- for (i=0; i<sizeOfRow; i++){- // if the variable is continuous- if ( !si.isInteger( matrixRow.getIndices()[i] ) ) {- // and the coefficient is strictly negative- if((sign*matrixRow.getElements()[i])<-epsilon_){- // and the continuous variable has a fintite upper bound- if (colupper[matrixRow.getIndices()[i]] < si.getInfinity()){- // then replace the variable with its upper bound.- b=b-(sign*matrixRow.getElements()[i]*colupper[matrixRow.getIndices()[i]]);- } - else - return 0;- }- // if the coefficient in strictly positive- else if((sign*matrixRow.getElements()[i])>epsilon_){- // and the continuous variable has a finite lower bound- if (collower[matrixRow.getIndices()[i]] > -si.getInfinity()){- // then replace the variable with its lower bound.- b=b-(sign*matrixRow.getElements()[i]*collower[matrixRow.getIndices()[i]]);- }- else- return 0;- }- // else the coefficient is essentially an explicitly stored zero; do- // nothing - }- // else: the variable is integer- else{- // if the integer variable is fixed, net it out of the integer inequality- if (colupper[matrixRow.getIndices()[i]]- collower[matrixRow.getIndices()[i]]<- epsilon_){- b=b-(sign*matrixRow.getElements()[i]*colupper[matrixRow.getIndices()[i]]);- }- // else the variable is a free integer variable and it becomes- // part of the integer inequality- else {- irow.insert(matrixRow.getIndices()[i],sign*matrixRow.getElements()[i]);- }- }- }- - // if there are no free integer variables, then abandon this row;- if(irow.getNumElements() == 0){- return 0;- }- - // Store the values and the signs of the coefficients separately.- // irow.elements stores the absolute values of the coefficients- // negative indicates the sign.- // Note: after this point b is essentially the effecitve rhs of a le- // contraint- {- const int s = irow.getNumElements();- const int * indices = irow.getIndices();- double * elements = irow.getElements();- for(i=0; i<s; i++){- if (elements[i] < -epsilon_) {- negative[indices[i]]= true; // store indicator of the sign - elements[i] *= -1; // store only positive values- }- }- }-- return 1;-}---//--------------------------------------------------------------------// power10ToMakeDoubleAnInt: -// given a vector of positive doubles x_i, i=1, size, and a positive-// tolerance dataTol, determine the smallest power of 10 needed so that-// x[i]*10**power is integer for all i.--// dataTol_ should be correlated to the accuracy of the data,-// and choosen to be the largest value that's tolerable.-// -// (Easily extended to take an input vector of arbitrary sign)-//--------------------------------------------------------------------//-int-CglSimpleRounding::power10ToMakeDoubleAnInt( - int size, // the length of the input vector x- const double * x, // the input vector of postive values - double dataTol) const // the (strictly postive) precision of the data--{- // Assumption: data precision is positive- assert( dataTol > 0 );--- int i; // loop iterator - int maxPower=0; // maximum power of 10 used to convert any x[i] to an- // integer - // this is the number we are after.- int power = 0; // power of 10 used to convert a particular x[i] to an- // integer --#ifdef OLD_MULT- double intPart; // the integer part of the number-#endif- double fracPart; // the fractional part of the number- // we keep multiplying by 10 until the fractional part is 0- // (well, really just until the factional part is less than- // dataTol) -- // JJF - code seems to fail sometimes as multiplying by 10 - so- // definition of dataTol changed - see header file-- const double multiplier[16]={1.0,1.0e1,1.0e2,1.0e3,1.0e4,1.0e5,- 1.0e6,1.0e7,1.0e8,1.0e9,1.0e10,1.0e11,- 1.0e12,1.0e13,1.0e14,1.0e15};-- // Loop through every element in the array in x- for (i=0; i<size; i++){- power = 0;--#ifdef OLD_MULT - // look at the fractional part of x[i]- // FYI: if you want to modify this member function to take an input- // vector x of arbitary sign, change this line below to - // fracPart = modf(fabs(x[i]),&intPart);- fracPart = modf(x[i],&intPart);-- // if the fractional part is close enough to 0 or 1, we're done with this- // value- while(!(fracPart < dataTol || 1-fracPart < dataTol )) {- // otherwise, multiply by 10 and look at the fractional part of the- // result. - ++power;- fracPart = fracPart*10.0;- fracPart = modf(fracPart,&intPart); - }-#else- // use fabs as safer and does no harm- double value = fabs(x[i]);- double scaledValue;- // Do loop - always using original value to stop round off error.- // If we don't find in 15 goes give up- for (power=0;power<16;power++) {- double tolerance = dataTol*multiplier[power];- scaledValue = value*multiplier[power];- fracPart = scaledValue-floor(scaledValue);- if(fracPart < tolerance || 1.0-fracPart < tolerance ) {- break;- }- }- if (power==16||scaledValue>2147483647) {-#ifdef CGL_DEBUG- printf("Overflow %g => %g, power %d\n",x[i],scaledValue,power);-#endif- return -1;- }-#endif -#ifdef CGL_DEBUG- printf("The smallest power of 10 to make %g integral = %i\n",x[i],power);-#endif-- - // keep track of the largest power needed so that at the end of the for- // loop- // x[i]*10**maxPower will be integral for all i- if (maxPower < power) maxPower=power;- }-- return maxPower;-}--//--------------------------------------------------------------------// Default Constructor -//--------------------------------------------------------------------CglSimpleRounding::CglSimpleRounding ()-:-CglCutGenerator(),-epsilon_(1.0e-08)-{- // nothing to do here-}-//--------------------------------------------------------------------// Copy constructor -//--------------------------------------------------------------------CglSimpleRounding::CglSimpleRounding (- const CglSimpleRounding & source)-:-CglCutGenerator(source),-epsilon_(source.epsilon_)-{ - // Nothing to do here-}---//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------CglCutGenerator *-CglSimpleRounding::clone() const-{- return new CglSimpleRounding(*this);-}--//--------------------------------------------------------------------// Destructor -//--------------------------------------------------------------------CglSimpleRounding::~CglSimpleRounding ()-{- // Nothing to do here-}--//-----------------------------------------------------------------// Assignment operator -//--------------------------------------------------------------------CglSimpleRounding &-CglSimpleRounding::operator=(- const CglSimpleRounding& rhs)-{- if (this != &rhs) {- CglCutGenerator::operator=(rhs);- epsilon_=rhs.epsilon_;- }- return *this;-}-// Create C++ lines to get to current state-std::string-CglSimpleRounding::generateCpp( FILE * fp) -{- CglSimpleRounding other;- fprintf(fp,"0#include \"CglSimpleRounding.hpp\"\n");- fprintf(fp,"3 CglSimpleRounding simpleRounding;\n");- if (getAggressiveness()!=other.getAggressiveness())- fprintf(fp,"3 simpleRounding.setAggressiveness(%d);\n",getAggressiveness());- else- fprintf(fp,"4 simpleRounding.setAggressiveness(%d);\n",getAggressiveness());- return "simpleRounding";-}
− cbits/coin/ClpDummyMatrix.cpp
@@ -1,263 +0,0 @@-/* $Id: ClpDummyMatrix.cpp 1665 2011-01-04 17:55:54Z lou $ */-// Copyright (C) 2003, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#include <cstdio>--#include "CoinPragma.hpp"--#include "ClpSimplex.hpp"-#include "ClpDummyMatrix.hpp"-#include "ClpFactorization.hpp"-#include "ClpMessage.hpp"--//#############################################################################-// Constructors / Destructor / Assignment-//#############################################################################--//--------------------------------------------------------------------// Default Constructor-//--------------------------------------------------------------------ClpDummyMatrix::ClpDummyMatrix ()- : ClpMatrixBase()-{- setType(14);- numberRows_ = 0;- numberColumns_ = 0;- numberElements_ = 0;-}--/* Constructor from data */-ClpDummyMatrix::ClpDummyMatrix(int numberColumns, int numberRows,- int numberElements)- : ClpMatrixBase()-{- setType(14);- numberRows_ = numberRows;- numberColumns_ = numberColumns;- numberElements_ = numberElements;-}-//--------------------------------------------------------------------// Copy constructor-//--------------------------------------------------------------------ClpDummyMatrix::ClpDummyMatrix (const ClpDummyMatrix & rhs)- : ClpMatrixBase(rhs)-{- numberRows_ = rhs.numberRows_;- numberColumns_ = rhs.numberColumns_;- numberElements_ = rhs.numberElements_;-}--ClpDummyMatrix::ClpDummyMatrix (const CoinPackedMatrix & )- : ClpMatrixBase()-{- std::cerr << "Constructor from CoinPackedMatrix nnot supported - ClpDummyMatrix" << std::endl;- abort();-}--//--------------------------------------------------------------------// Destructor-//--------------------------------------------------------------------ClpDummyMatrix::~ClpDummyMatrix ()-{-}--//-----------------------------------------------------------------// Assignment operator-//--------------------------------------------------------------------ClpDummyMatrix &-ClpDummyMatrix::operator=(const ClpDummyMatrix& rhs)-{- if (this != &rhs) {- ClpMatrixBase::operator=(rhs);- numberRows_ = rhs.numberRows_;- numberColumns_ = rhs.numberColumns_;- numberElements_ = rhs.numberElements_;- }- return *this;-}-//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------ClpMatrixBase * ClpDummyMatrix::clone() const-{- return new ClpDummyMatrix(*this);-}--/* Returns a new matrix in reverse order without gaps */-ClpMatrixBase *-ClpDummyMatrix::reverseOrderedCopy() const-{- std::cerr << "reverseOrderedCopy not supported - ClpDummyMatrix" << std::endl;- abort();- return NULL;-}-//unscaled versions-void-ClpDummyMatrix::times(double ,- const double * , double * ) const-{- std::cerr << "times not supported - ClpDummyMatrix" << std::endl;- abort();-}-void-ClpDummyMatrix::transposeTimes(double ,- const double * , double * ) const-{- std::cerr << "transposeTimes not supported - ClpDummyMatrix" << std::endl;- abort();-}-void-ClpDummyMatrix::times(double ,- const double * , double * ,- const double * ,- const double * ) const-{- std::cerr << "timesnot supported - ClpDummyMatrix" << std::endl;- abort();-}-void-ClpDummyMatrix::transposeTimes( double,- const double * , double * ,- const double * ,- const double * ) const-{- std::cerr << "transposeTimesnot supported - ClpDummyMatrix" << std::endl;- abort();-}-/* Return <code>x * A + y</code> in <code>z</code>.- Squashes small elements and knows about ClpSimplex */-void-ClpDummyMatrix::transposeTimes(const ClpSimplex * , double ,- const CoinIndexedVector * ,- CoinIndexedVector * ,- CoinIndexedVector * ) const-{- std::cerr << "transposeTimes not supported - ClpDummyMatrix" << std::endl;- abort();-}-/* Return <code>x *A in <code>z</code> but- just for indices in y */-void-ClpDummyMatrix::subsetTransposeTimes(const ClpSimplex * ,- const CoinIndexedVector * ,- const CoinIndexedVector * ,- CoinIndexedVector * ) const-{- std::cerr << "subsetTransposeTimes not supported - ClpDummyMatrix" << std::endl;- abort();-}-/// returns number of elements in column part of basis,-CoinBigIndex-ClpDummyMatrix::countBasis(const int * ,- int & )-{- std::cerr << "countBasis not supported - ClpDummyMatrix" << std::endl;- abort();- return 0;-}-void-ClpDummyMatrix::fillBasis(ClpSimplex * ,- const int * ,- int & ,- int * , int * ,- int * , int * ,- CoinFactorizationDouble * )-{- std::cerr << "fillBasis not supported - ClpDummyMatrix" << std::endl;- abort();-}-/* Unpacks a column into an CoinIndexedvector- */-void-ClpDummyMatrix::unpack(const ClpSimplex * , CoinIndexedVector * ,- int ) const-{- std::cerr << "unpack not supported - ClpDummyMatrix" << std::endl;- abort();-}-/* Unpacks a column into an CoinIndexedvector-** in packed foramt-Note that model is NOT const. Bounds and objective could-be modified if doing column generation (just for this variable) */-void-ClpDummyMatrix::unpackPacked(ClpSimplex * ,- CoinIndexedVector * ,- int ) const-{- std::cerr << "unpackPacked not supported - ClpDummyMatrix" << std::endl;- abort();-}-/* Adds multiple of a column into an CoinIndexedvector- You can use quickAdd to add to vector */-void-ClpDummyMatrix::add(const ClpSimplex * , CoinIndexedVector * ,- int , double ) const-{- std::cerr << "add not supported - ClpDummyMatrix" << std::endl;- abort();-}-/* Adds multiple of a column into an array */-void-ClpDummyMatrix::add(const ClpSimplex * , double * ,- int , double ) const-{- std::cerr << "add not supported - ClpDummyMatrix" << std::endl;- abort();-}--// Return a complete CoinPackedMatrix-CoinPackedMatrix *-ClpDummyMatrix::getPackedMatrix() const-{- std::cerr << "getPackedMatrix not supported - ClpDummyMatrix" << std::endl;- abort();- return NULL;-}-/* A vector containing the elements in the packed matrix. Note that there- might be gaps in this list, entries that do not belong to any- major-dimension vector. To get the actual elements one should look at- this vector together with vectorStarts and vectorLengths. */-const double *-ClpDummyMatrix::getElements() const-{- std::cerr << "getElements not supported - ClpDummyMatrix" << std::endl;- abort();- return NULL;-}--const CoinBigIndex *-ClpDummyMatrix::getVectorStarts() const-{- std::cerr << "getVectorStarts not supported - ClpDummyMatrix" << std::endl;- abort();- return NULL;-}-/* The lengths of the major-dimension vectors. */-const int *-ClpDummyMatrix::getVectorLengths() const-{- std::cerr << "get VectorLengths not supported - ClpDummyMatrix" << std::endl;- abort();- return NULL;-}-/* Delete the columns whose indices are listed in <code>indDel</code>. */-void ClpDummyMatrix::deleteCols(const int , const int * )-{- std::cerr << "deleteCols not supported - ClpDummyMatrix" << std::endl;- abort();-}-/* Delete the rows whose indices are listed in <code>indDel</code>. */-void ClpDummyMatrix::deleteRows(const int , const int * )-{- std::cerr << "deleteRows not supported - ClpDummyMatrix" << std::endl;- abort();-}-const int *-ClpDummyMatrix::getIndices() const-{- std::cerr << "getIndices not supported - ClpDummyMatrix" << std::endl;- abort();- return NULL;-}
− cbits/coin/ClpDynamicExampleMatrix.cpp
@@ -1,683 +0,0 @@-/* $Id: ClpDynamicExampleMatrix.cpp 1941 2013-04-10 16:52:27Z stefan $ */-// Copyright (C) 2004, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#include <cstdio>--#include "CoinPragma.hpp"-#include "CoinIndexedVector.hpp"-#include "CoinHelperFunctions.hpp"--#include "ClpSimplex.hpp"-#include "ClpFactorization.hpp"-#include "ClpQuadraticObjective.hpp"-#include "ClpNonLinearCost.hpp"-// at end to get min/max!-#include "ClpDynamicExampleMatrix.hpp"-#include "ClpMessage.hpp"-//#define CLP_DEBUG-//#define CLP_DEBUG_PRINT-//#############################################################################-// Constructors / Destructor / Assignment-//#############################################################################--//--------------------------------------------------------------------// Default Constructor-//--------------------------------------------------------------------ClpDynamicExampleMatrix::ClpDynamicExampleMatrix ()- : ClpDynamicMatrix(),- numberColumns_(0),- startColumnGen_(NULL),- rowGen_(NULL),- elementGen_(NULL),- costGen_(NULL),- fullStartGen_(NULL),- dynamicStatusGen_(NULL),- idGen_(NULL),- columnLowerGen_(NULL),- columnUpperGen_(NULL)-{- setType(25);-}--//--------------------------------------------------------------------// Copy constructor-//--------------------------------------------------------------------ClpDynamicExampleMatrix::ClpDynamicExampleMatrix (const ClpDynamicExampleMatrix & rhs)- : ClpDynamicMatrix(rhs)-{- numberColumns_ = rhs.numberColumns_;- startColumnGen_ = ClpCopyOfArray(rhs.startColumnGen_, numberColumns_ + 1);- CoinBigIndex numberElements = startColumnGen_[numberColumns_];- rowGen_ = ClpCopyOfArray(rhs.rowGen_, numberElements);;- elementGen_ = ClpCopyOfArray(rhs.elementGen_, numberElements);;- costGen_ = ClpCopyOfArray(rhs.costGen_, numberColumns_);- fullStartGen_ = ClpCopyOfArray(rhs.fullStartGen_, numberSets_ + 1);- dynamicStatusGen_ = ClpCopyOfArray(rhs.dynamicStatusGen_, numberColumns_);- idGen_ = ClpCopyOfArray(rhs.idGen_, maximumGubColumns_);- columnLowerGen_ = ClpCopyOfArray(rhs.columnLowerGen_, numberColumns_);- columnUpperGen_ = ClpCopyOfArray(rhs.columnUpperGen_, numberColumns_);-}--/* This is the real constructor*/-ClpDynamicExampleMatrix::ClpDynamicExampleMatrix(ClpSimplex * model, int numberSets,- int numberGubColumns, const int * starts,- const double * lower, const double * upper,- const CoinBigIndex * startColumn, const int * row,- const double * element, const double * cost,- const double * columnLower, const double * columnUpper,- const unsigned char * status,- const unsigned char * dynamicStatus,- int numberIds, const int *ids)- : ClpDynamicMatrix(model, numberSets, 0, NULL, lower, upper, NULL, NULL, NULL, NULL, NULL, NULL,- NULL, NULL)-{- setType(25);- numberColumns_ = numberGubColumns;- // start with safe values - then experiment- maximumGubColumns_ = numberColumns_;- maximumElements_ = startColumn[numberColumns_];- // delete odd stuff created by ClpDynamicMatrix constructor- delete [] startSet_;- startSet_ = new int [numberSets_];- delete [] next_;- next_ = new int [maximumGubColumns_];- delete [] row_;- delete [] element_;- delete [] startColumn_;- delete [] cost_;- delete [] columnLower_;- delete [] columnUpper_;- delete [] dynamicStatus_;- delete [] status_;- delete [] id_;- // and size correctly- row_ = new int [maximumElements_];- element_ = new double [maximumElements_];- startColumn_ = new CoinBigIndex [maximumGubColumns_+1];- // say no columns yet- numberGubColumns_ = 0;- startColumn_[0] = 0;- cost_ = new double[maximumGubColumns_];- dynamicStatus_ = new unsigned char [2*maximumGubColumns_];- memset(dynamicStatus_, 0, maximumGubColumns_);- id_ = new int[maximumGubColumns_];- if (columnLower)- columnLower_ = new double[maximumGubColumns_];- else- columnLower_ = NULL;- if (columnUpper)- columnUpper_ = new double[maximumGubColumns_];- else- columnUpper_ = NULL;- // space for ids- idGen_ = new int [maximumGubColumns_];- int iSet;- for (iSet = 0; iSet < numberSets_; iSet++)- startSet_[iSet] = -1;- // This starts code specific to this storage method- CoinBigIndex i;- fullStartGen_ = ClpCopyOfArray(starts, numberSets_ + 1);- startColumnGen_ = ClpCopyOfArray(startColumn, numberColumns_ + 1);- CoinBigIndex numberElements = startColumnGen_[numberColumns_];- rowGen_ = ClpCopyOfArray(row, numberElements);- elementGen_ = new double[numberElements];- for (i = 0; i < numberElements; i++)- elementGen_[i] = element[i];- costGen_ = new double[numberColumns_];- for (i = 0; i < numberColumns_; i++) {- costGen_[i] = cost[i];- // I don't think I need sorted but ...- CoinSort_2(rowGen_ + startColumnGen_[i], rowGen_ + startColumnGen_[i+1], elementGen_ + startColumnGen_[i]);- }- if (columnLower) {- columnLowerGen_ = new double[numberColumns_];- for (i = 0; i < numberColumns_; i++) {- columnLowerGen_[i] = columnLower[i];- if (columnLowerGen_[i]) {- printf("Non-zero lower bounds not allowed - subtract from model\n");- abort();- }- }- } else {- columnLowerGen_ = NULL;- }- if (columnUpper) {- columnUpperGen_ = new double[numberColumns_];- for (i = 0; i < numberColumns_; i++)- columnUpperGen_[i] = columnUpper[i];- } else {- columnUpperGen_ = NULL;- }- // end specific coding- if (columnUpper_) {- // set all upper bounds so we have enough space- double * columnUpper = model->columnUpper();- for(i = firstDynamic_; i < lastDynamic_; i++)- columnUpper[i] = 1.0e10;- }- status_ = new unsigned char [2*numberSets_+4];- if (status) {- memcpy(status_,status, numberSets_ * sizeof(char));- assert (dynamicStatus);- CoinMemcpyN(dynamicStatus, numberIds, dynamicStatus_);- assert (numberIds);- } else {- assert (!numberIds);- memset(status_, 0, numberSets_);- for (i = 0; i < numberSets_; i++) {- // make slack key- setStatus(i, ClpSimplex::basic);- }- }- dynamicStatusGen_ = new unsigned char [numberColumns_];- memset(dynamicStatusGen_, 0, numberColumns_); // for clarity- for (i = 0; i < numberColumns_; i++)- setDynamicStatusGen(i, atLowerBound);- // Populate with enough columns- if (!numberIds) {- // This could be made more sophisticated- for (iSet = 0; iSet < numberSets_; iSet++) {- int sequence = fullStartGen_[iSet];- CoinBigIndex start = startColumnGen_[sequence];- addColumn(startColumnGen_[sequence+1] - start,- rowGen_ + start,- elementGen_ + start,- costGen_[sequence],- columnLowerGen_ ? columnLowerGen_[sequence] : 0,- columnUpperGen_ ? columnUpperGen_[sequence] : 1.0e30,- iSet, getDynamicStatusGen(sequence));- idGen_[iSet] = sequence; // say which one in- setDynamicStatusGen(sequence, inSmall);- }- } else {- // put back old ones- int * set = new int[numberColumns_];- for (iSet = 0; iSet < numberSets_; iSet++) {- for (CoinBigIndex j = fullStartGen_[iSet]; j < fullStartGen_[iSet+1]; j++)- set[j] = iSet;- }- for (int i = 0; i < numberIds; i++) {- int sequence = ids[i];- CoinBigIndex start = startColumnGen_[sequence];- addColumn(startColumnGen_[sequence+1] - start,- rowGen_ + start,- elementGen_ + start,- costGen_[sequence],- columnLowerGen_ ? columnLowerGen_[sequence] : 0,- columnUpperGen_ ? columnUpperGen_[sequence] : 1.0e30,- set[sequence], getDynamicStatus(i));- idGen_[iSet] = sequence; // say which one in- setDynamicStatusGen(sequence, inSmall);- }- delete [] set;- }- if (!status) {- gubCrash();- } else {- initialProblem();- }-}-#if 0-// This constructor just takes over ownership-ClpDynamicExampleMatrix::ClpDynamicExampleMatrix(ClpSimplex * model, int numberSets,- int numberGubColumns, int * starts,- const double * lower, const double * upper,- int * startColumn, int * row,- double * element, double * cost,- double * columnLower, double * columnUpper,- const unsigned char * status,- const unsigned char * dynamicStatus,- int numberIds, const int *ids)- : ClpDynamicMatrix(model, numberSets, 0, NULL, lower, upper, NULL, NULL, NULL, NULL, NULL, NULL,- NULL, NULL)-{- setType(25);- numberColumns_ = numberGubColumns;- // start with safe values - then experiment- maximumGubColumns_ = numberColumns_;- maximumElements_ = startColumn[numberColumns_];- // delete odd stuff created by ClpDynamicMatrix constructor- delete [] startSet_;- startSet_ = new int [numberSets_];- delete [] next_;- next_ = new int [maximumGubColumns_];- delete [] row_;- delete [] element_;- delete [] startColumn_;- delete [] cost_;- delete [] columnLower_;- delete [] columnUpper_;- delete [] dynamicStatus_;- delete [] status_;- delete [] id_;- // and size correctly- row_ = new int [maximumElements_];- element_ = new double [maximumElements_];- startColumn_ = new CoinBigIndex [maximumGubColumns_+1];- // say no columns yet- numberGubColumns_ = 0;- startColumn_[0] = 0;- cost_ = new double[maximumGubColumns_];- dynamicStatus_ = new unsigned char [2*maximumGubColumns_];- memset(dynamicStatus_, 0, maximumGubColumns_);- id_ = new int[maximumGubColumns_];- if (columnLower)- columnLower_ = new double[maximumGubColumns_];- else- columnLower_ = NULL;- if (columnUpper)- columnUpper_ = new double[maximumGubColumns_];- else- columnUpper_ = NULL;- // space for ids- idGen_ = new int [maximumGubColumns_];- int iSet;- for (iSet = 0; iSet < numberSets_; iSet++)- startSet_[iSet] = -1;- // This starts code specific to this storage method- CoinBigIndex i;- fullStartGen_ = starts;- startColumnGen_ = startColumn;- rowGen_ = row;- elementGen_ = element;- costGen_ = cost;- for (i = 0; i < numberColumns_; i++) {- // I don't think I need sorted but ...- CoinSort_2(rowGen_ + startColumnGen_[i], rowGen_ + startColumnGen_[i+1], elementGen_ + startColumnGen_[i]);- }- if (columnLower) {- columnLowerGen_ = columnLower;- for (i = 0; i < numberColumns_; i++) {- if (columnLowerGen_[i]) {- printf("Non-zero lower bounds not allowed - subtract from model\n");- abort();- }- }- } else {- columnLowerGen_ = NULL;- }- if (columnUpper) {- columnUpperGen_ = columnUpper;- } else {- columnUpperGen_ = NULL;- }- // end specific coding- if (columnUpper_) {- // set all upper bounds so we have enough space- double * columnUpper = model->columnUpper();- for(i = firstDynamic_; i < lastDynamic_; i++)- columnUpper[i] = 1.0e10;- }- status_ = new unsigned char [2*numberSets_+4];- if (status) {- memcpy(status_,status, numberSets_ * sizeof(char));- assert (dynamicStatus);- CoinMemcpyN(dynamicStatus, numberIds, dynamicStatus_);- assert (numberIds);- } else {- assert (!numberIds);- memset(status_, 0, numberSets_);- for (i = 0; i < numberSets_; i++) {- // make slack key- setStatus(i, ClpSimplex::basic);- }- }- dynamicStatusGen_ = new unsigned char [numberColumns_];- memset(dynamicStatusGen_, 0, numberColumns_); // for clarity- for (i = 0; i < numberColumns_; i++)- setDynamicStatusGen(i, atLowerBound);- // Populate with enough columns- if (!numberIds) {- // This could be made more sophisticated- for (iSet = 0; iSet < numberSets_; iSet++) {- int sequence = fullStartGen_[iSet];- CoinBigIndex start = startColumnGen_[sequence];- addColumn(startColumnGen_[sequence+1] - start,- rowGen_ + start,- elementGen_ + start,- costGen_[sequence],- columnLowerGen_ ? columnLowerGen_[sequence] : 0,- columnUpperGen_ ? columnUpperGen_[sequence] : 1.0e30,- iSet, getDynamicStatusGen(sequence));- idGen_[iSet] = sequence; // say which one in- setDynamicStatusGen(sequence, inSmall);- }- } else {- // put back old ones- int * set = new int[numberColumns_];- for (iSet = 0; iSet < numberSets_; iSet++) {- for (CoinBigIndex j = fullStartGen_[iSet]; j < fullStartGen_[iSet+1]; j++)- set[j] = iSet;- }- for (int i = 0; i < numberIds; i++) {- int sequence = ids[i];- int iSet = set[sequence];- CoinBigIndex start = startColumnGen_[sequence];- addColumn(startColumnGen_[sequence+1] - start,- rowGen_ + start,- elementGen_ + start,- costGen_[sequence],- columnLowerGen_ ? columnLowerGen_[sequence] : 0,- columnUpperGen_ ? columnUpperGen_[sequence] : 1.0e30,- iSet, getDynamicStatus(i));- idGen_[i] = sequence; // say which one in- setDynamicStatusGen(sequence, inSmall);- }- delete [] set;- }- if (!status) {- gubCrash();- } else {- initialProblem();- }-}-#endif-//--------------------------------------------------------------------// Destructor-//--------------------------------------------------------------------ClpDynamicExampleMatrix::~ClpDynamicExampleMatrix ()-{- delete [] startColumnGen_;- delete [] rowGen_;- delete [] elementGen_;- delete [] costGen_;- delete [] fullStartGen_;- delete [] dynamicStatusGen_;- delete [] idGen_;- delete [] columnLowerGen_;- delete [] columnUpperGen_;-}--//-----------------------------------------------------------------// Assignment operator-//--------------------------------------------------------------------ClpDynamicExampleMatrix &-ClpDynamicExampleMatrix::operator=(const ClpDynamicExampleMatrix& rhs)-{- if (this != &rhs) {- ClpDynamicMatrix::operator=(rhs);- numberColumns_ = rhs.numberColumns_;- delete [] startColumnGen_;- delete [] rowGen_;- delete [] elementGen_;- delete [] costGen_;- delete [] fullStartGen_;- delete [] dynamicStatusGen_;- delete [] idGen_;- delete [] columnLowerGen_;- delete [] columnUpperGen_;- startColumnGen_ = ClpCopyOfArray(rhs.startColumnGen_, numberColumns_ + 1);- CoinBigIndex numberElements = startColumnGen_[numberColumns_];- rowGen_ = ClpCopyOfArray(rhs.rowGen_, numberElements);;- elementGen_ = ClpCopyOfArray(rhs.elementGen_, numberElements);;- costGen_ = ClpCopyOfArray(rhs.costGen_, numberColumns_);- fullStartGen_ = ClpCopyOfArray(rhs.fullStartGen_, numberSets_ + 1);- dynamicStatusGen_ = ClpCopyOfArray(rhs.dynamicStatusGen_, numberColumns_);- idGen_ = ClpCopyOfArray(rhs.idGen_, maximumGubColumns_);- columnLowerGen_ = ClpCopyOfArray(rhs.columnLowerGen_, numberColumns_);- columnUpperGen_ = ClpCopyOfArray(rhs.columnUpperGen_, numberColumns_);- }- return *this;-}-//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------ClpMatrixBase * ClpDynamicExampleMatrix::clone() const-{- return new ClpDynamicExampleMatrix(*this);-}-// Partial pricing-void-ClpDynamicExampleMatrix::partialPricing(ClpSimplex * model, double startFraction, double endFraction,- int & bestSequence, int & numberWanted)-{- numberWanted = currentWanted_;- assert(!model->rowScale());- if (!numberSets_) {- // no gub- ClpPackedMatrix::partialPricing(model, startFraction, endFraction, bestSequence, numberWanted);- } else {- // and do some proportion of full set- int startG2 = static_cast<int> (startFraction * numberSets_);- int endG2 = static_cast<int> (endFraction * numberSets_ + 0.1);- endG2 = CoinMin(endG2, numberSets_);- //printf("gub price - set start %d end %d\n",- // startG2,endG2);- double tolerance = model->currentDualTolerance();- double * reducedCost = model->djRegion();- const double * duals = model->dualRowSolution();- double bestDj;- int numberRows = model->numberRows();- int slackOffset = lastDynamic_ + numberRows;- int structuralOffset = slackOffset + numberSets_;- int structuralOffset2 = structuralOffset + maximumGubColumns_;- // If nothing found yet can go all the way to end- int endAll = endG2;- if (bestSequence < 0 && !startG2)- endAll = numberSets_;- if (bestSequence >= 0) {- if (bestSequence != savedBestSequence_)- bestDj = fabs(reducedCost[bestSequence]); // dj from slacks or permanent- else- bestDj = savedBestDj_;- } else {- bestDj = tolerance;- }- int saveSequence = bestSequence;- double djMod = 0.0;- double bestDjMod = 0.0;- //printf("iteration %d start %d end %d - wanted %d\n",model->numberIterations(),- // startG2,endG2,numberWanted);- int bestSet = -1;- int minSet = minimumObjectsScan_ < 0 ? 5 : minimumObjectsScan_;- int minNeg = minimumGoodReducedCosts_ < 0 ? 5 : minimumGoodReducedCosts_;- for (int iSet = startG2; iSet < endAll; iSet++) {- if (numberWanted + minNeg < originalWanted_ && iSet > startG2 + minSet) {- // give up- numberWanted = 0;- break;- } else if (iSet == endG2 && bestSequence >= 0) {- break;- }- int gubRow = toIndex_[iSet];- if (gubRow >= 0) {- djMod = duals[gubRow+numberStaticRows_]; // have I got sign right?- } else {- int iBasic = keyVariable_[iSet];- if (iBasic >= numberColumns_) {- djMod = 0.0; // set not in- } else {- // get dj without- djMod = 0.0;- for (CoinBigIndex j = startColumn_[iBasic];- j < startColumn_[iBasic+1]; j++) {- int jRow = row_[j];- djMod -= duals[jRow] * element_[j];- }- djMod += cost_[iBasic];- // See if gub slack possible - dj is djMod- if (getStatus(iSet) == ClpSimplex::atLowerBound) {- double value = -djMod;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flagged(iSet)) {- bestDj = value;- bestSequence = slackOffset + iSet;- bestDjMod = djMod;- bestSet = iSet;- } else {- // just to make sure we don't exit before got something- numberWanted++;- abort();- }- }- }- } else if (getStatus(iSet) == ClpSimplex::atUpperBound) {- double value = djMod;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flagged(iSet)) {- bestDj = value;- bestSequence = slackOffset + iSet;- bestDjMod = djMod;- bestSet = iSet;- } else {- // just to make sure we don't exit before got something- numberWanted++;- abort();- }- }- }- }- }- }- // do ones in small- int iSequence = startSet_[iSet];- while (iSequence >= 0) {- DynamicStatus status = getDynamicStatus(iSequence);- if (status == atLowerBound || status == atUpperBound) {- double value = cost_[iSequence] - djMod;- for (CoinBigIndex j = startColumn_[iSequence];- j < startColumn_[iSequence+1]; j++) {- int jRow = row_[j];- value -= duals[jRow] * element_[j];- }- // change sign if at lower bound- if (status == atLowerBound)- value = -value;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flagged(iSequence)) {- bestDj = value;- bestSequence = structuralOffset + iSequence;- bestDjMod = djMod;- bestSet = iSet;- } else {- // just to make sure we don't exit before got something- numberWanted++;- }- }- }- }- iSequence = next_[iSequence]; //onto next in set- }- // and now get best by column generation- // If no upper bounds we may not need status test- for (iSequence = fullStartGen_[iSet]; iSequence < fullStartGen_[iSet+1]; iSequence++) {- DynamicStatus status = getDynamicStatusGen(iSequence);- assert (status != atUpperBound && status != soloKey);- if (status == atLowerBound) {- double value = costGen_[iSequence] - djMod;- for (CoinBigIndex j = startColumnGen_[iSequence];- j < startColumnGen_[iSequence+1]; j++) {- int jRow = rowGen_[j];- value -= duals[jRow] * elementGen_[j];- }- // change sign as at lower bound- value = -value;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flaggedGen(iSequence)) {- bestDj = value;- bestSequence = structuralOffset2 + iSequence;- bestDjMod = djMod;- bestSet = iSet;- } else {- // just to make sure we don't exit before got something- numberWanted++;- }- }- }- }- }- if (numberWanted <= 0) {- numberWanted = 0;- break;- }- }- if (bestSequence != saveSequence) {- savedBestGubDual_ = bestDjMod;- savedBestDj_ = bestDj;- savedBestSequence_ = bestSequence;- savedBestSet_ = bestSet;- }- // Do packed part before gub- // always???- // Resize so just do to gub- numberActiveColumns_ = firstDynamic_;- int saveMinNeg = minimumGoodReducedCosts_;- if (bestSequence >= 0)- minimumGoodReducedCosts_ = -2;- currentWanted_ = numberWanted;- ClpPackedMatrix::partialPricing(model, startFraction, endFraction, bestSequence, numberWanted);- numberActiveColumns_ = matrix_->getNumCols();- minimumGoodReducedCosts_ = saveMinNeg;- // See if may be finished- if (!startG2 && bestSequence < 0)- infeasibilityWeight_ = model_->infeasibilityCost();- else if (bestSequence >= 0)- infeasibilityWeight_ = -1.0;- currentWanted_ = numberWanted;- }-}-/* Creates a variable. This is called after partial pricing and may modify matrix.- May update bestSequence.-*/-void-ClpDynamicExampleMatrix::createVariable(ClpSimplex * model, int & bestSequence)-{- int numberRows = model->numberRows();- int slackOffset = lastDynamic_ + numberRows;- int structuralOffset = slackOffset + numberSets_;- int bestSequence2 = savedBestSequence_ - structuralOffset;- if (bestSequence2 >= 0) {- // See if needs new- if (bestSequence2 >= maximumGubColumns_) {- bestSequence2 -= maximumGubColumns_;- int sequence = addColumn(startColumnGen_[bestSequence2+1] - startColumnGen_[bestSequence2],- rowGen_ + startColumnGen_[bestSequence2],- elementGen_ + startColumnGen_[bestSequence2],- costGen_[bestSequence2],- columnLowerGen_ ? columnLowerGen_[bestSequence2] : 0,- columnUpperGen_ ? columnUpperGen_[bestSequence2] : 1.0e30,- savedBestSet_, getDynamicStatusGen(bestSequence2));- savedBestSequence_ = structuralOffset + sequence;- idGen_[sequence] = bestSequence2;- setDynamicStatusGen(bestSequence2, inSmall);- }- }- ClpDynamicMatrix::createVariable(model, bestSequence/*, bestSequence2*/);- // clear for next iteration- savedBestSequence_ = -1;-}-/* If addColumn forces compression then this allows descendant to know what to do.- If >=0 then entry stayed in, if -1 then entry went out to lower bound.of zero.- Entries at upper bound (really nonzero) never go out (at present).-*/-void-ClpDynamicExampleMatrix::packDown(const int * in, int numberToPack)-{- int put = 0;- for (int i = 0; i < numberToPack; i++) {- int id = idGen_[i];- if (in[i] >= 0) {- // stays in- assert (put == in[i]); // true for now- idGen_[put++] = id;- } else {- // out to lower bound- setDynamicStatusGen(id, atLowerBound);- }- }- assert (put == numberGubColumns_);-}
− cbits/coin/ClpGubDynamicMatrix.cpp
@@ -1,2166 +0,0 @@-/* $Id: ClpGubDynamicMatrix.cpp 1732 2011-05-31 08:09:41Z forrest $ */-// Copyright (C) 2002, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).---#include <cstdio>--#include "CoinPragma.hpp"-#include "CoinIndexedVector.hpp"-#include "CoinHelperFunctions.hpp"--#include "ClpSimplex.hpp"-#include "ClpFactorization.hpp"-#include "ClpQuadraticObjective.hpp"-#include "ClpNonLinearCost.hpp"-// at end to get min/max!-#include "ClpGubDynamicMatrix.hpp"-#include "ClpMessage.hpp"-//#define CLP_DEBUG-//#define CLP_DEBUG_PRINT-//#############################################################################-// Constructors / Destructor / Assignment-//#############################################################################--//--------------------------------------------------------------------// Default Constructor-//--------------------------------------------------------------------ClpGubDynamicMatrix::ClpGubDynamicMatrix ()- : ClpGubMatrix(),- objectiveOffset_(0.0),- startColumn_(NULL),- row_(NULL),- element_(NULL),- cost_(NULL),- fullStart_(NULL),- id_(NULL),- dynamicStatus_(NULL),- lowerColumn_(NULL),- upperColumn_(NULL),- lowerSet_(NULL),- upperSet_(NULL),- numberGubColumns_(0),- firstAvailable_(0),- savedFirstAvailable_(0),- firstDynamic_(0),- lastDynamic_(0),- numberElements_(0)-{- setType(13);-}--//--------------------------------------------------------------------// Copy constructor-//--------------------------------------------------------------------ClpGubDynamicMatrix::ClpGubDynamicMatrix (const ClpGubDynamicMatrix & rhs)- : ClpGubMatrix(rhs)-{- objectiveOffset_ = rhs.objectiveOffset_;- numberGubColumns_ = rhs.numberGubColumns_;- firstAvailable_ = rhs.firstAvailable_;- savedFirstAvailable_ = rhs.savedFirstAvailable_;- firstDynamic_ = rhs.firstDynamic_;- lastDynamic_ = rhs.lastDynamic_;- numberElements_ = rhs.numberElements_;- startColumn_ = ClpCopyOfArray(rhs.startColumn_, numberGubColumns_ + 1);- CoinBigIndex numberElements = startColumn_[numberGubColumns_];- row_ = ClpCopyOfArray(rhs.row_, numberElements);;- element_ = ClpCopyOfArray(rhs.element_, numberElements);;- cost_ = ClpCopyOfArray(rhs.cost_, numberGubColumns_);- fullStart_ = ClpCopyOfArray(rhs.fullStart_, numberSets_ + 1);- id_ = ClpCopyOfArray(rhs.id_, lastDynamic_ - firstDynamic_);- lowerColumn_ = ClpCopyOfArray(rhs.lowerColumn_, numberGubColumns_);- upperColumn_ = ClpCopyOfArray(rhs.upperColumn_, numberGubColumns_);- dynamicStatus_ = ClpCopyOfArray(rhs.dynamicStatus_, numberGubColumns_);- lowerSet_ = ClpCopyOfArray(rhs.lowerSet_, numberSets_);- upperSet_ = ClpCopyOfArray(rhs.upperSet_, numberSets_);-}--/* This is the real constructor*/-ClpGubDynamicMatrix::ClpGubDynamicMatrix(ClpSimplex * model, int numberSets,- int numberGubColumns, const int * starts,- const double * lower, const double * upper,- const CoinBigIndex * startColumn, const int * row,- const double * element, const double * cost,- const double * lowerColumn, const double * upperColumn,- const unsigned char * status)- : ClpGubMatrix()-{- objectiveOffset_ = model->objectiveOffset();- model_ = model;- numberSets_ = numberSets;- numberGubColumns_ = numberGubColumns;- fullStart_ = ClpCopyOfArray(starts, numberSets_ + 1);- lower_ = ClpCopyOfArray(lower, numberSets_);- upper_ = ClpCopyOfArray(upper, numberSets_);- int numberColumns = model->numberColumns();- int numberRows = model->numberRows();- // Number of columns needed- int numberGubInSmall = numberSets_ + numberRows + 2 * model->factorizationFrequency() + 2;- // for small problems this could be too big- //numberGubInSmall = CoinMin(numberGubInSmall,numberGubColumns_);- int numberNeeded = numberGubInSmall + numberColumns;- firstAvailable_ = numberColumns;- savedFirstAvailable_ = numberColumns;- firstDynamic_ = numberColumns;- lastDynamic_ = numberNeeded;- startColumn_ = ClpCopyOfArray(startColumn, numberGubColumns_ + 1);- CoinBigIndex numberElements = startColumn_[numberGubColumns_];- row_ = ClpCopyOfArray(row, numberElements);- element_ = new double[numberElements];- CoinBigIndex i;- for (i = 0; i < numberElements; i++)- element_[i] = element[i];- cost_ = new double[numberGubColumns_];- for (i = 0; i < numberGubColumns_; i++) {- cost_[i] = cost[i];- // need sorted- CoinSort_2(row_ + startColumn_[i], row_ + startColumn_[i+1], element_ + startColumn_[i]);- }- if (lowerColumn) {- lowerColumn_ = new double[numberGubColumns_];- for (i = 0; i < numberGubColumns_; i++)- lowerColumn_[i] = lowerColumn[i];- } else {- lowerColumn_ = NULL;- }- if (upperColumn) {- upperColumn_ = new double[numberGubColumns_];- for (i = 0; i < numberGubColumns_; i++)- upperColumn_[i] = upperColumn[i];- } else {- upperColumn_ = NULL;- }- if (upperColumn || lowerColumn) {- lowerSet_ = new double[numberSets_];- for (i = 0; i < numberSets_; i++) {- if (lower[i] > -1.0e20)- lowerSet_[i] = lower[i];- else- lowerSet_[i] = -1.0e30;- }- upperSet_ = new double[numberSets_];- for (i = 0; i < numberSets_; i++) {- if (upper[i] < 1.0e20)- upperSet_[i] = upper[i];- else- upperSet_[i] = 1.0e30;- }- } else {- lowerSet_ = NULL;- upperSet_ = NULL;- }- start_ = NULL;- end_ = NULL;- dynamicStatus_ = NULL;- id_ = new int[numberGubInSmall];- for (i = 0; i < numberGubInSmall; i++)- id_[i] = -1;- ClpPackedMatrix* originalMatrixA =- dynamic_cast< ClpPackedMatrix*>(model->clpMatrix());- assert (originalMatrixA);- CoinPackedMatrix * originalMatrix = originalMatrixA->getPackedMatrix();- originalMatrixA->setMatrixNull(); // so can be deleted safely- // guess how much space needed- double guess = originalMatrix->getNumElements() + 10;- guess /= static_cast<double> (numberColumns);- guess *= 2 * numberGubColumns_;- numberElements_ = static_cast<int> (CoinMin(guess, 10000000.0));- numberElements_ = CoinMin(numberElements_, numberElements) + originalMatrix->getNumElements();- matrix_ = originalMatrix;- flags_ &= ~1;- // resize model (matrix stays same)- model->resize(numberRows, numberNeeded);- if (upperColumn_) {- // set all upper bounds so we have enough space- double * columnUpper = model->columnUpper();- for(i = firstDynamic_; i < lastDynamic_; i++)- columnUpper[i] = 1.0e10;- }- // resize matrix- // extra 1 is so can keep number of elements handy- originalMatrix->reserve(numberNeeded, numberElements_, true);- originalMatrix->reserve(numberNeeded + 1, numberElements_, false);- originalMatrix->getMutableVectorStarts()[numberColumns] = originalMatrix->getNumElements();- // redo number of columns- numberColumns = matrix_->getNumCols();- backward_ = new int[numberNeeded];- backToPivotRow_ = new int[numberNeeded];- // We know a bit better- delete [] changeCost_;- changeCost_ = new double [numberRows+numberSets_];- keyVariable_ = new int[numberSets_];- // signal to need new ordering- next_ = NULL;- for (int iColumn = 0; iColumn < numberNeeded; iColumn++)- backward_[iColumn] = -1;-- firstGub_ = firstDynamic_;- lastGub_ = lastDynamic_;- if (!lowerColumn_ && !upperColumn_)- gubType_ = 8;- if (status) {- status_ = ClpCopyOfArray(status, numberSets_);- } else {- status_ = new unsigned char [numberSets_];- memset(status_, 0, numberSets_);- int i;- for (i = 0; i < numberSets_; i++) {- // make slack key- setStatus(i, ClpSimplex::basic);- }- }- saveStatus_ = new unsigned char [numberSets_];- memset(saveStatus_, 0, numberSets_);- savedKeyVariable_ = new int [numberSets_];- memset(savedKeyVariable_, 0, numberSets_ * sizeof(int));-}--//--------------------------------------------------------------------// Destructor-//--------------------------------------------------------------------ClpGubDynamicMatrix::~ClpGubDynamicMatrix ()-{- delete [] startColumn_;- delete [] row_;- delete [] element_;- delete [] cost_;- delete [] fullStart_;- delete [] id_;- delete [] dynamicStatus_;- delete [] lowerColumn_;- delete [] upperColumn_;- delete [] lowerSet_;- delete [] upperSet_;-}--//-----------------------------------------------------------------// Assignment operator-//--------------------------------------------------------------------ClpGubDynamicMatrix &-ClpGubDynamicMatrix::operator=(const ClpGubDynamicMatrix& rhs)-{- if (this != &rhs) {- ClpGubMatrix::operator=(rhs);- delete [] startColumn_;- delete [] row_;- delete [] element_;- delete [] cost_;- delete [] fullStart_;- delete [] id_;- delete [] dynamicStatus_;- delete [] lowerColumn_;- delete [] upperColumn_;- delete [] lowerSet_;- delete [] upperSet_;- objectiveOffset_ = rhs.objectiveOffset_;- numberGubColumns_ = rhs.numberGubColumns_;- firstAvailable_ = rhs.firstAvailable_;- savedFirstAvailable_ = rhs.savedFirstAvailable_;- firstDynamic_ = rhs.firstDynamic_;- lastDynamic_ = rhs.lastDynamic_;- numberElements_ = rhs.numberElements_;- startColumn_ = ClpCopyOfArray(rhs.startColumn_, numberGubColumns_ + 1);- int numberElements = startColumn_[numberGubColumns_];- row_ = ClpCopyOfArray(rhs.row_, numberElements);;- element_ = ClpCopyOfArray(rhs.element_, numberElements);;- cost_ = ClpCopyOfArray(rhs.cost_, numberGubColumns_);- fullStart_ = ClpCopyOfArray(rhs.fullStart_, numberSets_ + 1);- id_ = ClpCopyOfArray(rhs.id_, lastDynamic_ - firstDynamic_);- lowerColumn_ = ClpCopyOfArray(rhs.lowerColumn_, numberGubColumns_);- upperColumn_ = ClpCopyOfArray(rhs.upperColumn_, numberGubColumns_);- dynamicStatus_ = ClpCopyOfArray(rhs.dynamicStatus_, numberGubColumns_);- lowerSet_ = ClpCopyOfArray(rhs.lowerSet_, numberSets_);- upperSet_ = ClpCopyOfArray(rhs.upperSet_, numberSets_);- }- return *this;-}-//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------ClpMatrixBase * ClpGubDynamicMatrix::clone() const-{- return new ClpGubDynamicMatrix(*this);-}-// Partial pricing-void-ClpGubDynamicMatrix::partialPricing(ClpSimplex * model, double startFraction, double endFraction,- int & bestSequence, int & numberWanted)-{- assert(!model->rowScale());- numberWanted = currentWanted_;- if (!numberSets_) {- // no gub- ClpPackedMatrix::partialPricing(model, startFraction, endFraction, bestSequence, numberWanted);- return;- } else {- // and do some proportion of full set- int startG2 = static_cast<int> (startFraction * numberSets_);- int endG2 = static_cast<int> (endFraction * numberSets_ + 0.1);- endG2 = CoinMin(endG2, numberSets_);- //printf("gub price - set start %d end %d\n",- // startG2,endG2);- double tolerance = model->currentDualTolerance();- double * reducedCost = model->djRegion();- const double * duals = model->dualRowSolution();- double * cost = model->costRegion();- double bestDj;- int numberRows = model->numberRows();- int numberColumns = lastDynamic_;- // If nothing found yet can go all the way to end- int endAll = endG2;- if (bestSequence < 0 && !startG2)- endAll = numberSets_;- if (bestSequence >= 0)- bestDj = fabs(reducedCost[bestSequence]);- else- bestDj = tolerance;- int saveSequence = bestSequence;- double djMod = 0.0;- double infeasibilityCost = model->infeasibilityCost();- double bestDjMod = 0.0;- //printf("iteration %d start %d end %d - wanted %d\n",model->numberIterations(),- // startG2,endG2,numberWanted);- int bestType = -1;- int bestSet = -1;- const double * element = matrix_->getElements();- const int * row = matrix_->getIndices();- const CoinBigIndex * startColumn = matrix_->getVectorStarts();- int * length = matrix_->getMutableVectorLengths();-#if 0- // make sure first available is clean (in case last iteration rejected)- cost[firstAvailable_] = 0.0;- length[firstAvailable_] = 0;- model->nonLinearCost()->setOne(firstAvailable_, 0.0, 0.0, COIN_DBL_MAX, 0.0);- model->setStatus(firstAvailable_, ClpSimplex::atLowerBound);- {- for (int i = firstAvailable_; i < lastDynamic_; i++)- assert(!cost[i]);- }-#endif-#ifdef CLP_DEBUG- {- for (int i = firstDynamic_; i < firstAvailable_; i++) {- assert (getDynamicStatus(id_[i-firstDynamic_]) == inSmall);- }- }-#endif- int minSet = minimumObjectsScan_ < 0 ? 5 : minimumObjectsScan_;- int minNeg = minimumGoodReducedCosts_ < 0 ? 5 : minimumGoodReducedCosts_;- for (int iSet = startG2; iSet < endAll; iSet++) {- if (numberWanted + minNeg < originalWanted_ && iSet > startG2 + minSet) {- // give up- numberWanted = 0;- break;- } else if (iSet == endG2 && bestSequence >= 0) {- break;- }- CoinBigIndex j;- int iBasic = keyVariable_[iSet];- if (iBasic >= numberColumns) {- djMod = - weight(iSet) * infeasibilityCost;- } else {- // get dj without- assert (model->getStatus(iBasic) == ClpSimplex::basic);- djMod = 0.0;-- for (j = startColumn[iBasic];- j < startColumn[iBasic] + length[iBasic]; j++) {- int jRow = row[j];- djMod -= duals[jRow] * element[j];- }- djMod += cost[iBasic];- // See if gub slack possible - dj is djMod- if (getStatus(iSet) == ClpSimplex::atLowerBound) {- double value = -djMod;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flagged(iSet)) {- bestDj = value;- bestSequence = numberRows + numberColumns + iSet;- bestDjMod = djMod;- bestType = 0;- bestSet = iSet;- } else {- // just to make sure we don't exit before got something- numberWanted++;- abort();- }- }- }- } else if (getStatus(iSet) == ClpSimplex::atUpperBound) {- double value = djMod;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flagged(iSet)) {- bestDj = value;- bestSequence = numberRows + numberColumns + iSet;- bestDjMod = djMod;- bestType = 0;- bestSet = iSet;- } else {- // just to make sure we don't exit before got something- numberWanted++;- abort();- }- }- }- }- }- for (int iSequence = fullStart_[iSet]; iSequence < fullStart_[iSet+1]; iSequence++) {- DynamicStatus status = getDynamicStatus(iSequence);- if (status != inSmall) {- double value = cost_[iSequence] - djMod;- for (j = startColumn_[iSequence];- j < startColumn_[iSequence+1]; j++) {- int jRow = row_[j];- value -= duals[jRow] * element_[j];- }- // change sign if at lower bound- if (status == atLowerBound)- value = -value;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flagged(iSequence)) {- bestDj = value;- bestSequence = iSequence;- bestDjMod = djMod;- bestType = 1;- bestSet = iSet;- } else {- // just to make sure we don't exit before got something- numberWanted++;- }- }- }- }- }- if (numberWanted <= 0) {- numberWanted = 0;- break;- }- }- // Do packed part before gub and small gub - but lightly- int saveMinNeg = minimumGoodReducedCosts_;- int saveSequence2 = bestSequence;- if (bestSequence >= 0)- minimumGoodReducedCosts_ = -2;- int saveLast = lastGub_;- lastGub_ = firstAvailable_;- currentWanted_ = numberWanted;- ClpGubMatrix::partialPricing(model, startFraction, endFraction, bestSequence, numberWanted);- minimumGoodReducedCosts_ = saveMinNeg;- lastGub_ = saveLast;- if (bestSequence != saveSequence2) {- bestType = -1; // in normal or small gub part- saveSequence = bestSequence;- }- if (bestSequence != saveSequence || bestType >= 0) {- double * lowerColumn = model->lowerRegion();- double * upperColumn = model->upperRegion();- double * solution = model->solutionRegion();- if (bestType > 0) {- // recompute dj and create- double value = cost_[bestSequence] - bestDjMod;- for (CoinBigIndex jBigIndex = startColumn_[bestSequence];- jBigIndex < startColumn_[bestSequence+1]; jBigIndex++) {- int jRow = row_[jBigIndex];- value -= duals[jRow] * element_[jBigIndex];- }- double * element = matrix_->getMutableElements();- int * row = matrix_->getMutableIndices();- CoinBigIndex * startColumn = matrix_->getMutableVectorStarts();- int * length = matrix_->getMutableVectorLengths();- CoinBigIndex numberElements = startColumn[firstAvailable_];- int numberThis = startColumn_[bestSequence+1] - startColumn_[bestSequence];- if (numberElements + numberThis > numberElements_) {- // need to redo- numberElements_ = CoinMax(3 * numberElements_ / 2, numberElements + numberThis);- matrix_->reserve(numberColumns, numberElements_);- element = matrix_->getMutableElements();- row = matrix_->getMutableIndices();- // these probably okay but be safe- startColumn = matrix_->getMutableVectorStarts();- length = matrix_->getMutableVectorLengths();- }- // already set startColumn[firstAvailable_]=numberElements;- length[firstAvailable_] = numberThis;- model->costRegion()[firstAvailable_] = cost_[bestSequence];- CoinBigIndex base = startColumn_[bestSequence];- for (int j = 0; j < numberThis; j++) {- row[numberElements] = row_[base+j];- element[numberElements++] = element_[base+j];- }- id_[firstAvailable_-firstDynamic_] = bestSequence;- //printf("best %d\n",bestSequence);- backward_[firstAvailable_] = bestSet;- model->solutionRegion()[firstAvailable_] = 0.0;- if (!lowerColumn_ && !upperColumn_) {- model->setStatus(firstAvailable_, ClpSimplex::atLowerBound);- lowerColumn[firstAvailable_] = 0.0;- upperColumn[firstAvailable_] = COIN_DBL_MAX;- } else {- DynamicStatus status = getDynamicStatus(bestSequence);- if (lowerColumn_)- lowerColumn[firstAvailable_] = lowerColumn_[bestSequence];- else- lowerColumn[firstAvailable_] = 0.0;- if (upperColumn_)- upperColumn[firstAvailable_] = upperColumn_[bestSequence];- else- upperColumn[firstAvailable_] = COIN_DBL_MAX;- if (status == atLowerBound) {- solution[firstAvailable_] = lowerColumn[firstAvailable_];- model->setStatus(firstAvailable_, ClpSimplex::atLowerBound);- } else {- solution[firstAvailable_] = upperColumn[firstAvailable_];- model->setStatus(firstAvailable_, ClpSimplex::atUpperBound);- }- }- model->nonLinearCost()->setOne(firstAvailable_, solution[firstAvailable_],- lowerColumn[firstAvailable_],- upperColumn[firstAvailable_], cost_[bestSequence]);- bestSequence = firstAvailable_;- // firstAvailable_ only updated if good pivot (in updatePivot)- startColumn[firstAvailable_+1] = numberElements;- //printf("price struct %d - dj %g gubpi %g\n",bestSequence,value,bestDjMod);- reducedCost[bestSequence] = value;- gubSlackIn_ = -1;- } else {- // slack - make last column- gubSlackIn_ = bestSequence - numberRows - numberColumns;- bestSequence = numberColumns + 2 * numberRows;- reducedCost[bestSequence] = bestDjMod;- //printf("price slack %d - gubpi %g\n",gubSlackIn_,bestDjMod);- model->setStatus(bestSequence, getStatus(gubSlackIn_));- if (getStatus(gubSlackIn_) == ClpSimplex::atUpperBound)- solution[bestSequence] = upper_[gubSlackIn_];- else- solution[bestSequence] = lower_[gubSlackIn_];- lowerColumn[bestSequence] = lower_[gubSlackIn_];- upperColumn[bestSequence] = upper_[gubSlackIn_];- model->costRegion()[bestSequence] = 0.0;- model->nonLinearCost()->setOne(bestSequence, solution[bestSequence], lowerColumn[bestSequence],- upperColumn[bestSequence], 0.0);- }- savedBestSequence_ = bestSequence;- savedBestDj_ = reducedCost[savedBestSequence_];- }- // See if may be finished- if (!startG2 && bestSequence < 0)- infeasibilityWeight_ = model_->infeasibilityCost();- else if (bestSequence >= 0)- infeasibilityWeight_ = -1.0;- }- currentWanted_ = numberWanted;-}-// This is local to Gub to allow synchronization when status is good-int-ClpGubDynamicMatrix::synchronize(ClpSimplex * model, int mode)-{- int returnNumber = 0;- switch (mode) {- case 0: {-#ifdef CLP_DEBUG- {- for (int i = 0; i < numberSets_; i++)- assert(toIndex_[i] == -1);- }-#endif- // lookup array- int * lookup = new int[lastDynamic_];- int iColumn;- int numberColumns = model->numberColumns();- double * element = matrix_->getMutableElements();- int * row = matrix_->getMutableIndices();- CoinBigIndex * startColumn = matrix_->getMutableVectorStarts();- int * length = matrix_->getMutableVectorLengths();- double * cost = model->costRegion();- double * lowerColumn = model->lowerRegion();- double * upperColumn = model->upperRegion();- int * pivotVariable = model->pivotVariable();- CoinBigIndex numberElements = startColumn[firstDynamic_];- // first just do lookup and basic stuff- int currentNumber = firstAvailable_;- firstAvailable_ = firstDynamic_;- int numberToDo = 0;- double objectiveChange = 0.0;- double * solution = model->solutionRegion();- for (iColumn = firstDynamic_; iColumn < currentNumber; iColumn++) {- int iSet = backward_[iColumn];- if (toIndex_[iSet] < 0) {- toIndex_[iSet] = 0;- fromIndex_[numberToDo++] = iSet;- }- if (model->getStatus(iColumn) == ClpSimplex::basic || iColumn == keyVariable_[iSet]) {- lookup[iColumn] = firstAvailable_;- if (iColumn != keyVariable_[iSet]) {- int iPivot = backToPivotRow_[iColumn];- backToPivotRow_[firstAvailable_] = iPivot;- pivotVariable[iPivot] = firstAvailable_;- }- firstAvailable_++;- } else {- int jColumn = id_[iColumn-firstDynamic_];- setDynamicStatus(jColumn, atLowerBound);- if (lowerColumn_ || upperColumn_) {- if (model->getStatus(iColumn) == ClpSimplex::atUpperBound)- setDynamicStatus(jColumn, atUpperBound);- // treat solution as if exactly at a bound- double value = solution[iColumn];- if (fabs(value - lowerColumn[iColumn]) < fabs(value - upperColumn[iColumn]))- value = lowerColumn[iColumn];- else- value = upperColumn[iColumn];- objectiveChange += cost[iColumn] * value;- // redo lower and upper on sets- double shift = value;- if (lowerSet_[iSet] > -1.0e20)- lower_[iSet] = lowerSet_[iSet] - shift;- if (upperSet_[iSet] < 1.0e20)- upper_[iSet] = upperSet_[iSet] - shift;- }- lookup[iColumn] = -1;- }- }- model->setObjectiveOffset(model->objectiveOffset() + objectiveChange);- firstAvailable_ = firstDynamic_;- for (iColumn = firstDynamic_; iColumn < currentNumber; iColumn++) {- if (lookup[iColumn] >= 0) {- // move- int jColumn = id_[iColumn-firstDynamic_];- id_[firstAvailable_-firstDynamic_] = jColumn;- int numberThis = startColumn_[jColumn+1] - startColumn_[jColumn];- length[firstAvailable_] = numberThis;- cost[firstAvailable_] = cost[iColumn];- lowerColumn[firstAvailable_] = lowerColumn[iColumn];- upperColumn[firstAvailable_] = upperColumn[iColumn];- double originalLower = lowerColumn_ ? lowerColumn_[jColumn] : 0.0;- double originalUpper = upperColumn_ ? upperColumn_[jColumn] : COIN_DBL_MAX;- if (originalUpper > 1.0e30)- originalUpper = COIN_DBL_MAX;- model->nonLinearCost()->setOne(firstAvailable_, solution[iColumn],- originalLower, originalUpper,- cost_[jColumn]);- CoinBigIndex base = startColumn_[jColumn];- for (int j = 0; j < numberThis; j++) {- row[numberElements] = row_[base+j];- element[numberElements++] = element_[base+j];- }- model->setStatus(firstAvailable_, model->getStatus(iColumn));- backward_[firstAvailable_] = backward_[iColumn];- solution[firstAvailable_] = solution[iColumn];- firstAvailable_++;- startColumn[firstAvailable_] = numberElements;- }- }- // clean up next_- int * temp = new int [firstAvailable_];- for (int jSet = 0; jSet < numberToDo; jSet++) {- int iSet = fromIndex_[jSet];- toIndex_[iSet] = -1;- int last = keyVariable_[iSet];- int j = next_[last];- bool setTemp = true;- if (last < lastDynamic_) {- last = lookup[last];- assert (last >= 0);- keyVariable_[iSet] = last;- } else if (j >= 0) {- int newJ = lookup[j];- assert (newJ >= 0);- j = next_[j];- next_[last] = newJ;- last = newJ;- } else {- next_[last] = -(iSet + numberColumns + 1);- setTemp = false;- }- while (j >= 0) {- int newJ = lookup[j];- assert (newJ >= 0);- temp[last] = newJ;- last = newJ;- j = next_[j];- }- if (setTemp)- temp[last] = -(keyVariable_[iSet] + 1);- if (lowerSet_) {- // we only need to get lower_ and upper_ correct- double shift = 0.0;- for (int j = fullStart_[iSet]; j < fullStart_[iSet+1]; j++)- if (getDynamicStatus(j) == atUpperBound)- shift += upperColumn_[j];- else if (getDynamicStatus(j) == atLowerBound && lowerColumn_)- shift += lowerColumn_[j];- if (lowerSet_[iSet] > -1.0e20)- lower_[iSet] = lowerSet_[iSet] - shift;- if (upperSet_[iSet] < 1.0e20)- upper_[iSet] = upperSet_[iSet] - shift;- }- }- // move to next_- CoinMemcpyN(temp + firstDynamic_, (firstAvailable_ - firstDynamic_), next_ + firstDynamic_);- // if odd iterations may be one out so adjust currentNumber- currentNumber = CoinMin(currentNumber + 1, lastDynamic_);- // zero solution- CoinZeroN(solution + firstAvailable_, currentNumber - firstAvailable_);- // zero cost- CoinZeroN(cost + firstAvailable_, currentNumber - firstAvailable_);- // zero lengths- CoinZeroN(length + firstAvailable_, currentNumber - firstAvailable_);- for ( iColumn = firstAvailable_; iColumn < currentNumber; iColumn++) {- model->nonLinearCost()->setOne(iColumn, 0.0, 0.0, COIN_DBL_MAX, 0.0);- model->setStatus(iColumn, ClpSimplex::atLowerBound);- backward_[iColumn] = -1;- }- delete [] lookup;- delete [] temp;- // make sure fromIndex clean- fromIndex_[0] = -1;- //#define CLP_DEBUG-#ifdef CLP_DEBUG- // debug- {- int i;- int numberRows = model->numberRows();- char * xxxx = new char[numberColumns];- memset(xxxx, 0, numberColumns);- for (i = 0; i < numberRows; i++) {- int iPivot = pivotVariable[i];- assert (model->getStatus(iPivot) == ClpSimplex::basic);- if (iPivot < numberColumns && backward_[iPivot] >= 0)- xxxx[iPivot] = 1;- }- for (i = 0; i < numberSets_; i++) {- int key = keyVariable_[i];- int iColumn = next_[key];- int k = 0;- while(iColumn >= 0) {- k++;- assert (k < 100);- assert (backward_[iColumn] == i);- iColumn = next_[iColumn];- }- int stop = -(key + 1);- while (iColumn != stop) {- assert (iColumn < 0);- iColumn = -iColumn - 1;- k++;- assert (k < 100);- assert (backward_[iColumn] == i);- iColumn = next_[iColumn];- }- iColumn = next_[key];- while (iColumn >= 0) {- assert (xxxx[iColumn]);- xxxx[iColumn] = 0;- iColumn = next_[iColumn];- }- }- for (i = 0; i < numberColumns; i++) {- if (i < numberColumns && backward_[i] >= 0) {- assert (!xxxx[i] || i == keyVariable_[backward_[i]]);- }- }- delete [] xxxx;- }- {- for (int i = 0; i < numberSets_; i++)- assert(toIndex_[i] == -1);- }-#endif- savedFirstAvailable_ = firstAvailable_;- }- break;- // flag a variable- case 1: {- // id will be sitting at firstAvailable- int sequence = id_[firstAvailable_-firstDynamic_];- assert (!flagged(sequence));- setFlagged(sequence);- model->clearFlagged(firstAvailable_);- }- break;- // unflag all variables- case 2: {- for (int i = 0; i < numberGubColumns_; i++) {- if (flagged(i)) {- unsetFlagged(i);- returnNumber++;- }- }- }- break;- // just reset costs and bounds (primal)- case 3: {- double * cost = model->costRegion();- double * solution = model->solutionRegion();- double * lowerColumn = model->columnLower();- double * upperColumn = model->columnUpper();- for (int i = firstDynamic_; i < firstAvailable_; i++) {- int jColumn = id_[i-firstDynamic_];- cost[i] = cost_[jColumn];- if (!lowerColumn_ && !upperColumn_) {- lowerColumn[i] = 0.0;- upperColumn[i] = COIN_DBL_MAX;- } else {- if (lowerColumn_)- lowerColumn[i] = lowerColumn_[jColumn];- else- lowerColumn[i] = 0.0;- if (upperColumn_)- upperColumn[i] = upperColumn_[jColumn];- else- upperColumn[i] = COIN_DBL_MAX;- }- if (model->nonLinearCost())- model->nonLinearCost()->setOne(i, solution[i],- lowerColumn[i],- upperColumn[i], cost_[jColumn]);- }- if (!model->numberIterations() && rhsOffset_) {- lastRefresh_ = - refreshFrequency_; // force refresh- }- }- break;- // and get statistics for column generation- case 4: {- // In theory we should subtract out ones we have done but ....- // If key slack then dual 0.0- // If not then slack could be dual infeasible- // dj for key is zero so that defines dual on set- int i;- int numberColumns = model->numberColumns();- double * dual = model->dualRowSolution();- double infeasibilityCost = model->infeasibilityCost();- double dualTolerance = model->dualTolerance();- double relaxedTolerance = dualTolerance;- // we can't really trust infeasibilities if there is dual error- double error = CoinMin(1.0e-2, model->largestDualError());- // allow tolerance at least slightly bigger than standard- relaxedTolerance = relaxedTolerance + error;- // but we will be using difference- relaxedTolerance -= dualTolerance;- double objectiveOffset = 0.0;- for (i = 0; i < numberSets_; i++) {- int kColumn = keyVariable_[i];- double value = 0.0;- if (kColumn < numberColumns) {- kColumn = id_[kColumn-firstDynamic_];- // dj without set- value = cost_[kColumn];- for (CoinBigIndex j = startColumn_[kColumn];- j < startColumn_[kColumn+1]; j++) {- int iRow = row_[j];- value -= dual[iRow] * element_[j];- }- double infeasibility = 0.0;- if (getStatus(i) == ClpSimplex::atLowerBound) {- if (-value > dualTolerance)- infeasibility = -value - dualTolerance;- } else if (getStatus(i) == ClpSimplex::atUpperBound) {- if (value > dualTolerance)- infeasibility = value - dualTolerance;- }- if (infeasibility > 0.0) {- sumDualInfeasibilities_ += infeasibility;- if (infeasibility > relaxedTolerance)- sumOfRelaxedDualInfeasibilities_ += infeasibility;- numberDualInfeasibilities_ ++;- }- } else {- // slack key - may not be feasible- assert (getStatus(i) == ClpSimplex::basic);- // negative as -1.0 for slack- value = -weight(i) * infeasibilityCost;- }- // Now subtract out from all- for (CoinBigIndex k = fullStart_[i]; k < fullStart_[i+1]; k++) {- if (getDynamicStatus(k) != inSmall) {- double djValue = cost_[k] - value;- for (CoinBigIndex j = startColumn_[k];- j < startColumn_[k+1]; j++) {- int iRow = row_[j];- djValue -= dual[iRow] * element_[j];- }- double infeasibility = 0.0;- double shift = 0.0;- if (getDynamicStatus(k) == atLowerBound) {- if (lowerColumn_)- shift = lowerColumn_[k];- if (djValue < -dualTolerance)- infeasibility = -djValue - dualTolerance;- } else {- // at upper bound- shift = upperColumn_[k];- if (djValue > dualTolerance)- infeasibility = djValue - dualTolerance;- }- objectiveOffset += shift * cost_[k];- if (infeasibility > 0.0) {- sumDualInfeasibilities_ += infeasibility;- if (infeasibility > relaxedTolerance)- sumOfRelaxedDualInfeasibilities_ += infeasibility;- numberDualInfeasibilities_ ++;- }- }- }- }- model->setObjectiveOffset(objectiveOffset_ - objectiveOffset);- }- break;- // see if time to re-factorize- case 5: {- if (firstAvailable_ > numberSets_ + model->numberRows() + model->factorizationFrequency())- returnNumber = 4;- }- break;- // return 1 if there may be changing bounds on variable (column generation)- case 6: {- returnNumber = (lowerColumn_ != NULL || upperColumn_ != NULL) ? 1 : 0;-#if 0- if (!returnNumber) {- // may be gub slacks- for (int i = 0; i < numberSets_; i++) {- if (upper_[i] > lower_[i]) {- returnNumber = 1;- break;- }- }- }-#endif- }- break;- // restore firstAvailable_- case 7: {- int iColumn;- int * length = matrix_->getMutableVectorLengths();- double * cost = model->costRegion();- double * solution = model->solutionRegion();- int currentNumber = firstAvailable_;- firstAvailable_ = savedFirstAvailable_;- // zero solution- CoinZeroN(solution + firstAvailable_, currentNumber - firstAvailable_);- // zero cost- CoinZeroN(cost + firstAvailable_, currentNumber - firstAvailable_);- // zero lengths- CoinZeroN(length + firstAvailable_, currentNumber - firstAvailable_);- for ( iColumn = firstAvailable_; iColumn < currentNumber; iColumn++) {- model->nonLinearCost()->setOne(iColumn, 0.0, 0.0, COIN_DBL_MAX, 0.0);- model->setStatus(iColumn, ClpSimplex::atLowerBound);- backward_[iColumn] = -1;- }- }- break;- // make sure set is clean- case 8: {- int sequenceIn = model->sequenceIn();- if (sequenceIn < model->numberColumns()) {- int iSet = backward_[sequenceIn];- if (iSet >= 0 && lowerSet_) {- // we only need to get lower_ and upper_ correct- double shift = 0.0;- for (int j = fullStart_[iSet]; j < fullStart_[iSet+1]; j++)- if (getDynamicStatus(j) == atUpperBound)- shift += upperColumn_[j];- else if (getDynamicStatus(j) == atLowerBound && lowerColumn_)- shift += lowerColumn_[j];- if (lowerSet_[iSet] > -1.0e20)- lower_[iSet] = lowerSet_[iSet] - shift;- if (upperSet_[iSet] < 1.0e20)- upper_[iSet] = upperSet_[iSet] - shift;- }- if (sequenceIn == firstAvailable_) {- // not really in small problem- int iBig = id_[sequenceIn-firstDynamic_];- if (model->getStatus(sequenceIn) == ClpSimplex::atLowerBound)- setDynamicStatus(iBig, atLowerBound);- else- setDynamicStatus(iBig, atUpperBound);- }- }- }- break;- // adjust lower,upper- case 9: {- int sequenceIn = model->sequenceIn();- if (sequenceIn >= firstDynamic_ && sequenceIn < lastDynamic_ && lowerSet_) {- int iSet = backward_[sequenceIn];- assert (iSet >= 0);- int inBig = id_[sequenceIn-firstDynamic_];- const double * solution = model->solutionRegion();- setDynamicStatus(inBig, inSmall);- if (lowerSet_[iSet] > -1.0e20)- lower_[iSet] += solution[sequenceIn];- if (upperSet_[iSet] < 1.0e20)- upper_[iSet] += solution[sequenceIn];- model->setObjectiveOffset(model->objectiveOffset() -- solution[sequenceIn]*cost_[inBig]);- }- }- }- return returnNumber;-}-// Add a new variable to a set-void-ClpGubDynamicMatrix::insertNonBasic(int sequence, int iSet)-{- int last = keyVariable_[iSet];- int j = next_[last];- while (j >= 0) {- last = j;- j = next_[j];- }- next_[last] = -(sequence + 1);- next_[sequence] = j;-}-// Sets up an effective RHS and does gub crash if needed-void-ClpGubDynamicMatrix::useEffectiveRhs(ClpSimplex * model, bool cheapest)-{- // Do basis - cheapest or slack if feasible (unless cheapest set)- int longestSet = 0;- int iSet;- for (iSet = 0; iSet < numberSets_; iSet++)- longestSet = CoinMax(longestSet, fullStart_[iSet+1] - fullStart_[iSet]);-- double * upper = new double[longestSet+1];- double * cost = new double[longestSet+1];- double * lower = new double[longestSet+1];- double * solution = new double[longestSet+1];- assert (!next_);- delete [] next_;- int numberColumns = model->numberColumns();- next_ = new int[numberColumns+numberSets_+CoinMax(2*longestSet, lastDynamic_-firstDynamic_)];- char * mark = new char[numberColumns];- memset(mark, 0, numberColumns);- for (int iColumn = 0; iColumn < numberColumns; iColumn++)- next_[iColumn] = COIN_INT_MAX;- int i;- int * keys = new int[numberSets_];- int * back = new int[numberGubColumns_];- CoinFillN(back, numberGubColumns_, -1);- for (i = 0; i < numberSets_; i++)- keys[i] = COIN_INT_MAX;- delete [] dynamicStatus_;- dynamicStatus_ = new unsigned char [numberGubColumns_];- memset(dynamicStatus_, 0, numberGubColumns_); // for clarity- for (i = 0; i < numberGubColumns_; i++)- setDynamicStatus(i, atLowerBound);- // set up chains- for (i = firstDynamic_; i < lastDynamic_; i++) {- if (id_[i-firstDynamic_] >= 0) {- if (model->getStatus(i) == ClpSimplex::basic)- mark[i] = 1;- int iSet = backward_[i];- assert (iSet >= 0);- int iNext = keys[iSet];- next_[i] = iNext;- keys[iSet] = i;- back[id_[i-firstDynamic_]] = i;- } else {- model->setStatus(i, ClpSimplex::atLowerBound);- backward_[i] = -1;- }- }- double * columnSolution = model->solutionRegion();- int numberRows = getNumRows();- toIndex_ = new int[numberSets_];- for (iSet = 0; iSet < numberSets_; iSet++)- toIndex_[iSet] = -1;- fromIndex_ = new int [numberRows+numberSets_];- double tolerance = model->primalTolerance();- double * element = matrix_->getMutableElements();- int * row = matrix_->getMutableIndices();- CoinBigIndex * startColumn = matrix_->getMutableVectorStarts();- int * length = matrix_->getMutableVectorLengths();- double objectiveOffset = 0.0;- for (iSet = 0; iSet < numberSets_; iSet++) {- int j;- int numberBasic = 0;- int iBasic = -1;- int iStart = fullStart_[iSet];- int iEnd = fullStart_[iSet+1];- // find one with smallest length- int smallest = numberRows + 1;- double value = 0.0;- j = keys[iSet];- while (j != COIN_INT_MAX) {- if (model->getStatus(j) == ClpSimplex::basic) {- if (length[j] < smallest) {- smallest = length[j];- iBasic = j;- }- numberBasic++;- }- value += columnSolution[j];- j = next_[j];- }- bool done = false;- if (numberBasic > 1 || (numberBasic == 1 && getStatus(iSet) == ClpSimplex::basic)) {- if (getStatus(iSet) == ClpSimplex::basic)- iBasic = iSet + numberColumns; // slack key - use- done = true;- } else if (numberBasic == 1) {- // see if can be key- double thisSolution = columnSolution[iBasic];- if (thisSolution < 0.0) {- value -= thisSolution;- thisSolution = 0.0;- columnSolution[iBasic] = thisSolution;- }- // try setting slack to a bound- assert (upper_[iSet] < 1.0e20 || lower_[iSet] > -1.0e20);- double cost1 = COIN_DBL_MAX;- int whichBound = -1;- if (upper_[iSet] < 1.0e20) {- // try slack at ub- double newBasic = thisSolution + upper_[iSet] - value;- if (newBasic >= -tolerance) {- // can go- whichBound = 1;- cost1 = newBasic * cost_[iBasic];- // But if exact then may be good solution- if (fabs(upper_[iSet] - value) < tolerance)- cost1 = -COIN_DBL_MAX;- }- }- if (lower_[iSet] > -1.0e20) {- // try slack at lb- double newBasic = thisSolution + lower_[iSet] - value;- if (newBasic >= -tolerance) {- // can go but is it cheaper- double cost2 = newBasic * cost_[iBasic];- // But if exact then may be good solution- if (fabs(lower_[iSet] - value) < tolerance)- cost2 = -COIN_DBL_MAX;- if (cost2 < cost1)- whichBound = 0;- }- }- if (whichBound != -1) {- // key- done = true;- if (whichBound) {- // slack to upper- columnSolution[iBasic] = thisSolution + upper_[iSet] - value;- setStatus(iSet, ClpSimplex::atUpperBound);- } else {- // slack to lower- columnSolution[iBasic] = thisSolution + lower_[iSet] - value;- setStatus(iSet, ClpSimplex::atLowerBound);- }- }- }- if (!done) {- if (!cheapest) {- // see if slack can be key- if (value >= lower_[iSet] - tolerance && value <= upper_[iSet] + tolerance) {- done = true;- setStatus(iSet, ClpSimplex::basic);- iBasic = iSet + numberColumns;- }- }- if (!done) {- // set non basic if there was one- if (iBasic >= 0)- model->setStatus(iBasic, ClpSimplex::atLowerBound);- // find cheapest- int numberInSet = iEnd - iStart;- if (!lowerColumn_) {- CoinZeroN(lower, numberInSet);- } else {- for (int j = 0; j < numberInSet; j++)- lower[j] = lowerColumn_[j+iStart];- }- if (!upperColumn_) {- CoinFillN(upper, numberInSet, COIN_DBL_MAX);- } else {- for (int j = 0; j < numberInSet; j++)- upper[j] = upperColumn_[j+iStart];- }- CoinFillN(solution, numberInSet, 0.0);- // and slack- iBasic = numberInSet;- solution[iBasic] = -value;- lower[iBasic] = -upper_[iSet];- upper[iBasic] = -lower_[iSet];- int kphase;- if (value >= lower_[iSet] - tolerance && value <= upper_[iSet] + tolerance) {- // feasible- kphase = 1;- cost[iBasic] = 0.0;- for (int j = 0; j < numberInSet; j++)- cost[j] = cost_[j+iStart];- } else {- // infeasible- kphase = 0;- // remember bounds are flipped so opposite to natural- if (value < lower_[iSet] - tolerance)- cost[iBasic] = 1.0;- else- cost[iBasic] = -1.0;- CoinZeroN(cost, numberInSet);- }- double dualTolerance = model->dualTolerance();- for (int iphase = kphase; iphase < 2; iphase++) {- if (iphase) {- cost[numberInSet] = 0.0;- for (int j = 0; j < numberInSet; j++)- cost[j] = cost_[j+iStart];- }- // now do one row lp- bool improve = true;- while (improve) {- improve = false;- double dual = cost[iBasic];- int chosen = -1;- double best = dualTolerance;- int way = 0;- for (int i = 0; i <= numberInSet; i++) {- double dj = cost[i] - dual;- double improvement = 0.0;- if (iphase || i < numberInSet)- assert (solution[i] >= lower[i] && solution[i] <= upper[i]);- if (dj > dualTolerance)- improvement = dj * (solution[i] - lower[i]);- else if (dj < -dualTolerance)- improvement = dj * (solution[i] - upper[i]);- if (improvement > best) {- best = improvement;- chosen = i;- if (dj < 0.0) {- way = 1;- } else {- way = -1;- }- }- }- if (chosen >= 0) {- improve = true;- // now see how far- if (way > 0) {- // incoming increasing so basic decreasing- // if phase 0 then go to nearest bound- double distance = upper[chosen] - solution[chosen];- double basicDistance;- if (!iphase) {- assert (iBasic == numberInSet);- assert (solution[iBasic] > upper[iBasic]);- basicDistance = solution[iBasic] - upper[iBasic];- } else {- basicDistance = solution[iBasic] - lower[iBasic];- }- // need extra coding for unbounded- assert (CoinMin(distance, basicDistance) < 1.0e20);- if (distance > basicDistance) {- // incoming becomes basic- solution[chosen] += basicDistance;- if (!iphase)- solution[iBasic] = upper[iBasic];- else- solution[iBasic] = lower[iBasic];- iBasic = chosen;- } else {- // flip- solution[chosen] = upper[chosen];- solution[iBasic] -= distance;- }- } else {- // incoming decreasing so basic increasing- // if phase 0 then go to nearest bound- double distance = solution[chosen] - lower[chosen];- double basicDistance;- if (!iphase) {- assert (iBasic == numberInSet);- assert (solution[iBasic] < lower[iBasic]);- basicDistance = lower[iBasic] - solution[iBasic];- } else {- basicDistance = upper[iBasic] - solution[iBasic];- }- // need extra coding for unbounded - for now just exit- if (CoinMin(distance, basicDistance) > 1.0e20) {- printf("unbounded on set %d\n", iSet);- iphase = 1;- iBasic = numberInSet;- break;- }- if (distance > basicDistance) {- // incoming becomes basic- solution[chosen] -= basicDistance;- if (!iphase)- solution[iBasic] = lower[iBasic];- else- solution[iBasic] = upper[iBasic];- iBasic = chosen;- } else {- // flip- solution[chosen] = lower[chosen];- solution[iBasic] += distance;- }- }- if (!iphase) {- if(iBasic < numberInSet)- break; // feasible- else if (solution[iBasic] >= lower[iBasic] &&- solution[iBasic] <= upper[iBasic])- break; // feasible (on flip)- }- }- }- }- // do solution i.e. bounds- if (lowerColumn_ || upperColumn_) {- for (int j = 0; j < numberInSet; j++) {- if (j != iBasic) {- objectiveOffset += solution[j] * cost[j];- if (lowerColumn_ && upperColumn_) {- if (fabs(solution[j] - lowerColumn_[j+iStart]) >- fabs(solution[j] - upperColumn_[j+iStart]))- setDynamicStatus(j + iStart, atUpperBound);- } else if (upperColumn_ && solution[j] > 0.0) {- setDynamicStatus(j + iStart, atUpperBound);- } else {- setDynamicStatus(j + iStart, atLowerBound);- }- }- }- }- // convert iBasic back and do bounds- if (iBasic == numberInSet) {- // slack basic- setStatus(iSet, ClpSimplex::basic);- iBasic = iSet + numberColumns;- } else {- iBasic += fullStart_[iSet];- if (back[iBasic] >= 0) {- // exists- iBasic = back[iBasic];- } else {- // create- CoinBigIndex numberElements = startColumn[firstAvailable_];- int numberThis = startColumn_[iBasic+1] - startColumn_[iBasic];- if (numberElements + numberThis > numberElements_) {- // need to redo- numberElements_ = CoinMax(3 * numberElements_ / 2, numberElements + numberThis);- matrix_->reserve(numberColumns, numberElements_);- element = matrix_->getMutableElements();- row = matrix_->getMutableIndices();- // these probably okay but be safe- startColumn = matrix_->getMutableVectorStarts();- length = matrix_->getMutableVectorLengths();- }- length[firstAvailable_] = numberThis;- model->costRegion()[firstAvailable_] = cost_[iBasic];- if (lowerColumn_)- model->lowerRegion()[firstAvailable_] = lowerColumn_[iBasic];- else- model->lowerRegion()[firstAvailable_] = 0.0;- if (upperColumn_)- model->upperRegion()[firstAvailable_] = upperColumn_[iBasic];- else- model->upperRegion()[firstAvailable_] = COIN_DBL_MAX;- columnSolution[firstAvailable_] = solution[iBasic-fullStart_[iSet]];- CoinBigIndex base = startColumn_[iBasic];- for (int j = 0; j < numberThis; j++) {- row[numberElements] = row_[base+j];- element[numberElements++] = element_[base+j];- }- // already set startColumn[firstAvailable_]=numberElements;- id_[firstAvailable_-firstDynamic_] = iBasic;- setDynamicStatus(iBasic, inSmall);- backward_[firstAvailable_] = iSet;- iBasic = firstAvailable_;- firstAvailable_++;- startColumn[firstAvailable_] = numberElements;- }- model->setStatus(iBasic, ClpSimplex::basic);- // remember bounds flipped- if (upper[numberInSet] == lower[numberInSet])- setStatus(iSet, ClpSimplex::isFixed);- else if (solution[numberInSet] == upper[numberInSet])- setStatus(iSet, ClpSimplex::atLowerBound);- else if (solution[numberInSet] == lower[numberInSet])- setStatus(iSet, ClpSimplex::atUpperBound);- else- abort();- }- for (j = iStart; j < iEnd; j++) {- int iBack = back[j];- if (iBack >= 0) {- if (model->getStatus(iBack) != ClpSimplex::basic) {- int inSet = j - iStart;- columnSolution[iBack] = solution[inSet];- if (upper[inSet] == lower[inSet])- model->setStatus(iBack, ClpSimplex::isFixed);- else if (solution[inSet] == upper[inSet])- model->setStatus(iBack, ClpSimplex::atUpperBound);- else if (solution[inSet] == lower[inSet])- model->setStatus(iBack, ClpSimplex::atLowerBound);- }- }- }- }- }- keyVariable_[iSet] = iBasic;- }- model->setObjectiveOffset(objectiveOffset_ - objectiveOffset);- delete [] lower;- delete [] solution;- delete [] upper;- delete [] cost;- // make sure matrix is in good shape- matrix_->orderMatrix();- // create effective rhs- delete [] rhsOffset_;- rhsOffset_ = new double[numberRows];- // and redo chains- memset(mark, 0, numberColumns);- for (int iColumnX = 0; iColumnX < firstAvailable_; iColumnX++)- next_[iColumnX] = COIN_INT_MAX;- for (i = 0; i < numberSets_; i++) {- keys[i] = COIN_INT_MAX;- int iKey = keyVariable_[i];- if (iKey < numberColumns)- model->setStatus(iKey, ClpSimplex::basic);- }- // set up chains- for (i = 0; i < firstAvailable_; i++) {- if (model->getStatus(i) == ClpSimplex::basic)- mark[i] = 1;- int iSet = backward_[i];- if (iSet >= 0) {- int iNext = keys[iSet];- next_[i] = iNext;- keys[iSet] = i;- }- }- for (i = 0; i < numberSets_; i++) {- if (keys[i] != COIN_INT_MAX) {- // something in set- int j;- if (getStatus(i) != ClpSimplex::basic) {- // make sure fixed if it is- if (upper_[i] == lower_[i])- setStatus(i, ClpSimplex::isFixed);- // slack not key - choose one with smallest length- int smallest = numberRows + 1;- int key = -1;- j = keys[i];- while (1) {- if (mark[j] && length[j] < smallest) {- key = j;- smallest = length[j];- }- if (next_[j] != COIN_INT_MAX) {- j = next_[j];- } else {- // correct end- next_[j] = -(keys[i] + 1);- break;- }- }- if (key >= 0) {- keyVariable_[i] = key;- } else {- // nothing basic - make slack key- //((ClpGubMatrix *)this)->setStatus(i,ClpSimplex::basic);- // fudge to avoid const problem- status_[i] = 1;- }- } else {- // slack key- keyVariable_[i] = numberColumns + i;- int j;- double sol = 0.0;- j = keys[i];- while (1) {- sol += columnSolution[j];- if (next_[j] != COIN_INT_MAX) {- j = next_[j];- } else {- // correct end- next_[j] = -(keys[i] + 1);- break;- }- }- if (sol > upper_[i] + tolerance) {- setAbove(i);- } else if (sol < lower_[i] - tolerance) {- setBelow(i);- } else {- setFeasible(i);- }- }- // Create next_- int key = keyVariable_[i];- redoSet(model, key, keys[i], i);- } else {- // nothing in set!- next_[i+numberColumns] = -(i + numberColumns + 1);- keyVariable_[i] = numberColumns + i;- double sol = 0.0;- if (sol > upper_[i] + tolerance) {- setAbove(i);- } else if (sol < lower_[i] - tolerance) {- setBelow(i);- } else {- setFeasible(i);- }- }- }- delete [] keys;- delete [] mark;- delete [] back;- rhsOffset(model, true);-}-/* Returns effective RHS if it is being used. This is used for long problems- or big gub or anywhere where going through full columns is- expensive. This may re-compute */-double *-ClpGubDynamicMatrix::rhsOffset(ClpSimplex * model, bool forceRefresh,- bool-#ifdef CLP_DEBUG- check-#endif- )-{- //forceRefresh=true;- //check=false;-#ifdef CLP_DEBUG- double * saveE = NULL;- if (rhsOffset_ && check) {- int numberRows = model->numberRows();- saveE = new double[numberRows];- }-#endif- if (rhsOffset_) {-#ifdef CLP_DEBUG- if (check) {- // no need - but check anyway- int numberRows = model->numberRows();- double * rhs = new double[numberRows];- int numberColumns = model->numberColumns();- int iRow;- CoinZeroN(rhs, numberRows);- // do ones at bounds before gub- const double * smallSolution = model->solutionRegion();- const double * element = matrix_->getElements();- const int * row = matrix_->getIndices();- const CoinBigIndex * startColumn = matrix_->getVectorStarts();- const int * length = matrix_->getVectorLengths();- int iColumn;- for (iColumn = 0; iColumn < firstDynamic_; iColumn++) {- if (model->getStatus(iColumn) != ClpSimplex::basic) {- double value = smallSolution[iColumn];- for (CoinBigIndex j = startColumn[iColumn];- j < startColumn[iColumn] + length[iColumn]; j++) {- int jRow = row[j];- rhs[jRow] -= value * element[j];- }- }- }- if (lowerColumn_ || upperColumn_) {- double * solution = new double [numberGubColumns_];- for (iColumn = 0; iColumn < numberGubColumns_; iColumn++) {- double value = 0.0;- if(getDynamicStatus(iColumn) == atUpperBound)- value = upperColumn_[iColumn];- else if (lowerColumn_)- value = lowerColumn_[iColumn];- solution[iColumn] = value;- }- // ones at bounds in small and gub- for (iColumn = firstDynamic_; iColumn < firstAvailable_; iColumn++) {- int jFull = id_[iColumn-firstDynamic_];- solution[jFull] = smallSolution[iColumn];- }- // zero all basic in small model- int * pivotVariable = model->pivotVariable();- for (iRow = 0; iRow < numberRows; iRow++) {- int iColumn = pivotVariable[iRow];- if (iColumn >= firstDynamic_ && iColumn < lastDynamic_) {- int iSequence = id_[iColumn-firstDynamic_];- solution[iSequence] = 0.0;- }- }- // and now compute value to use for key- ClpSimplex::Status iStatus;- for (int iSet = 0; iSet < numberSets_; iSet++) {- iColumn = keyVariable_[iSet];- if (iColumn < numberColumns) {- int iSequence = id_[iColumn-firstDynamic_];- solution[iSequence] = 0.0;- double b = 0.0;- // key is structural - where is slack- iStatus = getStatus(iSet);- assert (iStatus != ClpSimplex::basic);- if (iStatus == ClpSimplex::atLowerBound)- b = lowerSet_[iSet];- else- b = upperSet_[iSet];- // subtract out others at bounds- for (int j = fullStart_[iSet]; j < fullStart_[iSet+1]; j++)- b -= solution[j];- solution[iSequence] = b;- }- }- for (iColumn = 0; iColumn < numberGubColumns_; iColumn++) {- double value = solution[iColumn];- if (value) {- for (CoinBigIndex j = startColumn_[iColumn]; j < startColumn_[iColumn+1]; j++) {- int iRow = row_[j];- rhs[iRow] -= element_[j] * value;- }- }- }- // now do lower and upper bounds on sets- for (int iSet = 0; iSet < numberSets_; iSet++) {- iColumn = keyVariable_[iSet];- double shift = 0.0;- for (int j = fullStart_[iSet]; j < fullStart_[iSet+1]; j++) {- if (getDynamicStatus(j) != inSmall && j != iColumn) {- if (getDynamicStatus(j) == atLowerBound) {- if (lowerColumn_)- shift += lowerColumn_[j];- } else {- shift += upperColumn_[j];- }- }- }- if (lowerSet_[iSet] > -1.0e20)- assert(fabs(lower_[iSet] - (lowerSet_[iSet] - shift)) < 1.0e-3);- if (upperSet_[iSet] < 1.0e20)- assert(fabs(upper_[iSet] - ( upperSet_[iSet] - shift)) < 1.0e-3);- }- delete [] solution;- } else {- // no bounds- ClpSimplex::Status iStatus;- for (int iSet = 0; iSet < numberSets_; iSet++) {- int iColumn = keyVariable_[iSet];- if (iColumn < numberColumns) {- int iSequence = id_[iColumn-firstDynamic_];- double b = 0.0;- // key is structural - where is slack- iStatus = getStatus(iSet);- assert (iStatus != ClpSimplex::basic);- if (iStatus == ClpSimplex::atLowerBound)- b = lower_[iSet];- else- b = upper_[iSet];- if (b) {- for (CoinBigIndex j = startColumn_[iSequence]; j < startColumn_[iSequence+1]; j++) {- int iRow = row_[j];- rhs[iRow] -= element_[j] * b;- }- }- }- }- }- for (iRow = 0; iRow < numberRows; iRow++) {- if (fabs(rhs[iRow] - rhsOffset_[iRow]) > 1.0e-3)- printf("** bad effective %d - true %g old %g\n", iRow, rhs[iRow], rhsOffset_[iRow]);- }- CoinMemcpyN(rhs, numberRows, saveE);- delete [] rhs;- }-#endif- if (forceRefresh || (refreshFrequency_ && model->numberIterations() >=- lastRefresh_ + refreshFrequency_)) {- int numberRows = model->numberRows();- int numberColumns = model->numberColumns();- int iRow;- CoinZeroN(rhsOffset_, numberRows);- // do ones at bounds before gub- const double * smallSolution = model->solutionRegion();- const double * element = matrix_->getElements();- const int * row = matrix_->getIndices();- const CoinBigIndex * startColumn = matrix_->getVectorStarts();- const int * length = matrix_->getVectorLengths();- int iColumn;- for (iColumn = 0; iColumn < firstDynamic_; iColumn++) {- if (model->getStatus(iColumn) != ClpSimplex::basic) {- double value = smallSolution[iColumn];- for (CoinBigIndex j = startColumn[iColumn];- j < startColumn[iColumn] + length[iColumn]; j++) {- int jRow = row[j];- rhsOffset_[jRow] -= value * element[j];- }- }- }- if (lowerColumn_ || upperColumn_) {- double * solution = new double [numberGubColumns_];- for (iColumn = 0; iColumn < numberGubColumns_; iColumn++) {- double value = 0.0;- if(getDynamicStatus(iColumn) == atUpperBound)- value = upperColumn_[iColumn];- else if (lowerColumn_)- value = lowerColumn_[iColumn];- solution[iColumn] = value;- }- // ones in gub and in small problem- for (iColumn = firstDynamic_; iColumn < firstAvailable_; iColumn++) {- int jFull = id_[iColumn-firstDynamic_];- solution[jFull] = smallSolution[iColumn];- }- // zero all basic in small model- int * pivotVariable = model->pivotVariable();- for (iRow = 0; iRow < numberRows; iRow++) {- int iColumn = pivotVariable[iRow];- if (iColumn >= firstDynamic_ && iColumn < lastDynamic_) {- int iSequence = id_[iColumn-firstDynamic_];- solution[iSequence] = 0.0;- }- }- // and now compute value to use for key- ClpSimplex::Status iStatus;- int iSet;- for ( iSet = 0; iSet < numberSets_; iSet++) {- iColumn = keyVariable_[iSet];- if (iColumn < numberColumns) {- int iSequence = id_[iColumn-firstDynamic_];- solution[iSequence] = 0.0;- double b = 0.0;- // key is structural - where is slack- iStatus = getStatus(iSet);- assert (iStatus != ClpSimplex::basic);- if (iStatus == ClpSimplex::atLowerBound)- b = lowerSet_[iSet];- else- b = upperSet_[iSet];- // subtract out others at bounds- for (int j = fullStart_[iSet]; j < fullStart_[iSet+1]; j++)- b -= solution[j];- solution[iSequence] = b;- }- }- for (iColumn = 0; iColumn < numberGubColumns_; iColumn++) {- double value = solution[iColumn];- if (value) {- for (CoinBigIndex j = startColumn_[iColumn]; j < startColumn_[iColumn+1]; j++) {- int iRow = row_[j];- rhsOffset_[iRow] -= element_[j] * value;- }- }- }- // now do lower and upper bounds on sets- // and offset- double objectiveOffset = 0.0;- for ( iSet = 0; iSet < numberSets_; iSet++) {- iColumn = keyVariable_[iSet];- double shift = 0.0;- for (CoinBigIndex j = fullStart_[iSet]; j < fullStart_[iSet+1]; j++) {- if (getDynamicStatus(j) != inSmall) {- double value = 0.0;- if (getDynamicStatus(j) == atLowerBound) {- if (lowerColumn_)- value = lowerColumn_[j];- } else {- value = upperColumn_[j];- }- if (j != iColumn)- shift += value;- objectiveOffset += value * cost_[j];- }- }- if (lowerSet_[iSet] > -1.0e20)- lower_[iSet] = lowerSet_[iSet] - shift;- if (upperSet_[iSet] < 1.0e20)- upper_[iSet] = upperSet_[iSet] - shift;- }- delete [] solution;- model->setObjectiveOffset(objectiveOffset_ - objectiveOffset);- } else {- // no bounds- ClpSimplex::Status iStatus;- for (int iSet = 0; iSet < numberSets_; iSet++) {- int iColumn = keyVariable_[iSet];- if (iColumn < numberColumns) {- int iSequence = id_[iColumn-firstDynamic_];- double b = 0.0;- // key is structural - where is slack- iStatus = getStatus(iSet);- assert (iStatus != ClpSimplex::basic);- if (iStatus == ClpSimplex::atLowerBound)- b = lower_[iSet];- else- b = upper_[iSet];- if (b) {- for (CoinBigIndex j = startColumn_[iSequence]; j < startColumn_[iSequence+1]; j++) {- int iRow = row_[j];- rhsOffset_[iRow] -= element_[j] * b;- }- }- }- }- }-#ifdef CLP_DEBUG- if (saveE) {- for (iRow = 0; iRow < numberRows; iRow++) {- if (fabs(saveE[iRow] - rhsOffset_[iRow]) > 1.0e-3)- printf("** %d - old eff %g new %g\n", iRow, saveE[iRow], rhsOffset_[iRow]);- }- delete [] saveE;- }-#endif- lastRefresh_ = model->numberIterations();- }- }- return rhsOffset_;-}-/*- update information for a pivot (and effective rhs)-*/-int-ClpGubDynamicMatrix::updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue)-{-- // now update working model- int sequenceIn = model->sequenceIn();- int sequenceOut = model->sequenceOut();- bool doPrinting = (model->messageHandler()->logLevel() == 63);- bool print = false;- int iSet;- int trueIn = -1;- int trueOut = -1;- int numberRows = model->numberRows();- int numberColumns = model->numberColumns();- if (sequenceIn == firstAvailable_) {- if (doPrinting)- printf("New variable ");- if (sequenceIn != sequenceOut) {- insertNonBasic(firstAvailable_, backward_[firstAvailable_]);- setDynamicStatus(id_[sequenceIn-firstDynamic_], inSmall);- firstAvailable_++;- } else {- int bigSequence = id_[sequenceIn-firstDynamic_];- if (model->getStatus(sequenceIn) == ClpSimplex::atUpperBound)- setDynamicStatus(bigSequence, atUpperBound);- else- setDynamicStatus(bigSequence, atLowerBound);- }- synchronize(model, 8);- }- if (sequenceIn < lastDynamic_) {- iSet = backward_[sequenceIn];- if (iSet >= 0) {- int bigSequence = id_[sequenceIn-firstDynamic_];- trueIn = bigSequence + numberRows + numberColumns + numberSets_;- if (doPrinting)- printf(" incoming set %d big seq %d", iSet, bigSequence);- print = true;- }- } else if (sequenceIn >= numberRows + numberColumns) {- trueIn = numberRows + numberColumns + gubSlackIn_;- }- if (sequenceOut < lastDynamic_) {- iSet = backward_[sequenceOut];- if (iSet >= 0) {- int bigSequence = id_[sequenceOut-firstDynamic_];- trueOut = bigSequence + firstDynamic_;- if (getDynamicStatus(bigSequence) != inSmall) {- if (model->getStatus(sequenceOut) == ClpSimplex::atUpperBound)- setDynamicStatus(bigSequence, atUpperBound);- else- setDynamicStatus(bigSequence, atLowerBound);- }- if (doPrinting)- printf(" ,outgoing set %d big seq %d,", iSet, bigSequence);- print = true;- model->setSequenceIn(sequenceOut);- synchronize(model, 8);- model->setSequenceIn(sequenceIn);- }- }- if (print && doPrinting)- printf("\n");- ClpGubMatrix::updatePivot(model, oldInValue, oldOutValue);- // Redo true in and out- if (trueIn >= 0)- trueSequenceIn_ = trueIn;- if (trueOut >= 0)- trueSequenceOut_ = trueOut;- if (doPrinting && 0) {- for (int i = 0; i < numberSets_; i++) {- printf("set %d key %d lower %g upper %g\n", i, keyVariable_[i], lower_[i], upper_[i]);- for (int j = fullStart_[i]; j < fullStart_[i+1]; j++)- if (getDynamicStatus(j) == atUpperBound) {- bool print = true;- for (int k = firstDynamic_; k < firstAvailable_; k++) {- if (id_[k-firstDynamic_] == j)- print = false;- if (id_[k-firstDynamic_] == j)- assert(getDynamicStatus(j) == inSmall);- }- if (print)- printf("variable %d at ub\n", j);- }- }- }-#ifdef CLP_DEBUG- char * inSmall = new char [numberGubColumns_];- memset(inSmall, 0, numberGubColumns_);- for (int i = 0; i < numberGubColumns_; i++)- if (getDynamicStatus(i) == ClpGubDynamicMatrix::inSmall)- inSmall[i] = 1;- for (int i = firstDynamic_; i < firstAvailable_; i++) {- int k = id_[i-firstDynamic_];- inSmall[k] = 0;- }- for (int i = 0; i < numberGubColumns_; i++)- assert (!inSmall[i]);- delete [] inSmall;-#endif- return 0;-}-void-ClpGubDynamicMatrix::times(double scalar,- const double * x, double * y) const-{- if (model_->specialOptions() != 16) {- ClpPackedMatrix::times(scalar, x, y);- } else {- int iRow;- int numberColumns = model_->numberColumns();- int numberRows = model_->numberRows();- const double * element = matrix_->getElements();- const int * row = matrix_->getIndices();- const CoinBigIndex * startColumn = matrix_->getVectorStarts();- const int * length = matrix_->getVectorLengths();- int * pivotVariable = model_->pivotVariable();- int numberToDo = 0;- for (iRow = 0; iRow < numberRows; iRow++) {- y[iRow] -= scalar * rhsOffset_[iRow];- int iColumn = pivotVariable[iRow];- if (iColumn < numberColumns) {- int iSet = backward_[iColumn];- if (iSet >= 0 && toIndex_[iSet] < 0) {- toIndex_[iSet] = 0;- fromIndex_[numberToDo++] = iSet;- }- CoinBigIndex j;- double value = scalar * x[iColumn];- if (value) {- for (j = startColumn[iColumn];- j < startColumn[iColumn] + length[iColumn]; j++) {- int jRow = row[j];- y[jRow] += value * element[j];- }- }- }- }- // and gubs which are interacting- for (int jSet = 0; jSet < numberToDo; jSet++) {- int iSet = fromIndex_[jSet];- toIndex_[iSet] = -1;- int iKey = keyVariable_[iSet];- if (iKey < numberColumns) {- double valueKey;- if (getStatus(iSet) == ClpSimplex::atLowerBound)- valueKey = lower_[iSet];- else- valueKey = upper_[iSet];- double value = scalar * (x[iKey] - valueKey);- if (value) {- for (CoinBigIndex j = startColumn[iKey];- j < startColumn[iKey] + length[iKey]; j++) {- int jRow = row[j];- y[jRow] += value * element[j];- }- }- }- }- }-}-/* Just for debug - may be extended to other matrix types later.- Returns number and sum of primal infeasibilities.-*/-int-ClpGubDynamicMatrix::checkFeasible(ClpSimplex * /*model*/, double & sum) const-{- int numberRows = model_->numberRows();- double * rhs = new double[numberRows];- int numberColumns = model_->numberColumns();- int iRow;- CoinZeroN(rhs, numberRows);- // do ones at bounds before gub- const double * smallSolution = model_->solutionRegion();- const double * element = matrix_->getElements();- const int * row = matrix_->getIndices();- const CoinBigIndex * startColumn = matrix_->getVectorStarts();- const int * length = matrix_->getVectorLengths();- int iColumn;- int numberInfeasible = 0;- const double * rowLower = model_->rowLower();- const double * rowUpper = model_->rowUpper();- sum = 0.0;- for (iRow = 0; iRow < numberRows; iRow++) {- double value = smallSolution[numberColumns+iRow];- if (value < rowLower[iRow] - 1.0e-5 ||- value > rowUpper[iRow] + 1.0e-5) {- //printf("row %d %g %g %g\n",- // iRow,rowLower[iRow],value,rowUpper[iRow]);- numberInfeasible++;- sum += CoinMax(rowLower[iRow] - value, value - rowUpper[iRow]);- }- rhs[iRow] = value;- }- const double * columnLower = model_->columnLower();- const double * columnUpper = model_->columnUpper();- for (iColumn = 0; iColumn < firstDynamic_; iColumn++) {- double value = smallSolution[iColumn];- if (value < columnLower[iColumn] - 1.0e-5 ||- value > columnUpper[iColumn] + 1.0e-5) {- //printf("column %d %g %g %g\n",- // iColumn,columnLower[iColumn],value,columnUpper[iColumn]);- numberInfeasible++;- sum += CoinMax(columnLower[iColumn] - value, value - columnUpper[iColumn]);- }- for (CoinBigIndex j = startColumn[iColumn];- j < startColumn[iColumn] + length[iColumn]; j++) {- int jRow = row[j];- rhs[jRow] -= value * element[j];- }- }- double * solution = new double [numberGubColumns_];- for (iColumn = 0; iColumn < numberGubColumns_; iColumn++) {- double value = 0.0;- if(getDynamicStatus(iColumn) == atUpperBound)- value = upperColumn_[iColumn];- else if (lowerColumn_)- value = lowerColumn_[iColumn];- solution[iColumn] = value;- }- // ones in small and gub- for (iColumn = firstDynamic_; iColumn < firstAvailable_; iColumn++) {- int jFull = id_[iColumn-firstDynamic_];- solution[jFull] = smallSolution[iColumn];- }- // fill in all basic in small model- int * pivotVariable = model_->pivotVariable();- for (iRow = 0; iRow < numberRows; iRow++) {- int iColumn = pivotVariable[iRow];- if (iColumn >= firstDynamic_ && iColumn < lastDynamic_) {- int iSequence = id_[iColumn-firstDynamic_];- solution[iSequence] = smallSolution[iColumn];- }- }- // and now compute value to use for key- ClpSimplex::Status iStatus;- for (int iSet = 0; iSet < numberSets_; iSet++) {- iColumn = keyVariable_[iSet];- if (iColumn < numberColumns) {- int iSequence = id_[iColumn-firstDynamic_];- solution[iSequence] = 0.0;- double b = 0.0;- // key is structural - where is slack- iStatus = getStatus(iSet);- assert (iStatus != ClpSimplex::basic);- if (iStatus == ClpSimplex::atLowerBound)- b = lower_[iSet];- else- b = upper_[iSet];- // subtract out others at bounds- for (int j = fullStart_[iSet]; j < fullStart_[iSet+1]; j++)- b -= solution[j];- solution[iSequence] = b;- }- }- for (iColumn = 0; iColumn < numberGubColumns_; iColumn++) {- double value = solution[iColumn];- if ((lowerColumn_ && value < lowerColumn_[iColumn] - 1.0e-5) ||- (!lowerColumn_ && value < -1.0e-5) ||- (upperColumn_ && value > upperColumn_[iColumn] + 1.0e-5)) {- //printf("column %d %g %g %g\n",- // iColumn,lowerColumn_[iColumn],value,upperColumn_[iColumn]);- numberInfeasible++;- }- if (value) {- for (CoinBigIndex j = startColumn_[iColumn]; j < startColumn_[iColumn+1]; j++) {- int iRow = row_[j];- rhs[iRow] -= element_[j] * value;- }- }- }- for (iRow = 0; iRow < numberRows; iRow++) {- if (fabs(rhs[iRow]) > 1.0e-5)- printf("rhs mismatch %d %g\n", iRow, rhs[iRow]);- }- delete [] solution;- delete [] rhs;- return numberInfeasible;-}-// Cleans data after setWarmStart-void-ClpGubDynamicMatrix::cleanData(ClpSimplex * model)-{- // and redo chains- int numberColumns = model->numberColumns();- int iColumn;- // do backward- int * mark = new int [numberGubColumns_];- for (iColumn = 0; iColumn < numberGubColumns_; iColumn++)- mark[iColumn] = -1;- int i;- for (i = 0; i < firstDynamic_; i++) {- assert (backward_[i] == -1);- next_[i] = -1;- }- for (i = firstDynamic_; i < firstAvailable_; i++) {- iColumn = id_[i-firstDynamic_];- mark[iColumn] = i;- }- for (i = 0; i < numberSets_; i++) {- int iKey = keyVariable_[i];- int lastNext = -1;- int firstNext = -1;- for (CoinBigIndex k = fullStart_[i]; k < fullStart_[i+1]; k++) {- iColumn = mark[k];- if (iColumn >= 0) {- if (iColumn != iKey) {- if (lastNext >= 0)- next_[lastNext] = iColumn;- else- firstNext = iColumn;- lastNext = iColumn;- }- backward_[iColumn] = i;- }- }- setFeasible(i);- if (firstNext >= 0) {- // others- next_[iKey] = firstNext;- next_[lastNext] = -(iKey + 1);- } else if (iKey < numberColumns) {- next_[iKey] = -(iKey + 1);- }- }- delete [] mark;- // fill matrix- double * element = matrix_->getMutableElements();- int * row = matrix_->getMutableIndices();- CoinBigIndex * startColumn = matrix_->getMutableVectorStarts();- int * length = matrix_->getMutableVectorLengths();- CoinBigIndex numberElements = startColumn[firstDynamic_];- for (i = firstDynamic_; i < firstAvailable_; i++) {- int iColumn = id_[i-firstDynamic_];- int numberThis = startColumn_[iColumn+1] - startColumn_[iColumn];- length[i] = numberThis;- for (CoinBigIndex jBigIndex = startColumn_[iColumn];- jBigIndex < startColumn_[iColumn+1]; jBigIndex++) {- row[numberElements] = row_[jBigIndex];- element[numberElements++] = element_[jBigIndex];- }- startColumn[i+1] = numberElements;- }-}
− cbits/coin/ClpGubMatrix.cpp
@@ -1,4061 +0,0 @@-/* $Id: ClpGubMatrix.cpp 1931 2013-04-06 20:44:29Z stefan $ */-// Copyright (C) 2002, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).---#include <cstdio>--#include "CoinPragma.hpp"-#include "CoinIndexedVector.hpp"-#include "CoinHelperFunctions.hpp"--#include "ClpSimplex.hpp"-#include "ClpFactorization.hpp"-#include "ClpQuadraticObjective.hpp"-#include "ClpNonLinearCost.hpp"-// at end to get min/max!-#include "ClpGubMatrix.hpp"-//#include "ClpGubDynamicMatrix.hpp"-#include "ClpMessage.hpp"-//#define CLP_DEBUG-//#define CLP_DEBUG_PRINT-//#############################################################################-// Constructors / Destructor / Assignment-//#############################################################################--//--------------------------------------------------------------------// Default Constructor-//--------------------------------------------------------------------ClpGubMatrix::ClpGubMatrix ()- : ClpPackedMatrix(),- sumDualInfeasibilities_(0.0),- sumPrimalInfeasibilities_(0.0),- sumOfRelaxedDualInfeasibilities_(0.0),- sumOfRelaxedPrimalInfeasibilities_(0.0),- infeasibilityWeight_(0.0),- start_(NULL),- end_(NULL),- lower_(NULL),- upper_(NULL),- status_(NULL),- saveStatus_(NULL),- savedKeyVariable_(NULL),- backward_(NULL),- backToPivotRow_(NULL),- changeCost_(NULL),- keyVariable_(NULL),- next_(NULL),- toIndex_(NULL),- fromIndex_(NULL),- model_(NULL),- numberDualInfeasibilities_(0),- numberPrimalInfeasibilities_(0),- noCheck_(-1),- numberSets_(0),- saveNumber_(0),- possiblePivotKey_(0),- gubSlackIn_(-1),- firstGub_(0),- lastGub_(0),- gubType_(0)-{- setType(16);-}--//--------------------------------------------------------------------// Copy constructor-//--------------------------------------------------------------------ClpGubMatrix::ClpGubMatrix (const ClpGubMatrix & rhs)- : ClpPackedMatrix(rhs)-{- numberSets_ = rhs.numberSets_;- saveNumber_ = rhs.saveNumber_;- possiblePivotKey_ = rhs.possiblePivotKey_;- gubSlackIn_ = rhs.gubSlackIn_;- start_ = ClpCopyOfArray(rhs.start_, numberSets_);- end_ = ClpCopyOfArray(rhs.end_, numberSets_);- lower_ = ClpCopyOfArray(rhs.lower_, numberSets_);- upper_ = ClpCopyOfArray(rhs.upper_, numberSets_);- status_ = ClpCopyOfArray(rhs.status_, numberSets_);- saveStatus_ = ClpCopyOfArray(rhs.saveStatus_, numberSets_);- savedKeyVariable_ = ClpCopyOfArray(rhs.savedKeyVariable_, numberSets_);- int numberColumns = getNumCols();- backward_ = ClpCopyOfArray(rhs.backward_, numberColumns);- backToPivotRow_ = ClpCopyOfArray(rhs.backToPivotRow_, numberColumns);- changeCost_ = ClpCopyOfArray(rhs.changeCost_, getNumRows() + numberSets_);- fromIndex_ = ClpCopyOfArray(rhs.fromIndex_, getNumRows() + numberSets_ + 1);- keyVariable_ = ClpCopyOfArray(rhs.keyVariable_, numberSets_);- // find longest set- int * longest = new int[numberSets_];- CoinZeroN(longest, numberSets_);- int j;- for (j = 0; j < numberColumns; j++) {- int iSet = backward_[j];- if (iSet >= 0)- longest[iSet]++;- }- int length = 0;- for (j = 0; j < numberSets_; j++)- length = CoinMax(length, longest[j]);- next_ = ClpCopyOfArray(rhs.next_, numberColumns + numberSets_ + 2 * length);- toIndex_ = ClpCopyOfArray(rhs.toIndex_, numberSets_);- sumDualInfeasibilities_ = rhs. sumDualInfeasibilities_;- sumPrimalInfeasibilities_ = rhs.sumPrimalInfeasibilities_;- sumOfRelaxedDualInfeasibilities_ = rhs.sumOfRelaxedDualInfeasibilities_;- sumOfRelaxedPrimalInfeasibilities_ = rhs.sumOfRelaxedPrimalInfeasibilities_;- infeasibilityWeight_ = rhs.infeasibilityWeight_;- numberDualInfeasibilities_ = rhs.numberDualInfeasibilities_;- numberPrimalInfeasibilities_ = rhs.numberPrimalInfeasibilities_;- noCheck_ = rhs.noCheck_;- firstGub_ = rhs.firstGub_;- lastGub_ = rhs.lastGub_;- gubType_ = rhs.gubType_;- model_ = rhs.model_;-}--//--------------------------------------------------------------------// assign matrix (for space reasons)-//--------------------------------------------------------------------ClpGubMatrix::ClpGubMatrix (CoinPackedMatrix * rhs)- : ClpPackedMatrix(rhs),- sumDualInfeasibilities_(0.0),- sumPrimalInfeasibilities_(0.0),- sumOfRelaxedDualInfeasibilities_(0.0),- sumOfRelaxedPrimalInfeasibilities_(0.0),- infeasibilityWeight_(0.0),- start_(NULL),- end_(NULL),- lower_(NULL),- upper_(NULL),- status_(NULL),- saveStatus_(NULL),- savedKeyVariable_(NULL),- backward_(NULL),- backToPivotRow_(NULL),- changeCost_(NULL),- keyVariable_(NULL),- next_(NULL),- toIndex_(NULL),- fromIndex_(NULL),- model_(NULL),- numberDualInfeasibilities_(0),- numberPrimalInfeasibilities_(0),- noCheck_(-1),- numberSets_(0),- saveNumber_(0),- possiblePivotKey_(0),- gubSlackIn_(-1),- firstGub_(0),- lastGub_(0),- gubType_(0)-{- setType(16);-}--/* This takes over ownership (for space reasons) and is the- real constructor*/-ClpGubMatrix::ClpGubMatrix(ClpPackedMatrix * matrix, int numberSets,- const int * start, const int * end,- const double * lower, const double * upper,- const unsigned char * status)- : ClpPackedMatrix(matrix->matrix()),- sumDualInfeasibilities_(0.0),- sumPrimalInfeasibilities_(0.0),- sumOfRelaxedDualInfeasibilities_(0.0),- sumOfRelaxedPrimalInfeasibilities_(0.0),- numberDualInfeasibilities_(0),- numberPrimalInfeasibilities_(0),- saveNumber_(0),- possiblePivotKey_(0),- gubSlackIn_(-1)-{- model_ = NULL;- numberSets_ = numberSets;- start_ = ClpCopyOfArray(start, numberSets_);- end_ = ClpCopyOfArray(end, numberSets_);- lower_ = ClpCopyOfArray(lower, numberSets_);- upper_ = ClpCopyOfArray(upper, numberSets_);- // Check valid and ordered- int last = -1;- int numberColumns = matrix_->getNumCols();- int numberRows = matrix_->getNumRows();- backward_ = new int[numberColumns];- backToPivotRow_ = new int[numberColumns];- changeCost_ = new double [numberRows+numberSets_];- keyVariable_ = new int[numberSets_];- // signal to need new ordering- next_ = NULL;- for (int iColumn = 0; iColumn < numberColumns; iColumn++)- backward_[iColumn] = -1;-- int iSet;- for (iSet = 0; iSet < numberSets_; iSet++) {- // set key variable as slack- keyVariable_[iSet] = iSet + numberColumns;- if (start_[iSet] < 0 || start_[iSet] >= numberColumns)- throw CoinError("Index out of range", "constructor", "ClpGubMatrix");- if (end_[iSet] < 0 || end_[iSet] > numberColumns)- throw CoinError("Index out of range", "constructor", "ClpGubMatrix");- if (end_[iSet] <= start_[iSet])- throw CoinError("Empty or negative set", "constructor", "ClpGubMatrix");- if (start_[iSet] < last)- throw CoinError("overlapping or non-monotonic sets", "constructor", "ClpGubMatrix");- last = end_[iSet];- int j;- for (j = start_[iSet]; j < end_[iSet]; j++)- backward_[j] = iSet;- }- // Find type of gub- firstGub_ = numberColumns + 1;- lastGub_ = -1;- int i;- for (i = 0; i < numberColumns; i++) {- if (backward_[i] >= 0) {- firstGub_ = CoinMin(firstGub_, i);- lastGub_ = CoinMax(lastGub_, i);- }- }- gubType_ = 0;- // adjust lastGub_- if (lastGub_ > 0)- lastGub_++;- for (i = firstGub_; i < lastGub_; i++) {- if (backward_[i] < 0) {- gubType_ = 1;- printf("interior non gub %d\n", i);- break;- }- }- if (status) {- status_ = ClpCopyOfArray(status, numberSets_);- } else {- status_ = new unsigned char [numberSets_];- memset(status_, 0, numberSets_);- int i;- for (i = 0; i < numberSets_; i++) {- // make slack key- setStatus(i, ClpSimplex::basic);- }- }- saveStatus_ = new unsigned char [numberSets_];- memset(saveStatus_, 0, numberSets_);- savedKeyVariable_ = new int [numberSets_];- memset(savedKeyVariable_, 0, numberSets_ * sizeof(int));- noCheck_ = -1;- infeasibilityWeight_ = 0.0;-}--ClpGubMatrix::ClpGubMatrix (const CoinPackedMatrix & rhs)- : ClpPackedMatrix(rhs),- sumDualInfeasibilities_(0.0),- sumPrimalInfeasibilities_(0.0),- sumOfRelaxedDualInfeasibilities_(0.0),- sumOfRelaxedPrimalInfeasibilities_(0.0),- infeasibilityWeight_(0.0),- start_(NULL),- end_(NULL),- lower_(NULL),- upper_(NULL),- status_(NULL),- saveStatus_(NULL),- savedKeyVariable_(NULL),- backward_(NULL),- backToPivotRow_(NULL),- changeCost_(NULL),- keyVariable_(NULL),- next_(NULL),- toIndex_(NULL),- fromIndex_(NULL),- model_(NULL),- numberDualInfeasibilities_(0),- numberPrimalInfeasibilities_(0),- noCheck_(-1),- numberSets_(0),- saveNumber_(0),- possiblePivotKey_(0),- gubSlackIn_(-1),- firstGub_(0),- lastGub_(0),- gubType_(0)-{- setType(16);--}--//--------------------------------------------------------------------// Destructor-//--------------------------------------------------------------------ClpGubMatrix::~ClpGubMatrix ()-{- delete [] start_;- delete [] end_;- delete [] lower_;- delete [] upper_;- delete [] status_;- delete [] saveStatus_;- delete [] savedKeyVariable_;- delete [] backward_;- delete [] backToPivotRow_;- delete [] changeCost_;- delete [] keyVariable_;- delete [] next_;- delete [] toIndex_;- delete [] fromIndex_;-}--//-----------------------------------------------------------------// Assignment operator-//--------------------------------------------------------------------ClpGubMatrix &-ClpGubMatrix::operator=(const ClpGubMatrix& rhs)-{- if (this != &rhs) {- ClpPackedMatrix::operator=(rhs);- delete [] start_;- delete [] end_;- delete [] lower_;- delete [] upper_;- delete [] status_;- delete [] saveStatus_;- delete [] savedKeyVariable_;- delete [] backward_;- delete [] backToPivotRow_;- delete [] changeCost_;- delete [] keyVariable_;- delete [] next_;- delete [] toIndex_;- delete [] fromIndex_;- numberSets_ = rhs.numberSets_;- saveNumber_ = rhs.saveNumber_;- possiblePivotKey_ = rhs.possiblePivotKey_;- gubSlackIn_ = rhs.gubSlackIn_;- start_ = ClpCopyOfArray(rhs.start_, numberSets_);- end_ = ClpCopyOfArray(rhs.end_, numberSets_);- lower_ = ClpCopyOfArray(rhs.lower_, numberSets_);- upper_ = ClpCopyOfArray(rhs.upper_, numberSets_);- status_ = ClpCopyOfArray(rhs.status_, numberSets_);- saveStatus_ = ClpCopyOfArray(rhs.saveStatus_, numberSets_);- savedKeyVariable_ = ClpCopyOfArray(rhs.savedKeyVariable_, numberSets_);- int numberColumns = getNumCols();- backward_ = ClpCopyOfArray(rhs.backward_, numberColumns);- backToPivotRow_ = ClpCopyOfArray(rhs.backToPivotRow_, numberColumns);- changeCost_ = ClpCopyOfArray(rhs.changeCost_, getNumRows() + numberSets_);- fromIndex_ = ClpCopyOfArray(rhs.fromIndex_, getNumRows() + numberSets_ + 1);- keyVariable_ = ClpCopyOfArray(rhs.keyVariable_, numberSets_);- // find longest set- int * longest = new int[numberSets_];- CoinZeroN(longest, numberSets_);- int j;- for (j = 0; j < numberColumns; j++) {- int iSet = backward_[j];- if (iSet >= 0)- longest[iSet]++;- }- int length = 0;- for (j = 0; j < numberSets_; j++)- length = CoinMax(length, longest[j]);- next_ = ClpCopyOfArray(rhs.next_, numberColumns + numberSets_ + 2 * length);- toIndex_ = ClpCopyOfArray(rhs.toIndex_, numberSets_);- sumDualInfeasibilities_ = rhs. sumDualInfeasibilities_;- sumPrimalInfeasibilities_ = rhs.sumPrimalInfeasibilities_;- sumOfRelaxedDualInfeasibilities_ = rhs.sumOfRelaxedDualInfeasibilities_;- sumOfRelaxedPrimalInfeasibilities_ = rhs.sumOfRelaxedPrimalInfeasibilities_;- infeasibilityWeight_ = rhs.infeasibilityWeight_;- numberDualInfeasibilities_ = rhs.numberDualInfeasibilities_;- numberPrimalInfeasibilities_ = rhs.numberPrimalInfeasibilities_;- noCheck_ = rhs.noCheck_;- firstGub_ = rhs.firstGub_;- lastGub_ = rhs.lastGub_;- gubType_ = rhs.gubType_;- model_ = rhs.model_;- }- return *this;-}-//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------ClpMatrixBase * ClpGubMatrix::clone() const-{- return new ClpGubMatrix(*this);-}-/* Subset clone (without gaps). Duplicates are allowed- and order is as given */-ClpMatrixBase *-ClpGubMatrix::subsetClone (int numberRows, const int * whichRows,- int numberColumns,- const int * whichColumns) const-{- return new ClpGubMatrix(*this, numberRows, whichRows,- numberColumns, whichColumns);-}-/* Returns a new matrix in reverse order without gaps- Is allowed to return NULL if doesn't want to have row copy */-ClpMatrixBase *-ClpGubMatrix::reverseOrderedCopy() const-{- return NULL;-}-int-ClpGubMatrix::hiddenRows() const-{- return numberSets_;-}-/* Subset constructor (without gaps). Duplicates are allowed- and order is as given */-ClpGubMatrix::ClpGubMatrix (- const ClpGubMatrix & rhs,- int numberRows, const int * whichRows,- int numberColumns, const int * whichColumns)- : ClpPackedMatrix(rhs, numberRows, whichRows, numberColumns, whichColumns)-{- // Assuming no gub rows deleted- // We also assume all sets in same order- // Get array with backward pointers- int numberColumnsOld = rhs.matrix_->getNumCols();- int * array = new int [ numberColumnsOld];- int i;- for (i = 0; i < numberColumnsOld; i++)- array[i] = -1;- for (int iSet = 0; iSet < numberSets_; iSet++) {- for (int j = start_[iSet]; j < end_[iSet]; j++)- array[j] = iSet;- }- numberSets_ = -1;- int lastSet = -1;- bool inSet = false;- for (i = 0; i < numberColumns; i++) {- int iColumn = whichColumns[i];- int iSet = array[iColumn];- if (iSet < 0) {- inSet = false;- } else {- if (!inSet) {- // start of new set but check okay- if (iSet <= lastSet)- throw CoinError("overlapping or non-monotonic sets", "subset constructor", "ClpGubMatrix");- lastSet = iSet;- numberSets_++;- start_[numberSets_] = i;- end_[numberSets_] = i + 1;- lower_[numberSets_] = lower_[iSet];- upper_[numberSets_] = upper_[iSet];- inSet = true;- } else {- if (iSet < lastSet) {- throw CoinError("overlapping or non-monotonic sets", "subset constructor", "ClpGubMatrix");- } else if (iSet == lastSet) {- end_[numberSets_] = i + 1;- } else {- // new set- lastSet = iSet;- numberSets_++;- start_[numberSets_] = i;- end_[numberSets_] = i + 1;- lower_[numberSets_] = lower_[iSet];- upper_[numberSets_] = upper_[iSet];- }- }- }- }- delete [] array;- numberSets_++; // adjust- // Find type of gub- firstGub_ = numberColumns + 1;- lastGub_ = -1;- for (i = 0; i < numberColumns; i++) {- if (backward_[i] >= 0) {- firstGub_ = CoinMin(firstGub_, i);- lastGub_ = CoinMax(lastGub_, i);- }- }- if (lastGub_ > 0)- lastGub_++;- gubType_ = 0;- for (i = firstGub_; i < lastGub_; i++) {- if (backward_[i] < 0) {- gubType_ = 1;- break;- }- }-- // Make sure key is feasible if only key in set-}-ClpGubMatrix::ClpGubMatrix (- const CoinPackedMatrix & rhs,- int numberRows, const int * whichRows,- int numberColumns, const int * whichColumns)- : ClpPackedMatrix(rhs, numberRows, whichRows, numberColumns, whichColumns),- sumDualInfeasibilities_(0.0),- sumPrimalInfeasibilities_(0.0),- sumOfRelaxedDualInfeasibilities_(0.0),- sumOfRelaxedPrimalInfeasibilities_(0.0),- start_(NULL),- end_(NULL),- lower_(NULL),- upper_(NULL),- backward_(NULL),- backToPivotRow_(NULL),- changeCost_(NULL),- keyVariable_(NULL),- next_(NULL),- toIndex_(NULL),- fromIndex_(NULL),- numberDualInfeasibilities_(0),- numberPrimalInfeasibilities_(0),- numberSets_(0),- saveNumber_(0),- possiblePivotKey_(0),- gubSlackIn_(-1),- firstGub_(0),- lastGub_(0),- gubType_(0)-{- setType(16);-}-/* Return <code>x * A + y</code> in <code>z</code>.- Squashes small elements and knows about ClpSimplex */-void-ClpGubMatrix::transposeTimes(const ClpSimplex * model, double scalar,- const CoinIndexedVector * rowArray,- CoinIndexedVector * y,- CoinIndexedVector * columnArray) const-{- columnArray->clear();- double * pi = rowArray->denseVector();- int numberNonZero = 0;- int * index = columnArray->getIndices();- double * array = columnArray->denseVector();- int numberInRowArray = rowArray->getNumElements();- // maybe I need one in OsiSimplex- double zeroTolerance = model->zeroTolerance();- int numberRows = model->numberRows();- ClpPackedMatrix* rowCopy =- dynamic_cast< ClpPackedMatrix*>(model->rowCopy());- bool packed = rowArray->packedMode();- double factor = 0.3;- // We may not want to do by row if there may be cache problems- int numberColumns = model->numberColumns();- // It would be nice to find L2 cache size - for moment 512K- // Be slightly optimistic- if (numberColumns * sizeof(double) > 1000000) {- if (numberRows * 10 < numberColumns)- factor = 0.1;- else if (numberRows * 4 < numberColumns)- factor = 0.15;- else if (numberRows * 2 < numberColumns)- factor = 0.2;- //if (model->numberIterations()%50==0)- //printf("%d nonzero\n",numberInRowArray);- }- // reduce for gub- factor *= 0.5;- assert (!y->getNumElements());- if (numberInRowArray > factor * numberRows || !rowCopy) {- // do by column- int iColumn;- // get matrix data pointers- const int * row = matrix_->getIndices();- const CoinBigIndex * columnStart = matrix_->getVectorStarts();- const int * columnLength = matrix_->getVectorLengths();- const double * elementByColumn = matrix_->getElements();- const double * rowScale = model->rowScale();- int numberColumns = model->numberColumns();- int iSet = -1;- double djMod = 0.0;- if (packed) {- // need to expand pi into y- assert(y->capacity() >= numberRows);- double * piOld = pi;- pi = y->denseVector();- const int * whichRow = rowArray->getIndices();- int i;- if (!rowScale) {- // modify pi so can collapse to one loop- for (i = 0; i < numberInRowArray; i++) {- int iRow = whichRow[i];- pi[iRow] = scalar * piOld[i];- }- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- if (backward_[iColumn] != iSet) {- // get pi on gub row- iSet = backward_[iColumn];- if (iSet >= 0) {- int iBasic = keyVariable_[iSet];- if (iBasic < numberColumns) {- // get dj without- assert (model->getStatus(iBasic) == ClpSimplex::basic);- djMod = 0.0;- for (CoinBigIndex j = columnStart[iBasic];- j < columnStart[iBasic] + columnLength[iBasic]; j++) {- int jRow = row[j];- djMod -= pi[jRow] * elementByColumn[j];- }- } else {- djMod = 0.0;- }- } else {- djMod = 0.0;- }- }- double value = -djMod;- CoinBigIndex j;- for (j = columnStart[iColumn];- j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- value += pi[iRow] * elementByColumn[j];- }- if (fabs(value) > zeroTolerance) {- array[numberNonZero] = value;- index[numberNonZero++] = iColumn;- }- }- } else {- // scaled- // modify pi so can collapse to one loop- for (i = 0; i < numberInRowArray; i++) {- int iRow = whichRow[i];- pi[iRow] = scalar * piOld[i] * rowScale[iRow];- }- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- if (backward_[iColumn] != iSet) {- // get pi on gub row- iSet = backward_[iColumn];- if (iSet >= 0) {- int iBasic = keyVariable_[iSet];- if (iBasic < numberColumns) {- // get dj without- assert (model->getStatus(iBasic) == ClpSimplex::basic);- djMod = 0.0;- // scaled- for (CoinBigIndex j = columnStart[iBasic];- j < columnStart[iBasic] + columnLength[iBasic]; j++) {- int jRow = row[j];- djMod -= pi[jRow] * elementByColumn[j] * rowScale[jRow];- }- } else {- djMod = 0.0;- }- } else {- djMod = 0.0;- }- }- double value = -djMod;- CoinBigIndex j;- const double * columnScale = model->columnScale();- for (j = columnStart[iColumn];- j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- value += pi[iRow] * elementByColumn[j];- }- value *= columnScale[iColumn];- if (fabs(value) > zeroTolerance) {- array[numberNonZero] = value;- index[numberNonZero++] = iColumn;- }- }- }- // zero out- for (i = 0; i < numberInRowArray; i++) {- int iRow = whichRow[i];- pi[iRow] = 0.0;- }- } else {- // code later- assert (packed);- if (!rowScale) {- if (scalar == -1.0) {- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- double value = 0.0;- CoinBigIndex j;- for (j = columnStart[iColumn];- j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- value += pi[iRow] * elementByColumn[j];- }- if (fabs(value) > zeroTolerance) {- index[numberNonZero++] = iColumn;- array[iColumn] = -value;- }- }- } else if (scalar == 1.0) {- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- double value = 0.0;- CoinBigIndex j;- for (j = columnStart[iColumn];- j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- value += pi[iRow] * elementByColumn[j];- }- if (fabs(value) > zeroTolerance) {- index[numberNonZero++] = iColumn;- array[iColumn] = value;- }- }- } else {- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- double value = 0.0;- CoinBigIndex j;- for (j = columnStart[iColumn];- j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- value += pi[iRow] * elementByColumn[j];- }- value *= scalar;- if (fabs(value) > zeroTolerance) {- index[numberNonZero++] = iColumn;- array[iColumn] = value;- }- }- }- } else {- // scaled- if (scalar == -1.0) {- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- double value = 0.0;- CoinBigIndex j;- const double * columnScale = model->columnScale();- for (j = columnStart[iColumn];- j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- value += pi[iRow] * elementByColumn[j] * rowScale[iRow];- }- value *= columnScale[iColumn];- if (fabs(value) > zeroTolerance) {- index[numberNonZero++] = iColumn;- array[iColumn] = -value;- }- }- } else if (scalar == 1.0) {- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- double value = 0.0;- CoinBigIndex j;- const double * columnScale = model->columnScale();- for (j = columnStart[iColumn];- j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- value += pi[iRow] * elementByColumn[j] * rowScale[iRow];- }- value *= columnScale[iColumn];- if (fabs(value) > zeroTolerance) {- index[numberNonZero++] = iColumn;- array[iColumn] = value;- }- }- } else {- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- double value = 0.0;- CoinBigIndex j;- const double * columnScale = model->columnScale();- for (j = columnStart[iColumn];- j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- value += pi[iRow] * elementByColumn[j] * rowScale[iRow];- }- value *= scalar * columnScale[iColumn];- if (fabs(value) > zeroTolerance) {- index[numberNonZero++] = iColumn;- array[iColumn] = value;- }- }- }- }- }- columnArray->setNumElements(numberNonZero);- y->setNumElements(0);- } else {- // do by row- transposeTimesByRow(model, scalar, rowArray, y, columnArray);- }- if (packed)- columnArray->setPackedMode(true);- if (0) {- columnArray->checkClean();- int numberNonZero = columnArray->getNumElements();;- int * index = columnArray->getIndices();- double * array = columnArray->denseVector();- int i;- for (i = 0; i < numberNonZero; i++) {- int j = index[i];- double value;- if (packed)- value = array[i];- else- value = array[j];- printf("Ti %d %d %g\n", i, j, value);- }- }-}-/* Return <code>x * A + y</code> in <code>z</code>.- Squashes small elements and knows about ClpSimplex */-void-ClpGubMatrix::transposeTimesByRow(const ClpSimplex * model, double scalar,- const CoinIndexedVector * rowArray,- CoinIndexedVector * y,- CoinIndexedVector * columnArray) const-{- // Do packed part- ClpPackedMatrix::transposeTimesByRow(model, scalar, rowArray, y, columnArray);- if (numberSets_) {- /* what we need to do is do by row as normal but get list of sets touched- and then update those ones */- abort();- }-}-/* Return <code>x *A in <code>z</code> but- just for indices in y. */-void-ClpGubMatrix::subsetTransposeTimes(const ClpSimplex * model,- const CoinIndexedVector * rowArray,- const CoinIndexedVector * y,- CoinIndexedVector * columnArray) const-{- columnArray->clear();- double * pi = rowArray->denseVector();- double * array = columnArray->denseVector();- int jColumn;- // get matrix data pointers- const int * row = matrix_->getIndices();- const CoinBigIndex * columnStart = matrix_->getVectorStarts();- const int * columnLength = matrix_->getVectorLengths();- const double * elementByColumn = matrix_->getElements();- const double * rowScale = model->rowScale();- int numberToDo = y->getNumElements();- const int * which = y->getIndices();- assert (!rowArray->packedMode());- columnArray->setPacked();- int numberTouched = 0;- if (!rowScale) {- for (jColumn = 0; jColumn < numberToDo; jColumn++) {- int iColumn = which[jColumn];- double value = 0.0;- CoinBigIndex j;- for (j = columnStart[iColumn];- j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- value += pi[iRow] * elementByColumn[j];- }- array[jColumn] = value;- if (value) {- int iSet = backward_[iColumn];- if (iSet >= 0) {- int iBasic = keyVariable_[iSet];- if (iBasic == iColumn) {- toIndex_[iSet] = jColumn;- fromIndex_[numberTouched++] = iSet;- }- }- }- }- } else {- // scaled- for (jColumn = 0; jColumn < numberToDo; jColumn++) {- int iColumn = which[jColumn];- double value = 0.0;- CoinBigIndex j;- const double * columnScale = model->columnScale();- for (j = columnStart[iColumn];- j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- value += pi[iRow] * elementByColumn[j] * rowScale[iRow];- }- value *= columnScale[iColumn];- array[jColumn] = value;- if (value) {- int iSet = backward_[iColumn];- if (iSet >= 0) {- int iBasic = keyVariable_[iSet];- if (iBasic == iColumn) {- toIndex_[iSet] = jColumn;- fromIndex_[numberTouched++] = iSet;- }- }- }- }- }- // adjust djs- for (jColumn = 0; jColumn < numberToDo; jColumn++) {- int iColumn = which[jColumn];- int iSet = backward_[iColumn];- if (iSet >= 0) {- int kColumn = toIndex_[iSet];- if (kColumn >= 0)- array[jColumn] -= array[kColumn];- }- }- // and clear basic- for (int j = 0; j < numberTouched; j++) {- int iSet = fromIndex_[j];- int kColumn = toIndex_[iSet];- toIndex_[iSet] = -1;- array[kColumn] = 0.0;- }-}-/// returns number of elements in column part of basis,-CoinBigIndex-ClpGubMatrix::countBasis(const int * whichColumn,- int & numberColumnBasic)-{- int i;- int numberColumns = getNumCols();- const int * columnLength = matrix_->getVectorLengths();- int numberRows = getNumRows();- int numberBasic = 0;- CoinBigIndex numberElements = 0;- int lastSet = -1;- int key = -1;- int keyLength = -1;- double * work = new double[numberRows];- CoinZeroN(work, numberRows);- char * mark = new char[numberRows];- CoinZeroN(mark, numberRows);- const CoinBigIndex * columnStart = matrix_->getVectorStarts();- const int * row = matrix_->getIndices();- const double * elementByColumn = matrix_->getElements();- //ClpGubDynamicMatrix* gubx =- //dynamic_cast< ClpGubDynamicMatrix*>(this);- //int * id = gubx->id();- // just count- for (i = 0; i < numberColumnBasic; i++) {- int iColumn = whichColumn[i];- int iSet = backward_[iColumn];- int length = columnLength[iColumn];- if (iSet < 0 || keyVariable_[iSet] >= numberColumns) {- numberElements += length;- numberBasic++;- //printf("non gub - set %d id %d (column %d) nel %d\n",iSet,id[iColumn-20],iColumn,length);- } else {- // in gub set- if (iColumn != keyVariable_[iSet]) {- numberBasic++;- CoinBigIndex j;- // not key- if (lastSet < iSet) {- // erase work- if (key >= 0) {- for (j = columnStart[key]; j < columnStart[key] + keyLength; j++)- work[row[j]] = 0.0;- }- key = keyVariable_[iSet];- lastSet = iSet;- keyLength = columnLength[key];- for (j = columnStart[key]; j < columnStart[key] + keyLength; j++)- work[row[j]] = elementByColumn[j];- }- int extra = keyLength;- for (j = columnStart[iColumn]; j < columnStart[iColumn] + length; j++) {- int iRow = row[j];- double keyValue = work[iRow];- double value = elementByColumn[j];- if (!keyValue) {- if (fabs(value) > 1.0e-20)- extra++;- } else {- value -= keyValue;- if (fabs(value) <= 1.0e-20)- extra--;- }- }- numberElements += extra;- //printf("gub - set %d id %d (column %d) nel %d\n",iSet,id[iColumn-20],iColumn,extra);- }- }- }- delete [] work;- delete [] mark;- // update number of column basic- numberColumnBasic = numberBasic;- return numberElements;-}-void-ClpGubMatrix::fillBasis(ClpSimplex * model,- const int * whichColumn,- int & numberColumnBasic,- int * indexRowU, int * start,- int * rowCount, int * columnCount,- CoinFactorizationDouble * elementU)-{- int i;- int numberColumns = getNumCols();- const int * columnLength = matrix_->getVectorLengths();- int numberRows = getNumRows();- assert (next_ || !elementU) ;- CoinBigIndex numberElements = start[0];- int lastSet = -1;- int key = -1;- int keyLength = -1;- double * work = new double[numberRows];- CoinZeroN(work, numberRows);- char * mark = new char[numberRows];- CoinZeroN(mark, numberRows);- const CoinBigIndex * columnStart = matrix_->getVectorStarts();- const int * row = matrix_->getIndices();- const double * elementByColumn = matrix_->getElements();- const double * rowScale = model->rowScale();- int numberBasic = 0;- if (0) {- printf("%d basiccolumns\n", numberColumnBasic);- int i;- for (i = 0; i < numberSets_; i++) {- int k = keyVariable_[i];- if (k < numberColumns) {- printf("key %d on set %d, %d elements\n", k, i, columnStart[k+1] - columnStart[k]);- for (int j = columnStart[k]; j < columnStart[k+1]; j++)- printf("row %d el %g\n", row[j], elementByColumn[j]);- } else {- printf("slack key on set %d\n", i);- }- }- }- // fill- if (!rowScale) {- // no scaling- for (i = 0; i < numberColumnBasic; i++) {- int iColumn = whichColumn[i];- int iSet = backward_[iColumn];- int length = columnLength[iColumn];- if (0) {- int k = iColumn;- printf("column %d in set %d, %d elements\n", k, iSet, columnStart[k+1] - columnStart[k]);- for (int j = columnStart[k]; j < columnStart[k+1]; j++)- printf("row %d el %g\n", row[j], elementByColumn[j]);- }- CoinBigIndex j;- if (iSet < 0 || keyVariable_[iSet] >= numberColumns) {- for (j = columnStart[iColumn]; j < columnStart[iColumn] + columnLength[iColumn]; j++) {- double value = elementByColumn[j];- if (fabs(value) > 1.0e-20) {- int iRow = row[j];- indexRowU[numberElements] = iRow;- rowCount[iRow]++;- elementU[numberElements++] = value;- }- }- // end of column- columnCount[numberBasic] = numberElements - start[numberBasic];- numberBasic++;- start[numberBasic] = numberElements;- } else {- // in gub set- if (iColumn != keyVariable_[iSet]) {- // not key- if (lastSet != iSet) {- // erase work- if (key >= 0) {- for (j = columnStart[key]; j < columnStart[key] + keyLength; j++) {- int iRow = row[j];- work[iRow] = 0.0;- mark[iRow] = 0;- }- }- key = keyVariable_[iSet];- lastSet = iSet;- keyLength = columnLength[key];- for (j = columnStart[key]; j < columnStart[key] + keyLength; j++) {- int iRow = row[j];- work[iRow] = elementByColumn[j];- mark[iRow] = 1;- }- }- for (j = columnStart[iColumn]; j < columnStart[iColumn] + length; j++) {- int iRow = row[j];- double value = elementByColumn[j];- if (mark[iRow]) {- mark[iRow] = 0;- double keyValue = work[iRow];- value -= keyValue;- }- if (fabs(value) > 1.0e-20) {- indexRowU[numberElements] = iRow;- rowCount[iRow]++;- elementU[numberElements++] = value;- }- }- for (j = columnStart[key]; j < columnStart[key] + keyLength; j++) {- int iRow = row[j];- if (mark[iRow]) {- double value = -work[iRow];- if (fabs(value) > 1.0e-20) {- indexRowU[numberElements] = iRow;- rowCount[iRow]++;- elementU[numberElements++] = value;- }- } else {- // just put back mark- mark[iRow] = 1;- }- }- // end of column- columnCount[numberBasic] = numberElements - start[numberBasic];- numberBasic++;- start[numberBasic] = numberElements;- }- }- }- } else {- // scaling- const double * columnScale = model->columnScale();- for (i = 0; i < numberColumnBasic; i++) {- int iColumn = whichColumn[i];- int iSet = backward_[iColumn];- int length = columnLength[iColumn];- CoinBigIndex j;- if (iSet < 0 || keyVariable_[iSet] >= numberColumns) {- double scale = columnScale[iColumn];- for (j = columnStart[iColumn]; j < columnStart[iColumn] + columnLength[iColumn]; j++) {- int iRow = row[j];- double value = elementByColumn[j] * scale * rowScale[iRow];- if (fabs(value) > 1.0e-20) {- indexRowU[numberElements] = iRow;- rowCount[iRow]++;- elementU[numberElements++] = value;- }- }- // end of column- columnCount[numberBasic] = numberElements - start[numberBasic];- numberBasic++;- start[numberBasic] = numberElements;- } else {- // in gub set- if (iColumn != keyVariable_[iSet]) {- double scale = columnScale[iColumn];- // not key- if (lastSet < iSet) {- // erase work- if (key >= 0) {- for (j = columnStart[key]; j < columnStart[key] + keyLength; j++) {- int iRow = row[j];- work[iRow] = 0.0;- mark[iRow] = 0;- }- }- key = keyVariable_[iSet];- lastSet = iSet;- keyLength = columnLength[key];- double scale = columnScale[key];- for (j = columnStart[key]; j < columnStart[key] + keyLength; j++) {- int iRow = row[j];- work[iRow] = elementByColumn[j] * scale * rowScale[iRow];- mark[iRow] = 1;- }- }- for (j = columnStart[iColumn]; j < columnStart[iColumn] + length; j++) {- int iRow = row[j];- double value = elementByColumn[j] * scale * rowScale[iRow];- if (mark[iRow]) {- mark[iRow] = 0;- double keyValue = work[iRow];- value -= keyValue;- }- if (fabs(value) > 1.0e-20) {- indexRowU[numberElements] = iRow;- rowCount[iRow]++;- elementU[numberElements++] = value;- }- }- for (j = columnStart[key]; j < columnStart[key] + keyLength; j++) {- int iRow = row[j];- if (mark[iRow]) {- double value = -work[iRow];- if (fabs(value) > 1.0e-20) {- indexRowU[numberElements] = iRow;- rowCount[iRow]++;- elementU[numberElements++] = value;- }- } else {- // just put back mark- mark[iRow] = 1;- }- }- // end of column- columnCount[numberBasic] = numberElements - start[numberBasic];- numberBasic++;- start[numberBasic] = numberElements;- }- }- }- }- delete [] work;- delete [] mark;- // update number of column basic- numberColumnBasic = numberBasic;-}-/* Unpacks a column into an CoinIndexedvector- */-void-ClpGubMatrix::unpack(const ClpSimplex * model, CoinIndexedVector * rowArray,- int iColumn) const-{- assert (iColumn < model->numberColumns());- // Do packed part- ClpPackedMatrix::unpack(model, rowArray, iColumn);- int iSet = backward_[iColumn];- if (iSet >= 0) {- int iBasic = keyVariable_[iSet];- if (iBasic < model->numberColumns()) {- add(model, rowArray, iBasic, -1.0);- }- }-}-/* Unpacks a column into a CoinIndexedVector-** in packed format-Note that model is NOT const. Bounds and objective could-be modified if doing column generation (just for this variable) */-void-ClpGubMatrix::unpackPacked(ClpSimplex * model,- CoinIndexedVector * rowArray,- int iColumn) const-{- int numberColumns = model->numberColumns();- if (iColumn < numberColumns) {- // Do packed part- ClpPackedMatrix::unpackPacked(model, rowArray, iColumn);- int iSet = backward_[iColumn];- if (iSet >= 0) {- // columns are in order- int iBasic = keyVariable_[iSet];- if (iBasic < numberColumns) {- int number = rowArray->getNumElements();- const double * rowScale = model->rowScale();- const int * row = matrix_->getIndices();- const CoinBigIndex * columnStart = matrix_->getVectorStarts();- const int * columnLength = matrix_->getVectorLengths();- const double * elementByColumn = matrix_->getElements();- double * array = rowArray->denseVector();- int * index = rowArray->getIndices();- CoinBigIndex i;- int numberOld = number;- int lastIndex = 0;- int next = index[lastIndex];- if (!rowScale) {- for (i = columnStart[iBasic];- i < columnStart[iBasic] + columnLength[iBasic]; i++) {- int iRow = row[i];- while (iRow > next) {- lastIndex++;- if (lastIndex == numberOld)- next = matrix_->getNumRows();- else- next = index[lastIndex];- }- if (iRow < next) {- array[number] = -elementByColumn[i];- index[number++] = iRow;- } else {- assert (iRow == next);- array[lastIndex] -= elementByColumn[i];- if (!array[lastIndex])- array[lastIndex] = 1.0e-100;- }- }- } else {- // apply scaling- double scale = model->columnScale()[iBasic];- for (i = columnStart[iBasic];- i < columnStart[iBasic] + columnLength[iBasic]; i++) {- int iRow = row[i];- while (iRow > next) {- lastIndex++;- if (lastIndex == numberOld)- next = matrix_->getNumRows();- else- next = index[lastIndex];- }- if (iRow < next) {- array[number] = -elementByColumn[i] * scale * rowScale[iRow];- index[number++] = iRow;- } else {- assert (iRow == next);- array[lastIndex] -= elementByColumn[i] * scale * rowScale[iRow];- if (!array[lastIndex])- array[lastIndex] = 1.0e-100;- }- }- }- rowArray->setNumElements(number);- }- }- } else {- // key slack entering- int iBasic = keyVariable_[gubSlackIn_];- assert (iBasic < numberColumns);- int number = 0;- const double * rowScale = model->rowScale();- const int * row = matrix_->getIndices();- const CoinBigIndex * columnStart = matrix_->getVectorStarts();- const int * columnLength = matrix_->getVectorLengths();- const double * elementByColumn = matrix_->getElements();- double * array = rowArray->denseVector();- int * index = rowArray->getIndices();- CoinBigIndex i;- if (!rowScale) {- for (i = columnStart[iBasic];- i < columnStart[iBasic] + columnLength[iBasic]; i++) {- int iRow = row[i];- array[number] = elementByColumn[i];- index[number++] = iRow;- }- } else {- // apply scaling- double scale = model->columnScale()[iBasic];- for (i = columnStart[iBasic];- i < columnStart[iBasic] + columnLength[iBasic]; i++) {- int iRow = row[i];- array[number] = elementByColumn[i] * scale * rowScale[iRow];- index[number++] = iRow;- }- }- rowArray->setNumElements(number);- rowArray->setPacked();- }-}-/* Adds multiple of a column into an CoinIndexedvector- You can use quickAdd to add to vector */-void-ClpGubMatrix::add(const ClpSimplex * model, CoinIndexedVector * rowArray,- int iColumn, double multiplier) const-{- assert (iColumn < model->numberColumns());- // Do packed part- ClpPackedMatrix::add(model, rowArray, iColumn, multiplier);- int iSet = backward_[iColumn];- if (iSet >= 0 && iColumn != keyVariable_[iSet]) {- ClpPackedMatrix::add(model, rowArray, keyVariable_[iSet], -multiplier);- }-}-/* Adds multiple of a column into an array */-void-ClpGubMatrix::add(const ClpSimplex * model, double * array,- int iColumn, double multiplier) const-{- assert (iColumn < model->numberColumns());- // Do packed part- ClpPackedMatrix::add(model, array, iColumn, multiplier);- if (iColumn < model->numberColumns()) {- int iSet = backward_[iColumn];- if (iSet >= 0 && iColumn != keyVariable_[iSet] && keyVariable_[iSet] < model->numberColumns()) {- ClpPackedMatrix::add(model, array, keyVariable_[iSet], -multiplier);- }- }-}-// Partial pricing-void-ClpGubMatrix::partialPricing(ClpSimplex * model, double startFraction, double endFraction,- int & bestSequence, int & numberWanted)-{- numberWanted = currentWanted_;- if (numberSets_) {- // Do packed part before gub- int numberColumns = matrix_->getNumCols();- double ratio = static_cast<double> (firstGub_) /- static_cast<double> (numberColumns);- ClpPackedMatrix::partialPricing(model, startFraction * ratio,- endFraction * ratio, bestSequence, numberWanted);- if (numberWanted || minimumGoodReducedCosts_ < -1) {- // do gub- const double * element = matrix_->getElements();- const int * row = matrix_->getIndices();- const CoinBigIndex * startColumn = matrix_->getVectorStarts();- const int * length = matrix_->getVectorLengths();- const double * rowScale = model->rowScale();- const double * columnScale = model->columnScale();- int iSequence;- CoinBigIndex j;- double tolerance = model->currentDualTolerance();- double * reducedCost = model->djRegion();- const double * duals = model->dualRowSolution();- const double * cost = model->costRegion();- double bestDj;- int numberColumns = model->numberColumns();- int numberRows = model->numberRows();- if (bestSequence >= 0)- bestDj = fabs(this->reducedCost(model, bestSequence));- else- bestDj = tolerance;- int sequenceOut = model->sequenceOut();- int saveSequence = bestSequence;- int startG = firstGub_ + static_cast<int> (startFraction * (lastGub_ - firstGub_));- int endG = firstGub_ + static_cast<int> (endFraction * (lastGub_ - firstGub_));- endG = CoinMin(lastGub_, endG + 1);- // If nothing found yet can go all the way to end- int endAll = endG;- if (bestSequence < 0 && !startG)- endAll = lastGub_;- int minSet = minimumObjectsScan_ < 0 ? 5 : minimumObjectsScan_;- int minNeg = minimumGoodReducedCosts_ == -1 ? 5 : minimumGoodReducedCosts_;- int nSets = 0;- int iSet = -1;- double djMod = 0.0;- double infeasibilityCost = model->infeasibilityCost();- if (rowScale) {- double bestDjMod = 0.0;- // scaled- for (iSequence = startG; iSequence < endAll; iSequence++) {- if (numberWanted + minNeg < originalWanted_ && nSets > minSet) {- // give up- numberWanted = 0;- break;- } else if (iSequence == endG && bestSequence >= 0) {- break;- }- if (backward_[iSequence] != iSet) {- // get pi on gub row- iSet = backward_[iSequence];- if (iSet >= 0) {- nSets++;- int iBasic = keyVariable_[iSet];- if (iBasic >= numberColumns) {- djMod = - weight(iSet) * infeasibilityCost;- } else {- // get dj without- assert (model->getStatus(iBasic) == ClpSimplex::basic);- djMod = 0.0;- // scaled- for (j = startColumn[iBasic];- j < startColumn[iBasic] + length[iBasic]; j++) {- int jRow = row[j];- djMod -= duals[jRow] * element[j] * rowScale[jRow];- }- // allow for scaling- djMod += cost[iBasic] / columnScale[iBasic];- // See if gub slack possible - dj is djMod- if (getStatus(iSet) == ClpSimplex::atLowerBound) {- double value = -djMod;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flagged(iSet)) {- bestDj = value;- bestSequence = numberRows + numberColumns + iSet;- bestDjMod = djMod;- } else {- // just to make sure we don't exit before got something- numberWanted++;- abort();- }- }- }- } else if (getStatus(iSet) == ClpSimplex::atUpperBound) {- double value = djMod;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flagged(iSet)) {- bestDj = value;- bestSequence = numberRows + numberColumns + iSet;- bestDjMod = djMod;- } else {- // just to make sure we don't exit before got something- numberWanted++;- abort();- }- }- }- }- }- } else {- // not in set- djMod = 0.0;- }- }- if (iSequence != sequenceOut) {- double value;- ClpSimplex::Status status = model->getStatus(iSequence);-- switch(status) {-- case ClpSimplex::basic:- case ClpSimplex::isFixed:- break;- case ClpSimplex::isFree:- case ClpSimplex::superBasic:- value = -djMod;- // scaled- for (j = startColumn[iSequence];- j < startColumn[iSequence] + length[iSequence]; j++) {- int jRow = row[j];- value -= duals[jRow] * element[j] * rowScale[jRow];- }- value = fabs(cost[iSequence] + value * columnScale[iSequence]);- if (value > FREE_ACCEPT * tolerance) {- numberWanted--;- // we are going to bias towards free (but only if reasonable)- value *= FREE_BIAS;- if (value > bestDj) {- // check flagged variable and correct dj- if (!model->flagged(iSequence)) {- bestDj = value;- bestSequence = iSequence;- bestDjMod = djMod;- } else {- // just to make sure we don't exit before got something- numberWanted++;- }- }- }- break;- case ClpSimplex::atUpperBound:- value = -djMod;- // scaled- for (j = startColumn[iSequence];- j < startColumn[iSequence] + length[iSequence]; j++) {- int jRow = row[j];- value -= duals[jRow] * element[j] * rowScale[jRow];- }- value = cost[iSequence] + value * columnScale[iSequence];- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!model->flagged(iSequence)) {- bestDj = value;- bestSequence = iSequence;- bestDjMod = djMod;- } else {- // just to make sure we don't exit before got something- numberWanted++;- }- }- }- break;- case ClpSimplex::atLowerBound:- value = -djMod;- // scaled- for (j = startColumn[iSequence];- j < startColumn[iSequence] + length[iSequence]; j++) {- int jRow = row[j];- value -= duals[jRow] * element[j] * rowScale[jRow];- }- value = -(cost[iSequence] + value * columnScale[iSequence]);- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!model->flagged(iSequence)) {- bestDj = value;- bestSequence = iSequence;- bestDjMod = djMod;- } else {- // just to make sure we don't exit before got something- numberWanted++;- }- }- }- break;- }- }- if (!numberWanted)- break;- }- if (bestSequence != saveSequence) {- if (bestSequence < numberRows + numberColumns) {- // recompute dj- double value = bestDjMod;- // scaled- for (j = startColumn[bestSequence];- j < startColumn[bestSequence] + length[bestSequence]; j++) {- int jRow = row[j];- value -= duals[jRow] * element[j] * rowScale[jRow];- }- reducedCost[bestSequence] = cost[bestSequence] + value * columnScale[bestSequence];- gubSlackIn_ = -1;- } else {- // slack - make last column- gubSlackIn_ = bestSequence - numberRows - numberColumns;- bestSequence = numberColumns + 2 * numberRows;- reducedCost[bestSequence] = bestDjMod;- model->setStatus(bestSequence, getStatus(gubSlackIn_));- if (getStatus(gubSlackIn_) == ClpSimplex::atUpperBound)- model->solutionRegion()[bestSequence] = upper_[gubSlackIn_];- else- model->solutionRegion()[bestSequence] = lower_[gubSlackIn_];- model->lowerRegion()[bestSequence] = lower_[gubSlackIn_];- model->upperRegion()[bestSequence] = upper_[gubSlackIn_];- model->costRegion()[bestSequence] = 0.0;- }- savedBestSequence_ = bestSequence;- savedBestDj_ = reducedCost[savedBestSequence_];- }- } else {- double bestDjMod = 0.0;- //printf("iteration %d start %d end %d - wanted %d\n",model->numberIterations(),- // startG,endG,numberWanted);- for (iSequence = startG; iSequence < endG; iSequence++) {- if (numberWanted + minNeg < originalWanted_ && nSets > minSet) {- // give up- numberWanted = 0;- break;- } else if (iSequence == endG && bestSequence >= 0) {- break;- }- if (backward_[iSequence] != iSet) {- // get pi on gub row- iSet = backward_[iSequence];- if (iSet >= 0) {- nSets++;- int iBasic = keyVariable_[iSet];- if (iBasic >= numberColumns) {- djMod = - weight(iSet) * infeasibilityCost;- } else {- // get dj without- assert (model->getStatus(iBasic) == ClpSimplex::basic);- djMod = 0.0;-- for (j = startColumn[iBasic];- j < startColumn[iBasic] + length[iBasic]; j++) {- int jRow = row[j];- djMod -= duals[jRow] * element[j];- }- djMod += cost[iBasic];- // See if gub slack possible - dj is djMod- if (getStatus(iSet) == ClpSimplex::atLowerBound) {- double value = -djMod;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flagged(iSet)) {- bestDj = value;- bestSequence = numberRows + numberColumns + iSet;- bestDjMod = djMod;- } else {- // just to make sure we don't exit before got something- numberWanted++;- abort();- }- }- }- } else if (getStatus(iSet) == ClpSimplex::atUpperBound) {- double value = djMod;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!flagged(iSet)) {- bestDj = value;- bestSequence = numberRows + numberColumns + iSet;- bestDjMod = djMod;- } else {- // just to make sure we don't exit before got something- numberWanted++;- abort();- }- }- }- }- }- } else {- // not in set- djMod = 0.0;- }- }- if (iSequence != sequenceOut) {- double value;- ClpSimplex::Status status = model->getStatus(iSequence);-- switch(status) {-- case ClpSimplex::basic:- case ClpSimplex::isFixed:- break;- case ClpSimplex::isFree:- case ClpSimplex::superBasic:- value = cost[iSequence] - djMod;- for (j = startColumn[iSequence];- j < startColumn[iSequence] + length[iSequence]; j++) {- int jRow = row[j];- value -= duals[jRow] * element[j];- }- value = fabs(value);- if (value > FREE_ACCEPT * tolerance) {- numberWanted--;- // we are going to bias towards free (but only if reasonable)- value *= FREE_BIAS;- if (value > bestDj) {- // check flagged variable and correct dj- if (!model->flagged(iSequence)) {- bestDj = value;- bestSequence = iSequence;- bestDjMod = djMod;- } else {- // just to make sure we don't exit before got something- numberWanted++;- }- }- }- break;- case ClpSimplex::atUpperBound:- value = cost[iSequence] - djMod;- for (j = startColumn[iSequence];- j < startColumn[iSequence] + length[iSequence]; j++) {- int jRow = row[j];- value -= duals[jRow] * element[j];- }- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!model->flagged(iSequence)) {- bestDj = value;- bestSequence = iSequence;- bestDjMod = djMod;- } else {- // just to make sure we don't exit before got something- numberWanted++;- }- }- }- break;- case ClpSimplex::atLowerBound:- value = cost[iSequence] - djMod;- for (j = startColumn[iSequence];- j < startColumn[iSequence] + length[iSequence]; j++) {- int jRow = row[j];- value -= duals[jRow] * element[j];- }- value = -value;- if (value > tolerance) {- numberWanted--;- if (value > bestDj) {- // check flagged variable and correct dj- if (!model->flagged(iSequence)) {- bestDj = value;- bestSequence = iSequence;- bestDjMod = djMod;- } else {- // just to make sure we don't exit before got something- numberWanted++;- }- }- }- break;- }- }- if (!numberWanted)- break;- }- if (bestSequence != saveSequence) {- if (bestSequence < numberRows + numberColumns) {- // recompute dj- double value = cost[bestSequence] - bestDjMod;- for (j = startColumn[bestSequence];- j < startColumn[bestSequence] + length[bestSequence]; j++) {- int jRow = row[j];- value -= duals[jRow] * element[j];- }- //printf("price struct %d - dj %g gubpi %g\n",bestSequence,value,bestDjMod);- reducedCost[bestSequence] = value;- gubSlackIn_ = -1;- } else {- // slack - make last column- gubSlackIn_ = bestSequence - numberRows - numberColumns;- bestSequence = numberColumns + 2 * numberRows;- reducedCost[bestSequence] = bestDjMod;- //printf("price slack %d - gubpi %g\n",gubSlackIn_,bestDjMod);- model->setStatus(bestSequence, getStatus(gubSlackIn_));- if (getStatus(gubSlackIn_) == ClpSimplex::atUpperBound)- model->solutionRegion()[bestSequence] = upper_[gubSlackIn_];- else- model->solutionRegion()[bestSequence] = lower_[gubSlackIn_];- model->lowerRegion()[bestSequence] = lower_[gubSlackIn_];- model->upperRegion()[bestSequence] = upper_[gubSlackIn_];- model->costRegion()[bestSequence] = 0.0;- }- }- }- // See if may be finished- if (startG == firstGub_ && bestSequence < 0)- infeasibilityWeight_ = model_->infeasibilityCost();- else if (bestSequence >= 0)- infeasibilityWeight_ = -1.0;- }- if (numberWanted) {- // Do packed part after gub- double offset = static_cast<double> (lastGub_) /- static_cast<double> (numberColumns);- double ratio = static_cast<double> (numberColumns) /- static_cast<double> (numberColumns) - offset;- double start2 = offset + ratio * startFraction;- double end2 = CoinMin(1.0, offset + ratio * endFraction + 1.0e-6);- ClpPackedMatrix::partialPricing(model, start2, end2, bestSequence, numberWanted);- }- } else {- // no gub- ClpPackedMatrix::partialPricing(model, startFraction, endFraction, bestSequence, numberWanted);- }- if (bestSequence >= 0)- infeasibilityWeight_ = -1.0; // not optimal- currentWanted_ = numberWanted;-}-/* expands an updated column to allow for extra rows which the main- solver does not know about and returns number added.-*/-int-ClpGubMatrix::extendUpdated(ClpSimplex * model, CoinIndexedVector * update, int mode)-{- // I think we only need to bother about sets with two in basis or incoming set- int number = update->getNumElements();- double * array = update->denseVector();- int * index = update->getIndices();- int i;- assert (!number || update->packedMode());- int * pivotVariable = model->pivotVariable();- int numberRows = model->numberRows();- int numberColumns = model->numberColumns();- int numberTotal = numberRows + numberColumns;- int sequenceIn = model->sequenceIn();- int returnCode = 0;- int iSetIn;- if (sequenceIn < numberColumns) {- iSetIn = backward_[sequenceIn];- gubSlackIn_ = -1; // in case set- } else if (sequenceIn < numberRows + numberColumns) {- iSetIn = -1;- gubSlackIn_ = -1; // in case set- } else {- iSetIn = gubSlackIn_;- }- double * lower = model->lowerRegion();- double * upper = model->upperRegion();- double * cost = model->costRegion();- double * solution = model->solutionRegion();- int number2 = number;- if (!mode) {- double primalTolerance = model->primalTolerance();- double infeasibilityCost = model->infeasibilityCost();- // extend- saveNumber_ = number;- for (i = 0; i < number; i++) {- int iRow = index[i];- int iPivot = pivotVariable[iRow];- if (iPivot < numberColumns) {- int iSet = backward_[iPivot];- if (iSet >= 0) {- // two (or more) in set- int iIndex = toIndex_[iSet];- double otherValue = array[i];- double value;- if (iIndex < 0) {- toIndex_[iSet] = number2;- int iNew = number2 - number;- fromIndex_[number2-number] = iSet;- iIndex = number2;- index[number2] = numberRows + iNew;- // do key stuff- int iKey = keyVariable_[iSet];- if (iKey < numberColumns) {- // Save current cost of key- changeCost_[number2-number] = cost[iKey];- if (iSet != iSetIn)- value = 0.0;- else if (iSetIn != gubSlackIn_)- value = 1.0;- else- value = -1.0;- pivotVariable[numberRows+iNew] = iKey;- // Do I need to recompute?- double sol;- assert (getStatus(iSet) != ClpSimplex::basic);- if (getStatus(iSet) == ClpSimplex::atLowerBound)- sol = lower_[iSet];- else- sol = upper_[iSet];- if ((gubType_ & 8) != 0) {- int iColumn = next_[iKey];- // sum all non-key variables- while(iColumn >= 0) {- sol -= solution[iColumn];- iColumn = next_[iColumn];- }- } else {- int stop = -(iKey + 1);- int iColumn = next_[iKey];- // sum all non-key variables- while(iColumn != stop) {- if (iColumn < 0)- iColumn = -iColumn - 1;- sol -= solution[iColumn];- iColumn = next_[iColumn];- }- }- solution[iKey] = sol;- if (model->algorithm() > 0)- model->nonLinearCost()->setOne(iKey, sol);- //assert (fabs(sol-solution[iKey])<1.0e-3);- } else {- // gub slack is basic- // Save current cost of key- changeCost_[number2-number] = -weight(iSet) * infeasibilityCost;- otherValue = - otherValue; //allow for - sign on slack- if (iSet != iSetIn)- value = 0.0;- else- value = -1.0;- pivotVariable[numberRows+iNew] = iNew + numberTotal;- model->djRegion()[iNew+numberTotal] = 0.0;- double sol = 0.0;- if ((gubType_ & 8) != 0) {- int iColumn = next_[iKey];- // sum all non-key variables- while(iColumn >= 0) {- sol += solution[iColumn];- iColumn = next_[iColumn];- }- } else {- int stop = -(iKey + 1);- int iColumn = next_[iKey];- // sum all non-key variables- while(iColumn != stop) {- if (iColumn < 0)- iColumn = -iColumn - 1;- sol += solution[iColumn];- iColumn = next_[iColumn];- }- }- solution[iNew+numberTotal] = sol;- // and do cost in nonLinearCost- if (model->algorithm() > 0)- model->nonLinearCost()->setOne(iNew + numberTotal, sol, lower_[iSet], upper_[iSet]);- if (sol > upper_[iSet] + primalTolerance) {- setAbove(iSet);- lower[iNew+numberTotal] = upper_[iSet];- upper[iNew+numberTotal] = COIN_DBL_MAX;- } else if (sol < lower_[iSet] - primalTolerance) {- setBelow(iSet);- lower[iNew+numberTotal] = -COIN_DBL_MAX;- upper[iNew+numberTotal] = lower_[iSet];- } else {- setFeasible(iSet);- lower[iNew+numberTotal] = lower_[iSet];- upper[iNew+numberTotal] = upper_[iSet];- }- cost[iNew+numberTotal] = weight(iSet) * infeasibilityCost;- }- number2++;- } else {- value = array[iIndex];- int iKey = keyVariable_[iSet];- if (iKey >= numberColumns)- otherValue = - otherValue; //allow for - sign on slack- }- value -= otherValue;- array[iIndex] = value;- }- }- }- if (iSetIn >= 0 && toIndex_[iSetIn] < 0) {- // Do incoming- update->setPacked(); // just in case no elements- toIndex_[iSetIn] = number2;- int iNew = number2 - number;- fromIndex_[number2-number] = iSetIn;- // Save current cost of key- double currentCost;- int key = keyVariable_[iSetIn];- if (key < numberColumns)- currentCost = cost[key];- else- currentCost = -weight(iSetIn) * infeasibilityCost;- changeCost_[number2-number] = currentCost;- index[number2] = numberRows + iNew;- // do key stuff- int iKey = keyVariable_[iSetIn];- if (iKey < numberColumns) {- if (gubSlackIn_ < 0)- array[number2] = 1.0;- else- array[number2] = -1.0;- pivotVariable[numberRows+iNew] = iKey;- // Do I need to recompute?- double sol;- assert (getStatus(iSetIn) != ClpSimplex::basic);- if (getStatus(iSetIn) == ClpSimplex::atLowerBound)- sol = lower_[iSetIn];- else- sol = upper_[iSetIn];- if ((gubType_ & 8) != 0) {- int iColumn = next_[iKey];- // sum all non-key variables- while(iColumn >= 0) {- sol -= solution[iColumn];- iColumn = next_[iColumn];- }- } else {- // bounds exist - sum over all except key- int stop = -(iKey + 1);- int iColumn = next_[iKey];- // sum all non-key variables- while(iColumn != stop) {- if (iColumn < 0)- iColumn = -iColumn - 1;- sol -= solution[iColumn];- iColumn = next_[iColumn];- }- }- solution[iKey] = sol;- if (model->algorithm() > 0)- model->nonLinearCost()->setOne(iKey, sol);- //assert (fabs(sol-solution[iKey])<1.0e-3);- } else {- // gub slack is basic- array[number2] = -1.0;- pivotVariable[numberRows+iNew] = iNew + numberTotal;- model->djRegion()[iNew+numberTotal] = 0.0;- double sol = 0.0;- if ((gubType_ & 8) != 0) {- int iColumn = next_[iKey];- // sum all non-key variables- while(iColumn >= 0) {- sol += solution[iColumn];- iColumn = next_[iColumn];- }- } else {- // bounds exist - sum over all except key- int stop = -(iKey + 1);- int iColumn = next_[iKey];- // sum all non-key variables- while(iColumn != stop) {- if (iColumn < 0)- iColumn = -iColumn - 1;- sol += solution[iColumn];- iColumn = next_[iColumn];- }- }- solution[iNew+numberTotal] = sol;- // and do cost in nonLinearCost- if (model->algorithm() > 0)- model->nonLinearCost()->setOne(iNew + numberTotal, sol, lower_[iSetIn], upper_[iSetIn]);- if (sol > upper_[iSetIn] + primalTolerance) {- setAbove(iSetIn);- lower[iNew+numberTotal] = upper_[iSetIn];- upper[iNew+numberTotal] = COIN_DBL_MAX;- } else if (sol < lower_[iSetIn] - primalTolerance) {- setBelow(iSetIn);- lower[iNew+numberTotal] = -COIN_DBL_MAX;- upper[iNew+numberTotal] = lower_[iSetIn];- } else {- setFeasible(iSetIn);- lower[iNew+numberTotal] = lower_[iSetIn];- upper[iNew+numberTotal] = upper_[iSetIn];- }- cost[iNew+numberTotal] = weight(iSetIn) * infeasibilityCost;- }- number2++;- }- // mark end- fromIndex_[number2-number] = -1;- returnCode = number2 - number;- // make sure lower_ upper_ adjusted- synchronize(model, 9);- } else {- // take off?- if (number > saveNumber_) {- // clear- double theta = model->theta();- double * solution = model->solutionRegion();- for (i = saveNumber_; i < number; i++) {- int iRow = index[i];- int iColumn = pivotVariable[iRow];-#ifdef CLP_DEBUG_PRINT- printf("Column %d (set %d) lower %g, upper %g - alpha %g - old value %g, new %g (theta %g)\n",- iColumn, fromIndex_[i-saveNumber_], lower[iColumn], upper[iColumn], array[i],- solution[iColumn], solution[iColumn] - model->theta()*array[i], model->theta());-#endif- double value = array[i];- array[i] = 0.0;- int iSet = fromIndex_[i-saveNumber_];- toIndex_[iSet] = -1;- if (iSet == iSetIn && iColumn < numberColumns) {- // update as may need value- solution[iColumn] -= theta * value;- }- }- }-#ifdef CLP_DEBUG- for (i = 0; i < numberSets_; i++)- assert(toIndex_[i] == -1);-#endif- number2 = saveNumber_;- }- update->setNumElements(number2);- return returnCode;-}-/*- utility primal function for dealing with dynamic constraints- mode=n see ClpGubMatrix.hpp for definition- Remember to update here when settled down-*/-void-ClpGubMatrix::primalExpanded(ClpSimplex * model, int mode)-{- int numberColumns = model->numberColumns();- switch (mode) {- // If key variable then slot in gub rhs so will get correct contribution- case 0: {- int i;- double * solution = model->solutionRegion();- ClpSimplex::Status iStatus;- for (i = 0; i < numberSets_; i++) {- int iColumn = keyVariable_[i];- if (iColumn < numberColumns) {- // key is structural - where is slack- iStatus = getStatus(i);- assert (iStatus != ClpSimplex::basic);- if (iStatus == ClpSimplex::atLowerBound)- solution[iColumn] = lower_[i];- else- solution[iColumn] = upper_[i];- }- }- }- break;- // Compute values of key variables- case 1: {- int i;- double * solution = model->solutionRegion();- //const int * columnLength = matrix_->getVectorLengths();- //const CoinBigIndex * columnStart = matrix_->getVectorStarts();- //const int * row = matrix_->getIndices();- //const double * elementByColumn = matrix_->getElements();- //int * pivotVariable = model->pivotVariable();- sumPrimalInfeasibilities_ = 0.0;- numberPrimalInfeasibilities_ = 0;- double primalTolerance = model->primalTolerance();- double relaxedTolerance = primalTolerance;- // we can't really trust infeasibilities if there is primal error- double error = CoinMin(1.0e-2, model->largestPrimalError());- // allow tolerance at least slightly bigger than standard- relaxedTolerance = relaxedTolerance + error;- // but we will be using difference- relaxedTolerance -= primalTolerance;- sumOfRelaxedPrimalInfeasibilities_ = 0.0;- for (i = 0; i < numberSets_; i++) { // Could just be over basics (esp if no bounds)- int kColumn = keyVariable_[i];- double value = 0.0;- if ((gubType_ & 8) != 0) {- int iColumn = next_[kColumn];- // sum all non-key variables- while(iColumn >= 0) {- value += solution[iColumn];- iColumn = next_[iColumn];- }- } else {- // bounds exist - sum over all except key- int stop = -(kColumn + 1);- int iColumn = next_[kColumn];- // sum all non-key variables- while(iColumn != stop) {- if (iColumn < 0)- iColumn = -iColumn - 1;- value += solution[iColumn];- iColumn = next_[iColumn];- }- }- if (kColumn < numberColumns) {- // make sure key is basic - so will be skipped in values pass- model->setStatus(kColumn, ClpSimplex::basic);- // feasibility will be done later- assert (getStatus(i) != ClpSimplex::basic);- if (getStatus(i) == ClpSimplex::atUpperBound)- solution[kColumn] = upper_[i] - value;- else- solution[kColumn] = lower_[i] - value;- //printf("Value of key structural %d for set %d is %g\n",kColumn,i,solution[kColumn]);- } else {- // slack is key- assert (getStatus(i) == ClpSimplex::basic);- double infeasibility = 0.0;- if (value > upper_[i] + primalTolerance) {- infeasibility = value - upper_[i] - primalTolerance;- setAbove(i);- } else if (value < lower_[i] - primalTolerance) {- infeasibility = lower_[i] - value - primalTolerance ;- setBelow(i);- } else {- setFeasible(i);- }- //printf("Value of key slack for set %d is %g\n",i,value);- if (infeasibility > 0.0) {- sumPrimalInfeasibilities_ += infeasibility;- if (infeasibility > relaxedTolerance)- sumOfRelaxedPrimalInfeasibilities_ += infeasibility;- numberPrimalInfeasibilities_ ++;- }- }- }- }- break;- // Report on infeasibilities of key variables- case 2: {- model->setSumPrimalInfeasibilities(model->sumPrimalInfeasibilities() +- sumPrimalInfeasibilities_);- model->setNumberPrimalInfeasibilities(model->numberPrimalInfeasibilities() +- numberPrimalInfeasibilities_);- model->setSumOfRelaxedPrimalInfeasibilities(model->sumOfRelaxedPrimalInfeasibilities() +- sumOfRelaxedPrimalInfeasibilities_);- }- break;- }-}-/*- utility dual function for dealing with dynamic constraints- mode=n see ClpGubMatrix.hpp for definition- Remember to update here when settled down-*/-void-ClpGubMatrix::dualExpanded(ClpSimplex * model,- CoinIndexedVector * array,- double * /*other*/, int mode)-{- switch (mode) {- // modify costs before transposeUpdate- case 0: {- int i;- double * cost = model->costRegion();- // not dual values yet- //assert (!other);- //double * work = array->denseVector();- double infeasibilityCost = model->infeasibilityCost();- int * pivotVariable = model->pivotVariable();- int numberRows = model->numberRows();- int numberColumns = model->numberColumns();- for (i = 0; i < numberRows; i++) {- int iPivot = pivotVariable[i];- if (iPivot < numberColumns) {- int iSet = backward_[iPivot];- if (iSet >= 0) {- int kColumn = keyVariable_[iSet];- double costValue;- if (kColumn < numberColumns) {- // structural has cost- costValue = cost[kColumn];- } else {- // slack is key- assert (getStatus(iSet) == ClpSimplex::basic);- // negative as -1.0 for slack- costValue = -weight(iSet) * infeasibilityCost;- }- array->add(i, -costValue); // was work[i]-costValue- }- }- }- }- break;- // create duals for key variables (without check on dual infeasible)- case 1: {- // If key slack then dual 0.0 (if feasible)- // dj for key is zero so that defines dual on set- int i;- double * dj = model->djRegion();- int numberColumns = model->numberColumns();- double infeasibilityCost = model->infeasibilityCost();- for (i = 0; i < numberSets_; i++) {- int kColumn = keyVariable_[i];- if (kColumn < numberColumns) {- // dj without set- double value = dj[kColumn];- // Now subtract out from all- dj[kColumn] = 0.0;- int iColumn = next_[kColumn];- // modify all non-key variables- while(iColumn >= 0) {- dj[iColumn] -= value;- iColumn = next_[iColumn];- }- } else {- // slack key - may not be feasible- assert (getStatus(i) == ClpSimplex::basic);- // negative as -1.0 for slack- double value = -weight(i) * infeasibilityCost;- if (value) {- int iColumn = next_[kColumn];- // modify all non-key variables basic- while(iColumn >= 0) {- dj[iColumn] -= value;- iColumn = next_[iColumn];- }- }- }- }- }- break;- // as 1 but check slacks and compute djs- case 2: {- // If key slack then dual 0.0- // If not then slack could be dual infeasible- // dj for key is zero so that defines dual on set- int i;- // make sure fromIndex will not confuse pricing- fromIndex_[0] = -1;- possiblePivotKey_ = -1;- // Create array- int numberColumns = model->numberColumns();- int * pivotVariable = model->pivotVariable();- int numberRows = model->numberRows();- for (i = 0; i < numberRows; i++) {- int iPivot = pivotVariable[i];- if (iPivot < numberColumns)- backToPivotRow_[iPivot] = i;- }- if (noCheck_ >= 0) {- if (infeasibilityWeight_ != model->infeasibilityCost()) {- // don't bother checking- sumDualInfeasibilities_ = 100.0;- numberDualInfeasibilities_ = 1;- sumOfRelaxedDualInfeasibilities_ = 100.0;- return;- }- }- double * dj = model->djRegion();- double * dual = model->dualRowSolution();- double * cost = model->costRegion();- ClpSimplex::Status iStatus;- const int * columnLength = matrix_->getVectorLengths();- const CoinBigIndex * columnStart = matrix_->getVectorStarts();- const int * row = matrix_->getIndices();- const double * elementByColumn = matrix_->getElements();- double infeasibilityCost = model->infeasibilityCost();- sumDualInfeasibilities_ = 0.0;- numberDualInfeasibilities_ = 0;- double dualTolerance = model->dualTolerance();- double relaxedTolerance = dualTolerance;- // we can't really trust infeasibilities if there is dual error- double error = CoinMin(1.0e-2, model->largestDualError());- // allow tolerance at least slightly bigger than standard- relaxedTolerance = relaxedTolerance + error;- // but we will be using difference- relaxedTolerance -= dualTolerance;- sumOfRelaxedDualInfeasibilities_ = 0.0;- for (i = 0; i < numberSets_; i++) {- int kColumn = keyVariable_[i];- if (kColumn < numberColumns) {- // dj without set- double value = cost[kColumn];- for (CoinBigIndex j = columnStart[kColumn];- j < columnStart[kColumn] + columnLength[kColumn]; j++) {- int iRow = row[j];- value -= dual[iRow] * elementByColumn[j];- }- // Now subtract out from all- dj[kColumn] -= value;- int stop = -(kColumn + 1);- kColumn = next_[kColumn];- while (kColumn != stop) {- if (kColumn < 0)- kColumn = -kColumn - 1;- double djValue = dj[kColumn] - value;- dj[kColumn] = djValue;;- double infeasibility = 0.0;- iStatus = model->getStatus(kColumn);- if (iStatus == ClpSimplex::atLowerBound) {- if (djValue < -dualTolerance)- infeasibility = -djValue - dualTolerance;- } else if (iStatus == ClpSimplex::atUpperBound) {- // at upper bound- if (djValue > dualTolerance)- infeasibility = djValue - dualTolerance;- }- if (infeasibility > 0.0) {- sumDualInfeasibilities_ += infeasibility;- if (infeasibility > relaxedTolerance)- sumOfRelaxedDualInfeasibilities_ += infeasibility;- numberDualInfeasibilities_ ++;- }- kColumn = next_[kColumn];- }- // check slack- iStatus = getStatus(i);- assert (iStatus != ClpSimplex::basic);- double infeasibility = 0.0;- // dj of slack is -(-1.0)value- if (iStatus == ClpSimplex::atLowerBound) {- if (value < -dualTolerance)- infeasibility = -value - dualTolerance;- } else if (iStatus == ClpSimplex::atUpperBound) {- // at upper bound- if (value > dualTolerance)- infeasibility = value - dualTolerance;- }- if (infeasibility > 0.0) {- sumDualInfeasibilities_ += infeasibility;- if (infeasibility > relaxedTolerance)- sumOfRelaxedDualInfeasibilities_ += infeasibility;- numberDualInfeasibilities_ ++;- }- } else {- // slack key - may not be feasible- assert (getStatus(i) == ClpSimplex::basic);- // negative as -1.0 for slack- double value = -weight(i) * infeasibilityCost;- if (value) {- // Now subtract out from all- int kColumn = i + numberColumns;- int stop = -(kColumn + 1);- kColumn = next_[kColumn];- while (kColumn != stop) {- if (kColumn < 0)- kColumn = -kColumn - 1;- double djValue = dj[kColumn] - value;- dj[kColumn] = djValue;;- double infeasibility = 0.0;- iStatus = model->getStatus(kColumn);- if (iStatus == ClpSimplex::atLowerBound) {- if (djValue < -dualTolerance)- infeasibility = -djValue - dualTolerance;- } else if (iStatus == ClpSimplex::atUpperBound) {- // at upper bound- if (djValue > dualTolerance)- infeasibility = djValue - dualTolerance;- }- if (infeasibility > 0.0) {- sumDualInfeasibilities_ += infeasibility;- if (infeasibility > relaxedTolerance)- sumOfRelaxedDualInfeasibilities_ += infeasibility;- numberDualInfeasibilities_ ++;- }- kColumn = next_[kColumn];- }- }- }- }- // and get statistics for column generation- synchronize(model, 4);- infeasibilityWeight_ = -1.0;- }- break;- // Report on infeasibilities of key variables- case 3: {- model->setSumDualInfeasibilities(model->sumDualInfeasibilities() +- sumDualInfeasibilities_);- model->setNumberDualInfeasibilities(model->numberDualInfeasibilities() +- numberDualInfeasibilities_);- model->setSumOfRelaxedDualInfeasibilities(model->sumOfRelaxedDualInfeasibilities() +- sumOfRelaxedDualInfeasibilities_);- }- break;- // modify costs before transposeUpdate for partial pricing- case 4: {- // First compute new costs etc for interesting gubs- int iLook = 0;- int iSet = fromIndex_[0];- double primalTolerance = model->primalTolerance();- const double * cost = model->costRegion();- double * solution = model->solutionRegion();- double infeasibilityCost = model->infeasibilityCost();- int numberColumns = model->numberColumns();- int numberChanged = 0;- int * pivotVariable = model->pivotVariable();- while (iSet >= 0) {- int key = keyVariable_[iSet];- double value = 0.0;- // sum over all except key- if ((gubType_ & 8) != 0) {- int iColumn = next_[key];- // sum all non-key variables- while(iColumn >= 0) {- value += solution[iColumn];- iColumn = next_[iColumn];- }- } else {- // bounds exist - sum over all except key- int stop = -(key + 1);- int iColumn = next_[key];- // sum all non-key variables- while(iColumn != stop) {- if (iColumn < 0)- iColumn = -iColumn - 1;- value += solution[iColumn];- iColumn = next_[iColumn];- }- }- double costChange;- double oldCost = changeCost_[iLook];- if (key < numberColumns) {- assert (getStatus(iSet) != ClpSimplex::basic);- double sol;- if (getStatus(iSet) == ClpSimplex::atUpperBound)- sol = upper_[iSet] - value;- else- sol = lower_[iSet] - value;- solution[key] = sol;- // fix up cost- model->nonLinearCost()->setOne(key, sol);-#ifdef CLP_DEBUG_PRINT- printf("yy Value of key structural %d for set %d is %g - cost %g old cost %g\n", key, iSet, sol,- cost[key], oldCost);-#endif- costChange = cost[key] - oldCost;- } else {- // slack is key- if (value > upper_[iSet] + primalTolerance) {- setAbove(iSet);- } else if (value < lower_[iSet] - primalTolerance) {- setBelow(iSet);- } else {- setFeasible(iSet);- }- // negative as -1.0 for slack- costChange = -weight(iSet) * infeasibilityCost - oldCost;-#ifdef CLP_DEBUG_PRINT- printf("yy Value of key slack for set %d is %g - cost %g old cost %g\n", iSet, value,- weight(iSet)*infeasibilityCost, oldCost);-#endif- }- if (costChange) {- fromIndex_[numberChanged] = iSet;- toIndex_[iSet] = numberChanged;- changeCost_[numberChanged++] = costChange;- }- iSet = fromIndex_[++iLook];- }- if (numberChanged || possiblePivotKey_ >= 0) {- // first do those in list already- int number = array->getNumElements();- array->setPacked();- int i;- double * work = array->denseVector();- int * which = array->getIndices();- for (i = 0; i < number; i++) {- int iRow = which[i];- int iPivot = pivotVariable[iRow];- if (iPivot < numberColumns) {- int iSet = backward_[iPivot];- if (iSet >= 0 && toIndex_[iSet] >= 0) {- double newValue = work[i] + changeCost_[toIndex_[iSet]];- if (!newValue)- newValue = 1.0e-100;- work[i] = newValue;- // mark as done- backward_[iPivot] = -1;- }- }- if (possiblePivotKey_ == iRow) {- double newValue = work[i] - model->dualIn();- if (!newValue)- newValue = 1.0e-100;- work[i] = newValue;- possiblePivotKey_ = -1;- }- }- // now do rest and clean up- for (i = 0; i < numberChanged; i++) {- int iSet = fromIndex_[i];- int key = keyVariable_[iSet];- int iColumn = next_[key];- double change = changeCost_[i];- while (iColumn >= 0) {- if (backward_[iColumn] >= 0) {- int iRow = backToPivotRow_[iColumn];- assert (iRow >= 0);- work[number] = change;- if (possiblePivotKey_ == iRow) {- double newValue = work[number] - model->dualIn();- if (!newValue)- newValue = 1.0e-100;- work[number] = newValue;- possiblePivotKey_ = -1;- }- which[number++] = iRow;- } else {- // reset- backward_[iColumn] = iSet;- }- iColumn = next_[iColumn];- }- toIndex_[iSet] = -1;- }- if (possiblePivotKey_ >= 0) {- work[number] = -model->dualIn();- which[number++] = possiblePivotKey_;- possiblePivotKey_ = -1;- }- fromIndex_[0] = -1;- array->setNumElements(number);- }- }- break;- }-}-// This is local to Gub to allow synchronization when status is good-int-ClpGubMatrix::synchronize(ClpSimplex *, int)-{- return 0;-}-/*- general utility function for dealing with dynamic constraints- mode=n see ClpGubMatrix.hpp for definition- Remember to update here when settled down-*/-int-ClpGubMatrix::generalExpanded(ClpSimplex * model, int mode, int &number)-{- int returnCode = 0;- int numberColumns = model->numberColumns();- switch (mode) {- // Fill in pivotVariable but not for key variables- case 0: {- if (!next_ ) {- // do ordering- assert (!rhsOffset_);- // create and do gub crash- useEffectiveRhs(model, false);- }- int i;- int numberBasic = number;- // Use different array so can build from true pivotVariable_- //int * pivotVariable = model->pivotVariable();- int * pivotVariable = model->rowArray(0)->getIndices();- for (i = 0; i < numberColumns; i++) {- if (model->getColumnStatus(i) == ClpSimplex::basic) {- int iSet = backward_[i];- if (iSet < 0 || i != keyVariable_[iSet])- pivotVariable[numberBasic++] = i;- }- }- number = numberBasic;- if (model->numberIterations())- assert (number == model->numberRows());- }- break;- // Make all key variables basic- case 1: {- int i;- for (i = 0; i < numberSets_; i++) {- int iColumn = keyVariable_[i];- if (iColumn < numberColumns)- model->setColumnStatus(iColumn, ClpSimplex::basic);- }- }- break;- // Do initial extra rows + maximum basic- case 2: {- returnCode = getNumRows() + 1;- number = model->numberRows() + numberSets_;- }- break;- // Before normal replaceColumn- case 3: {- int sequenceIn = model->sequenceIn();- int sequenceOut = model->sequenceOut();- int numberColumns = model->numberColumns();- int numberRows = model->numberRows();- int pivotRow = model->pivotRow();- if (gubSlackIn_ >= 0)- assert (sequenceIn > numberRows + numberColumns);- if (sequenceIn == sequenceOut)- return -1;- int iSetIn = -1;- int iSetOut = -1;- if (sequenceOut < numberColumns) {- iSetOut = backward_[sequenceOut];- } else if (sequenceOut >= numberRows + numberColumns) {- assert (pivotRow >= numberRows);- int iExtra = pivotRow - numberRows;- assert (iExtra >= 0);- if (iSetOut < 0)- iSetOut = fromIndex_[iExtra];- else- assert(iSetOut == fromIndex_[iExtra]);- }- if (sequenceIn < numberColumns) {- iSetIn = backward_[sequenceIn];- } else if (gubSlackIn_ >= 0) {- iSetIn = gubSlackIn_;- }- possiblePivotKey_ = -1;- number = 0; // say do ordinary- int * pivotVariable = model->pivotVariable();- if (pivotRow >= numberRows) {- int iExtra = pivotRow - numberRows;- //const int * length = matrix_->getVectorLengths();-- assert (sequenceOut >= numberRows + numberColumns ||- sequenceOut == keyVariable_[iSetOut]);- int incomingColumn = sequenceIn; // to be used in updates- if (iSetIn != iSetOut) {- // We need to find a possible pivot for incoming- // look through rowArray_[1]- int n = model->rowArray(1)->getNumElements();- int * which = model->rowArray(1)->getIndices();- double * array = model->rowArray(1)->denseVector();- double bestAlpha = 1.0e-5;- //int shortest=numberRows+1;- for (int i = 0; i < n; i++) {- int iRow = which[i];- int iPivot = pivotVariable[iRow];- if (iPivot < numberColumns && backward_[iPivot] == iSetOut) {- if (fabs(array[i]) > fabs(bestAlpha)) {- bestAlpha = array[i];- possiblePivotKey_ = iRow;- }- }- }- assert (possiblePivotKey_ >= 0); // could set returnCode=4- number = 1;- if (sequenceIn >= numberRows + numberColumns) {- number = 3;- // need swap as gub slack in and must become key- // is this best way- int key = keyVariable_[iSetIn];- assert (key < numberColumns);- // check other basic- int iColumn = next_[key];- // set new key to be used by unpack- keyVariable_[iSetIn] = iSetIn + numberColumns;- // change cost in changeCost- {- int iLook = 0;- int iSet = fromIndex_[0];- while (iSet >= 0) {- if (iSet == iSetIn) {- changeCost_[iLook] = 0.0;- break;- }- iSet = fromIndex_[++iLook];- }- }- while (iColumn >= 0) {- if (iColumn != sequenceOut) {- // need partial ftran and skip accuracy check in replaceColumn-#ifdef CLP_DEBUG_PRINT- printf("TTTTTry 5\n");-#endif- int iRow = backToPivotRow_[iColumn];- assert (iRow >= 0);- unpack(model, model->rowArray(3), iColumn);- model->factorization()->updateColumnFT(model->rowArray(2), model->rowArray(3));- double alpha = model->rowArray(3)->denseVector()[iRow];- //if (!alpha)- //printf("zero alpha a\n");- int updateStatus = model->factorization()->replaceColumn(model,- model->rowArray(2),- model->rowArray(3),- iRow, alpha);- returnCode = CoinMax(updateStatus, returnCode);- model->rowArray(3)->clear();- if (returnCode)- break;- }- iColumn = next_[iColumn];- }- if (!returnCode) {- // now factorization looks as if key is out- // pivot back in-#ifdef CLP_DEBUG_PRINT- printf("TTTTTry 6\n");-#endif- unpack(model, model->rowArray(3), key);- model->factorization()->updateColumnFT(model->rowArray(2), model->rowArray(3));- pivotRow = possiblePivotKey_;- double alpha = model->rowArray(3)->denseVector()[pivotRow];- //if (!alpha)- //printf("zero alpha b\n");- int updateStatus = model->factorization()->replaceColumn(model,- model->rowArray(2),- model->rowArray(3),- pivotRow, alpha);- returnCode = CoinMax(updateStatus, returnCode);- model->rowArray(3)->clear();- }- // restore key- keyVariable_[iSetIn] = key;- // now alternate column can replace key on out- incomingColumn = pivotVariable[possiblePivotKey_];- } else {-#ifdef CLP_DEBUG_PRINT- printf("TTTTTTry 4 %d\n", possiblePivotKey_);-#endif- int updateStatus = model->factorization()->replaceColumn(model,- model->rowArray(2),- model->rowArray(1),- possiblePivotKey_,- bestAlpha);- returnCode = CoinMax(updateStatus, returnCode);- incomingColumn = pivotVariable[possiblePivotKey_];- }-- //returnCode=4; // need swap- } else {- // key swap- number = -1;- }- int key = keyVariable_[iSetOut];- if (key < numberColumns)- assert(key == sequenceOut);- // check if any other basic- int iColumn = next_[key];- if (returnCode)- iColumn = -1; // skip if error on previous- // set new key to be used by unpack- if (incomingColumn < numberColumns)- keyVariable_[iSetOut] = incomingColumn;- else- keyVariable_[iSetOut] = iSetIn + numberColumns;- double * cost = model->costRegion();- if (possiblePivotKey_ < 0) {- double dj = model->djRegion()[sequenceIn] - cost[sequenceIn];- changeCost_[iExtra] = -dj;-#ifdef CLP_DEBUG_PRINT- printf("modifying changeCost %d by %g - cost %g\n", iExtra, dj, cost[sequenceIn]);-#endif- }- while (iColumn >= 0) {- if (iColumn != incomingColumn) {- number = -2;- // need partial ftran and skip accuracy check in replaceColumn-#ifdef CLP_DEBUG_PRINT- printf("TTTTTTry 1\n");-#endif- int iRow = backToPivotRow_[iColumn];- assert (iRow >= 0 && iRow < numberRows);- unpack(model, model->rowArray(3), iColumn);- model->factorization()->updateColumnFT(model->rowArray(2), model->rowArray(3));- double * array = model->rowArray(3)->denseVector();- double alpha = array[iRow];- //if (!alpha)- //printf("zero alpha d\n");- int updateStatus = model->factorization()->replaceColumn(model,- model->rowArray(2),- model->rowArray(3),- iRow, alpha);- returnCode = CoinMax(updateStatus, returnCode);- model->rowArray(3)->clear();- if (returnCode)- break;- }- iColumn = next_[iColumn];- }- // restore key- keyVariable_[iSetOut] = key;- } else if (sequenceIn >= numberRows + numberColumns) {- number = 2;- //returnCode=4;- // need swap as gub slack in and must become key- // is this best way- int key = keyVariable_[iSetIn];- assert (key < numberColumns);- // check other basic- int iColumn = next_[key];- // set new key to be used by unpack- keyVariable_[iSetIn] = iSetIn + numberColumns;- // change cost in changeCost- {- int iLook = 0;- int iSet = fromIndex_[0];- while (iSet >= 0) {- if (iSet == iSetIn) {- changeCost_[iLook] = 0.0;- break;- }- iSet = fromIndex_[++iLook];- }- }- while (iColumn >= 0) {- if (iColumn != sequenceOut) {- // need partial ftran and skip accuracy check in replaceColumn-#ifdef CLP_DEBUG_PRINT- printf("TTTTTry 2\n");-#endif- int iRow = backToPivotRow_[iColumn];- assert (iRow >= 0);- unpack(model, model->rowArray(3), iColumn);- model->factorization()->updateColumnFT(model->rowArray(2), model->rowArray(3));- double alpha = model->rowArray(3)->denseVector()[iRow];- //if (!alpha)- //printf("zero alpha e\n");- int updateStatus = model->factorization()->replaceColumn(model,- model->rowArray(2),- model->rowArray(3),- iRow, alpha);- returnCode = CoinMax(updateStatus, returnCode);- model->rowArray(3)->clear();- if (returnCode)- break;- }- iColumn = next_[iColumn];- }- if (!returnCode) {- // now factorization looks as if key is out- // pivot back in-#ifdef CLP_DEBUG_PRINT- printf("TTTTTry 3\n");-#endif- unpack(model, model->rowArray(3), key);- model->factorization()->updateColumnFT(model->rowArray(2), model->rowArray(3));- double alpha = model->rowArray(3)->denseVector()[pivotRow];- //if (!alpha)- //printf("zero alpha f\n");- int updateStatus = model->factorization()->replaceColumn(model,- model->rowArray(2),- model->rowArray(3),- pivotRow, alpha);- returnCode = CoinMax(updateStatus, returnCode);- model->rowArray(3)->clear();- }- // restore key- keyVariable_[iSetIn] = key;- } else {- // normal - but might as well do here- returnCode = model->factorization()->replaceColumn(model,- model->rowArray(2),- model->rowArray(1),- model->pivotRow(),- model->alpha());- }- }-#ifdef CLP_DEBUG_PRINT- printf("Update type after %d - status %d - pivot row %d\n",- number, returnCode, model->pivotRow());-#endif- // see if column generation says time to re-factorize- returnCode = CoinMax(returnCode, synchronize(model, 5));- number = -1; // say no need for normal replaceColumn- break;- // To see if can dual or primal- case 4: {- returnCode = 1;- }- break;- // save status- case 5: {- synchronize(model, 0);- CoinMemcpyN(status_, numberSets_, saveStatus_);- CoinMemcpyN(keyVariable_, numberSets_, savedKeyVariable_);- }- break;- // restore status- case 6: {- CoinMemcpyN(saveStatus_, numberSets_, status_);- CoinMemcpyN(savedKeyVariable_, numberSets_, keyVariable_);- // restore firstAvailable_- synchronize(model, 7);- // redo next_- int i;- int * last = new int[numberSets_];- for (i = 0; i < numberSets_; i++) {- int iKey = keyVariable_[i];- assert(iKey >= numberColumns || backward_[iKey] == i);- last[i] = iKey;- // make sure basic- //if (iKey<numberColumns)- //model->setStatus(iKey,ClpSimplex::basic);- }- for (i = 0; i < numberColumns; i++) {- int iSet = backward_[i];- if (iSet >= 0) {- next_[last[iSet]] = i;- last[iSet] = i;- }- }- for (i = 0; i < numberSets_; i++) {- next_[last[i]] = -(keyVariable_[i] + 1);- redoSet(model, keyVariable_[i], keyVariable_[i], i);- }- delete [] last;- // redo pivotVariable- int * pivotVariable = model->pivotVariable();- int iRow;- int numberBasic = 0;- int numberRows = model->numberRows();- for (iRow = 0; iRow < numberRows; iRow++) {- if (model->getRowStatus(iRow) == ClpSimplex::basic) {- numberBasic++;- pivotVariable[iRow] = iRow + numberColumns;- } else {- pivotVariable[iRow] = -1;- }- }- i = 0;- int iColumn;- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- if (model->getStatus(iColumn) == ClpSimplex::basic) {- int iSet = backward_[iColumn];- if (iSet < 0 || keyVariable_[iSet] != iColumn) {- while (pivotVariable[i] >= 0) {- i++;- assert (i < numberRows);- }- pivotVariable[i] = iColumn;- backToPivotRow_[iColumn] = i;- numberBasic++;- }- }- }- assert (numberBasic == numberRows);- rhsOffset(model, true);- }- break;- // flag a variable- case 7: {- assert (number == model->sequenceIn());- synchronize(model, 1);- synchronize(model, 8);- }- break;- // unflag all variables- case 8: {- returnCode = synchronize(model, 2);- }- break;- // redo costs in primal- case 9: {- returnCode = synchronize(model, 3);- }- break;- // return 1 if there may be changing bounds on variable (column generation)- case 10: {- returnCode = synchronize(model, 6);- }- break;- // make sure set is clean- case 11: {- assert (number == model->sequenceIn());- returnCode = synchronize(model, 8);- }- break;- default:- break;- }- return returnCode;-}-// Sets up an effective RHS and does gub crash if needed-void-ClpGubMatrix::useEffectiveRhs(ClpSimplex * model, bool cheapest)-{- // Do basis - cheapest or slack if feasible (unless cheapest set)- int longestSet = 0;- int iSet;- for (iSet = 0; iSet < numberSets_; iSet++)- longestSet = CoinMax(longestSet, end_[iSet] - start_[iSet]);-- double * upper = new double[longestSet+1];- double * cost = new double[longestSet+1];- double * lower = new double[longestSet+1];- double * solution = new double[longestSet+1];- assert (!next_);- int numberColumns = getNumCols();- const int * columnLength = matrix_->getVectorLengths();- const double * columnLower = model->lowerRegion();- const double * columnUpper = model->upperRegion();- double * columnSolution = model->solutionRegion();- const double * objective = model->costRegion();- int numberRows = getNumRows();- toIndex_ = new int[numberSets_];- for (iSet = 0; iSet < numberSets_; iSet++)- toIndex_[iSet] = -1;- fromIndex_ = new int [getNumRows()+1];- double tolerance = model->primalTolerance();- bool noNormalBounds = true;- gubType_ &= ~8;- bool gotBasis = false;- for (iSet = 0; iSet < numberSets_; iSet++) {- if (keyVariable_[iSet] < numberColumns)- gotBasis = true;- CoinBigIndex j;- CoinBigIndex iStart = start_[iSet];- CoinBigIndex iEnd = end_[iSet];- for (j = iStart; j < iEnd; j++) {- if (columnLower[j] && columnLower[j] > -1.0e20)- noNormalBounds = false;- if (columnUpper[j] && columnUpper[j] < 1.0e20)- noNormalBounds = false;- }- }- if (noNormalBounds)- gubType_ |= 8;- if (!gotBasis) {- for (iSet = 0; iSet < numberSets_; iSet++) {- CoinBigIndex j;- int numberBasic = 0;- int iBasic = -1;- CoinBigIndex iStart = start_[iSet];- CoinBigIndex iEnd = end_[iSet];- // find one with smallest length- int smallest = numberRows + 1;- double value = 0.0;- for (j = iStart; j < iEnd; j++) {- if (model->getStatus(j) == ClpSimplex::basic) {- if (columnLength[j] < smallest) {- smallest = columnLength[j];- iBasic = j;- }- numberBasic++;- }- value += columnSolution[j];- }- bool done = false;- if (numberBasic > 1 || (numberBasic == 1 && getStatus(iSet) == ClpSimplex::basic)) {- if (getStatus(iSet) == ClpSimplex::basic)- iBasic = iSet + numberColumns; // slack key - use- done = true;- } else if (numberBasic == 1) {- // see if can be key- double thisSolution = columnSolution[iBasic];- if (thisSolution > columnUpper[iBasic]) {- value -= thisSolution - columnUpper[iBasic];- thisSolution = columnUpper[iBasic];- columnSolution[iBasic] = thisSolution;- }- if (thisSolution < columnLower[iBasic]) {- value -= thisSolution - columnLower[iBasic];- thisSolution = columnLower[iBasic];- columnSolution[iBasic] = thisSolution;- }- // try setting slack to a bound- assert (upper_[iSet] < 1.0e20 || lower_[iSet] > -1.0e20);- double cost1 = COIN_DBL_MAX;- int whichBound = -1;- if (upper_[iSet] < 1.0e20) {- // try slack at ub- double newBasic = thisSolution + upper_[iSet] - value;- if (newBasic >= columnLower[iBasic] - tolerance &&- newBasic <= columnUpper[iBasic] + tolerance) {- // can go- whichBound = 1;- cost1 = newBasic * objective[iBasic];- // But if exact then may be good solution- if (fabs(upper_[iSet] - value) < tolerance)- cost1 = -COIN_DBL_MAX;- }- }- if (lower_[iSet] > -1.0e20) {- // try slack at lb- double newBasic = thisSolution + lower_[iSet] - value;- if (newBasic >= columnLower[iBasic] - tolerance &&- newBasic <= columnUpper[iBasic] + tolerance) {- // can go but is it cheaper- double cost2 = newBasic * objective[iBasic];- // But if exact then may be good solution- if (fabs(lower_[iSet] - value) < tolerance)- cost2 = -COIN_DBL_MAX;- if (cost2 < cost1)- whichBound = 0;- }- }- if (whichBound != -1) {- // key- done = true;- if (whichBound) {- // slack to upper- columnSolution[iBasic] = thisSolution + upper_[iSet] - value;- setStatus(iSet, ClpSimplex::atUpperBound);- } else {- // slack to lower- columnSolution[iBasic] = thisSolution + lower_[iSet] - value;- setStatus(iSet, ClpSimplex::atLowerBound);- }- }- }- if (!done) {- if (!cheapest) {- // see if slack can be key- if (value >= lower_[iSet] - tolerance && value <= upper_[iSet] + tolerance) {- done = true;- setStatus(iSet, ClpSimplex::basic);- iBasic = iSet + numberColumns;- }- }- if (!done) {- // set non basic if there was one- if (iBasic >= 0)- model->setStatus(iBasic, ClpSimplex::atLowerBound);- // find cheapest- int numberInSet = iEnd - iStart;- CoinMemcpyN(columnLower + iStart, numberInSet, lower);- CoinMemcpyN(columnUpper + iStart, numberInSet, upper);- CoinMemcpyN(columnSolution + iStart, numberInSet, solution);- // and slack- iBasic = numberInSet;- solution[iBasic] = -value;- lower[iBasic] = -upper_[iSet];- upper[iBasic] = -lower_[iSet];- int kphase;- if (value >= lower_[iSet] - tolerance && value <= upper_[iSet] + tolerance) {- // feasible- kphase = 1;- cost[iBasic] = 0.0;- CoinMemcpyN(objective + iStart, numberInSet, cost);- } else {- // infeasible- kphase = 0;- // remember bounds are flipped so opposite to natural- if (value < lower_[iSet] - tolerance)- cost[iBasic] = 1.0;- else- cost[iBasic] = -1.0;- CoinZeroN(cost, numberInSet);- }- double dualTolerance = model->dualTolerance();- for (int iphase = kphase; iphase < 2; iphase++) {- if (iphase) {- cost[numberInSet] = 0.0;- CoinMemcpyN(objective + iStart, numberInSet, cost);- }- // now do one row lp- bool improve = true;- while (improve) {- improve = false;- double dual = cost[iBasic];- int chosen = -1;- double best = dualTolerance;- int way = 0;- for (int i = 0; i <= numberInSet; i++) {- double dj = cost[i] - dual;- double improvement = 0.0;- if (iphase || i < numberInSet)- assert (solution[i] >= lower[i] && solution[i] <= upper[i]);- if (dj > dualTolerance)- improvement = dj * (solution[i] - lower[i]);- else if (dj < -dualTolerance)- improvement = dj * (solution[i] - upper[i]);- if (improvement > best) {- best = improvement;- chosen = i;- if (dj < 0.0) {- way = 1;- } else {- way = -1;- }- }- }- if (chosen >= 0) {- improve = true;- // now see how far- if (way > 0) {- // incoming increasing so basic decreasing- // if phase 0 then go to nearest bound- double distance = upper[chosen] - solution[chosen];- double basicDistance;- if (!iphase) {- assert (iBasic == numberInSet);- assert (solution[iBasic] > upper[iBasic]);- basicDistance = solution[iBasic] - upper[iBasic];- } else {- basicDistance = solution[iBasic] - lower[iBasic];- }- // need extra coding for unbounded- assert (CoinMin(distance, basicDistance) < 1.0e20);- if (distance > basicDistance) {- // incoming becomes basic- solution[chosen] += basicDistance;- if (!iphase)- solution[iBasic] = upper[iBasic];- else- solution[iBasic] = lower[iBasic];- iBasic = chosen;- } else {- // flip- solution[chosen] = upper[chosen];- solution[iBasic] -= distance;- }- } else {- // incoming decreasing so basic increasing- // if phase 0 then go to nearest bound- double distance = solution[chosen] - lower[chosen];- double basicDistance;- if (!iphase) {- assert (iBasic == numberInSet);- assert (solution[iBasic] < lower[iBasic]);- basicDistance = lower[iBasic] - solution[iBasic];- } else {- basicDistance = upper[iBasic] - solution[iBasic];- }- // need extra coding for unbounded - for now just exit- if (CoinMin(distance, basicDistance) > 1.0e20) {- printf("unbounded on set %d\n", iSet);- iphase = 1;- iBasic = numberInSet;- break;- }- if (distance > basicDistance) {- // incoming becomes basic- solution[chosen] -= basicDistance;- if (!iphase)- solution[iBasic] = lower[iBasic];- else- solution[iBasic] = upper[iBasic];- iBasic = chosen;- } else {- // flip- solution[chosen] = lower[chosen];- solution[iBasic] += distance;- }- }- if (!iphase) {- if(iBasic < numberInSet)- break; // feasible- else if (solution[iBasic] >= lower[iBasic] &&- solution[iBasic] <= upper[iBasic])- break; // feasible (on flip)- }- }- }- }- // convert iBasic back and do bounds- if (iBasic == numberInSet) {- // slack basic- setStatus(iSet, ClpSimplex::basic);- iBasic = iSet + numberColumns;- } else {- iBasic += start_[iSet];- model->setStatus(iBasic, ClpSimplex::basic);- // remember bounds flipped- if (upper[numberInSet] == lower[numberInSet])- setStatus(iSet, ClpSimplex::isFixed);- else if (solution[numberInSet] == upper[numberInSet])- setStatus(iSet, ClpSimplex::atLowerBound);- else if (solution[numberInSet] == lower[numberInSet])- setStatus(iSet, ClpSimplex::atUpperBound);- else- abort();- }- for (j = iStart; j < iEnd; j++) {- if (model->getStatus(j) != ClpSimplex::basic) {- int inSet = j - iStart;- columnSolution[j] = solution[inSet];- if (upper[inSet] == lower[inSet])- model->setStatus(j, ClpSimplex::isFixed);- else if (solution[inSet] == upper[inSet])- model->setStatus(j, ClpSimplex::atUpperBound);- else if (solution[inSet] == lower[inSet])- model->setStatus(j, ClpSimplex::atLowerBound);- }- }- }- }- keyVariable_[iSet] = iBasic;- }- }- delete [] lower;- delete [] solution;- delete [] upper;- delete [] cost;- // make sure matrix is in good shape- matrix_->orderMatrix();- // create effective rhs- delete [] rhsOffset_;- rhsOffset_ = new double[numberRows];- delete [] next_;- next_ = new int[numberColumns+numberSets_+2*longestSet];- char * mark = new char[numberColumns];- memset(mark, 0, numberColumns);- for (int iColumn = 0; iColumn < numberColumns; iColumn++)- next_[iColumn] = COIN_INT_MAX;- int i;- int * keys = new int[numberSets_];- for (i = 0; i < numberSets_; i++)- keys[i] = COIN_INT_MAX;- // set up chains- for (i = 0; i < numberColumns; i++) {- if (model->getStatus(i) == ClpSimplex::basic)- mark[i] = 1;- int iSet = backward_[i];- if (iSet >= 0) {- int iNext = keys[iSet];- next_[i] = iNext;- keys[iSet] = i;- }- }- for (i = 0; i < numberSets_; i++) {- int j;- if (getStatus(i) != ClpSimplex::basic) {- // make sure fixed if it is- if (upper_[i] == lower_[i])- setStatus(i, ClpSimplex::isFixed);- // slack not key - choose one with smallest length- int smallest = numberRows + 1;- int key = -1;- j = keys[i];- if (j != COIN_INT_MAX) {- while (1) {- if (mark[j] && columnLength[j] < smallest && !gotBasis) {- key = j;- smallest = columnLength[j];- }- if (next_[j] != COIN_INT_MAX) {- j = next_[j];- } else {- // correct end- next_[j] = -(keys[i] + 1);- break;- }- }- } else {- next_[i+numberColumns] = -(numberColumns + i + 1);- }- if (gotBasis)- key = keyVariable_[i];- if (key >= 0) {- keyVariable_[i] = key;- } else {- // nothing basic - make slack key- //((ClpGubMatrix *)this)->setStatus(i,ClpSimplex::basic);- // fudge to avoid const problem- status_[i] = 1;- }- } else {- // slack key- keyVariable_[i] = numberColumns + i;- int j;- double sol = 0.0;- j = keys[i];- if (j != COIN_INT_MAX) {- while (1) {- sol += columnSolution[j];- if (next_[j] != COIN_INT_MAX) {- j = next_[j];- } else {- // correct end- next_[j] = -(keys[i] + 1);- break;- }- }- } else {- next_[i+numberColumns] = -(numberColumns + i + 1);- }- if (sol > upper_[i] + tolerance) {- setAbove(i);- } else if (sol < lower_[i] - tolerance) {- setBelow(i);- } else {- setFeasible(i);- }- }- // Create next_- int key = keyVariable_[i];- redoSet(model, key, keys[i], i);- }- delete [] keys;- delete [] mark;- rhsOffset(model, true);-}-// redoes next_ for a set.-void-ClpGubMatrix::redoSet(ClpSimplex * model, int newKey, int oldKey, int iSet)-{- int numberColumns = model->numberColumns();- int * save = next_ + numberColumns + numberSets_;- int number = 0;- int stop = -(oldKey + 1);- int j = next_[oldKey];- while (j != stop) {- if (j < 0)- j = -j - 1;- if (j != newKey)- save[number++] = j;- j = next_[j];- }- // and add oldkey- if (newKey != oldKey)- save[number++] = oldKey;- // now do basic- int lastMarker = -(newKey + 1);- keyVariable_[iSet] = newKey;- next_[newKey] = lastMarker;- int last = newKey;- for ( j = 0; j < number; j++) {- int iColumn = save[j];- if (iColumn < numberColumns) {- if (model->getStatus(iColumn) == ClpSimplex::basic) {- next_[last] = iColumn;- next_[iColumn] = lastMarker;- last = iColumn;- }- }- }- // now add in non-basic- for ( j = 0; j < number; j++) {- int iColumn = save[j];- if (iColumn < numberColumns) {- if (model->getStatus(iColumn) != ClpSimplex::basic) {- next_[last] = -(iColumn + 1);- next_[iColumn] = lastMarker;- last = iColumn;- }- }- }--}-/* Returns effective RHS if it is being used. This is used for long problems- or big gub or anywhere where going through full columns is- expensive. This may re-compute */-double *-ClpGubMatrix::rhsOffset(ClpSimplex * model, bool forceRefresh, bool-#ifdef CLP_DEBUG- check-#endif- )-{- //forceRefresh=true;- if (rhsOffset_) {-#ifdef CLP_DEBUG- if (check) {- // no need - but check anyway- // zero out basic- int numberRows = model->numberRows();- int numberColumns = model->numberColumns();- double * solution = new double [numberColumns];- double * rhs = new double[numberRows];- CoinMemcpyN(model->solutionRegion(), numberColumns, solution);- CoinZeroN(rhs, numberRows);- int iRow;- for (int iColumn = 0; iColumn < numberColumns; iColumn++) {- if (model->getColumnStatus(iColumn) == ClpSimplex::basic)- solution[iColumn] = 0.0;- }- for (int iSet = 0; iSet < numberSets_; iSet++) {- int iColumn = keyVariable_[iSet];- if (iColumn < numberColumns)- solution[iColumn] = 0.0;- }- times(-1.0, solution, rhs);- delete [] solution;- const double * columnSolution = model->solutionRegion();- // and now subtract out non basic- ClpSimplex::Status iStatus;- for (int iSet = 0; iSet < numberSets_; iSet++) {- int iColumn = keyVariable_[iSet];- if (iColumn < numberColumns) {- double b = 0.0;- // key is structural - where is slack- iStatus = getStatus(iSet);- assert (iStatus != ClpSimplex::basic);- if (iStatus == ClpSimplex::atLowerBound)- b = lower_[iSet];- else- b = upper_[iSet];- // subtract out others at bounds- if ((gubType_ & 8) == 0) {- int stop = -(iColumn + 1);- int jColumn = next_[iColumn];- // sum all non-basic variables - first skip basic- while(jColumn >= 0)- jColumn = next_[jColumn];- while(jColumn != stop) {- assert (jColumn < 0);- jColumn = -jColumn - 1;- b -= columnSolution[jColumn];- jColumn = next_[jColumn];- }- }- // subtract out- ClpPackedMatrix::add(model, rhs, iColumn, -b);- }- }- for (iRow = 0; iRow < numberRows; iRow++) {- if (fabs(rhs[iRow] - rhsOffset_[iRow]) > 1.0e-3)- printf("** bad effective %d - true %g old %g\n", iRow, rhs[iRow], rhsOffset_[iRow]);- }- delete [] rhs;- }-#endif- if (forceRefresh || (refreshFrequency_ && model->numberIterations() >=- lastRefresh_ + refreshFrequency_)) {- // zero out basic- int numberRows = model->numberRows();- int numberColumns = model->numberColumns();- double * solution = new double [numberColumns];- CoinMemcpyN(model->solutionRegion(), numberColumns, solution);- CoinZeroN(rhsOffset_, numberRows);- for (int iColumn = 0; iColumn < numberColumns; iColumn++) {- if (model->getColumnStatus(iColumn) == ClpSimplex::basic)- solution[iColumn] = 0.0;- }- int iSet;- for ( iSet = 0; iSet < numberSets_; iSet++) {- int iColumn = keyVariable_[iSet];- if (iColumn < numberColumns)- solution[iColumn] = 0.0;- }- times(-1.0, solution, rhsOffset_);- delete [] solution;- lastRefresh_ = model->numberIterations();- const double * columnSolution = model->solutionRegion();- // and now subtract out non basic- ClpSimplex::Status iStatus;- for ( iSet = 0; iSet < numberSets_; iSet++) {- int iColumn = keyVariable_[iSet];- if (iColumn < numberColumns) {- double b = 0.0;- // key is structural - where is slack- iStatus = getStatus(iSet);- assert (iStatus != ClpSimplex::basic);- if (iStatus == ClpSimplex::atLowerBound)- b = lower_[iSet];- else- b = upper_[iSet];- // subtract out others at bounds- if ((gubType_ & 8) == 0) {- int stop = -(iColumn + 1);- int jColumn = next_[iColumn];- // sum all non-basic variables - first skip basic- while(jColumn >= 0)- jColumn = next_[jColumn];- while(jColumn != stop) {- assert (jColumn < 0);- jColumn = -jColumn - 1;- b -= columnSolution[jColumn];- jColumn = next_[jColumn];- }- }- // subtract out- if (b)- ClpPackedMatrix::add(model, rhsOffset_, iColumn, -b);- }- }- }- }- return rhsOffset_;-}-/*- update information for a pivot (and effective rhs)-*/-int-ClpGubMatrix::updatePivot(ClpSimplex * model, double oldInValue, double /*oldOutValue*/)-{- int sequenceIn = model->sequenceIn();- int sequenceOut = model->sequenceOut();- double * solution = model->solutionRegion();- int numberColumns = model->numberColumns();- int numberRows = model->numberRows();- int pivotRow = model->pivotRow();- int iSetIn;- // Correct sequence in- trueSequenceIn_ = sequenceIn;- if (sequenceIn < numberColumns) {- iSetIn = backward_[sequenceIn];- } else if (sequenceIn < numberColumns + numberRows) {- iSetIn = -1;- } else {- iSetIn = gubSlackIn_;- trueSequenceIn_ = numberColumns + numberRows + iSetIn;- }- int iSetOut = -1;- trueSequenceOut_ = sequenceOut;- if (sequenceOut < numberColumns) {- iSetOut = backward_[sequenceOut];- } else if (sequenceOut >= numberRows + numberColumns) {- assert (pivotRow >= numberRows);- int iExtra = pivotRow - numberRows;- assert (iExtra >= 0);- if (iSetOut < 0)- iSetOut = fromIndex_[iExtra];- else- assert(iSetOut == fromIndex_[iExtra]);- trueSequenceOut_ = numberColumns + numberRows + iSetOut;- }- if (rhsOffset_) {- // update effective rhs- if (sequenceIn == sequenceOut) {- assert (sequenceIn < numberRows + numberColumns); // should be easy to deal with- if (sequenceIn < numberColumns)- add(model, rhsOffset_, sequenceIn, oldInValue - solution[sequenceIn]);- } else {- if (sequenceIn < numberColumns) {- // we need to test if WILL be key- ClpPackedMatrix::add(model, rhsOffset_, sequenceIn, oldInValue);- if (iSetIn >= 0) {- // old contribution to rhsOffset_- int key = keyVariable_[iSetIn];- if (key < numberColumns) {- double oldB = 0.0;- ClpSimplex::Status iStatus = getStatus(iSetIn);- if (iStatus == ClpSimplex::atLowerBound)- oldB = lower_[iSetIn];- else- oldB = upper_[iSetIn];- // subtract out others at bounds- if ((gubType_ & 8) == 0) {- int stop = -(key + 1);- int iColumn = next_[key];- // skip basic- while (iColumn >= 0)- iColumn = next_[iColumn];- // sum all non-key variables- while(iColumn != stop) {- assert (iColumn < 0);- iColumn = -iColumn - 1;- if (iColumn == sequenceIn)- oldB -= oldInValue;- else if ( iColumn != sequenceOut )- oldB -= solution[iColumn];- iColumn = next_[iColumn];- }- }- if (oldB)- ClpPackedMatrix::add(model, rhsOffset_, key, oldB);- }- }- } else if (sequenceIn < numberRows + numberColumns) {- //rhsOffset_[sequenceIn-numberColumns] -= oldInValue;- } else {-#ifdef CLP_DEBUG_PRINT- printf("** in is key slack %d\n", sequenceIn);-#endif- // old contribution to rhsOffset_- int key = keyVariable_[iSetIn];- if (key < numberColumns) {- double oldB = 0.0;- ClpSimplex::Status iStatus = getStatus(iSetIn);- if (iStatus == ClpSimplex::atLowerBound)- oldB = lower_[iSetIn];- else- oldB = upper_[iSetIn];- // subtract out others at bounds- if ((gubType_ & 8) == 0) {- int stop = -(key + 1);- int iColumn = next_[key];- // skip basic- while (iColumn >= 0)- iColumn = next_[iColumn];- // sum all non-key variables- while(iColumn != stop) {- assert (iColumn < 0);- iColumn = -iColumn - 1;- if ( iColumn != sequenceOut )- oldB -= solution[iColumn];- iColumn = next_[iColumn];- }- }- if (oldB)- ClpPackedMatrix::add(model, rhsOffset_, key, oldB);- }- }- if (sequenceOut < numberColumns) {- ClpPackedMatrix::add(model, rhsOffset_, sequenceOut, -solution[sequenceOut]);- if (iSetOut >= 0) {- // old contribution to rhsOffset_- int key = keyVariable_[iSetOut];- if (key < numberColumns && iSetIn != iSetOut) {- double oldB = 0.0;- ClpSimplex::Status iStatus = getStatus(iSetOut);- if (iStatus == ClpSimplex::atLowerBound)- oldB = lower_[iSetOut];- else- oldB = upper_[iSetOut];- // subtract out others at bounds- if ((gubType_ & 8) == 0) {- int stop = -(key + 1);- int iColumn = next_[key];- // skip basic- while (iColumn >= 0)- iColumn = next_[iColumn];- // sum all non-key variables- while(iColumn != stop) {- assert (iColumn < 0);- iColumn = -iColumn - 1;- if (iColumn == sequenceIn)- oldB -= oldInValue;- else if ( iColumn != sequenceOut )- oldB -= solution[iColumn];- iColumn = next_[iColumn];- }- }- if (oldB)- ClpPackedMatrix::add(model, rhsOffset_, key, oldB);- }- }- } else if (sequenceOut < numberRows + numberColumns) {- //rhsOffset_[sequenceOut-numberColumns] -= -solution[sequenceOut];- } else {-#ifdef CLP_DEBUG_PRINT- printf("** out is key slack %d\n", sequenceOut);-#endif- assert (pivotRow >= numberRows);- }- }- }- int * pivotVariable = model->pivotVariable();- // may need to deal with key- // Also need coding to mark/allow key slack entering- if (pivotRow >= numberRows) {- assert (sequenceOut >= numberRows + numberColumns || sequenceOut == keyVariable_[iSetOut]);-#ifdef CLP_DEBUG_PRINT- if (sequenceIn >= numberRows + numberColumns)- printf("key slack %d in, set out %d\n", gubSlackIn_, iSetOut);- printf("** danger - key out for set %d in %d (set %d)\n", iSetOut, sequenceIn,- iSetIn);-#endif- // if slack out mark correctly- if (sequenceOut >= numberRows + numberColumns) {- double value = model->valueOut();- if (value == upper_[iSetOut]) {- setStatus(iSetOut, ClpSimplex::atUpperBound);- } else if (value == lower_[iSetOut]) {- setStatus(iSetOut, ClpSimplex::atLowerBound);- } else {- if (fabs(value - upper_[iSetOut]) <- fabs(value - lower_[iSetOut])) {- setStatus(iSetOut, ClpSimplex::atUpperBound);- } else {- setStatus(iSetOut, ClpSimplex::atLowerBound);- }- }- if (upper_[iSetOut] == lower_[iSetOut])- setStatus(iSetOut, ClpSimplex::isFixed);- setFeasible(iSetOut);- }- if (iSetOut == iSetIn) {- // key swap- int key;- if (sequenceIn >= numberRows + numberColumns) {- key = numberColumns + iSetIn;- setStatus(iSetIn, ClpSimplex::basic);- } else {- key = sequenceIn;- }- redoSet(model, key, keyVariable_[iSetIn], iSetIn);- } else {- // key was chosen- assert (possiblePivotKey_ >= 0 && possiblePivotKey_ < numberRows);- int key = pivotVariable[possiblePivotKey_];- // and set incoming here- if (sequenceIn >= numberRows + numberColumns) {- // slack in - so use old key- sequenceIn = keyVariable_[iSetIn];- model->setStatus(sequenceIn, ClpSimplex::basic);- setStatus(iSetIn, ClpSimplex::basic);- redoSet(model, iSetIn + numberColumns, keyVariable_[iSetIn], iSetIn);- }- //? do not do if iSetIn<0 ? as will be done later- pivotVariable[possiblePivotKey_] = sequenceIn;- if (sequenceIn < numberColumns)- backToPivotRow_[sequenceIn] = possiblePivotKey_;- redoSet(model, key, keyVariable_[iSetOut], iSetOut);- }- } else {- if (sequenceOut < numberColumns) {- if (iSetIn >= 0 && iSetOut == iSetIn) {- // key not out - only problem is if slack in- int key;- if (sequenceIn >= numberRows + numberColumns) {- key = numberColumns + iSetIn;- setStatus(iSetIn, ClpSimplex::basic);- assert (pivotRow < numberRows);- // must swap with current key- int key = keyVariable_[iSetIn];- model->setStatus(key, ClpSimplex::basic);- pivotVariable[pivotRow] = key;- backToPivotRow_[key] = pivotRow;- } else {- key = keyVariable_[iSetIn];- }- redoSet(model, key, keyVariable_[iSetIn], iSetIn);- } else if (iSetOut >= 0) {- // just redo set- int key = keyVariable_[iSetOut];;- redoSet(model, key, keyVariable_[iSetOut], iSetOut);- }- }- }- if (iSetIn >= 0 && iSetIn != iSetOut) {- int key = keyVariable_[iSetIn];- if (sequenceIn == numberColumns + 2 * numberRows) {- // key slack in- assert (pivotRow < numberRows);- // must swap with current key- model->setStatus(key, ClpSimplex::basic);- pivotVariable[pivotRow] = key;- backToPivotRow_[key] = pivotRow;- setStatus(iSetIn, ClpSimplex::basic);- key = iSetIn + numberColumns;- }- // redo set to allow for new one- redoSet(model, key, keyVariable_[iSetIn], iSetIn);- }- // update pivot- if (sequenceIn < numberColumns) {- if (pivotRow < numberRows) {- backToPivotRow_[sequenceIn] = pivotRow;- } else {- if (possiblePivotKey_ >= 0) {- assert (possiblePivotKey_ < numberRows);- backToPivotRow_[sequenceIn] = possiblePivotKey_;- pivotVariable[possiblePivotKey_] = sequenceIn;- }- }- } else if (sequenceIn >= numberRows + numberColumns) {- // key in - something should have been done before- int key = keyVariable_[iSetIn];- assert (key == numberColumns + iSetIn);- //pivotVariable[pivotRow]=key;- //backToPivotRow_[key]=pivotRow;- //model->setStatus(key,ClpSimplex::basic);- //key=numberColumns+iSetIn;- setStatus(iSetIn, ClpSimplex::basic);- redoSet(model, key, keyVariable_[iSetIn], iSetIn);- }-#ifdef CLP_DEBUG- {- char * xx = new char[numberColumns+numberRows];- memset(xx, 0, numberRows + numberColumns);- for (int i = 0; i < numberRows; i++) {- int iPivot = pivotVariable[i];- assert (iPivot < numberRows + numberColumns);- assert (!xx[iPivot]);- xx[iPivot] = 1;- if (iPivot < numberColumns) {- int iBack = backToPivotRow_[iPivot];- assert (i == iBack);- }- }- delete [] xx;- }-#endif- if (rhsOffset_) {- // update effective rhs- if (sequenceIn != sequenceOut) {- if (sequenceIn < numberColumns) {- if (iSetIn >= 0) {- // new contribution to rhsOffset_- int key = keyVariable_[iSetIn];- if (key < numberColumns) {- double newB = 0.0;- ClpSimplex::Status iStatus = getStatus(iSetIn);- if (iStatus == ClpSimplex::atLowerBound)- newB = lower_[iSetIn];- else- newB = upper_[iSetIn];- // subtract out others at bounds- if ((gubType_ & 8) == 0) {- int stop = -(key + 1);- int iColumn = next_[key];- // skip basic- while (iColumn >= 0)- iColumn = next_[iColumn];- // sum all non-key variables- while(iColumn != stop) {- assert (iColumn < 0);- iColumn = -iColumn - 1;- newB -= solution[iColumn];- iColumn = next_[iColumn];- }- }- if (newB)- ClpPackedMatrix::add(model, rhsOffset_, key, -newB);- }- }- }- if (iSetOut >= 0) {- // new contribution to rhsOffset_- int key = keyVariable_[iSetOut];- if (key < numberColumns && iSetIn != iSetOut) {- double newB = 0.0;- ClpSimplex::Status iStatus = getStatus(iSetOut);- if (iStatus == ClpSimplex::atLowerBound)- newB = lower_[iSetOut];- else- newB = upper_[iSetOut];- // subtract out others at bounds- if ((gubType_ & 8) == 0) {- int stop = -(key + 1);- int iColumn = next_[key];- // skip basic- while (iColumn >= 0)- iColumn = next_[iColumn];- // sum all non-key variables- while(iColumn != stop) {- assert (iColumn < 0);- iColumn = -iColumn - 1;- newB -= solution[iColumn];- iColumn = next_[iColumn];- }- }- if (newB)- ClpPackedMatrix::add(model, rhsOffset_, key, -newB);- }- }- }- }-#ifdef CLP_DEBUG- // debug- {- int i;- char * xxxx = new char[numberColumns];- memset(xxxx, 0, numberColumns);- for (i = 0; i < numberRows; i++) {- int iPivot = pivotVariable[i];- assert (model->getStatus(iPivot) == ClpSimplex::basic);- if (iPivot < numberColumns && backward_[iPivot] >= 0)- xxxx[iPivot] = 1;- }- double primalTolerance = model->primalTolerance();- for (i = 0; i < numberSets_; i++) {- int key = keyVariable_[i];- double value = 0.0;- // sum over all except key- int iColumn = next_[key];- // sum all non-key variables- int k = 0;- int stop = -(key + 1);- while (iColumn != stop) {- if (iColumn < 0)- iColumn = -iColumn - 1;- value += solution[iColumn];- k++;- assert (k < 100);- assert (backward_[iColumn] == i);- iColumn = next_[iColumn];- }- iColumn = next_[key];- if (key < numberColumns) {- // feasibility will be done later- assert (getStatus(i) != ClpSimplex::basic);- double sol;- if (getStatus(i) == ClpSimplex::atUpperBound)- sol = upper_[i] - value;- else- sol = lower_[i] - value;- //printf("xx Value of key structural %d for set %d is %g - cost %g\n",key,i,sol,- // cost[key]);- //if (fabs(sol-solution[key])>1.0e-3)- //printf("** stored value was %g\n",solution[key]);- } else {- // slack is key- double infeasibility = 0.0;- if (value > upper_[i] + primalTolerance) {- infeasibility = value - upper_[i] - primalTolerance;- //setAbove(i);- } else if (value < lower_[i] - primalTolerance) {- infeasibility = lower_[i] - value - primalTolerance ;- //setBelow(i);- } else {- //setFeasible(i);- }- //printf("xx Value of key slack for set %d is %g\n",i,value);- }- while (iColumn >= 0) {- assert (xxxx[iColumn]);- xxxx[iColumn] = 0;- iColumn = next_[iColumn];- }- }- for (i = 0; i < numberColumns; i++) {- if (i < numberColumns && backward_[i] >= 0) {- assert (!xxxx[i] || i == keyVariable_[backward_[i]]);- }- }- delete [] xxxx;- }-#endif- return 0;-}-// Switches off dj checking each factorization (for BIG models)-void-ClpGubMatrix::switchOffCheck()-{- noCheck_ = 0;- infeasibilityWeight_ = 0.0;-}-// Correct sequence in and out to give true value-void-ClpGubMatrix::correctSequence(const ClpSimplex * /*model*/, int & sequenceIn, int & sequenceOut)-{- if (sequenceIn != -999) {- sequenceIn = trueSequenceIn_;- sequenceOut = trueSequenceOut_;- }-}
− cbits/coin/Clp_C_Interface.cpp
@@ -1,1323 +0,0 @@-// $Id: Clp_C_Interface.cpp 1928 2013-04-06 12:54:16Z stefan $-// Copyright (C) 2003, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).---#include "CoinPragma.hpp"--#include <cmath>-#include <cstring>--#include "CoinHelperFunctions.hpp"-#include "ClpSimplex.hpp"-#include "ClpInterior.hpp"-#ifndef SLIM_CLP-#include "Idiot.hpp"-#endif-#include <cfloat>-// Get C stuff but with extern C-#define CLP_EXTERN_C-#include "Coin_C_defines.h"--/// To allow call backs-class CMessageHandler : public CoinMessageHandler {--public:- /**@name Overrides */- //@{- virtual int print();- //@}- /**@name set and get */- //@{- /// Model- const Clp_Simplex * model() const;- void setModel(Clp_Simplex * model);- /// Call back- void setCallBack(clp_callback callback);- //@}-- /**@name Constructors, destructor */- //@{- /** Default constructor. */- CMessageHandler();- /// Constructor with pointer to model- CMessageHandler(Clp_Simplex * model,- FILE * userPointer = NULL);- /** Destructor */- virtual ~CMessageHandler();- //@}-- /**@name Copy method */- //@{- /** The copy constructor. */- CMessageHandler(const CMessageHandler&);- /** The copy constructor from an CoinSimplexMessageHandler. */- CMessageHandler(const CoinMessageHandler&);-- CMessageHandler& operator=(const CMessageHandler&);- /// Clone- virtual CoinMessageHandler * clone() const ;- //@}---protected:- /**@name Data members- The data members are protected to allow access for derived classes. */- //@{- /// Pointer back to model- Clp_Simplex * model_;- /// call back- clp_callback callback_;- //@}-};---//--------------------------------------------------------------------// Default Constructor-//--------------------------------------------------------------------CMessageHandler::CMessageHandler ()- : CoinMessageHandler(),- model_(NULL),- callback_(NULL)-{-}--//--------------------------------------------------------------------// Copy constructor-//--------------------------------------------------------------------CMessageHandler::CMessageHandler (const CMessageHandler & rhs)- : CoinMessageHandler(rhs),- model_(rhs.model_),- callback_(rhs.callback_)-{-}--CMessageHandler::CMessageHandler (const CoinMessageHandler & rhs)- : CoinMessageHandler(rhs),- model_(NULL),- callback_(NULL)-{-}--// Constructor with pointer to model-CMessageHandler::CMessageHandler(Clp_Simplex * model,- FILE * )- : CoinMessageHandler(),- model_(model),- callback_(NULL)-{-}--//--------------------------------------------------------------------// Destructor-//--------------------------------------------------------------------CMessageHandler::~CMessageHandler ()-{-}--//-----------------------------------------------------------------// Assignment operator-//--------------------------------------------------------------------CMessageHandler &-CMessageHandler::operator=(const CMessageHandler& rhs)-{- if (this != &rhs) {- CoinMessageHandler::operator=(rhs);- model_ = rhs.model_;- callback_ = rhs.callback_;- }- return *this;-}-//--------------------------------------------------------------------// Clone-//--------------------------------------------------------------------CoinMessageHandler * CMessageHandler::clone() const-{- return new CMessageHandler(*this);-}--int-CMessageHandler::print()-{- if (callback_) {- int messageNumber = currentMessage().externalNumber();- if (currentSource() != "Clp")- messageNumber += 1000000;- int i;- int nDouble = numberDoubleFields();- assert (nDouble <= 10);- double vDouble[10];- for (i = 0; i < nDouble; i++)- vDouble[i] = doubleValue(i);- int nInt = numberIntFields();- assert (nInt <= 10);- int vInt[10];- for (i = 0; i < nInt; i++)- vInt[i] = intValue(i);- int nString = numberStringFields();- assert (nString <= 10);- char * vString[10];- for (i = 0; i < nString; i++) {- std::string value = stringValue(i);- vString[i] = CoinStrdup(value.c_str());- }- callback_(model_, messageNumber,- nDouble, vDouble,- nInt, vInt,- nString, vString);- for (i = 0; i < nString; i++)- free(vString[i]);-- }- return CoinMessageHandler::print();-}-const Clp_Simplex *-CMessageHandler::model() const-{- return model_;-}-void-CMessageHandler::setModel(Clp_Simplex * model)-{- model_ = model;-}-// Call back-void-CMessageHandler::setCallBack(clp_callback callback)-{- callback_ = callback;-}--#include "Clp_C_Interface.h"-#include <string>-#include <stdio.h>-#include <iostream>--#if defined(__MWERKS__)-#pragma export on-#endif-/* Default constructor */-COINLIBAPI Clp_Simplex * COINLINKAGE-Clp_newModel()-{- Clp_Simplex * model = new Clp_Simplex;- model->model_ = new ClpSimplex();- model->handler_ = NULL;- return model;-}-/* Destructor */-COINLIBAPI void COINLINKAGE-Clp_deleteModel(Clp_Simplex * model)-{- delete model->model_;- delete model->handler_;- delete model;-}--/* Loads a problem (the constraints on the- rows are given by lower and upper bounds). If a pointer is NULL then the- following values are the default:- <ul>- <li> <code>colub</code>: all columns have upper bound infinity- <li> <code>collb</code>: all columns have lower bound 0- <li> <code>rowub</code>: all rows have upper bound infinity- <li> <code>rowlb</code>: all rows have lower bound -infinity- <li> <code>obj</code>: all variables have 0 objective coefficient- </ul>-*/-/* Just like the other loadProblem() method except that the matrix is- given in a standard column major ordered format (without gaps). */-COINLIBAPI void COINLINKAGE-Clp_loadProblem (Clp_Simplex * model, const int numcols, const int numrows,- const CoinBigIndex * start, const int* index,- const double* value,- const double* collb, const double* colub,- const double* obj,- const double* rowlb, const double* rowub)-{- const char prefix[] = "Clp_c_Interface::Clp_loadProblem(): ";- const int verbose = 0;- if (verbose > 1) {- printf("%s numcols = %i, numrows = %i\n",- prefix, numcols, numrows);- printf("%s model = %p, start = %p, index = %p, value = %p\n",- prefix, reinterpret_cast<const void *>(model), reinterpret_cast<const void *>(start), reinterpret_cast<const void *>(index), reinterpret_cast<const void *>(value));- printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",- prefix, reinterpret_cast<const void *>(collb), reinterpret_cast<const void *>(colub), reinterpret_cast<const void *>(obj), reinterpret_cast<const void *>(rowlb), reinterpret_cast<const void *>(rowub));- }- model->model_->loadProblem(numcols, numrows, start, index, value,- collb, colub, obj, rowlb, rowub);-}-/* read quadratic part of the objective (the matrix part) */-COINLIBAPI void COINLINKAGE-Clp_loadQuadraticObjective(Clp_Simplex * model,- const int numberColumns,- const CoinBigIndex * start,- const int * column,- const double * element)-{-- model->model_->loadQuadraticObjective(numberColumns,- start, column, element);--}-/* Read an mps file from the given filename */-COINLIBAPI int COINLINKAGE-Clp_readMps(Clp_Simplex * model, const char *filename,- int keepNames,- int ignoreErrors)-{- return model->model_->readMps(filename, keepNames != 0, ignoreErrors != 0);-}-/* Copy in integer informations */-COINLIBAPI void COINLINKAGE-Clp_copyInIntegerInformation(Clp_Simplex * model, const char * information)-{- model->model_->copyInIntegerInformation(information);-}-/* Drop integer informations */-COINLIBAPI void COINLINKAGE-Clp_deleteIntegerInformation(Clp_Simplex * model)-{- model->model_->deleteIntegerInformation();-}-/* Resizes rim part of model */-COINLIBAPI void COINLINKAGE-Clp_resize (Clp_Simplex * model, int newNumberRows, int newNumberColumns)-{- model->model_->resize(newNumberRows, newNumberColumns);-}-/* Deletes rows */-COINLIBAPI void COINLINKAGE-Clp_deleteRows(Clp_Simplex * model, int number, const int * which)-{- model->model_->deleteRows(number, which);-}-/* Add rows */-COINLIBAPI void COINLINKAGE-Clp_addRows(Clp_Simplex * model, int number, const double * rowLower,- const double * rowUpper,- const int * rowStarts, const int * columns,- const double * elements)-{- model->model_->addRows(number, rowLower, rowUpper, rowStarts, columns, elements);-}--/* Deletes columns */-COINLIBAPI void COINLINKAGE-Clp_deleteColumns(Clp_Simplex * model, int number, const int * which)-{- model->model_->deleteColumns(number, which);-}-/* Add columns */-COINLIBAPI void COINLINKAGE-Clp_addColumns(Clp_Simplex * model, int number, const double * columnLower,- const double * columnUpper,- const double * objective,- const int * columnStarts, const int * rows,- const double * elements)-{- model->model_->addColumns(number, columnLower, columnUpper, objective,- columnStarts, rows, elements);-}-/* Change row lower bounds */-COINLIBAPI void COINLINKAGE-Clp_chgRowLower(Clp_Simplex * model, const double * rowLower)-{- model->model_->chgRowLower(rowLower);-}-/* Change row upper bounds */-COINLIBAPI void COINLINKAGE-Clp_chgRowUpper(Clp_Simplex * model, const double * rowUpper)-{- model->model_->chgRowUpper(rowUpper);-}-/* Change column lower bounds */-COINLIBAPI void COINLINKAGE-Clp_chgColumnLower(Clp_Simplex * model, const double * columnLower)-{- model->model_->chgColumnLower(columnLower);-}-/* Change column upper bounds */-COINLIBAPI void COINLINKAGE-Clp_chgColumnUpper(Clp_Simplex * model, const double * columnUpper)-{- model->model_->chgColumnUpper(columnUpper);-}-/* Change objective coefficients */-COINLIBAPI void COINLINKAGE-Clp_chgObjCoefficients(Clp_Simplex * model, const double * objIn)-{- model->model_->chgObjCoefficients(objIn);-}-/* Drops names - makes lengthnames 0 and names empty */-COINLIBAPI void COINLINKAGE-Clp_dropNames(Clp_Simplex * model)-{- model->model_->dropNames();-}-/* Copies in names */-COINLIBAPI void COINLINKAGE-Clp_copyNames(Clp_Simplex * model, const char * const * rowNamesIn,- const char * const * columnNamesIn)-{- int iRow;- std::vector<std::string> rowNames;- int numberRows = model->model_->numberRows();- rowNames.reserve(numberRows);- for (iRow = 0; iRow < numberRows; iRow++) {- rowNames.push_back(rowNamesIn[iRow]);- }-- int iColumn;- std::vector<std::string> columnNames;- int numberColumns = model->model_->numberColumns();- columnNames.reserve(numberColumns);- for (iColumn = 0; iColumn < numberColumns; iColumn++) {- columnNames.push_back(columnNamesIn[iColumn]);- }- model->model_->copyNames(rowNames, columnNames);-}--/* Number of rows */-COINLIBAPI int COINLINKAGE-Clp_numberRows(Clp_Simplex * model)-{- return model->model_->numberRows();-}-/* Number of columns */-COINLIBAPI int COINLINKAGE-Clp_numberColumns(Clp_Simplex * model)-{- return model->model_->numberColumns();-}-/* Primal tolerance to use */-COINLIBAPI double COINLINKAGE-Clp_primalTolerance(Clp_Simplex * model)-{- return model->model_->primalTolerance();-}-COINLIBAPI void COINLINKAGE-Clp_setPrimalTolerance(Clp_Simplex * model, double value)-{- model->model_->setPrimalTolerance(value);-}-/* Dual tolerance to use */-COINLIBAPI double COINLINKAGE-Clp_dualTolerance(Clp_Simplex * model)-{- return model->model_->dualTolerance();-}-COINLIBAPI void COINLINKAGE-Clp_setDualTolerance(Clp_Simplex * model, double value)-{- model->model_->setDualTolerance(value);-}-/* Dual objective limit */-COINLIBAPI double COINLINKAGE-Clp_dualObjectiveLimit(Clp_Simplex * model)-{- return model->model_->dualObjectiveLimit();-}-COINLIBAPI void COINLINKAGE-Clp_setDualObjectiveLimit(Clp_Simplex * model, double value)-{- model->model_->setDualObjectiveLimit(value);-}-/* Objective offset */-COINLIBAPI double COINLINKAGE-Clp_objectiveOffset(Clp_Simplex * model)-{- return model->model_->objectiveOffset();-}-COINLIBAPI void COINLINKAGE-Clp_setObjectiveOffset(Clp_Simplex * model, double value)-{- model->model_->setObjectiveOffset(value);-}-/* Fills in array with problem name */-COINLIBAPI void COINLINKAGE-Clp_problemName(Clp_Simplex * model, int maxNumberCharacters, char * array)-{- std::string name = model->model_->problemName();- maxNumberCharacters = CoinMin(maxNumberCharacters,- ((int) strlen(name.c_str()))+1) ;- strncpy(array, name.c_str(), maxNumberCharacters - 1);- array[maxNumberCharacters-1] = '\0';-}-/* Sets problem name. Must have \0 at end. */-COINLIBAPI int COINLINKAGE-Clp_setProblemName(Clp_Simplex * model, int /*maxNumberCharacters*/, char * array)-{- return model->model_->setStrParam(ClpProbName, array);-}-/* Number of iterations */-COINLIBAPI int COINLINKAGE-Clp_numberIterations(Clp_Simplex * model)-{- return model->model_->numberIterations();-}-COINLIBAPI void COINLINKAGE-Clp_setNumberIterations(Clp_Simplex * model, int numberIterations)-{- model->model_->setNumberIterations(numberIterations);-}-/* Maximum number of iterations */-COINLIBAPI int maximumIterations(Clp_Simplex * model)-{- return model->model_->maximumIterations();-}-COINLIBAPI void COINLINKAGE-Clp_setMaximumIterations(Clp_Simplex * model, int value)-{- model->model_->setMaximumIterations(value);-}-/* Maximum time in seconds (from when set called) */-COINLIBAPI double COINLINKAGE-Clp_maximumSeconds(Clp_Simplex * model)-{- return model->model_->maximumSeconds();-}-COINLIBAPI void COINLINKAGE-Clp_setMaximumSeconds(Clp_Simplex * model, double value)-{- model->model_->setMaximumSeconds(value);-}-/* Returns true if hit maximum iteratio`ns (or time) */-COINLIBAPI int COINLINKAGE-Clp_hitMaximumIterations(Clp_Simplex * model)-{- return model->model_->hitMaximumIterations() ? 1 : 0;-}-/* Status of problem:- 0 - optimal- 1 - primal infeasible- 2 - dual infeasible- 3 - stopped on iterations etc- 4 - stopped due to errors-*/-COINLIBAPI int COINLINKAGE-Clp_status(Clp_Simplex * model)-{- return model->model_->status();-}-/* Set problem status */-COINLIBAPI void COINLINKAGE-Clp_setProblemStatus(Clp_Simplex * model, int problemStatus)-{- model->model_->setProblemStatus(problemStatus);-}-/* Secondary status of problem - may get extended- 0 - none- 1 - primal infeasible because dual limit reached- 2 - scaled problem optimal - unscaled has primal infeasibilities- 3 - scaled problem optimal - unscaled has dual infeasibilities- 4 - scaled problem optimal - unscaled has both dual and primal infeasibilities-*/-COINLIBAPI int COINLINKAGE-Clp_secondaryStatus(Clp_Simplex * model)-{- return model->model_->secondaryStatus();-}-COINLIBAPI void COINLINKAGE-Clp_setSecondaryStatus(Clp_Simplex * model, int status)-{- model->model_->setSecondaryStatus(status);-}-/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */-COINLIBAPI double COINLINKAGE-Clp_optimizationDirection(Clp_Simplex * model)-{- return model->model_->optimizationDirection();-}-COINLIBAPI void COINLINKAGE-Clp_setOptimizationDirection(Clp_Simplex * model, double value)-{- model->model_->setOptimizationDirection(value);-}-/* Primal row solution */-COINLIBAPI double * COINLINKAGE-Clp_primalRowSolution(Clp_Simplex * model)-{- return model->model_->primalRowSolution();-}-/* Primal column solution */-COINLIBAPI double * COINLINKAGE-Clp_primalColumnSolution(Clp_Simplex * model)-{- return model->model_->primalColumnSolution();-}-/* Dual row solution */-COINLIBAPI double * COINLINKAGE-Clp_dualRowSolution(Clp_Simplex * model)-{- return model->model_->dualRowSolution();-}-/* Reduced costs */-COINLIBAPI double * COINLINKAGE-Clp_dualColumnSolution(Clp_Simplex * model)-{- return model->model_->dualColumnSolution();-}-/* Row lower */-COINLIBAPI double* COINLINKAGE-Clp_rowLower(Clp_Simplex * model)-{- return model->model_->rowLower();-}-/* Row upper */-COINLIBAPI double* COINLINKAGE-Clp_rowUpper(Clp_Simplex * model)-{- return model->model_->rowUpper();-}-/* Objective */-COINLIBAPI double * COINLINKAGE-Clp_objective(Clp_Simplex * model)-{- return model->model_->objective();-}-/* Column Lower */-COINLIBAPI double * COINLINKAGE-Clp_columnLower(Clp_Simplex * model)-{- return model->model_->columnLower();-}-/* Column Upper */-COINLIBAPI double * COINLINKAGE-Clp_columnUpper(Clp_Simplex * model)-{- return model->model_->columnUpper();-}-/* Number of elements in matrix */-COINLIBAPI int COINLINKAGE-Clp_getNumElements(Clp_Simplex * model)-{- return model->model_->getNumElements();-}-// Column starts in matrix-COINLIBAPI const CoinBigIndex * COINLINKAGE Clp_getVectorStarts(Clp_Simplex * model)-{- CoinPackedMatrix * matrix;- matrix = model->model_->matrix();- return (matrix == NULL) ? NULL : matrix->getVectorStarts();-}--// Row indices in matrix-COINLIBAPI const int * COINLINKAGE Clp_getIndices(Clp_Simplex * model)-{- CoinPackedMatrix * matrix = model->model_->matrix();- return (matrix == NULL) ? NULL : matrix->getIndices();-}--// Column vector lengths in matrix-COINLIBAPI const int * COINLINKAGE Clp_getVectorLengths(Clp_Simplex * model)-{- CoinPackedMatrix * matrix = model->model_->matrix();- return (matrix == NULL) ? NULL : matrix->getVectorLengths();-}--// Element values in matrix-COINLIBAPI const double * COINLINKAGE Clp_getElements(Clp_Simplex * model)-{- CoinPackedMatrix * matrix = model->model_->matrix();- return (matrix == NULL) ? NULL : matrix->getElements();-}-/* Objective value */-COINLIBAPI double COINLINKAGE-Clp_objectiveValue(Clp_Simplex * model)-{- return model->model_->objectiveValue();-}-/* Integer information */-COINLIBAPI char * COINLINKAGE-Clp_integerInformation(Clp_Simplex * model)-{- return model->model_->integerInformation();-}-/* Infeasibility/unbounded ray (NULL returned if none/wrong)- Up to user to use free() on these arrays. */-COINLIBAPI double * COINLINKAGE-Clp_infeasibilityRay(Clp_Simplex * model)-{- const double * ray = model->model_->internalRay();- double * array = NULL;- int numberRows = model->model_->numberRows(); - int status = model->model_->status();- if (status == 1 && ray) {- array = static_cast<double*>(malloc(numberRows*sizeof(double)));- memcpy(array,ray,numberRows*sizeof(double));-#ifdef PRINT_RAY_METHOD- printf("Infeasibility ray obtained by algorithm %s\n",model->model_->algorithm()>0 ?- "primal" : "dual");-#endif- }- return array;-}-COINLIBAPI double * COINLINKAGE-Clp_unboundedRay(Clp_Simplex * model)-{- const double * ray = model->model_->internalRay();- double * array = NULL;- int numberColumns = model->model_->numberColumns(); - int status = model->model_->status();- if (status == 2 && ray) {- array = static_cast<double*>(malloc(numberColumns*sizeof(double)));- memcpy(array,ray,numberColumns*sizeof(double));- }- return array;-}-/* See if status array exists (partly for OsiClp) */-COINLIBAPI int COINLINKAGE-Clp_statusExists(Clp_Simplex * model)-{- return model->model_->statusExists() ? 1 : 0;-}-/* Return address of status array (char[numberRows+numberColumns]) */-COINLIBAPI unsigned char * COINLINKAGE-Clp_statusArray(Clp_Simplex * model)-{- return model->model_->statusArray();-}-/* Copy in status vector */-COINLIBAPI void COINLINKAGE-Clp_copyinStatus(Clp_Simplex * model, const unsigned char * statusArray)-{- model->model_->copyinStatus(statusArray);-}--/* User pointer for whatever reason */-COINLIBAPI void COINLINKAGE-Clp_setUserPointer (Clp_Simplex * model, void * pointer)-{- model->model_->setUserPointer(pointer);-}-COINLIBAPI void * COINLINKAGE-Clp_getUserPointer (Clp_Simplex * model)-{- return model->model_->getUserPointer();-}-/* Pass in Callback function */-COINLIBAPI void COINLINKAGE-Clp_registerCallBack(Clp_Simplex * model,- clp_callback userCallBack)-{- // Will be copy of users one- delete model->handler_;- model->handler_ = new CMessageHandler(*(model->model_->messageHandler()));- model->handler_->setCallBack(userCallBack);- model->handler_->setModel(model);- model->model_->passInMessageHandler(model->handler_);-}-/* Unset Callback function */-COINLIBAPI void COINLINKAGE-Clp_clearCallBack(Clp_Simplex * model)-{- delete model->handler_;- model->handler_ = NULL;-}-/* Amount of print out:- 0 - none- 1 - just final- 2 - just factorizations- 3 - as 2 plus a bit more- 4 - verbose- above that 8,16,32 etc just for selective debug-*/-COINLIBAPI void COINLINKAGE-Clp_setLogLevel(Clp_Simplex * model, int value)-{- model->model_->setLogLevel(value);-}-COINLIBAPI int COINLINKAGE-Clp_logLevel(Clp_Simplex * model)-{- return model->model_->logLevel();-}-/* length of names (0 means no names0 */-COINLIBAPI int COINLINKAGE-Clp_lengthNames(Clp_Simplex * model)-{- return model->model_->lengthNames();-}-/* Fill in array (at least lengthNames+1 long) with a row name */-COINLIBAPI void COINLINKAGE-Clp_rowName(Clp_Simplex * model, int iRow, char * name)-{- std::string rowName = model->model_->rowName(iRow);- strcpy(name, rowName.c_str());-}-/* Fill in array (at least lengthNames+1 long) with a column name */-COINLIBAPI void COINLINKAGE-Clp_columnName(Clp_Simplex * model, int iColumn, char * name)-{- std::string columnName = model->model_->columnName(iColumn);- strcpy(name, columnName.c_str());-}--/* General solve algorithm which can do presolve.- See ClpSolve.hpp for options-*/-COINLIBAPI int COINLINKAGE-Clp_initialSolve(Clp_Simplex * model)-{- return model->model_->initialSolve();-}-/* Pass solve options. (Exception to direct analogue rule) */-COINLIBAPI int COINLINKAGE-Clp_initialSolveWithOptions(Clp_Simplex * model, Clp_Solve * s)-{- return model->model_->initialSolve(s->options);-}-/* Barrier initial solve */-COINLIBAPI int COINLINKAGE-Clp_initialBarrierSolve(Clp_Simplex * model0)-{- ClpSimplex *model = model0->model_;-- return model->initialBarrierSolve();--}-/* Barrier initial solve */-COINLIBAPI int COINLINKAGE-Clp_initialBarrierNoCrossSolve(Clp_Simplex * model0)-{- ClpSimplex *model = model0->model_;-- return model->initialBarrierNoCrossSolve();--}-/* Dual initial solve */-COINLIBAPI int COINLINKAGE-Clp_initialDualSolve(Clp_Simplex * model)-{- return model->model_->initialDualSolve();-}-/* Primal initial solve */-COINLIBAPI int COINLINKAGE-Clp_initialPrimalSolve(Clp_Simplex * model)-{- return model->model_->initialPrimalSolve();-}-/* Dual algorithm - see ClpSimplexDual.hpp for method */-COINLIBAPI int COINLINKAGE-Clp_dual(Clp_Simplex * model, int ifValuesPass)-{- return model->model_->dual(ifValuesPass);-}-/* Primal algorithm - see ClpSimplexPrimal.hpp for method */-COINLIBAPI int COINLINKAGE-Clp_primal(Clp_Simplex * model, int ifValuesPass)-{- return model->model_->primal(ifValuesPass);-}-/* Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) */-COINLIBAPI void COINLINKAGE-Clp_scaling(Clp_Simplex * model, int mode)-{- model->model_->scaling(mode);-}-/* Gets scalingFlag */-COINLIBAPI int COINLINKAGE-Clp_scalingFlag(Clp_Simplex * model)-{- return model->model_->scalingFlag();-}-/* Crash - at present just aimed at dual, returns- -2 if dual preferred and crash basis created- -1 if dual preferred and all slack basis preferred- 0 if basis going in was not all slack- 1 if primal preferred and all slack basis preferred- 2 if primal preferred and crash basis created.-- if gap between bounds <="gap" variables can be flipped-- If "pivot" is- 0 No pivoting (so will just be choice of algorithm)- 1 Simple pivoting e.g. gub- 2 Mini iterations-*/-COINLIBAPI int COINLINKAGE-Clp_crash(Clp_Simplex * model, double gap, int pivot)-{- return model->model_->crash(gap, pivot);-}-/* If problem is primal feasible */-COINLIBAPI int COINLINKAGE-Clp_primalFeasible(Clp_Simplex * model)-{- return model->model_->primalFeasible() ? 1 : 0;-}-/* If problem is dual feasible */-COINLIBAPI int COINLINKAGE-Clp_dualFeasible(Clp_Simplex * model)-{- return model->model_->dualFeasible() ? 1 : 0;-}-/* Dual bound */-COINLIBAPI double COINLINKAGE-Clp_dualBound(Clp_Simplex * model)-{- return model->model_->dualBound();-}-COINLIBAPI void COINLINKAGE-Clp_setDualBound(Clp_Simplex * model, double value)-{- model->model_->setDualBound(value);-}-/* Infeasibility cost */-COINLIBAPI double COINLINKAGE-Clp_infeasibilityCost(Clp_Simplex * model)-{- return model->model_->infeasibilityCost();-}-COINLIBAPI void COINLINKAGE-Clp_setInfeasibilityCost(Clp_Simplex * model, double value)-{- model->model_->setInfeasibilityCost(value);-}-/* Perturbation:- 50 - switch on perturbation- 100 - auto perturb if takes too long (1.0e-6 largest nonzero)- 101 - we are perturbed- 102 - don't try perturbing again- default is 100- others are for playing-*/-COINLIBAPI int COINLINKAGE-Clp_perturbation(Clp_Simplex * model)-{- return model->model_->perturbation();-}-COINLIBAPI void COINLINKAGE-Clp_setPerturbation(Clp_Simplex * model, int value)-{- model->model_->setPerturbation(value);-}-/* Current (or last) algorithm */-COINLIBAPI int COINLINKAGE-Clp_algorithm(Clp_Simplex * model)-{- return model->model_->algorithm();-}-/* Set algorithm */-COINLIBAPI void COINLINKAGE-Clp_setAlgorithm(Clp_Simplex * model, int value)-{- model->model_->setAlgorithm(value);-}-/* Sum of dual infeasibilities */-COINLIBAPI double COINLINKAGE-Clp_sumDualInfeasibilities(Clp_Simplex * model)-{- return model->model_->sumDualInfeasibilities();-}-/* Number of dual infeasibilities */-COINLIBAPI int COINLINKAGE-Clp_numberDualInfeasibilities(Clp_Simplex * model)-{- return model->model_->numberDualInfeasibilities();-}-/* Sum of primal infeasibilities */-COINLIBAPI double COINLINKAGE-Clp_sumPrimalInfeasibilities(Clp_Simplex * model)-{- return model->model_->sumPrimalInfeasibilities();-}-/* Number of primal infeasibilities */-COINLIBAPI int COINLINKAGE-Clp_numberPrimalInfeasibilities(Clp_Simplex * model)-{- return model->model_->numberPrimalInfeasibilities();-}-/* Save model to file, returns 0 if success. This is designed for- use outside algorithms so does not save iterating arrays etc.- It does not save any messaging information.- Does not save scaling values.- It does not know about all types of virtual functions.-*/-COINLIBAPI int COINLINKAGE-Clp_saveModel(Clp_Simplex * model, const char * fileName)-{- return model->model_->saveModel(fileName);-}-/* Restore model from file, returns 0 if success,- deletes current model */-COINLIBAPI int COINLINKAGE-Clp_restoreModel(Clp_Simplex * model, const char * fileName)-{- return model->model_->restoreModel(fileName);-}--/* Just check solution (for external use) - sets sum of- infeasibilities etc */-COINLIBAPI void COINLINKAGE-Clp_checkSolution(Clp_Simplex * model)-{- model->model_->checkSolution();-}-/* Number of rows */-COINLIBAPI int COINLINKAGE-Clp_getNumRows(Clp_Simplex * model)-{- return model->model_->getNumRows();-}-/* Number of columns */-COINLIBAPI int COINLINKAGE-Clp_getNumCols(Clp_Simplex * model)-{- return model->model_->getNumCols();-}-/* Number of iterations */-COINLIBAPI int COINLINKAGE-Clp_getIterationCount(Clp_Simplex * model)-{- return model->model_->getIterationCount();-}-/* Are there a numerical difficulties? */-COINLIBAPI int COINLINKAGE-Clp_isAbandoned(Clp_Simplex * model)-{- return model->model_->isAbandoned() ? 1 : 0;-}-/* Is optimality proven? */-COINLIBAPI int COINLINKAGE-Clp_isProvenOptimal(Clp_Simplex * model)-{- return model->model_->isProvenOptimal() ? 1 : 0;-}-/* Is primal infeasiblity proven? */-COINLIBAPI int COINLINKAGE-Clp_isProvenPrimalInfeasible(Clp_Simplex * model)-{- return model->model_->isProvenPrimalInfeasible() ? 1 : 0;-}-/* Is dual infeasiblity proven? */-COINLIBAPI int COINLINKAGE-Clp_isProvenDualInfeasible(Clp_Simplex * model)-{- return model->model_->isProvenDualInfeasible() ? 1 : 0;-}-/* Is the given primal objective limit reached? */-COINLIBAPI int COINLINKAGE-Clp_isPrimalObjectiveLimitReached(Clp_Simplex * model)-{- return model->model_->isPrimalObjectiveLimitReached() ? 1 : 0;-}-/* Is the given dual objective limit reached? */-COINLIBAPI int COINLINKAGE-Clp_isDualObjectiveLimitReached(Clp_Simplex * model)-{- return model->model_->isDualObjectiveLimitReached() ? 1 : 0;-}-/* Iteration limit reached? */-COINLIBAPI int COINLINKAGE-Clp_isIterationLimitReached(Clp_Simplex * model)-{- return model->model_->isIterationLimitReached() ? 1 : 0;-}-/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */-COINLIBAPI double COINLINKAGE-Clp_getObjSense(Clp_Simplex * model)-{- return model->model_->getObjSense();-}-/* Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */-COINLIBAPI void COINLINKAGE-Clp_setObjSense(Clp_Simplex * model, double objsen)-{- model->model_->setOptimizationDirection(objsen);-}-/* Primal row solution */-COINLIBAPI const double * COINLINKAGE-Clp_getRowActivity(Clp_Simplex * model)-{- return model->model_->getRowActivity();-}-/* Primal column solution */-COINLIBAPI const double * COINLINKAGE-Clp_getColSolution(Clp_Simplex * model)-{- return model->model_->getColSolution();-}-COINLIBAPI void COINLINKAGE-Clp_setColSolution(Clp_Simplex * model, const double * input)-{- model->model_->setColSolution(input);-}-/* Dual row solution */-COINLIBAPI const double * COINLINKAGE-Clp_getRowPrice(Clp_Simplex * model)-{- return model->model_->getRowPrice();-}-/* Reduced costs */-COINLIBAPI const double * COINLINKAGE-Clp_getReducedCost(Clp_Simplex * model)-{- return model->model_->getReducedCost();-}-/* Row lower */-COINLIBAPI const double* COINLINKAGE-Clp_getRowLower(Clp_Simplex * model)-{- return model->model_->getRowLower();-}-/* Row upper */-COINLIBAPI const double* COINLINKAGE-Clp_getRowUpper(Clp_Simplex * model)-{- return model->model_->getRowUpper();-}-/* Objective */-COINLIBAPI const double * COINLINKAGE-Clp_getObjCoefficients(Clp_Simplex * model)-{- return model->model_->getObjCoefficients();-}-/* Column Lower */-COINLIBAPI const double * COINLINKAGE-Clp_getColLower(Clp_Simplex * model)-{- return model->model_->getColLower();-}-/* Column Upper */-COINLIBAPI const double * COINLINKAGE-Clp_getColUpper(Clp_Simplex * model)-{- return model->model_->getColUpper();-}-/* Objective value */-COINLIBAPI double COINLINKAGE-Clp_getObjValue(Clp_Simplex * model)-{- return model->model_->getObjValue();-}-/* Get variable basis info */-COINLIBAPI int COINLINKAGE-Clp_getColumnStatus(Clp_Simplex * model, int sequence)-{- return (int) model->model_->getColumnStatus(sequence);-}-/* Get row basis info */-COINLIBAPI int COINLINKAGE-Clp_getRowStatus(Clp_Simplex * model, int sequence)-{- return (int) model->model_->getRowStatus(sequence);-}-/* Set variable basis info */-COINLIBAPI void COINLINKAGE-Clp_setColumnStatus(Clp_Simplex * model, int sequence, int value)-{- if (value >= 0 && value <= 5) {- model->model_->setColumnStatus(sequence, (ClpSimplex::Status) value );- if (value == 3 || value == 5)- model->model_->primalColumnSolution()[sequence] =- model->model_->columnLower()[sequence];- else if (value == 2)- model->model_->primalColumnSolution()[sequence] =- model->model_->columnUpper()[sequence];- }-}-/* Set row basis info */-COINLIBAPI void COINLINKAGE-Clp_setRowStatus(Clp_Simplex * model, int sequence, int value)-{- if (value >= 0 && value <= 5) {- model->model_->setRowStatus(sequence, (ClpSimplex::Status) value );- if (value == 3 || value == 5)- model->model_->primalRowSolution()[sequence] =- model->model_->rowLower()[sequence];- else if (value == 2)- model->model_->primalRowSolution()[sequence] =- model->model_->rowUpper()[sequence];- }-}-/* Small element value - elements less than this set to zero,- default is 1.0e-20 */-COINLIBAPI double COINLINKAGE-Clp_getSmallElementValue(Clp_Simplex * model)-{- return model->model_->getSmallElementValue();-}-COINLIBAPI void COINLINKAGE-Clp_setSmallElementValue(Clp_Simplex * model, double value)-{- model->model_->setSmallElementValue(value);-}-/* Print model */-COINLIBAPI void COINLINKAGE-Clp_printModel(Clp_Simplex * model, const char * prefix)-{- ClpSimplex *clp_simplex = model->model_;- int numrows = clp_simplex->numberRows();- int numcols = clp_simplex->numberColumns();- int numelem = clp_simplex->getNumElements();- const CoinBigIndex *start = clp_simplex->matrix()->getVectorStarts();- const int *index = clp_simplex->matrix()->getIndices();- const double *value = clp_simplex->matrix()->getElements();- const double *collb = model->model_->columnLower();- const double *colub = model->model_->columnUpper();- const double *obj = model->model_->objective();- const double *rowlb = model->model_->rowLower();- const double *rowub = model->model_->rowUpper();- printf("%s numcols = %i, numrows = %i, numelem = %i\n",- prefix, numcols, numrows, numelem);- printf("%s model = %p, start = %p, index = %p, value = %p\n",- prefix, reinterpret_cast<const void *>(model), reinterpret_cast<const void *>(start), reinterpret_cast<const void *>(index), reinterpret_cast<const void *>(value));- clp_simplex->matrix()->dumpMatrix(NULL);- {- int i;- for (i = 0; i <= numcols; i++)- printf("%s start[%i] = %i\n", prefix, i, start[i]);- for (i = 0; i < numelem; i++)- printf("%s index[%i] = %i, value[%i] = %g\n",- prefix, i, index[i], i, value[i]);- }-- printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",- prefix, reinterpret_cast<const void *>(collb), reinterpret_cast<const void *>(colub), reinterpret_cast<const void *>(obj), reinterpret_cast<const void *>(rowlb), reinterpret_cast<const void *>(rowub));- printf("%s optimization direction = %g\n", prefix, Clp_optimizationDirection(model));- printf(" (1 - minimize, -1 - maximize, 0 - ignore)\n");- {- int i;- for (i = 0; i < numcols; i++)- printf("%s collb[%i] = %g, colub[%i] = %g, obj[%i] = %g\n",- prefix, i, collb[i], i, colub[i], i, obj[i]);- for (i = 0; i < numrows; i++)- printf("%s rowlb[%i] = %g, rowub[%i] = %g\n",- prefix, i, rowlb[i], i, rowub[i]);- }-}--#ifndef SLIM_CLP-/** Solve the problem with the idiot code */-/* tryhard values:- tryhard & 7:- 0: NOT lightweight, 105 iterations within a pass (when mu stays fixed)- 1: lightweight, but focus more on optimality (mu is high)- (23 iters in a pass)- 2: lightweight, but focus more on feasibility (11 iters in a pass)- 3: lightweight, but focus more on feasibility (23 iters in a pass, so it- goes closer to opt than option 2)- tryhard >> 3:- number of passes, the larger the number the closer it gets to optimality-*/-COINLIBAPI void COINLINKAGE-Clp_idiot(Clp_Simplex * model, int tryhard)-{- ClpSimplex *clp = model->model_;- Idiot info(*clp);- int numberpass = tryhard >> 3;- int lightweight = tryhard & 7;- info.setLightweight(lightweight);- info.crash(numberpass, clp->messageHandler(), clp->messagesPointer(), false);-}-#endif--COINLIBAPI Clp_Solve * COINLINKAGE -ClpSolve_new() -{ - return new Clp_Solve(); -}--COINLIBAPI void COINLINKAGE -ClpSolve_delete(Clp_Solve * solve) -{ - delete solve; -}--// space- and error-saving macros-#define ClpSolveGetIntProperty(prop) \-COINLIBAPI int COINLINKAGE \-ClpSolve_ ## prop (Clp_Solve *s) \-{ \- return s->options.prop(); \-}--#define ClpSolveSetIntProperty(prop) \-COINLIBAPI void COINLINKAGE \-ClpSolve_ ## prop (Clp_Solve *s, int val) \-{ \- s->options.prop(val); \-}--COINLIBAPI void COINLINKAGE -ClpSolve_setSpecialOption(Clp_Solve * s, int which, int value, int extraInfo) -{- s->options.setSpecialOption(which,value,extraInfo);-}--COINLIBAPI int COINLINKAGE -ClpSolve_getSpecialOption(Clp_Solve * s, int which)-{- return s->options.getSpecialOption(which);-}--COINLIBAPI void COINLINKAGE -ClpSolve_setSolveType(Clp_Solve * s, int method, int extraInfo)-{- s->options.setSolveType(static_cast<ClpSolve::SolveType>(method), extraInfo);-}--ClpSolveGetIntProperty(getSolveType)--COINLIBAPI void COINLINKAGE ClpSolve_setPresolveType(Clp_Solve * s, int amount, int extraInfo)-{- s->options.setPresolveType(static_cast<ClpSolve::PresolveType>(amount),extraInfo);-}--ClpSolveGetIntProperty(getPresolveType)--ClpSolveGetIntProperty(getPresolvePasses)---COINLIBAPI int COINLINKAGE -ClpSolve_getExtraInfo(Clp_Solve * s, int which) {- return s->options.getExtraInfo(which);-}--ClpSolveSetIntProperty(setInfeasibleReturn)-ClpSolveGetIntProperty(infeasibleReturn)--ClpSolveGetIntProperty(doDual)-ClpSolveSetIntProperty(setDoDual)--ClpSolveGetIntProperty(doSingleton)-ClpSolveSetIntProperty(setDoSingleton)--ClpSolveGetIntProperty(doDoubleton)-ClpSolveSetIntProperty(setDoDoubleton)--ClpSolveGetIntProperty(doTripleton)-ClpSolveSetIntProperty(setDoTripleton)--ClpSolveGetIntProperty(doTighten)-ClpSolveSetIntProperty(setDoTighten)--ClpSolveGetIntProperty(doForcing)-ClpSolveSetIntProperty(setDoForcing)--ClpSolveGetIntProperty(doImpliedFree)-ClpSolveSetIntProperty(setDoImpliedFree)--ClpSolveGetIntProperty(doDupcol)-ClpSolveSetIntProperty(setDoDupcol)--ClpSolveGetIntProperty(doDuprow)-ClpSolveSetIntProperty(setDoDuprow)--ClpSolveGetIntProperty(doSingletonColumn)-ClpSolveSetIntProperty(setDoSingletonColumn)--ClpSolveGetIntProperty(presolveActions)-ClpSolveSetIntProperty(setPresolveActions)--ClpSolveGetIntProperty(substitution)-ClpSolveSetIntProperty(setSubstitution)--#if defined(__MWERKS__)-#pragma export off-#endif-
− cbits/coin/CoinAlloc.cpp
@@ -1,176 +0,0 @@-/* $Id: CoinAlloc.cpp 1373 2011-01-03 23:57:44Z lou $ */-// Copyright (C) 2007, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#include <cassert>-#include <cstdlib>-#include <new>-#include "CoinAlloc.hpp"--#if (COINUTILS_MEMPOOL_MAXPOOLED >= 0)--//=============================================================================--CoinMempool::CoinMempool(size_t entry) :-#if (COIN_MEMPOOL_SAVE_BLOCKHEADS==1)- block_heads_(NULL),- block_num_(0),- max_block_num_(0),-#endif- last_block_size_(0),- first_free_(NULL),- entry_size_(entry)-{-#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1)- pthread_mutex_init(&mutex_, NULL);-#endif- assert((entry_size_/COINUTILS_MEMPOOL_ALIGNMENT)*COINUTILS_MEMPOOL_ALIGNMENT- == entry_size_);-}--//=============================================================================--CoinMempool::~CoinMempool()-{-#if (COIN_MEMPOOL_SAVE_BLOCKHEADS==1)- for (size_t i = 0; i < block_num_; ++i) {- free(block_heads_[i]);- }-#endif-#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1)- pthread_mutex_destroy(&mutex_);-#endif-}--//==============================================================================--char* -CoinMempool::alloc()-{- lock_mutex();- if (first_free_ == NULL) {- unlock_mutex();- char* block = allocate_new_block();- lock_mutex();-#if (COIN_MEMPOOL_SAVE_BLOCKHEADS==1)- // see if we can record another block head. If not, then resize- // block_heads- if (max_block_num_ == block_num_) {- max_block_num_ = 2 * block_num_ + 10;- char** old_block_heads = block_heads_;- block_heads_ = (char**)malloc(max_block_num_ * sizeof(char*));- CoinMemcpyN( old_block_heads,block_num_,block_heads_);- free(old_block_heads);- }- // save the new block- block_heads_[block_num_++] = block;-#endif- // link in the new block- *(char**)(block+((last_block_size_-1)*entry_size_)) = first_free_;- first_free_ = block;- }- char* p = first_free_;- first_free_ = *(char**)p;- unlock_mutex();- return p;-}--//=============================================================================--char*-CoinMempool::allocate_new_block()-{- last_block_size_ = static_cast<int>(1.5 * last_block_size_ + 32);- char* block = static_cast<char*>(std::malloc(last_block_size_*entry_size_));- // link the entries in the new block together- for (int i = last_block_size_-2; i >= 0; --i) {- *(char**)(block+(i*entry_size_)) = block+((i+1)*entry_size_);- }- // terminate the linked list with a null pointer- *(char**)(block+((last_block_size_-1)*entry_size_)) = NULL;- return block;-}--//#############################################################################--CoinAlloc CoinAllocator;--CoinAlloc::CoinAlloc() :- pool_(NULL),- maxpooled_(COINUTILS_MEMPOOL_MAXPOOLED)-{- const char* maxpooled = std::getenv("COINUTILS_MEMPOOL_MAXPOOLED");- if (maxpooled) {- maxpooled_ = std::atoi(maxpooled);- }- const size_t poolnum = maxpooled_ / COINUTILS_MEMPOOL_ALIGNMENT;- maxpooled_ = poolnum * COINUTILS_MEMPOOL_ALIGNMENT;- if (maxpooled_ > 0) {- pool_ = (CoinMempool*)malloc(sizeof(CoinMempool)*poolnum);- for (int i = poolnum-1; i >= 0; --i) {- new (&pool_[i]) CoinMempool(i*COINUTILS_MEMPOOL_ALIGNMENT);- }- }-}--//#############################################################################--#if defined(COINUTILS_MEMPOOL_OVERRIDE_NEW) && (COINUTILS_MEMPOOL_OVERRIDE_NEW == 1)-void* operator new(std::size_t sz) throw (std::bad_alloc)-{ - return CoinAllocator.alloc(sz); -}--void* operator new[](std::size_t sz) throw (std::bad_alloc)-{ - return CoinAllocator.alloc(sz); -}--void operator delete(void* p) throw()-{ - CoinAllocator.dealloc(p); -}- -void operator delete[](void* p) throw()-{ - CoinAllocator.dealloc(p); -}- -void* operator new(std::size_t sz, const std::nothrow_t&) throw()-{- void *p = NULL;- try {- p = CoinAllocator.alloc(sz);- }- catch (std::bad_alloc &ba) {- return NULL;- }- return p;-}--void* operator new[](std::size_t sz, const std::nothrow_t&) throw()-{- void *p = NULL;- try {- p = CoinAllocator.alloc(sz);- }- catch (std::bad_alloc &ba) {- return NULL;- }- return p;-}--void operator delete(void* p, const std::nothrow_t&) throw()-{- CoinAllocator.dealloc(p); -} --void operator delete[](void* p, const std::nothrow_t&) throw()-{- CoinAllocator.dealloc(p); -} --#endif--#endif /*(COINUTILS_MEMPOOL_MAXPOOLED >= 0)*/
− cbits/coin/CoinParam.cpp
@@ -1,566 +0,0 @@-/* $Id: CoinParam.cpp 1424 2011-05-02 08:02:28Z stefan $ */-// Copyright (C) 2006, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#include <string>-#include <cassert>-#include <iostream>--#include "CoinPragma.hpp"-#include "CoinParam.hpp"--/*- Constructors and destructors-- There's a generic constructor and one for integer, double, keyword, string,- and action parameters.-*/--/*- Default constructor.-*/-CoinParam::CoinParam () - : type_(coinParamInvalid),- name_(),- lengthName_(0),- lengthMatch_(0),- lowerDblValue_(0.0),- upperDblValue_(0.0),- dblValue_(0.0),- lowerIntValue_(0),- upperIntValue_(0),- intValue_(0),- strValue_(),- definedKwds_(),- currentKwd_(-1),- pushFunc_(0),- pullFunc_(0),- shortHelp_(),- longHelp_(),- display_(false)-{- /* Nothing to be done here */-}---/*- Constructor for double parameter-*/-CoinParam::CoinParam (std::string name, std::string help,- double lower, double upper, double dflt, bool display)- : type_(coinParamDbl),- name_(name),- lengthName_(0),- lengthMatch_(0),- lowerDblValue_(lower),- upperDblValue_(upper),- dblValue_(dflt),- lowerIntValue_(0),- upperIntValue_(0),- intValue_(0),- strValue_(),- definedKwds_(),- currentKwd_(-1),- pushFunc_(0),- pullFunc_(0),- shortHelp_(help),- longHelp_(),- display_(display)-{- processName() ;-}--/*- Constructor for integer parameter-*/-CoinParam::CoinParam (std::string name, std::string help,- int lower, int upper, int dflt, bool display)- : type_(coinParamInt),- name_(name),- lengthName_(0),- lengthMatch_(0),- lowerDblValue_(0.0),- upperDblValue_(0.0),- dblValue_(0.0),- lowerIntValue_(lower),- upperIntValue_(upper),- intValue_(dflt),- strValue_(),- definedKwds_(),- currentKwd_(-1),- pushFunc_(0),- pullFunc_(0),- shortHelp_(help),- longHelp_(),- display_(display)-{- processName() ;-}--/*- Constructor for keyword parameter.-*/-CoinParam::CoinParam (std::string name, std::string help,- std::string firstValue, int dflt, bool display)- : type_(coinParamKwd),- name_(name),- lengthName_(0),- lengthMatch_(0),- lowerDblValue_(0.0),- upperDblValue_(0.0),- dblValue_(0.0),- lowerIntValue_(0),- upperIntValue_(0),- intValue_(0),- strValue_(),- definedKwds_(),- currentKwd_(dflt),- pushFunc_(0),- pullFunc_(0),- shortHelp_(help),- longHelp_(),- display_(display)-{- processName() ;- definedKwds_.push_back(firstValue) ;-}--/*- Constructor for string parameter.-*/-CoinParam::CoinParam (std::string name, std::string help,- std::string dflt, bool display)- : type_(coinParamStr),- name_(name),- lengthName_(0),- lengthMatch_(0),- lowerDblValue_(0.0),- upperDblValue_(0.0),- dblValue_(0.0),- lowerIntValue_(0),- upperIntValue_(0),- intValue_(0),- strValue_(dflt),- definedKwds_(),- currentKwd_(0),- pushFunc_(0),- pullFunc_(0),- shortHelp_(help),- longHelp_(),- display_(display)-{- processName() ;-}--/*- Constructor for action parameter.-*/-CoinParam::CoinParam (std::string name, std::string help, bool display)- : type_(coinParamAct),- name_(name),- lengthName_(0),- lengthMatch_(0),- lowerDblValue_(0.0),- upperDblValue_(0.0),- dblValue_(0.0),- lowerIntValue_(0),- upperIntValue_(0),- intValue_(0),- strValue_(),- definedKwds_(),- currentKwd_(0),- pushFunc_(0),- pullFunc_(0),- shortHelp_(help),- longHelp_(),- display_(display)-{- processName() ;-}--/*- Copy constructor.-*/-CoinParam::CoinParam (const CoinParam &orig)- : type_(orig.type_),- lengthName_(orig.lengthName_),- lengthMatch_(orig.lengthMatch_),- lowerDblValue_(orig.lowerDblValue_),- upperDblValue_(orig.upperDblValue_),- dblValue_(orig.dblValue_),- lowerIntValue_(orig.lowerIntValue_),- upperIntValue_(orig.upperIntValue_),- intValue_(orig.intValue_),- currentKwd_(orig.currentKwd_),- pushFunc_(orig.pushFunc_),- pullFunc_(orig.pullFunc_),- display_(orig.display_)-{- name_ = orig.name_ ;- strValue_ = orig.strValue_ ;- definedKwds_ = orig.definedKwds_ ;- shortHelp_ = orig.shortHelp_ ;- longHelp_ = orig.longHelp_ ;-}--/*- Clone-*/--CoinParam *CoinParam::clone ()-{- return (new CoinParam(*this)) ;-}--CoinParam &CoinParam::operator= (const CoinParam &rhs)-{- if (this != &rhs)- { type_ = rhs.type_ ;- name_ = rhs.name_ ;- lengthName_ = rhs.lengthName_ ;- lengthMatch_ = rhs.lengthMatch_ ;- lowerDblValue_ = rhs.lowerDblValue_ ;- upperDblValue_ = rhs.upperDblValue_ ;- dblValue_ = rhs.dblValue_ ;- lowerIntValue_ = rhs.lowerIntValue_ ;- upperIntValue_ = rhs.upperIntValue_ ;- intValue_ = rhs.intValue_ ;- strValue_ = rhs.strValue_ ;- definedKwds_ = rhs.definedKwds_ ;- currentKwd_ = rhs.currentKwd_ ;- pushFunc_ = rhs.pushFunc_ ;- pullFunc_ = rhs.pullFunc_ ;- shortHelp_ = rhs.shortHelp_ ;- longHelp_ = rhs.longHelp_ ;- display_ = rhs.display_ ; }-- return *this ; }--/*- Destructor-*/-CoinParam::~CoinParam ()-{ /* Nothing more to do */ }---/*- Methods to manipulate a CoinParam object.-*/--/*- Process the parameter name.- - Process the name for efficient matching: determine if an `!' is present. If- so, locate and record the position and remove the `!'.-*/--void CoinParam::processName()--{ std::string::size_type shriekPos = name_.find('!') ;- lengthName_ = name_.length() ;- if (shriekPos == std::string::npos)- { lengthMatch_ = lengthName_ ; }- else- { lengthMatch_ = shriekPos ;- name_ = name_.substr(0,shriekPos)+name_.substr(shriekPos+1) ;- lengthName_-- ; }-- return ; }--/*- Check an input string to see if it matches the parameter name. The whole- input string must match, and the length of the match must exceed the- minimum match length. A match is impossible if the string is longer than- the name.-- Returns: 0 for no match, 1 for a successful match, 2 if the match is short-*/-int CoinParam::matches (std::string input) const-{- size_t inputLen = input.length() ;- if (inputLen <= lengthName_)- { size_t i ;- for (i = 0 ; i < inputLen ; i++)- { if (tolower(name_[i]) != tolower(input[i])) - break ; }- if (i < inputLen)- { return (0) ; }- else- if (i >= lengthMatch_)- { return (1) ; }- else- { return (2) ; } }- - return (0) ;-}---/*- Return the parameter name, formatted to indicate how it'll be matched.- E.g., some!Name will come back as some(Name).-*/-std::string CoinParam::matchName () const-{ - if (lengthMatch_ == lengthName_) - { return name_ ; }- else- { return name_.substr(0,lengthMatch_)+"("+name_.substr(lengthMatch_)+")" ; }-}---/*- Print the long help message and a message about appropriate values.-*/-void CoinParam::printLongHelp() const-{- if (longHelp_ != "")- { CoinParamUtils::printIt(longHelp_.c_str()) ; }- else- if (shortHelp_ != "")- { CoinParamUtils::printIt(shortHelp_.c_str()) ; }- else- { CoinParamUtils::printIt("No help provided.") ; }-- switch (type_)- { case coinParamDbl:- { std::cout << "<Range of values is " << lowerDblValue_ << " to "- << upperDblValue_ << ";\n\tcurrent " << dblValue_ << ">"- << std::endl ;- assert (upperDblValue_>lowerDblValue_) ;- break ; }- case coinParamInt:- { std::cout << "<Range of values is " << lowerIntValue_ << " to "- << upperIntValue_ << ";\n\tcurrent " << intValue_ << ">"- << std::endl ;- assert (upperIntValue_>lowerIntValue_) ;- break ; }- case coinParamKwd:- { printKwds() ;- break ; }- case coinParamStr:- { std::cout << "<Current value is " ;- if (strValue_ == "")- { std::cout << "(unset)>" ; }- else- { std::cout << "`" << strValue_ << "'>" ; }- std::cout << std::endl ;- break ; }- case coinParamAct:- { break ; }- default:- { std::cout << "!! invalid parameter type !!" << std::endl ;- assert (false) ; } }-}---/*- Methods to manipulate the value of a parameter.-*/--/*- Methods to manipulate the values associated with a keyword parameter.-*/--/*- Add a keyword to the list for a keyword parameter.-*/-void CoinParam::appendKwd (std::string kwd)-{ - assert (type_ == coinParamKwd) ;-- definedKwds_.push_back(kwd) ;-}--/*- Scan the keywords of a keyword parameter and return the integer index of- the keyword matching the input, or -1 for no match.-*/-int CoinParam::kwdIndex (std::string input) const-{- assert (type_ == coinParamKwd) ;-- int whichItem = -1 ;- size_t numberItems = definedKwds_.size() ;- if (numberItems > 0)- { size_t inputLen = input.length() ;- size_t it ;-/*- Open a loop to check each keyword against the input string. We don't record- the match length for keywords, so we need to check each one for an `!' and- do the necessary preprocessing (record position and elide `!') before- checking for a match of the required length.-*/- for (it = 0 ; it < numberItems ; it++)- { std::string kwd = definedKwds_[it] ;- std::string::size_type shriekPos = kwd.find('!') ;- size_t kwdLen = kwd.length() ;- size_t matchLen = kwdLen ;- if (shriekPos != std::string::npos)- { matchLen = shriekPos ;- kwd = kwd.substr(0,shriekPos)+kwd.substr(shriekPos+1) ;- kwdLen = kwd.length() ; }-/*- Match is possible only if input is shorter than the keyword. The entire input- must match and the match must exceed the minimum length.-*/- if (inputLen <= kwdLen)- { unsigned int i ;- for (i = 0 ; i < inputLen ; i++)- { if (tolower(kwd[i]) != tolower(input[i])) - break ; }- if (i >= inputLen && i >= matchLen)- { whichItem = static_cast<int>(it) ;- break ; } } } }-- return (whichItem) ;-}--/*- Set current value for a keyword parameter using a string.-*/-void CoinParam::setKwdVal (const std::string value)-{- assert (type_ == coinParamKwd) ;-- int action = kwdIndex(value) ;- if (action >= 0)- { currentKwd_ = action ; }-}--/*- Set current value for keyword parameter using an integer. Echo the new value- to cout if requested.-*/-void CoinParam::setKwdVal (int value, bool printIt)-{- assert (type_ == coinParamKwd) ;- assert (value >= 0 && unsigned(value) < definedKwds_.size()) ;-- if (printIt && value != currentKwd_)- { std::cout << "Option for " << name_ << " changed from "- << definedKwds_[currentKwd_] << " to "- << definedKwds_[value] << std::endl ; }-- currentKwd_ = value ;-}--/*- Return the string corresponding to the current value.-*/-std::string CoinParam::kwdVal() const-{- assert (type_ == coinParamKwd) ;- - return (definedKwds_[currentKwd_]) ;-}--/*- Print the keywords for a keyword parameter, formatted to indicate how they'll- be matched. (E.g., some!Name prints as some(Name).). Follow with current- value.-*/-void CoinParam::printKwds () const-{- assert (type_ == coinParamKwd) ;-- std::cout << "Possible options for " << name_ << " are:" ;- unsigned int it ;- int maxAcross = 5 ;- for (it = 0 ; it < definedKwds_.size() ; it++)- { std::string kwd = definedKwds_[it] ;- std::string::size_type shriekPos = kwd.find('!') ;- if (shriekPos != std::string::npos)- { kwd = kwd.substr(0,shriekPos)+"("+kwd.substr(shriekPos+1)+")" ; }- if (it%maxAcross == 0)- { std::cout << std::endl ; }- std::cout << " " << kwd ; }- std::cout << std::endl ;-- assert (currentKwd_ >= 0 && unsigned(currentKwd_) < definedKwds_.size()) ;-- std::string current = definedKwds_[currentKwd_] ;- std::string::size_type shriekPos = current.find('!') ;- if (shriekPos != std::string::npos)- { current = current.substr(0,shriekPos)+- "("+current.substr(shriekPos+1)+")" ; }- std::cout << " <current: " << current << ">" << std::endl ;-}---/*- Methods to manipulate the value of a string parameter.-*/--void CoinParam::setStrVal (std::string value)-{ - assert (type_ == coinParamStr) ;-- strValue_ = value ;-}--std::string CoinParam::strVal () const-{- assert (type_ == coinParamStr) ;-- return (strValue_) ;-}---/*- Methods to manipulate the value of a double parameter.-*/--void CoinParam::setDblVal (double value)-{ - assert (type_ == coinParamDbl) ;-- dblValue_ = value ;-}--double CoinParam::dblVal () const-{- assert (type_ == coinParamDbl) ;-- return (dblValue_) ;-}---/*- Methods to manipulate the value of an integer parameter.-*/--void CoinParam::setIntVal (int value)-{ - assert (type_ == coinParamInt) ;-- intValue_ = value ;-}--int CoinParam::intVal () const-{- assert (type_ == coinParamInt) ;-- return (intValue_) ;-}--/*- A print function (friend of the class)-*/--std::ostream &operator<< (std::ostream &s, const CoinParam ¶m)-{- switch (param.type())- { case CoinParam::coinParamDbl:- { return (s << param.dblVal()) ; }- case CoinParam::coinParamInt:- { return (s << param.intVal()) ; }- case CoinParam::coinParamKwd:- { return (s << param.kwdVal()) ; }- case CoinParam::coinParamStr:- { return (s << param.strVal()) ; }- case CoinParam::coinParamAct:- { return (s << "<evokes action>") ; }- default:- { return (s << "!! invalid parameter type !!") ; } }-}
− cbits/coin/CoinParamUtils.cpp
@@ -1,800 +0,0 @@-/* $Id: CoinParamUtils.cpp 1468 2011-09-03 17:19:13Z stefan $ */-// Copyright (C) 2007, International Business Machines-// Corporation and others. All Rights Reserved.-// This code is licensed under the terms of the Eclipse Public License (EPL).--#include <cassert>-#include <cerrno>-#include <iostream>--#include "CoinUtilsConfig.h"-#include "CoinParam.hpp"-#include <cstdlib>-#include <cstring>-#include <cstdio>--#ifdef COIN_HAS_READLINE -#include <readline/readline.h>-#include <readline/history.h>-#endif--/* Unnamed local namespace */-namespace-{--/*- cmdField: The index of the current command line field. Forced to -1 when- accepting commands from stdin (interactive) or a command file.- readSrc: Current input source.-- pendingVal: When the form param=value is encountered, both keyword and value- form one command line field. We need to return `param' as the- field and somehow keep the value around for the upcoming call- that'll request it. That's the purpose of pendingVal.-*/--int cmdField = 1 ;-FILE *readSrc = stdin ;-std::string pendingVal = "" ;---/*- Get next command or field in command. When in interactive mode, prompt the- user and read the resulting line of input.-*/-std::string nextField (const char *prompt)-{- static char line[1000] ;- static char *where = NULL ;- std::string field ;- const char *dflt_prompt = "Eh? " ;-- if (prompt == 0)- { prompt = dflt_prompt ; }-/*- Do we have a line at the moment? If not, acquire one. When we're done,- line holds the input line and where points to the start of the line. If we're- using the readline library, add non-empty lines to the history list.-*/- if (!where) {-#ifdef COIN_HAS_READLINE- if (readSrc == stdin)- { where = readline(prompt) ;- if (where)- { if (*where)- add_history (where) ;- strcpy(line,where) ;- free(where) ;- where = line ; } }- else- { where = fgets(line,1000,readSrc) ; }-#else- if (readSrc == stdin)- { fprintf(stdout,"%s",prompt) ;- fflush(stdout) ; }- where = fgets(line,1000,readSrc) ;-#endif-/*- If where is NULL, we have EOF. Return a null string.-*/- if (!where)- return field ;-/*- Clean the image. Trailing junk first. The line will be cut off at the last- non-whitespace character, but we need to scan until we find the end of the- string or some other non-printing character to make sure we don't miss a- printing character after whitespace.-*/- char *lastNonBlank = line-1 ;- for (where = line ; *where != '\0' ; where++)- { if (*where != '\t' && *where < ' ')- { break ; }- if (*where != '\t' && *where != ' ')- { lastNonBlank = where ; } }- *(lastNonBlank+1) = '\0' ;- where = line ; }-/*- Munch through leading white space.-*/- while (*where == ' ' || *where == '\t')- where++ ;-/*- See if we can separate a field; if so, copy it over into field for return.- If we're out of line, return the string "EOL".-*/- char *saveWhere = where ;- while (*where != ' ' && *where != '\t' && *where!='\0')- where++ ;- if (where != saveWhere)- { char save = *where ;- *where = '\0' ;- field = saveWhere ;- *where = save ; }- else- { where = NULL ;- field = "EOL" ; }-- return (field) ; }--}---/* Visible functions */--namespace CoinParamUtils-{--/*- As mentioned above, cmdField set to -1 is the indication that we're reading- from stdin or a file.-*/-void setInputSrc (FILE *src)--{ if (src != 0)- { cmdField = -1 ;- readSrc = src ; } }--/*- A utility to allow clients to determine if we're processing parameters from- the comand line or otherwise.-*/-bool isCommandLine ()--{ assert(cmdField != 0) ;- - if (cmdField > 0)- { return (true) ; }- else- { return (false) ; } }--/*- A utility to allow clients to determine if we're accepting parameters- interactively.-*/-bool isInteractive ()--{ assert(cmdField != 0) ;- - if (cmdField < 0 && readSrc == stdin)- { return (true) ; }- else- { return (false) ; } }--/*- Utility functions for acquiring input.-*/---/*- Return the next field (word) from the current command line. Generally, this- is expected to be of the form `-param' or `--param', with special cases as- set out below.-- If we're in interactive mode (cmdField == -1), nextField does all the work- to prompt the user and return the next field from the resulting input. It is- assumed that the user knows not to use `-' or `--' prefixes in interactive- mode.-- If we're in command line mode (cmdField > 0), cmdField indicates the- current command line word. The order of processing goes like this:- * A stand-alone `-' is converted to `stdin'- * A stand-alone '--' is returned as a word; interpretation is up to the- client.- * A prefix of '-' or '--' is stripped from the field.- If the result is `stdin', it's assumed we're switching to interactive mode- and the user is prompted for another command.-- Whatever results from the above sequence is returned to the client as the- next field. An empty string indicates end of input.-- Prompt will be used by nextField if it's necessary to prompt the user for- a command (only when reading from stdin).-- If provided, pfx is set to the prefix ("-", "--", or "") stripped from the- field. Lack of prefix is not necessarily an error because of the following- scenario: To read a file, the verbose command might be "foo -import- myfile". But we might want to allow a short form, "foo myfile". And we'd- like "foo import" to be interpreted as "foo -import import" (i.e., import the- file named `import').-*/--std::string getCommand (int argc, const char *argv[],- const std::string prompt, std::string *pfx)--{ std::string field = "EOL" ;- pendingVal = "" ;- int pfxlen ;-- if (pfx != 0)- { (*pfx) = "" ; }-/*- Acquire the next field, and convert as outlined above if we're processing- command line parameters.-*/- while (field == "EOL")- { pfxlen = 0 ;- if (cmdField > 0)- { if (cmdField < argc)- { field = argv[cmdField++] ;- if (field == "-")- { field = "stdin" ; }- else- if (field == "--")- { /* Prevent `--' from being eaten by next case. */ }- else- { if (field[0] == '-')- { pfxlen = 1 ;- if (field[1] == '-')- pfxlen = 2 ;- if (pfx != 0)- (*pfx) = field.substr(0,pfxlen) ;- field = field.substr(pfxlen) ; } } }- else- { field = "" ; } }- else- { field = nextField(prompt.c_str()) ; }- if (field == "stdin")- { std::cout << "Switching to line mode" << std::endl ;- cmdField = -1 ;- field = nextField(prompt.c_str()) ; } }-/*- Are we left with something of the form param=value? If so, separate the- pieces, returning `param' and saving `value' for later use as per comments- at the head of the file.-*/- std::string::size_type found = field.find('=');- if (found != std::string::npos)- { pendingVal = field.substr(found+1) ;- field = field.substr(0,found) ; }-- return (field) ; }---/*- Function to look up a parameter keyword (name) in the parameter vector and- deal with the result. The keyword may end in one or more `?' characters;- this is a query for information about matching parameters.-- If we have a single match satisfying the minimal match requirements, and- there's no query, we simply return the index of the matching parameter in- the parameter vector. If there are no matches, and no query, the return- value will be -3. No matches on a query returns -1.-- A single short match, or a single match of any length with a query, will- result in a short help message-- If present, these values are set as follows:- * matchCntp is set to the number of parameters that matched.- * shortCntp is set to the number of matches that failed to meet the minimum- match requirement.- * queryCntp is set to the number of trailing `?' characters at the end- of name.-- Return values:- >0: index of the single unique match for the name- -1: query present- -2: no query, one or more short matches- -3: no query, no match- -4: multiple full matches (indicates configuration error)-- The final three parameters (matchCnt, shortCnt, queryCnt) are optional and- default to null. Use them if you want more detail on the match.-*/--int lookupParam (std::string name, CoinParamVec ¶mVec,- int *matchCntp, int *shortCntp, int *queryCntp)--{- int retval = -3 ;-- if (matchCntp != 0)- { *matchCntp = 0 ; }- if (shortCntp != 0)- { *shortCntp = 0 ; }- if (queryCntp != 0)- { *queryCntp = 0 ; }-/*- Is there anything here at all? -*/- if (name.length() == 0)- { return (retval) ; }-/*- Scan the parameter name to see if it ends in one or more `?' characters. If- so, take it as a request to return a list of parameters that match name up- to the first `?'. The strings '?' and '???' are considered to be valid- parameter names (short and long help, respectively) and are handled as- special cases: If the whole string is `?'s, one and three are commands as- is, while 2 and 4 or more are queries about `?' or `???'.-*/- int numQuery = 0 ;- { int length = static_cast<int>(name.length()) ;- int i ;- for (i = length-1 ; i >= 0 && name[i] == '?' ; i--)- { numQuery++ ; }- if (numQuery == length)- { switch (length)- { case 1:- case 3:- { numQuery = 0 ;- break ; }- case 2:- { numQuery -= 1 ;- break ; }- default:- { numQuery -= 3 ;- break ; } } }- name = name.substr(0,length-numQuery) ;- if (queryCntp != 0)- { *queryCntp = numQuery ; } }-/*- See if we can match the parameter name. On return, matchNdx is set to the- last match satisfying the minimal match criteria, or -1 if there's no- match. matchCnt is the number of matches satisfying the minimum match- length, and shortCnt is possible matches that were short of the minimum- match length,-*/- int matchNdx = -1 ;- int shortCnt = 0 ;- int matchCnt = CoinParamUtils::matchParam(paramVec,name,matchNdx,shortCnt) ;-/*- Set up return values before we get into further processing.-*/- if (matchCntp != 0)- { *matchCntp = matchCnt ; }- if (shortCntp != 0)- { *shortCntp = shortCnt ; }- if (numQuery > 0)- { retval = -1 ; }- else- { if (matchCnt+shortCnt == 0)- { retval = -3 ; }- else- if (matchCnt > 1)- { retval = -4 ; }- else- { retval = -2 ; } }-/*- No matches? Nothing more to be done here.-*/- if (matchCnt+shortCnt == 0)- { return (retval) ; }-/*- A unique match and no `?' in the name says we have our parameter. Return- the result.-*/- if (matchCnt == 1 && shortCnt == 0 && numQuery == 0)- { assert (matchNdx >= 0 && matchNdx < static_cast<int>(paramVec.size())) ;- return (matchNdx) ; }-/*- A single match? There are two possibilities:- * The string specified is shorter than the match length requested by the- parameter. (Useful for avoiding inadvertent execution of commands that- the client might regret.)- * The string specified contained a `?', in which case we print the help.- The match may or may not be short.-*/- if (matchCnt+shortCnt == 1)- { CoinParamUtils::shortOrHelpOne(paramVec,matchNdx,name,numQuery) ;- return (retval) ; }-/*- The final case: multiple matches. Most commonly this will be multiple short- matches. If we have multiple matches satisfying the minimal length- criteria, we have a configuration problem. The other question is whether- the user wanted help information. Two question marks gets short help.-*/- if (matchCnt > 1)- { std::cout- << "Configuration error! `" << name- <<"' was fully matched " << matchCnt << " times!"- << std::endl ; }- std::cout- << "Multiple matches for `" << name << "'; possible completions:"- << std::endl ;- CoinParamUtils::shortOrHelpMany(paramVec,name,numQuery) ;-- return (retval) ; }---/*- Utility functions to acquire parameter values from the command line. For- all of these, a pendingVal is consumed if it exists.-*/---/*- Read a string and return a pointer to the string. Set valid to indicate the- result of parsing: 0: okay, 1: <unused>, 2: not present.-*/--std::string getStringField (int argc, const char *argv[], int *valid)--{ std::string field ;-- if (pendingVal != "")- { field = pendingVal ;- pendingVal = "" ; }- else- { field = "EOL" ;- if (cmdField > 0)- { if (cmdField < argc)- { field = argv[cmdField++] ; } }- else- { field = nextField(0) ; } }-- if (valid != 0)- { if (field != "EOL")- { *valid = 0 ; }- else- { *valid = 2 ; } }-- return (field) ; }--/*- Read an int and return the value. Set valid to indicate the result of- parsing: 0: okay, 1: parse error, 2: not present.-*/--int getIntField (int argc, const char *argv[], int *valid)--{ std::string field ;-- if (pendingVal != "")- { field = pendingVal ;- pendingVal = "" ; }- else- { field = "EOL" ;- if (cmdField > 0)- { if (cmdField < argc)- { field = argv[cmdField++] ; } }- else- { field = nextField(0) ; } }-/*- The only way to check for parse error here is to set the system variable- errno to 0 and then see if it's nonzero after we try to convert the string- to integer.-*/- int value = 0 ;- errno = 0 ;- if (field != "EOL")- { value = atoi(field.c_str()) ; }-- if (valid != 0)- { if (field != "EOL")- { if (errno == 0)- { *valid = 0 ; }- else- { *valid = 1 ; } }- else- { *valid = 2 ; } }-- return (value) ; }---/*- Read a double and return the value. Set valid to indicate the result of- parsing: 0: okay, 1: bad parse, 2: not present. But we'll never return- valid == 1 because atof gives us no way to tell.)-*/--double getDoubleField (int argc, const char *argv[], int *valid)--{ std::string field ;-- if (pendingVal != "")- { field = pendingVal ;- pendingVal = "" ; }- else- { field = "EOL" ;- if (cmdField > 0)- { if (cmdField < argc)- { field = argv[cmdField++] ; } }- else- { field = nextField(0) ; } }-/*- The only way to check for parse error here is to set the system variable- errno to 0 and then see if it's nonzero after we try to convert the string- to integer.-*/- double value = 0.0 ;- errno = 0 ;- if (field != "EOL")- { value = atof(field.c_str()) ; }-- if (valid != 0)- { if (field != "EOL")- { if (errno == 0)- { *valid = 0 ; }- else- { *valid = 1 ; } }- else- { *valid = 2 ; } }-- return (value) ; }---/*- Utility function to scan a parameter vector for matches. Sets matchNdx to- the index of the last parameter that meets the minimal match criteria (but- note there should be at most one such parameter if the parameter vector is- properly configured). Sets shortCnt to the number of short matches (should- be zero in a properly configured vector if a minimal match is found).- Returns the number of matches satisfying the minimal match requirement- (should be 0 or 1 in a properly configured vector).-- The routine allows for the possibility of null entries in the parameter- vector.-- In order to handle `?' and `???', there's nothing to it but to force a- unique match if we match `?' exactly. (This is another quirk of clp/cbc- parameter parsing, which we need to match for historical reasons.)-*/--int matchParam (const CoinParamVec ¶mVec, std::string name,- int &matchNdx, int &shortCnt)--{ - int vecLen = static_cast<int>(paramVec.size()) ;- int matchCnt = 0 ;-- matchNdx = -1 ;- shortCnt = 0 ;-- for (int i = 0 ; i < vecLen ; i++)- { CoinParam *param = paramVec[i] ;- if (param == 0) continue ;- int match = paramVec[i]->matches(name) ;- if (match == 1)- { matchNdx = i ;- matchCnt++ ;- if (name == "?")- { matchCnt = 1 ;- break ; } }- else- { shortCnt += match>>1 ; } }-- return (matchCnt) ;-}--/*- Now a bunch of routines that are useful in the context of generating help- messages.-*/--/*- Simple formatting routine for long messages. Used to print long help for- parameters. Lines are broken at the first white space after 65 characters,- or when an explicit return (`\n') character is scanned. Leading spaces are- suppressed.-*/--void printIt (const char *msg)--{ int length = static_cast<int>(strlen(msg)) ;- char temp[101] ;- int i ;- int n = 0 ;- for (i = 0 ; i < length ; i++)- { if (msg[i] == '\n' ||- (n >= 65 && (msg[i] == ' ' || msg[i] == '\t')))- { temp[n] = '\0' ;- std::cout << temp << std::endl ;- n = 0 ; }- else- if (n || msg[i] != ' ')- { temp[n++] = msg[i] ; } }- if (n > 0)- { temp[n] = '\0' ;- std::cout << temp << std::endl ; }-- return ; }---/*- Utility function for the case where a name matches a single parameter, but- either it's short, or the user wanted help, or both.-- The routine allows for the possibility that there are null entries in the- parameter vector, but matchNdx should point to a valid entry if it's >= 0.-*/--void shortOrHelpOne (CoinParamVec ¶mVec,- int matchNdx, std::string name, int numQuery)--{ int i ;- int numParams = static_cast<int>(paramVec.size()) ;- int lclNdx = -1 ;-/*- For a short match, we need to look up the parameter again. This should find- a short match, given the conditions where this routine is called. But be- prepared to find a full match.- - If matchNdx >= 0, just use the index we're handed.-*/- if (matchNdx < 0) - { int match = 0 ;- for (i = 0 ; i < numParams ; i++)- { CoinParam *param = paramVec[i] ;- if (param == 0) continue ;- int match = param->matches(name) ;- if (match != 0)- { lclNdx = i ;- break ; } }-- assert (lclNdx >= 0) ;-- if (match == 1)- { std::cout- << "Match for '" << name << "': "- << paramVec[matchNdx]->matchName() << "." ; }- else- { std::cout- << "Short match for '" << name << "'; possible completion: "- << paramVec[lclNdx]->matchName() << "." ; } }- else- { assert(matchNdx >= 0 && matchNdx < static_cast<int>(paramVec.size())) ;- std::cout << "Match for `" << name << "': "- << paramVec[matchNdx]->matchName() ;- lclNdx = matchNdx ; }-/*- Print some help, if there was a `?' in the name. `??' gets the long help.-*/- if (numQuery > 0)- { std::cout << std::endl ;- if (numQuery == 1)- { std::cout << paramVec[lclNdx]->shortHelp() ; }- else- { paramVec[lclNdx]->printLongHelp() ; } }- std::cout << std::endl ;-- return ; }--/*- Utility function for the case where a name matches multiple parameters.- Zero or one `?' gets just the matching names, while `??' gets short help- with each match.-- The routine allows for the possibility that there are null entries in the- parameter vector.-*/--void shortOrHelpMany (CoinParamVec ¶mVec, std::string name, int numQuery)--{ int numParams = static_cast<int>(paramVec.size()) ;-/*- Scan the parameter list. For each match, print just the name, or the name- and short help.-*/- int lineLen = 0 ;- bool printed = false ;- for (int i = 0 ; i < numParams ; i++)- { CoinParam *param = paramVec[i] ;- if (param == 0) continue ;- int match = param->matches(name) ;- if (match > 0)- { std::string nme = param->matchName() ;- int len = static_cast<int>(nme.length()) ;- if (numQuery >= 2) - { std::cout << nme << " : " << param->shortHelp() ;- std::cout << std::endl ; }- else- { lineLen += 2+len ;- if (lineLen > 80)- { std::cout << std::endl ;- lineLen = 2+len ; }- std::cout << " " << nme ;- printed = true ; } } }-- if (printed)- { std::cout << std::endl ; }-- return ; }---/*- A generic help message that explains the basic operation of parameter- parsing.-*/--void printGenericHelp ()--{ std::cout << std::endl ;- std::cout- << "For command line arguments, keywords have a leading `-' or '--'; "- << std::endl ;- std::cout- << "-stdin or just - switches to stdin with a prompt."- << std::endl ;- std::cout- << "When prompted, one command per line, without the leading `-'."- << std::endl ;- std::cout- << "abcd value sets abcd to value."- << std::endl ;- std::cout- << "abcd without a value (where one is expected) gives the current value."- << std::endl ;- std::cout- << "abcd? gives a list of possible matches; if there's only one, a short"- << std::endl ;- std::cout- << "help message is printed."- << std::endl ;- std::cout- << "abcd?? prints the short help for all matches; if there's only one"- << std::endl ;- std::cout- << "match, a longer help message and current value are printed."- << std::endl ;- - return ; }---/*- Utility function for various levels of `help' command. The entries between- paramVec[firstParam] and paramVec[lastParam], inclusive, will be printed.- If shortHelp is true, the short help message will be printed for each- parameter. If longHelp is true, the long help message will be printed for- each parameter. If hidden is true, even parameters with display = false- will be printed. Each line is prefaced with the specified prefix.-- The routine allows for the possibility that there are null entries in the- parameter vector.-*/--void printHelp (CoinParamVec ¶mVec, int firstParam, int lastParam,- std::string prefix,- bool shortHelp, bool longHelp, bool hidden)--{ bool noHelp = !(shortHelp || longHelp) ;- int i ;- int pfxLen = static_cast<int>(prefix.length()) ;- bool printed = false ;-- if (noHelp)- { int lineLen = 0 ;- for (i = firstParam ; i <= lastParam ; i++)- { CoinParam *param = paramVec[i] ;- if (param == 0) continue ;- if (param->display() || hidden)- { std::string nme = param->matchName() ;- int len = static_cast<int>(nme.length()) ;- if (!printed)- { std::cout << std::endl << prefix ;- lineLen += pfxLen ;- printed = true ; }- lineLen += 2+len ;- if (lineLen > 80)- { std::cout << std::endl << prefix ;- lineLen = pfxLen+2+len ; }- std::cout << " " << nme ; } }- if (printed)- { std::cout << std::endl ; } }- else- if (shortHelp)- { for (i = firstParam ; i <= lastParam ; i++)- { CoinParam *param = paramVec[i] ;- if (param == 0) continue ;- if (param->display() || hidden)- { std::cout << std::endl << prefix ;- std::cout << param->matchName() ;- std::cout << ": " ;- std::cout << param->shortHelp() ; } }- std::cout << std::endl ; }- else- if (longHelp)- { for (i = firstParam ; i <= lastParam ; i++)- { CoinParam *param = paramVec[i] ;- if (param == 0) continue ;- if (param->display() || hidden)- { std::cout << std::endl << prefix ;- std::cout << "Command: " << param->matchName() ;- std::cout << std::endl << prefix ;- std::cout << "---- description" << std::endl ;- printIt(param->longHelp().c_str()) ;- std::cout << prefix << "----" << std::endl ; } } }-- std::cout << std::endl ;-- return ; } --} // end namespace CoinParamUtils
+ examples/Base.hs view
@@ -0,0 +1,36 @@+module Base where++import Numeric.Limp.Rep+import Numeric.Limp.Program+import Numeric.Limp.Solvers.Cbc++data V0++deriving instance Ord V0+deriving instance Eq V0+deriving instance Show V0++data V2 = A | B+ deriving (Ord, Eq, Show)+++solve_problem :: (Show z, Show r, Ord z, Ord r) => (Direction -> Program z r IntDouble) -> IO ()+solve_problem problem+ = do let a1 = solve $ problem Minimise+ putStrLn "*** Minimise *** "+ show_result a1++ let a2 = solve $ problem Maximise+ putStrLn "*** Maximise *** "+ show_result a2++show_result :: (Show z, Show r, Ord z, Ord r) => Either Error (Assignment z r IntDouble) -> IO ()+show_result as+ = case as of+ Left e+ -> do putStrLn "Error:"+ print e+ Right a+ -> do putStrLn "Success:"+ print a+
+ examples/Clustering.hs view
@@ -0,0 +1,114 @@+-- Example program based on one generated by our fusion/clustering algorithm+--+-- sum1 = fold (+) 0 xs+-- nor1 = map (/ sum1) xs+-- ys = filter (> 0) xs+-- sum2 = fold (+) 0 ys+-- nor2 = map (/ sum2) xs+--++module Clustering (clustering) where++import Base+import Numeric.Limp.Rep+import Numeric.Limp.Program++import qualified Numeric.Limp.Canon as C+import qualified Numeric.Limp.Canon.Pretty as C++-- | One for each combinator+data Node+ = Sum1 | Nor1 | Ys | Sum2 | Nor2+ deriving (Ord, Eq, Show)++-- | The integer variables:+-- forall a b. 0 <= F a b <= 1 :: Z+-- F a b == 0 iff a and b are fused+data VZ+ = F Node Node+ deriving (Ord, Eq, Show)++-- | The real variables:+-- forall a b. F a b == 0 ==> O a == O b+-- O a > O b if edge from a to b+data VR+ = O Node+ deriving (Ord, Eq, Show)+++problem1 :: Direction -> Program VZ VR IntDouble+problem1 dir+ = program dir+ objective+ constraints+ bounds++--Minimise 5f(sum1, ys) + 1f(sum1, sum2)+-- + 5f(sum1, nor2) + 5f(ys, sum2)+-- + 5f(ys, nor1) + 5f(sum2, nor1)+-- + 5f(nor1, nor2)+objective+ = f100 Sum1 Ys .+. f1 Sum1 Sum2+ .+. f100 Sum1 Nor2 .+. f100 Ys Sum2+ .+. f100 Ys Nor1 .+. f1 Sum2 Nor1+ .+. f100 Nor1 Nor2++--Subject to +-- f(sum1, ys) ≤ f(sum1, sum2)+-- f(sum2, ys) ≤ f(sum1, sum2)+-- -5f(sum1, ys) ≤ o(ys) - o(sum1) ≤ 5f(sum1, ys)+-- -5f(sum1, sum2) ≤ o(sum2) - o(sum1) ≤ 5f(sum1, sum2)+-- 1f(ys, sum2) ≤ o(sum2) - o(ys) ≤ 5f(ys, sum2)+-- -5f(nor1, nor2) ≤ o(nor2) - o(nor1) ≤ 5f(nor1, nor2)+-- o(sum1) < o(nor1)+-- o(sum2) < o(nor2)+--+constraints+ = filt Sum1 Sum2 Ys+ :&& filt Sum2 Nor1 Ys+ :&& odiff (-5) Sum1 Ys 5+ :&& odiff (-5) Sum1 Sum2 5+ :&& odiff 1 Ys Sum2 5+ :&& odiff (-5) Ys Nor1 5+ :&& odiff (-5) Nor1 Nor2 5+ :&& odiff (-5) Sum1 Nor2 5+ :&& odiff (-5) Sum2 Nor1 5+ :&& o Sum1 `lt` o Nor1+ :&& o Sum2 `lt` o Nor2+ where++ o = r1 . O++ lt a b = a .+. c1 :<= b++ filt a b c+ = f1 a c :<= f1 a b+ :&& f1 b c :<= f1 a b++ odiff p a b q+ = Between (p *. f1 a b) (o b .-. o a) (q *. f1 a b)++bounds+ = [ binary $ F Sum1 Sum2+ , binary $ F Sum1 Ys+ , binary $ F Sum1 Nor2+ , binary $ F Ys Sum2+ , binary $ F Nor1 Ys+ , binary $ F Nor1 Sum2+ , binary $ F Nor1 Nor2+ ]++f100 :: Node -> Node -> Linear VZ VR IntDouble KZ+f100 a b+ = 100 *. f1 a b++f1 :: Node -> Node -> Linear VZ VR IntDouble KZ+f1 a b+ = z1 $ F (min a b) (max a b)+++clustering :: IO ()+clustering+ = do solve_problem problem1+ putStr (show $ C.program $ problem1 Minimise)+
+ examples/Infeasible.hs view
@@ -0,0 +1,21 @@+module Infeasible (infeasible) where++import Base+import Numeric.Limp.Rep+import Numeric.Limp.Program++-- Minimise 1+-- Subject to a >= b + 1+-- b >= a + 1+problem1 :: Direction -> Program V0 V2 IntDouble+problem1 dir+ = program dir+ c1+ ( r1 A :>= r1 B .+. c1+ :&& r1 B :>= r1 A .+. c1)+ []++infeasible :: IO ()+infeasible+ = do solve_problem problem1+
+ examples/Simple.hs view
@@ -0,0 +1,59 @@+module Simple (simple) where++import Base+import Numeric.Limp.Rep+import Numeric.Limp.Program++-- Minimise a + b+-- Subject to a + 2b >= 3+-- Where 0 <= a <= 10 :: Z+-- 0 <= b <= 10 :: R+problem1 :: Direction -> Program String String IntDouble+problem1 dir+ = program dir+ (z1 "a" .+. r1 "b" )+ (z1 "a" .+. r "b" 2 :>= con 3)+ [ lowerUpperZ 0 "a" 10+ , lowerUpperR 0 "b" 10 ]++-- As above, but swap coefficients on >= 3 constraint.+--+-- Minimise a + b+-- Subject to 2a + b >= 3+-- Where 0 <= a <= 10 :: Z+-- 0 <= b <= 10 :: R+problem2 :: Direction -> Program String String IntDouble+problem2 dir+ = program dir+ (z1 "a" .+. r1 "b" )+ (z "a" 2 .+. r1 "b" :>= con 3)+ [ lowerUpperZ 0 "a" 10+ , lowerUpperR 0 "b" 10 ]+++-- Leave out the bounds on variables+--+-- Minimise a + b+-- Subject to a >= b+-- b >= a+-- a >= 3+-- b <= 10+-- Where a :: Z+-- b :: R+problem3 :: Direction -> Program String String IntDouble+problem3 dir+ = program dir+ (z1 "a" .+. r1 "b")+ ( z1 "a" :>= r1 "b"+ :&& r1 "b" :>= z1 "a"+ :&& z1 "a" :>= con 3+ :&& r1 "b" :<= con 10)+ [ ]+++simple :: IO ()+simple+ = do solve_problem problem1+ solve_problem problem2+ solve_problem problem3+
+ examples/Stupid.hs view
@@ -0,0 +1,19 @@+-- Stupid examples that might just fail+module Stupid (stupid) where++import Base+import Numeric.Limp.Rep+import Numeric.Limp.Program++problem1 :: Direction -> Program String String IntDouble+problem1 dir+ = program dir+ c1+ CTrue+ []++stupid :: IO ()+stupid+ = do solve_problem problem1++
limp-cbc.cabal view
@@ -1,5 +1,5 @@ name: limp-cbc-version: 0.3.2.0+version: 0.3.2.1 synopsis: bindings for integer linear programming solver Coin/CBC description: very simple binding to external solver, CBC. CBC is somewhat faster than GLPK, and also has a more permissive licence.@@ -294,6 +294,7 @@ extra-libraries: Cbc Clp CbcSolver Cgl Osi OsiCbc OsiClp OsiCommonTests CoinUtils CoinMP stdc++ include-dirs: cbits includes: Cbc.h+ c-sources: cbits/Cbc.cpp else extra-libraries: stdc++ include-dirs: cbits, cbits/coin@@ -302,31 +303,23 @@ c-sources: cbits/Cbc.cpp- cbits/coin/Cbc_ampl.cpp- cbits/coin/Cbc_C_Interface.cpp- cbits/coin/CbcBranchAllDifferent.cpp cbits/coin/CbcBranchCut.cpp cbits/coin/CbcBranchDecision.cpp cbits/coin/CbcBranchDefaultDecision.cpp cbits/coin/CbcBranchDynamic.cpp cbits/coin/CbcBranchingObject.cpp cbits/coin/CbcBranchLotsize.cpp- cbits/coin/CbcBranchToFixLots.cpp- cbits/coin/CbcCbcParam.cpp cbits/coin/CbcClique.cpp cbits/coin/CbcCompareDefault.cpp cbits/coin/CbcCompareDepth.cpp- cbits/coin/CbcCompareEstimate.cpp- cbits/coin/CbcCompareObjective.cpp cbits/coin/CbcConsequence.cpp cbits/coin/CbcCountRowCut.cpp cbits/coin/CbcCutGenerator.cpp cbits/coin/CbcCutModifier.cpp- cbits/coin/CbcCutSubsetModifier.cpp cbits/coin/CbcDummyBranchingObject.cpp+ cbits/coin/CbcOrClpParam.cpp cbits/coin/CbcEventHandler.cpp cbits/coin/CbcFathom.cpp- cbits/coin/CbcFathomDynamicProgramming.cpp cbits/coin/CbcFixVariable.cpp cbits/coin/CbcFollowOn.cpp cbits/coin/CbcFullNodeInfo.cpp@@ -350,7 +343,6 @@ cbits/coin/CbcHeuristicRINS.cpp cbits/coin/CbcHeuristicVND.cpp cbits/coin/CbcLinked.cpp- cbits/coin/CbcLinkedUtils.cpp cbits/coin/CbcMessage.cpp cbits/coin/CbcMipStartIO.cpp cbits/coin/CbcModel.cpp@@ -375,7 +367,6 @@ cbits/coin/CbcTree.cpp cbits/coin/CbcTreeLocal.cpp cbits/coin/Cgl012cut.cpp- cbits/coin/CglAllDifferent.cpp cbits/coin/CglClique.cpp cbits/coin/CglCliqueHelper.cpp cbits/coin/CglCutGenerator.cpp@@ -389,12 +380,9 @@ cbits/coin/CglLandPMessages.cpp cbits/coin/CglLandPSimplex.cpp cbits/coin/CglLandPTabRow.cpp- cbits/coin/CglLandPTest.cpp cbits/coin/CglLandPUtils.cpp cbits/coin/CglLandPValidator.cpp- cbits/coin/CglLiftAndProject.cpp cbits/coin/CglMessage.cpp- cbits/coin/CglMixedIntegerRounding.cpp cbits/coin/CglMixedIntegerRounding2.cpp cbits/coin/CglOddHole.cpp cbits/coin/CglParam.cpp@@ -405,12 +393,10 @@ cbits/coin/CglRedSplit2Param.cpp cbits/coin/CglRedSplitParam.cpp cbits/coin/CglResidualCapacity.cpp- cbits/coin/CglSimpleRounding.cpp cbits/coin/CglStored.cpp cbits/coin/CglTreeInfo.cpp cbits/coin/CglTwomir.cpp cbits/coin/CglZeroHalf.cpp- cbits/coin/Clp_C_Interface.cpp cbits/coin/ClpCholeskyBase.cpp cbits/coin/ClpCholeskyDense.cpp cbits/coin/ClpConstraint.cpp@@ -419,13 +405,9 @@ cbits/coin/ClpDualRowDantzig.cpp cbits/coin/ClpDualRowPivot.cpp cbits/coin/ClpDualRowSteepest.cpp- cbits/coin/ClpDummyMatrix.cpp- cbits/coin/ClpDynamicExampleMatrix.cpp cbits/coin/ClpDynamicMatrix.cpp cbits/coin/ClpEventHandler.cpp cbits/coin/ClpFactorization.cpp- cbits/coin/ClpGubDynamicMatrix.cpp- cbits/coin/ClpGubMatrix.cpp cbits/coin/ClpHelperFunctions.cpp cbits/coin/ClpInterior.cpp cbits/coin/ClpLinearObjective.cpp@@ -454,7 +436,6 @@ cbits/coin/ClpSimplexOther.cpp cbits/coin/ClpSimplexPrimal.cpp cbits/coin/ClpSolve.cpp- cbits/coin/CoinAlloc.cpp cbits/coin/CoinBuild.cpp cbits/coin/CoinDenseFactorization.cpp cbits/coin/CoinDenseVector.cpp@@ -479,8 +460,6 @@ cbits/coin/CoinPackedMatrix.cpp cbits/coin/CoinPackedVector.cpp cbits/coin/CoinPackedVectorBase.cpp- cbits/coin/CoinParam.cpp- cbits/coin/CoinParamUtils.cpp cbits/coin/CoinPostsolveMatrix.cpp cbits/coin/CoinPrePostsolveMatrix.cpp cbits/coin/CoinPresolveDoubleton.cpp@@ -531,6 +510,12 @@ type: exitcode-stdio-1.0 hs-source-dirs: examples main-is: Test.hs+ other-modules:+ Base+ Clustering+ Infeasible+ Simple+ Stupid build-depends: base, limp, limp-cbc default-language: Haskell2010 default-extensions: TemplateHaskell TypeFamilies FlexibleContexts GeneralizedNewtypeDeriving DataKinds GADTs RankNTypes StandaloneDeriving