diff options
Diffstat (limited to 'newstructure/thirdparty/linux/include/coin/CbcLinked.hpp')
-rw-r--r-- | newstructure/thirdparty/linux/include/coin/CbcLinked.hpp | 1406 |
1 files changed, 1406 insertions, 0 deletions
diff --git a/newstructure/thirdparty/linux/include/coin/CbcLinked.hpp b/newstructure/thirdparty/linux/include/coin/CbcLinked.hpp new file mode 100644 index 0000000..daa977c --- /dev/null +++ b/newstructure/thirdparty/linux/include/coin/CbcLinked.hpp @@ -0,0 +1,1406 @@ +/* $Id: CbcLinked.hpp 1899 2013-04-09 18:12:08Z 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). + +#ifndef CglLinked_H +#define CglLinked_H +/* THIS CONTAINS STUFF THAT SHOULD BE IN + OsiSolverLink + OsiBranchLink + CglTemporary +*/ +#include "CoinModel.hpp" +#include "OsiClpSolverInterface.hpp" +#include "OsiChooseVariable.hpp" +#include "CbcFathom.hpp" +class CbcModel; +class CoinPackedMatrix; +class OsiLinkedBound; +class OsiObject; +class CglStored; +class CglTemporary; +/** + +This is to allow the user to replace initialSolve and resolve +This version changes coefficients +*/ + +class OsiSolverLink : public CbcOsiSolver { + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + + /// Resolve an LP relaxation after problem modification + virtual void resolve(); + + /** + Problem specific + Returns -1 if node fathomed and no solution + 0 if did nothing + 1 if node fathomed and solution + allFixed is true if all LinkedBound variables are fixed + */ + virtual int fathom(bool allFixed) ; + /** Solves nonlinear problem from CoinModel using SLP - may be used as crash + for other algorithms when number of iterations small. + Also exits if all problematical variables are changing + less than deltaTolerance + Returns solution array + */ + double * nonlinearSLP(int numberPasses, double deltaTolerance); + /** Solve linearized quadratic objective branch and bound. + Return cutoff and OA cut + */ + double linearizedBAB(CglStored * cut) ; + /** Solves nonlinear problem from CoinModel using SLP - and then tries to get + heuristic solution + Returns solution array + mode - + 0 just get continuous + 1 round and try normal bab + 2 use defaultBound_ to bound integer variables near current solution + */ + double * heuristicSolution(int numberPasses, double deltaTolerance, int mode); + + /// Do OA cuts + int doAOCuts(CglTemporary * cutGen, const double * solution, const double * solution2); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiSolverLink (); + + /** This creates from a coinModel object + + if errors.then number of sets is -1 + + This creates linked ordered sets information. It assumes - + + for product terms syntax is yy*f(zz) + also just f(zz) is allowed + and even a constant + + modelObject not const as may be changed as part of process. + */ + OsiSolverLink( CoinModel & modelObject); + // Other way with existing object + void load( CoinModel & modelObject, bool tightenBounds = false, int logLevel = 1); + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiSolverLink (const OsiSolverLink &); + + /// Assignment operator + OsiSolverLink & operator=(const OsiSolverLink& rhs); + + /// Destructor + virtual ~OsiSolverLink (); + + //@} + + + /**@name Sets and Gets */ + //@{ + /// Add a bound modifier + void addBoundModifier(bool upperBoundAffected, bool useUpperBound, int whichVariable, int whichVariableAffected, + double multiplier = 1.0); + /// Update coefficients - returns number updated if in updating mode + int updateCoefficients(ClpSimplex * solver, CoinPackedMatrix * matrix); + /// Analyze constraints to see which are convex (quadratic) + void analyzeObjects(); + /// Add reformulated bilinear constraints + void addTighterConstraints(); + /// Objective value of best solution found internally + inline double bestObjectiveValue() const { + return bestObjectiveValue_; + } + /// Set objective value of best solution found internally + inline void setBestObjectiveValue(double value) { + bestObjectiveValue_ = value; + } + /// Best solution found internally + inline const double * bestSolution() const { + return bestSolution_; + } + /// Set best solution found internally + void setBestSolution(const double * solution, int numberColumns); + /// Set special options + inline void setSpecialOptions2(int value) { + specialOptions2_ = value; + } + /// Say convex (should work it out) - if convex false then strictly concave + void sayConvex(bool convex); + /// Get special options + inline int specialOptions2() const { + return specialOptions2_; + } + /** Clean copy of matrix + So we can add rows + */ + CoinPackedMatrix * cleanMatrix() const { + return matrix_; + } + /** Row copy of matrix + Just genuine columns and rows + Linear part + */ + CoinPackedMatrix * originalRowCopy() const { + return originalRowCopy_; + } + /// Copy of quadratic model if one + ClpSimplex * quadraticModel() const { + return quadraticModel_; + } + /// Gets correct form for a quadratic row - user to delete + CoinPackedMatrix * quadraticRow(int rowNumber, double * linear) const; + /// Default meshSize + inline double defaultMeshSize() const { + return defaultMeshSize_; + } + inline void setDefaultMeshSize(double value) { + defaultMeshSize_ = value; + } + /// Default maximumbound + inline double defaultBound() const { + return defaultBound_; + } + inline void setDefaultBound(double value) { + defaultBound_ = value; + } + /// Set integer priority + inline void setIntegerPriority(int value) { + integerPriority_ = value; + } + /// Get integer priority + inline int integerPriority() const { + return integerPriority_; + } + /// Objective transfer variable if one + inline int objectiveVariable() const { + return objectiveVariable_; + } + /// Set biLinear priority + inline void setBiLinearPriority(int value) { + biLinearPriority_ = value; + } + /// Get biLinear priority + inline int biLinearPriority() const { + return biLinearPriority_; + } + /// Return CoinModel + inline const CoinModel * coinModel() const { + return &coinModel_; + } + /// Set all biLinear priorities on x-x variables + void setBiLinearPriorities(int value, double meshSize = 1.0); + /** Set options and priority on all or some biLinear variables + 1 - on I-I + 2 - on I-x + 4 - on x-x + or combinations. + -1 means leave (for priority value and strategy value) + */ + void setBranchingStrategyOnVariables(int strategyValue, int priorityValue = -1, + int mode = 7); + /// Set all mesh sizes on x-x variables + void setMeshSizes(double value); + /** Two tier integer problem where when set of variables with priority + less than this are fixed the problem becomes an easier integer problem + */ + void setFixedPriority(int priorityValue); + //@} + + //--------------------------------------------------------------------------- + +protected: + + + /**@name functions */ + //@{ + /// Do real work of initialize + //void initialize(ClpSimplex * & solver, OsiObject ** & object) const; + /// Do real work of delete + void gutsOfDestructor(bool justNullify = false); + /// Do real work of copy + void gutsOfCopy(const OsiSolverLink & rhs) ; + //@} + + /**@name Private member data */ + //@{ + /** Clean copy of matrix + Marked coefficients will be multiplied by L or U + */ + CoinPackedMatrix * matrix_; + /** Row copy of matrix + Just genuine columns and rows + */ + CoinPackedMatrix * originalRowCopy_; + /// Copy of quadratic model if one + ClpSimplex * quadraticModel_; + /// Number of rows with nonLinearities + int numberNonLinearRows_; + /// Starts of lists + int * startNonLinear_; + /// Row number for a list + int * rowNonLinear_; + /** Indicator whether is convex, concave or neither + -1 concave, 0 neither, +1 convex + */ + int * convex_; + /// Indices in a list/row + int * whichNonLinear_; + /// Model in CoinModel format + CoinModel coinModel_; + /// Number of variables in tightening phase + int numberVariables_; + /// Information + OsiLinkedBound * info_; + /** + 0 bit (1) - call fathom (may do mini B&B) + 1 bit (2) - quadratic only in objective (add OA cuts) + 2 bit (4) - convex + 3 bit (8) - try adding OA cuts + 4 bit (16) - add linearized constraints + */ + int specialOptions2_; + /// Objective transfer row if one + int objectiveRow_; + /// Objective transfer variable if one + int objectiveVariable_; + /// Objective value of best solution found internally + double bestObjectiveValue_; + /// Default mesh + double defaultMeshSize_; + /// Default maximum bound + double defaultBound_; + /// Best solution found internally + double * bestSolution_; + /// Priority for integers + int integerPriority_; + /// Priority for bilinear + int biLinearPriority_; + /// Number of variables which when fixed help + int numberFix_; + /// list of fixed variables + int * fixVariables_; + //@} +}; +/** + List of bounds which depend on other bounds +*/ + +class OsiLinkedBound { + +public: + //--------------------------------------------------------------------------- + /**@name Action methods */ + //@{ + /// Update other bounds + void updateBounds(ClpSimplex * solver); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiLinkedBound (); + /// Useful Constructor + OsiLinkedBound(OsiSolverInterface * model, int variable, + int numberAffected, const int * positionL, + const int * positionU, const double * multiplier); + + /// Copy constructor + OsiLinkedBound (const OsiLinkedBound &); + + /// Assignment operator + OsiLinkedBound & operator=(const OsiLinkedBound& rhs); + + /// Destructor + ~OsiLinkedBound (); + + //@} + + /**@name Sets and Gets */ + //@{ + /// Get variable + inline int variable() const { + return variable_; + } + /// Add a bound modifier + void addBoundModifier(bool upperBoundAffected, bool useUpperBound, int whichVariable, + double multiplier = 1.0); + //@} + +private: + typedef struct { + double multiplier; // to use in computation + int affected; // variable or element affected + /* + 0 - LB of variable affected + 1 - UB of variable affected + 2 - element in position (affected) affected + */ + unsigned char affect; + unsigned char ubUsed; // nonzero if UB of this variable is used + /* + 0 - use x*multiplier + 1 - use multiplier/x + 2 - if UB use min of current upper and x*multiplier, if LB use max of current lower and x*multiplier + */ + unsigned char type; // type of computation + } boundElementAction; + + /**@name Private member data */ + //@{ + /// Pointer back to model + OsiSolverInterface * model_; + /// Variable + int variable_; + /// Number of variables/elements affected + int numberAffected_; + /// Maximum number of variables/elements affected + int maximumAffected_; + /// Actions + boundElementAction * affected_; + //@} +}; +#include "CbcHeuristic.hpp" +/** heuristic - just picks up any good solution + */ + +class CbcHeuristicDynamic3 : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicDynamic3 (); + + /* Constructor with model + */ + CbcHeuristicDynamic3 (CbcModel & model); + + // Copy constructor + CbcHeuristicDynamic3 ( const CbcHeuristicDynamic3 &); + + // Destructor + ~CbcHeuristicDynamic3 (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// update model + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + /// Returns true if can deal with "odd" problems e.g. sos type 2 + virtual bool canDealWithOdd() const { + return true; + } + +protected: +private: + /// Illegal Assignment operator + CbcHeuristicDynamic3 & operator=(const CbcHeuristicDynamic3& rhs); +}; + +#include "OsiBranchingObject.hpp" + +/** Define Special Linked Ordered Sets. + +*/ +class CoinWarmStartBasis; + +class OsiOldLink : public OsiSOS { + +public: + + // Default Constructor + OsiOldLink (); + + /** Useful constructor - A valid solution is if all variables are zero + apart from k*numberLink to (k+1)*numberLink-1 where k is 0 through + numberInSet-1. The length of weights array is numberInSet. + For this constructor the variables in matrix are the numberInSet*numberLink + starting at first. If weights null then 0,1,2.. + */ + OsiOldLink (const OsiSolverInterface * solver, int numberMembers, + int numberLinks, int first, + const double * weights, int setNumber); + /** Useful constructor - A valid solution is if all variables are zero + apart from k*numberLink to (k+1)*numberLink-1 where k is 0 through + numberInSet-1. The length of weights array is numberInSet. + For this constructor the variables are given by list - grouped. + If weights null then 0,1,2.. + */ + OsiOldLink (const OsiSolverInterface * solver, int numberMembers, + int numberLinks, int typeSOS, const int * which, + const double * weights, int setNumber); + + // Copy constructor + OsiOldLink ( const OsiOldLink &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiOldLink & operator=( const OsiOldLink& rhs); + + // Destructor + virtual ~OsiOldLink (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Number of links for each member + inline int numberLinks() const { + return numberLinks_; + } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const { + return false; + } + +private: + /// data + + /// Number of links + int numberLinks_; +}; +/** Branching object for Linked ordered sets + + */ +class OsiOldLinkBranchingObject : public OsiSOSBranchingObject { + +public: + + // Default Constructor + OsiOldLinkBranchingObject (); + + // Useful constructor + OsiOldLinkBranchingObject (OsiSolverInterface * solver, const OsiOldLink * originalObject, + int way, + double separator); + + // Copy constructor + OsiOldLinkBranchingObject ( const OsiOldLinkBranchingObject &); + + // Assignment operator + OsiOldLinkBranchingObject & operator=( const OsiOldLinkBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiOldLinkBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver = NULL); +private: + /// data +}; +/** Define data for one link + +*/ + + +class OsiOneLink { + +public: + + // Default Constructor + OsiOneLink (); + + /** Useful constructor - + + */ + OsiOneLink (const OsiSolverInterface * solver, int xRow, int xColumn, int xyRow, + const char * functionString); + + // Copy constructor + OsiOneLink ( const OsiOneLink &); + + // Assignment operator + OsiOneLink & operator=( const OsiOneLink& rhs); + + // Destructor + virtual ~OsiOneLink (); + + /// data + + /// Row which defines x (if -1 then no x) + int xRow_; + /// Column which defines x + int xColumn_; + /// Output row + int xyRow; + /// Function + std::string function_; +}; +/** Define Special Linked Ordered Sets. New style + + members and weights may be stored in SOS object + + This is for y and x*f(y) and z*g(y) etc + +*/ + + +class OsiLink : public OsiSOS { + +public: + + // Default Constructor + OsiLink (); + + /** Useful constructor - + + */ + OsiLink (const OsiSolverInterface * solver, int yRow, + int yColumn, double meshSize); + + // Copy constructor + OsiLink ( const OsiLink &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiLink & operator=( const OsiLink& rhs); + + // Destructor + virtual ~OsiLink (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Number of links for each member + inline int numberLinks() const { + return numberLinks_; + } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const { + return false; + } + +private: + /// data + /// Current increment for y points + double meshSize_; + /// Links + OsiOneLink * data_; + /// Number of links + int numberLinks_; + /// Row which defines y + int yRow_; + /// Column which defines y + int yColumn_; +}; +/** Branching object for Linked ordered sets + + */ +class OsiLinkBranchingObject : public OsiTwoWayBranchingObject { + +public: + + // Default Constructor + OsiLinkBranchingObject (); + + // Useful constructor + OsiLinkBranchingObject (OsiSolverInterface * solver, const OsiLink * originalObject, + int way, + double separator); + + // Copy constructor + OsiLinkBranchingObject ( const OsiLinkBranchingObject &); + + // Assignment operator + OsiLinkBranchingObject & operator=( const OsiLinkBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiLinkBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver = NULL); +private: + /// data +}; +/** Define BiLinear objects + + This models x*y where one or both are integer + +*/ + + +class OsiBiLinear : public OsiObject2 { + +public: + + // Default Constructor + OsiBiLinear (); + + /** Useful constructor - + This Adds in rows and variables to construct valid Linked Ordered Set + Adds extra constraints to match other x/y + So note not const solver + */ + OsiBiLinear (OsiSolverInterface * solver, int xColumn, + int yColumn, int xyRow, double coefficient, + double xMesh, double yMesh, + int numberExistingObjects = 0, const OsiObject ** objects = NULL ); + + /** Useful constructor - + This Adds in rows and variables to construct valid Linked Ordered Set + Adds extra constraints to match other x/y + So note not const model + */ + OsiBiLinear (CoinModel * coinModel, int xColumn, + int yColumn, int xyRow, double coefficient, + double xMesh, double yMesh, + int numberExistingObjects = 0, const OsiObject ** objects = NULL ); + + // Copy constructor + OsiBiLinear ( const OsiBiLinear &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiBiLinear & operator=( const OsiBiLinear& rhs); + + // Destructor + virtual ~OsiBiLinear (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + // This does NOT set mutable stuff + virtual double checkInfeasibility(const OsiBranchingInformation * info) const; + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const { + return (branchingStrategy_&4) != 0; + } + /// X column + inline int xColumn() const { + return xColumn_; + } + /// Y column + inline int yColumn() const { + return yColumn_; + } + /// X row + inline int xRow() const { + return xRow_; + } + /// Y row + inline int yRow() const { + return yRow_; + } + /// XY row + inline int xyRow() const { + return xyRow_; + } + /// Coefficient + inline double coefficient() const { + return coefficient_; + } + /// Set coefficient + inline void setCoefficient(double value) { + coefficient_ = value; + } + /// First lambda (of 4) + inline int firstLambda() const { + return firstLambda_; + } + /// X satisfied if less than this away from mesh + inline double xSatisfied() const { + return xSatisfied_; + } + inline void setXSatisfied(double value) { + xSatisfied_ = value; + } + /// Y satisfied if less than this away from mesh + inline double ySatisfied() const { + return ySatisfied_; + } + inline void setYSatisfied(double value) { + ySatisfied_ = value; + } + /// X other satisfied if less than this away from mesh + inline double xOtherSatisfied() const { + return xOtherSatisfied_; + } + inline void setXOtherSatisfied(double value) { + xOtherSatisfied_ = value; + } + /// Y other satisfied if less than this away from mesh + inline double yOtherSatisfied() const { + return yOtherSatisfied_; + } + inline void setYOtherSatisfied(double value) { + yOtherSatisfied_ = value; + } + /// X meshSize + inline double xMeshSize() const { + return xMeshSize_; + } + inline void setXMeshSize(double value) { + xMeshSize_ = value; + } + /// Y meshSize + inline double yMeshSize() const { + return yMeshSize_; + } + inline void setYMeshSize(double value) { + yMeshSize_ = value; + } + /// XY satisfied if two version differ by less than this + inline double xySatisfied() const { + return xySatisfied_; + } + inline void setXYSatisfied(double value) { + xySatisfied_ = value; + } + /// Set sizes and other stuff + void setMeshSizes(const OsiSolverInterface * solver, double x, double y); + /** branching strategy etc + bottom 2 bits + 0 branch on either, 1 branch on x, 2 branch on y + next bit + 4 set to say don't update coefficients + next bit + 8 set to say don't use in feasible region + next bit + 16 set to say - Always satisfied !! + */ + inline int branchingStrategy() const { + return branchingStrategy_; + } + inline void setBranchingStrategy(int value) { + branchingStrategy_ = value; + } + /** Simple quadratic bound marker. + 0 no + 1 L if coefficient pos, G if negative i.e. value is ub on xy + 2 G if coefficient pos, L if negative i.e. value is lb on xy + 3 E + If bound then real coefficient is 1.0 and coefficient_ is bound + */ + inline int boundType() const { + return boundType_; + } + inline void setBoundType(int value) { + boundType_ = value; + } + /// Does work of branching + void newBounds(OsiSolverInterface * solver, int way, short xOrY, double separator) const; + /// Updates coefficients - returns number updated + int updateCoefficients(const double * lower, const double * upper, double * objective, + CoinPackedMatrix * matrix, CoinWarmStartBasis * basis) const; + /// Returns true value of single xyRow coefficient + double xyCoefficient(const double * solution) const; + /// Get LU coefficients from matrix + void getCoefficients(const OsiSolverInterface * solver, double xB[2], double yB[2], double xybar[4]) const; + /// Compute lambdas (third entry in each .B is current value) (nonzero if bad) + double computeLambdas(const double xB[3], const double yB[3], const double xybar[4], double lambda[4]) const; + /// Adds in data for extra row with variable coefficients + void addExtraRow(int row, double multiplier); + /// Sets infeasibility and other when pseudo shadow prices + void getPseudoShadow(const OsiBranchingInformation * info); + /// Gets sum of movements to correct value + double getMovement(const OsiBranchingInformation * info); + +protected: + /// Compute lambdas if coefficients not changing + void computeLambdas(const OsiSolverInterface * solver, double lambda[4]) const; + /// data + + /// Coefficient + double coefficient_; + /// x mesh + double xMeshSize_; + /// y mesh + double yMeshSize_; + /// x satisfied if less than this away from mesh + double xSatisfied_; + /// y satisfied if less than this away from mesh + double ySatisfied_; + /// X other satisfied if less than this away from mesh + double xOtherSatisfied_; + /// Y other satisfied if less than this away from mesh + double yOtherSatisfied_; + /// xy satisfied if less than this away from true + double xySatisfied_; + /// value of x or y to branch about + mutable double xyBranchValue_; + /// x column + int xColumn_; + /// y column + int yColumn_; + /// First lambda (of 4) + int firstLambda_; + /** branching strategy etc + bottom 2 bits + 0 branch on either, 1 branch on x, 2 branch on y + next bit + 4 set to say don't update coefficients + next bit + 8 set to say don't use in feasible region + next bit + 16 set to say - Always satisfied !! + */ + int branchingStrategy_; + /** Simple quadratic bound marker. + 0 no + 1 L if coefficient pos, G if negative i.e. value is ub on xy + 2 G if coefficient pos, L if negative i.e. value is lb on xy + 3 E + If bound then real coefficient is 1.0 and coefficient_ is bound + */ + int boundType_; + /// x row + int xRow_; + /// y row (-1 if x*x) + int yRow_; + /// Output row + int xyRow_; + /// Convexity row + int convexity_; + /// Number of extra rows (coefficients to be modified) + int numberExtraRows_; + /// Multiplier for coefficient on row + double * multiplier_; + /// Row number + int * extraRow_; + /// Which chosen -1 none, 0 x, 1 y + mutable short chosen_; +}; +/** Branching object for BiLinear objects + + */ +class OsiBiLinearBranchingObject : public OsiTwoWayBranchingObject { + +public: + + // Default Constructor + OsiBiLinearBranchingObject (); + + // Useful constructor + OsiBiLinearBranchingObject (OsiSolverInterface * solver, const OsiBiLinear * originalObject, + int way, + double separator, int chosen); + + // Copy constructor + OsiBiLinearBranchingObject ( const OsiBiLinearBranchingObject &); + + // Assignment operator + OsiBiLinearBranchingObject & operator=( const OsiBiLinearBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiBiLinearBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver = NULL); + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const; +private: + /// data + /// 1 means branch on x, 2 branch on y + short chosen_; +}; +/** Define Continuous BiLinear objects for an == bound + + This models x*y = b where both are continuous + +*/ + + +class OsiBiLinearEquality : public OsiBiLinear { + +public: + + // Default Constructor + OsiBiLinearEquality (); + + /** Useful constructor - + This Adds in rows and variables to construct Ordered Set + for x*y = b + So note not const solver + */ + OsiBiLinearEquality (OsiSolverInterface * solver, int xColumn, + int yColumn, int xyRow, double rhs, + double xMesh); + + // Copy constructor + OsiBiLinearEquality ( const OsiBiLinearEquality &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiBiLinearEquality & operator=( const OsiBiLinearEquality& rhs); + + // Destructor + virtual ~OsiBiLinearEquality (); + + /// Possible improvement + virtual double improvement(const OsiSolverInterface * solver) const; + /** change grid + if type 0 then use solution and make finer + if 1 then back to original + returns mesh size + */ + double newGrid(OsiSolverInterface * solver, int type) const; + /// Number of points + inline int numberPoints() const { + return numberPoints_; + } + inline void setNumberPoints(int value) { + numberPoints_ = value; + } + +private: + /// Number of points + int numberPoints_; +}; +/// Define a single integer class - but one where you keep branching until fixed even if satisfied + + +class OsiSimpleFixedInteger : public OsiSimpleInteger { + +public: + + /// Default Constructor + OsiSimpleFixedInteger (); + + /// Useful constructor - passed solver index + OsiSimpleFixedInteger (const OsiSolverInterface * solver, int iColumn); + + /// Useful constructor - passed solver index and original bounds + OsiSimpleFixedInteger (int iColumn, double lower, double upper); + + /// Useful constructor - passed simple integer + OsiSimpleFixedInteger (const OsiSimpleInteger &); + + /// Copy constructor + OsiSimpleFixedInteger ( const OsiSimpleFixedInteger &); + + /// Clone + virtual OsiObject * clone() const; + + /// Assignment operator + OsiSimpleFixedInteger & operator=( const OsiSimpleFixedInteger& rhs); + + /// Destructor + virtual ~OsiSimpleFixedInteger (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; +protected: + /// data + +}; +/** Define a single variable class which is involved with OsiBiLinear objects. + This is used so can make better decision on where to branch as it can look at + all objects. + + This version sees if it can re-use code from OsiSimpleInteger + even if not an integer variable. If not then need to duplicate code. +*/ + + +class OsiUsesBiLinear : public OsiSimpleInteger { + +public: + + /// Default Constructor + OsiUsesBiLinear (); + + /// Useful constructor - passed solver index + OsiUsesBiLinear (const OsiSolverInterface * solver, int iColumn, int type); + + /// Useful constructor - passed solver index and original bounds + OsiUsesBiLinear (int iColumn, double lower, double upper, int type); + + /// Useful constructor - passed simple integer + OsiUsesBiLinear (const OsiSimpleInteger & rhs, int type); + + /// Copy constructor + OsiUsesBiLinear ( const OsiUsesBiLinear & rhs); + + /// Clone + virtual OsiObject * clone() const; + + /// Assignment operator + OsiUsesBiLinear & operator=( const OsiUsesBiLinear& rhs); + + /// Destructor + virtual ~OsiUsesBiLinear (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current value. + + Given an current value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /// Add all bi-linear objects + void addBiLinearObjects(OsiSolverLink * solver); +protected: + /// data + /// Number of bilinear objects (maybe could be more general) + int numberBiLinear_; + /// Type of variable - 0 continuous, 1 integer + int type_; + /// Objects + OsiObject ** objects_; +}; +/** This class chooses a variable to branch on + + This is just as OsiChooseStrong but it fakes it so only + first so many are looked at in this phase + +*/ + +class OsiChooseStrongSubset : public OsiChooseStrong { + +public: + + /// Default Constructor + OsiChooseStrongSubset (); + + /// Constructor from solver (so we can set up arrays etc) + OsiChooseStrongSubset (const OsiSolverInterface * solver); + + /// Copy constructor + OsiChooseStrongSubset (const OsiChooseStrongSubset &); + + /// Assignment operator + OsiChooseStrongSubset & operator= (const OsiChooseStrongSubset& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~OsiChooseStrongSubset (); + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. + If returns -1 then has worked out node is infeasible! + */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + + /// Number of objects to use + inline int numberObjectsToUse() const { + return numberObjectsToUse_; + } + /// Set number of objects to use + inline void setNumberObjectsToUse(int value) { + numberObjectsToUse_ = value; + } + +protected: + // Data + /// Number of objects to be used (and set in solver) + int numberObjectsToUse_; +}; + +#include <string> + +#include "CglStored.hpp" + +class CoinWarmStartBasis; +/** Stored Temporary Cut Generator Class - destroyed after first use */ +class CglTemporary : public CglStored { + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Stored cuts for the model of the + solver interface, si. + + Insert the generated cuts into OsiCut, cs. + + This generator just looks at previously stored cuts + and inserts any that are violated by enough + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglTemporary (); + + /// Copy constructor + CglTemporary (const CglTemporary & rhs); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglTemporary & + operator=(const CglTemporary& rhs); + + /// Destructor + virtual + ~CglTemporary (); + //@} + +private: + +// Private member methods + + // Private member data +}; +//############################################################################# + +/** + +This is to allow the user to replace initialSolve and resolve +*/ + +class OsiSolverLinearizedQuadratic : public OsiClpSolverInterface { + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiSolverLinearizedQuadratic (); + /// Useful constructor (solution should be good) + OsiSolverLinearizedQuadratic( ClpSimplex * quadraticModel); + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiSolverLinearizedQuadratic (const OsiSolverLinearizedQuadratic &); + + /// Assignment operator + OsiSolverLinearizedQuadratic & operator=(const OsiSolverLinearizedQuadratic& rhs); + + /// Destructor + virtual ~OsiSolverLinearizedQuadratic (); + + //@} + + + /**@name Sets and Gets */ + //@{ + /// Objective value of best solution found internally + inline double bestObjectiveValue() const { + return bestObjectiveValue_; + } + /// Best solution found internally + const double * bestSolution() const { + return bestSolution_; + } + /// Set special options + inline void setSpecialOptions3(int value) { + specialOptions3_ = value; + } + /// Get special options + inline int specialOptions3() const { + return specialOptions3_; + } + /// Copy of quadratic model if one + ClpSimplex * quadraticModel() const { + return quadraticModel_; + } + //@} + + //--------------------------------------------------------------------------- + +protected: + + + /**@name functions */ + //@{ + + /**@name Private member data */ + //@{ + /// Objective value of best solution found internally + double bestObjectiveValue_; + /// Copy of quadratic model if one + ClpSimplex * quadraticModel_; + /// Best solution found internally + double * bestSolution_; + /** + 0 bit (1) - don't do mini B&B + 1 bit (2) - quadratic only in objective + */ + int specialOptions3_; + //@} +}; +class ClpSimplex; +/** Return an approximate solution to a CoinModel. + Lots of bounds may be odd to force a solution. + mode = 0 just tries to get a continuous solution +*/ +ClpSimplex * approximateSolution(CoinModel & coinModel, + int numberPasses, double deltaTolerance, + int mode = 0); +#endif + |