// $Id: CbcHeuristicDW.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 CbcHeuristicDW_H #define CbcHeuristicDW_H #include "CbcHeuristic.hpp" /** This is unlike the other heuristics in that it is very very compute intensive. It tries to find a DW structure and use that */ class CbcHeuristicDW : public CbcHeuristic { public: // Default Constructor CbcHeuristicDW(); /* Constructor with model - assumed before cuts */ CbcHeuristicDW(CbcModel &model, int keepContinuous = 0); /* Constructor with model - assumed before cuts */ CbcHeuristicDW(CbcModel &model, int callBack(CbcHeuristicDW *currentHeuristic, CbcModel *thisModel, int whereFrom), int keepContinuous = 0); // Copy constructor CbcHeuristicDW(const CbcHeuristicDW &); // Destructor ~CbcHeuristicDW(); /// Clone virtual CbcHeuristic *clone() const; /// Assignment operator CbcHeuristicDW &operator=(const CbcHeuristicDW &rhs); /// Create C++ lines to get to current state virtual void generateCpp(FILE *fp); /// Resets stuff if model changes virtual void resetModel(CbcModel *model); /// update model (This is needed if cliques update matrix etc) 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) This does Relaxation Induced Neighborhood Search */ virtual int solution(double &objectiveValue, double *newSolution); /** Return number of blocks <=0 - no usable structure */ inline int numberBlocks() const { return numberBlocks_; } /// Pass in a solution void passInSolution(const double *solution); /// Pass in continuous solution void passInContinuousSolution(const double *solution); /** DW Proposal actions fullDWEverySoOften - 0 - off k - every k times solution gets better */ void setProposalActions(int fullDWEverySoOften); /// Objective value when whichDw created double objectiveValueWhen(int whichDW) const; /// Number of columns in DW int numberColumnsDW(int whichDW) const; /// Solver inline OsiSolverInterface *solver() const { return solver_; } /// DW model (user must delete) OsiSolverInterface *DWModel(int whichDW) const; /// Best objective value inline double bestObjective() const { return bestObjective_; } /// Best solution found so far inline const double *bestSolution() const { return bestSolution_; } /// Continuous solution inline const double *continuousSolution() const { return continuousSolution_; } /// Reduced costs of fixed solution inline const double *fixedDj() const { return fixedDj_; } /// Objective at which DW updated inline const double *objectiveDW() const { return objectiveDW_; } /// Number of times we have added to DW model inline int numberDWTimes() const { return numberDWTimes_; } /// Number of columns in DW inline const int *numberColumnsDW() const { return numberColumnsDW_; } /// Set number of passes inline void setNumberPasses(int value) { numberPasses_ = value; } /// Set number of passes without better solution inline void setNumberBadPasses(int value) { numberBadPasses_ = value; } /// Set number free integers needed (Base value) inline void setNumberNeeded(int value) { nNeededBase_ = value; } /// Get number free integers needed (Base value) inline int getNumberNeeded() const { return nNeededBase_; } /// Set number free integers needed (Current value) inline void setCurrentNumberNeeded(int value) { nNeeded_ = value; } /// Get number free integers needed (Current value) inline int getCurrentNumberNeeded() const { return nNeeded_; } /// Set number nodes (could be done in callback) (Base value) inline void setNumberNodes(int value) { nNodesBase_ = value; } /// Get number nodes (could be done in callback) (Base value) inline int getNumberNodes() const { return nNodesBase_; } /// Set number nodes (could be done in callback) (Current value) inline void setCurrentNumberNodes(int value) { nNodes_ = value; } /// Get number nodes (could be done in callback) (Current value) inline int getCurrentNumberNodes() const { return nNodes_; } /// Set target objective inline void setTargetObjective(double value) { targetObjective_ = value; } /// Sets how often to do it inline void setHowOften(int value) { howOften_ = value; } /// Block for every row inline const int *whichRowBlock() const { return whichRowBlock_; } /// Block for every column inline const int *whichColumnBlock() const { return whichColumnBlock_; } /// Initial Lower bounds inline double *initialLower() const { return saveLower_; } /// Initial Upper bounds inline double *initialUpper() const { return saveUpper_; } /// Local integer arrays (each numberBlocks_ long) inline int *intArrays() const { return intArray_; } /// Local double arrays (each numberBlocks_ long) inline double *doubleArrays() const { return doubleArray_; } /// Phase of solution inline int phase() const { return phase_; } /// Pass number inline int pass() const { return pass_; } /// Which columns are in block inline const int *columnsInBlock() const { return columnsInBlock_; } /// Starts for columnsInBlock inline const int *startColumnBlock() const { return startColumnBlock_; } /// Number of integer variables in each block inline const int *intsInBlock() const { return intsInBlock_; } /// Objective value (could also check validity) double objectiveValue(const double *solution); private: /// Guts of copy void gutsOfCopy(const CbcHeuristicDW &rhs); /// Guts of delete void gutsOfDelete(); /// Set default values void setDefaults(); /// Find structure void findStructure(); /// Set up DW structure void setupDWStructures(); /// Add DW proposals int addDW(const double *solution, int numberBlocksUsed, const int *whichBlocks); protected: typedef int (*heuristicCallBack)(CbcHeuristicDW *, CbcModel *, int); // Data /// Target objective double targetObjective_; /// Best objective value double bestObjective_; /// Objective value last time double lastObjective_; /** Call back whereFrom - 0 - after blocks found but before data setup 1 - after blocks sorted but before used 2 - just before normal branch and bound 3 - after DW has been updated 4 - if better solution found 5 - every time a block might be used next few for adjustment of nNeeded etc 6 - complete search done - no solution 7 - stopped on nodes - no improvement 8 - improving (same as 4 but after nNeeded changed Pointers to local data given by following pointers */ heuristicCallBack functionPointer_; /// Local integer arrays (each numberBlocks_ long) int *intArray_; /// Local double arrays (each numberBlocks_ long) double *doubleArray_; /// Base solver OsiSolverInterface *solver_; /// DW solver OsiSolverInterface *dwSolver_; /// Best solution found so far double *bestSolution_; /// Continuous solution double *continuousSolution_; /// Reduced costs of fixed solution double *fixedDj_; /// Original lower bounds double *saveLower_; /// Original Upper bounds double *saveUpper_; /// random numbers for master rows double *random_; /// Weights for each proposal double *weights_; /// Objective at which DW updated double *objectiveDW_; /// Number of columns in each DW int *numberColumnsDW_; /// Block for every row int *whichRowBlock_; /// Block for every column int *whichColumnBlock_; /// Block number for each proposal int *dwBlock_; /// Points back to master rows int *backwardRow_; /// Which rows are in blocke int *rowsInBlock_; /// Which columns are in block int *columnsInBlock_; /// Starts for rowsInBlock int *startRowBlock_; /// Starts for columnsInBlock int *startColumnBlock_; /// Number of integer variables in each block int *intsInBlock_; /// Bits set for 1 integers in each block unsigned int *fingerPrint_; /// Affinity each block has for other (will be triangular?) unsigned short *affinity_; /** DW Proposal actions fullDWEverySoOften - 0 - off k - every k times solution gets better */ int fullDWEverySoOften_; /// Number of passes int numberPasses_; /// How often to do (code can change) int howOften_; /// Current maximum number of DW proposals int maximumDW_; /// Number of DW proposals int numberDW_; /// Number of times we have added to DW model int numberDWTimes_; /// Number of unsigned ints needed for each block of fingerPrint int sizeFingerPrint_; /// Number of columns in master int numberMasterColumns_; /// Number of rows in master int numberMasterRows_; /// Number of blocks int numberBlocks_; /// Action on decomposition - 1 keep continuous, 0 don't int keepContinuous_; /// Phase of solution int phase_; /// Pass number int pass_; /// Base number of integers needed int nNeededBase_; /// Base number of nodes needed int nNodesBase_; /// Base number of integers needed int nNeeded_; /// Base number of nodes needed int nNodes_; /// Number of passes without better solution int numberBadPasses_; // 0 - fine, 1 can't be better, 2 max node int solveState_; }; #endif /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2 */