limp-cbc-0.3.2.0: cbits/coin/CglTreeInfo.hpp
// $Id: CglTreeInfo.hpp 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).
#ifndef CglTreeInfo_H
#define CglTreeInfo_H
#include "OsiCuts.hpp"
#include "OsiSolverInterface.hpp"
#include "CoinHelperFunctions.hpp"
class CglStored;
/** Information about where the cut generator is invoked from. */
class CglTreeInfo {
public:
/// The level of the search tree node
int level;
/** How many times the cut generator was already invoked in this search tree
node */
int pass;
/** The number of rows in the original formulation. Some generators may not
want to consider already generated rows when generating new ones. */
int formulation_rows;
/** Options
1 - treat costed integers as important
2 - switch off some stuff as variables semi-integer
4 - set global cut flag if at root node
8 - set global cut flag if at root node and first pass
16 - set global cut flag and make cuts globally valid
32 - last round of cuts did nothing - maybe be more aggressive
64 - in preprocessing stage
128 - looks like solution
256 - want alternate cuts
512 - in sub tree (i.e. parent model)
1024 - in must call again mode or after everything mode
*/
int options;
/// Set true if in tree (to avoid ambiguity at first branch)
bool inTree;
/** Replacement array. Before Branch and Cut it may be beneficial to strengthen rows
rather than adding cuts. If this array is not NULL then the cut generator can
place a pointer to the stronger cut in this array which is number of rows in size.
A null (i.e. zero elements and free rhs) cut indicates that the row is useless
and can be removed.
The calling function can then replace those rows.
*/
OsiRowCut ** strengthenRow;
/// Optional pointer to thread specific random number generator
CoinThreadRandom * randomNumberGenerator;
/// Default constructor
CglTreeInfo ();
/// Copy constructor
CglTreeInfo (
const CglTreeInfo &);
/// Clone
virtual CglTreeInfo * clone() const;
/// Assignment operator
CglTreeInfo &
operator=(
const CglTreeInfo& rhs);
/// Destructor
virtual
~CglTreeInfo ();
/// Take action if cut generator can fix a variable (toValue -1 for down, +1 for up)
virtual bool fixes(int , int , int ,bool) {return false;}
/** Initalizes fixing arrays etc - returns >0 if we want to save info
0 if we don't and -1 if is to be used */
virtual int initializeFixing(const OsiSolverInterface * ) {return 0;}
};
/** Derived class to pick up probing info. */
typedef struct {
//unsigned int oneFixed:1; // nonzero if variable to 1 fixes all
//unsigned int sequence:31; // variable (in matrix) (but also see cliqueRow_)
unsigned int fixes;
} cliqueEntry;
class CglTreeProbingInfo : public CglTreeInfo {
public:
/// Default constructor
CglTreeProbingInfo ();
/// Constructor from model
CglTreeProbingInfo (const OsiSolverInterface * model);
/// Copy constructor
CglTreeProbingInfo (
const CglTreeProbingInfo &);
/// Clone
virtual CglTreeInfo * clone() const;
/// Assignment operator
CglTreeProbingInfo &
operator=(
const CglTreeProbingInfo& rhs);
/// Destructor
virtual
~CglTreeProbingInfo ();
OsiSolverInterface * analyze(const OsiSolverInterface & si, int createSolver=0);
/** Take action if cut generator can fix a variable
(toValue -1 for down, +1 for up)
Returns true if still room, false if not */
virtual bool fixes(int variable, int toValue, int fixedVariable,bool fixedToLower);
/** Initalizes fixing arrays etc - returns >0 if we want to save info
0 if we don't and -1 if is to be used */
virtual int initializeFixing(const OsiSolverInterface * model) ;
/// Fix entries in a solver using implications
int fixColumns(OsiSolverInterface & si) const;
/// Fix entries in a solver using implications for one variable
int fixColumns(int iColumn, int value, OsiSolverInterface & si) const;
/// Packs down entries
int packDown();
/// Generate cuts from implications
void generateCuts(const OsiSolverInterface & si, OsiCuts & cs,
const CglTreeInfo info) const;
/// Entries for fixing variables
inline cliqueEntry * fixEntries()
{ convert(); return fixEntry_;}
/// Starts of integer variable going to zero
inline int * toZero()
{ convert(); return toZero_;}
/// Starts of integer variable going to one
inline int * toOne()
{ convert(); return toOne_;}
/// List of 0-1 integer variables
inline int * integerVariable() const
{ return integerVariable_;}
/// Backward look up
inline int * backward() const
{ return backward_;}
/// Number of variables
inline int numberVariables() const
{ return numberVariables_;}
/// Number of 0-1 variables
inline int numberIntegers() const
{ return numberIntegers_;}
private:
/// Converts to ordered
void convert();
protected:
/// Entries for fixing variables
cliqueEntry * fixEntry_;
/// Starts of integer variable going to zero
int * toZero_;
/// Starts of integer variable going to one
int * toOne_;
/// List of 0-1 integer variables
int * integerVariable_;
/// Backward look up
int * backward_;
/// Entries for fixing variable when collecting
int * fixingEntry_;
/// Number of variables
int numberVariables_;
/// Number of 0-1 variables
int numberIntegers_;
/// Maximum number in fixEntry_
int maximumEntries_;
/// Number entries in fixingEntry_ (and fixEntry_) or -2 if correct style
int numberEntries_;
};
inline int sequenceInCliqueEntry(const cliqueEntry & cEntry)
{ return cEntry.fixes&0x7fffffff;}
inline void setSequenceInCliqueEntry(cliqueEntry & cEntry,int sequence)
{ cEntry.fixes = sequence|(cEntry.fixes&0x80000000);}
inline bool oneFixesInCliqueEntry(const cliqueEntry & cEntry)
{ return (cEntry.fixes&0x80000000)!=0;}
inline void setOneFixesInCliqueEntry(cliqueEntry & cEntry,bool oneFixes)
{ cEntry.fixes = (oneFixes ? 0x80000000 : 0)|(cEntry.fixes&0x7fffffff);}
#endif