summaryrefslogtreecommitdiff
path: root/build/Bonmin/include/coin/CglProbing.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'build/Bonmin/include/coin/CglProbing.hpp')
-rw-r--r--build/Bonmin/include/coin/CglProbing.hpp543
1 files changed, 543 insertions, 0 deletions
diff --git a/build/Bonmin/include/coin/CglProbing.hpp b/build/Bonmin/include/coin/CglProbing.hpp
new file mode 100644
index 0000000..5ca8996
--- /dev/null
+++ b/build/Bonmin/include/coin/CglProbing.hpp
@@ -0,0 +1,543 @@
+// $Id: CglProbing.hpp 1201 2014-03-07 17:24:04Z 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).
+
+#ifndef CglProbing_H
+#define CglProbing_H
+
+#include <string>
+
+#include "CglCutGenerator.hpp"
+ /** Only useful type of disaggregation is most normal
+ For now just done for 0-1 variables
+ Can be used for building cliques
+ */
+ typedef struct {
+ //unsigned int zeroOne:1; // nonzero if affected variable is 0-1
+ //unsigned int whenAtUB:1; // nonzero if fixing happens when this variable at 1
+ //unsigned int affectedToUB:1; // nonzero if affected variable fixed to UB
+ //unsigned int affected:29; // If 0-1 then 0-1 sequence, otherwise true
+ unsigned int affected;
+ } disaggregationAction;
+
+/** Probing Cut Generator Class */
+class CglProbing : public CglCutGenerator {
+ friend void CglProbingUnitTest(const OsiSolverInterface * siP,
+ const std::string mpdDir );
+
+public:
+
+
+ /**@name Generate Cuts */
+ //@{
+ /** Generate probing/disaggregation cuts for the model of the
+ solver interface, si.
+
+ This is a simplification of probing ideas put into OSL about
+ ten years ago. The only known documentation is a copy of a
+ talk handout - we think Robin Lougee-Heimer has a copy!
+
+ For selected integer variables (e.g. unsatisfied ones) the effect of
+ setting them up or down is investigated. Setting a variable up
+ may in turn set other variables (continuous as well as integer).
+ There are various possible results:
+
+ 1) It is shown that problem is infeasible (this may also be
+ because objective function or reduced costs show worse than
+ best solution). If the other way is feasible we can generate
+ a column cut (and continue probing), if not feasible we can
+ say problem infeasible.
+
+ 2) If both ways are feasible, it can happen that x to 0 implies y to 1
+ ** and x to 1 implies y to 1 (again a column cut). More common
+ is that x to 0 implies y to 1 and x to 1 implies y to 0 so we could
+ substitute for y which might lead later to more powerful cuts.
+ ** This is not done in this code as there is no mechanism for
+ returning information.
+
+ 3) When x to 1 a constraint went slack by c. We can tighten the
+ constraint ax + .... <= b (where a may be zero) to
+ (a+c)x + .... <= b. If this cut is violated then it is
+ generated.
+
+ 4) Similarly we can generate implied disaggregation cuts
+
+ Note - differences to cuts in OSL.
+
+ a) OSL had structures intended to make this faster.
+ b) The "chaining" in 2) was done
+ c) Row cuts modified original constraint rather than adding cut
+ b) This code can cope with general integer variables.
+
+ Insert the generated cuts into OsiCut, cs.
+
+ If a "snapshot" of a matrix exists then this will be used.
+ Presumably this will give global cuts and will be faster.
+ No check is done to see if cuts will be global.
+
+ Otherwise use current matrix.
+
+ Both row cuts and column cuts may be returned
+
+ The mode options are:
+ 0) Only unsatisfied integer variables will be looked at.
+ If no information exists for that variable then
+ probing will be done so as a by-product you "may" get a fixing
+ or infeasibility. This will be fast and is only available
+ if a snapshot exists (otherwise as 1).
+ The bounds in the snapshot are the ones used.
+ 1) Look at unsatisfied integer variables, using current bounds.
+ Probing will be done on all looked at.
+ 2) Look at all integer variables, using current bounds.
+ Probing will be done on all
+
+ ** If generateCutsAndModify is used then new relaxed
+ row bounds and tightened column bounds are generated
+ Returns number of infeasibilities
+ */
+ virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
+ const CglTreeInfo info = CglTreeInfo());
+ int generateCutsAndModify( const OsiSolverInterface & si, OsiCuts & cs,
+ CglTreeInfo * info);
+ //@}
+
+ /**@name snapshot etc */
+ //@{
+ /** Create a copy of matrix which is to be used
+ this is to speed up process and to give global cuts
+ Can give an array with 1 set to select, 0 to ignore
+ column bounds are tightened
+ If array given then values of 1 will be set to 0 if redundant.
+ Objective may be added as constraint
+ Returns 1 if infeasible otherwise 0
+ */
+ int snapshot ( const OsiSolverInterface & si,
+ char * possible=NULL,
+ bool withObjective=true);
+ /// Deletes snapshot
+ void deleteSnapshot ( );
+ /** Creates cliques for use by probing.
+ Only cliques >= minimumSize and < maximumSize created
+ Can also try and extend cliques as a result of probing (root node).
+ Returns number of cliques found.
+ */
+ int createCliques( OsiSolverInterface & si,
+ int minimumSize=2, int maximumSize=100);
+ /// Delete all clique information
+ void deleteCliques();
+ /** Create a fake model by adding cliques
+ if type&4 then delete rest of model first,
+ if 1 then add proper cliques, 2 add fake cliques */
+ OsiSolverInterface * cliqueModel(const OsiSolverInterface * model,
+ int type);
+ //@}
+
+ /**@name Get tighter column bounds */
+ //@{
+ /// Lower
+ const double * tightLower() const;
+ /// Upper
+ const double * tightUpper() const;
+ /// Array which says tighten continuous
+ const char * tightenBounds() const
+ { return tightenBounds_;}
+ //@}
+
+ /**@name Get possible freed up row bounds - only valid after mode==3 */
+ //@{
+ /// Lower
+ const double * relaxedRowLower() const;
+ /// Upper
+ const double * relaxedRowUpper() const;
+ //@}
+
+ /**@name Change mode */
+ //@{
+ /// Set
+ void setMode(int mode);
+ /// Get
+ int getMode() const;
+ //@}
+
+ /**@name Change maxima */
+ //@{
+ /// Set maximum number of passes per node
+ void setMaxPass(int value);
+ /// Get maximum number of passes per node
+ int getMaxPass() const;
+ /// Set log level - 0 none, 1 - a bit, 2 - more details
+ void setLogLevel(int value);
+ /// Get log level
+ int getLogLevel() const;
+ /// Set maximum number of unsatisfied variables to look at
+ void setMaxProbe(int value);
+ /// Get maximum number of unsatisfied variables to look at
+ int getMaxProbe() const;
+ /// Set maximum number of variables to look at in one probe
+ void setMaxLook(int value);
+ /// Get maximum number of variables to look at in one probe
+ int getMaxLook() const;
+ /// Set maximum number of elements in row for it to be considered
+ void setMaxElements(int value);
+ /// Get maximum number of elements in row for it to be considered
+ int getMaxElements() const;
+ /// Set maximum number of passes per node (root node)
+ void setMaxPassRoot(int value);
+ /// Get maximum number of passes per node (root node)
+ int getMaxPassRoot() const;
+ /// Set maximum number of unsatisfied variables to look at (root node)
+ void setMaxProbeRoot(int value);
+ /// Get maximum number of unsatisfied variables to look at (root node)
+ int getMaxProbeRoot() const;
+ /// Set maximum number of variables to look at in one probe (root node)
+ void setMaxLookRoot(int value);
+ /// Get maximum number of variables to look at in one probe (root node)
+ int getMaxLookRoot() const;
+ /// Set maximum number of elements in row for it to be considered (root node)
+ void setMaxElementsRoot(int value);
+ /// Get maximum number of elements in row for it to be considered (root node)
+ int getMaxElementsRoot() const;
+ /**
+ Returns true if may generate Row cuts in tree (rather than root node).
+ Used so know if matrix will change in tree. Really
+ meant so column cut generators can still be active
+ without worrying code.
+ Default is true
+ */
+ virtual bool mayGenerateRowCutsInTree() const;
+ //@}
+
+ /**@name Get information back from probing */
+ //@{
+ /// Number looked at this time
+ inline int numberThisTime() const
+ { return numberThisTime_;}
+ /// Which ones looked at this time
+ inline const int * lookedAt() const
+ { return lookedAt_;}
+ //@}
+
+ /**@name Stop or restart row cuts (otherwise just fixing from probing) */
+ //@{
+ /// Set
+ /// 0 no cuts, 1 just disaggregation type, 2 coefficient ( 3 both)
+ void setRowCuts(int type);
+ /// Get
+ int rowCuts() const;
+ //@}
+ /// Clique type
+ typedef struct {
+ unsigned int equality:1; // nonzero if clique is ==
+ } CliqueType;
+
+ /**@name Information on cliques */
+ //@{
+ /// Number of cliques
+ inline int numberCliques() const
+ { return numberCliques_;}
+ /// Clique type
+ inline CliqueType * cliqueType() const
+ { return cliqueType_;}
+ /// Start of each clique
+ inline int * cliqueStart() const
+ { return cliqueStart_;}
+ /// Entries for clique
+ inline CliqueEntry * cliqueEntry() const
+ { return cliqueEntry_;}
+ //@}
+
+ /**@name Whether use objective as constraint */
+ //@{
+ /** Set
+ 0 don't
+ 1 do
+ -1 don't even think about it
+ */
+ void setUsingObjective(int yesNo);
+ /// Get
+ int getUsingObjective() const;
+ //@}
+
+ /**@name Mark which continuous variables are to be tightened */
+ //@{
+ /// Mark variables to be tightened
+ void tightenThese(const OsiSolverInterface & solver, int number, const int * which);
+ //@}
+
+ /**@name Constructors and destructors */
+ //@{
+ /// Default constructor
+ CglProbing ();
+
+ /// Copy constructor
+ CglProbing (
+ const CglProbing &);
+
+ /// Clone
+ virtual CglCutGenerator * clone() const;
+
+ /// Assignment operator
+ CglProbing &
+ operator=(
+ const CglProbing& rhs);
+
+ /// Destructor
+ virtual
+ ~CglProbing ();
+
+ /// This can be used to refresh any inforamtion
+ virtual void refreshSolver(OsiSolverInterface * solver);
+ /// Create C++ lines to get to current state
+ virtual std::string generateCpp( FILE * fp);
+ //@}
+
+private:
+
+ // Private member methods
+ /**@name probe */
+ //@{
+ /// Does probing and adding cuts (without cliques and mode_!=0)
+ int probe( const OsiSolverInterface & si,
+ const OsiRowCutDebugger * debugger,
+ OsiCuts & cs,
+ double * colLower, double * colUpper, CoinPackedMatrix *rowCopy,
+ CoinPackedMatrix *columnCopy,const CoinBigIndex * rowStartPos,
+ const int * realRow, const double * rowLower, const double * rowUpper,
+ const char * intVar, double * minR, double * maxR, int * markR,
+ CglTreeInfo * info);
+ /// Does probing and adding cuts (with cliques)
+ int probeCliques( const OsiSolverInterface & si,
+ const OsiRowCutDebugger * debugger,
+ OsiCuts & cs,
+ double * colLower, double * colUpper, CoinPackedMatrix *rowCopy,
+ CoinPackedMatrix *columnCopy, const int * realRow,
+ double * rowLower, double * rowUpper,
+ char * intVar, double * minR, double * maxR, int * markR,
+ CglTreeInfo * info);
+ /// Does probing and adding cuts for clique slacks
+ int probeSlacks( const OsiSolverInterface & si,
+ const OsiRowCutDebugger * debugger,
+ OsiCuts & cs,
+ double * colLower, double * colUpper, CoinPackedMatrix *rowCopy,
+ CoinPackedMatrix *columnCopy,
+ double * rowLower, double * rowUpper,
+ char * intVar, double * minR, double * maxR,int * markR,
+ CglTreeInfo * info);
+ /** Does most of work of generateCuts
+ Returns number of infeasibilities */
+ int gutsOfGenerateCuts( const OsiSolverInterface & si,
+ OsiCuts & cs,
+ double * rowLower, double * rowUpper,
+ double * colLower, double * colUpper,
+ CglTreeInfo * info);
+ /// Sets up clique information for each row
+ void setupRowCliqueInformation(const OsiSolverInterface & si);
+ /** This tightens column bounds (and can declare infeasibility)
+ It may also declare rows to be redundant */
+ int tighten(double *colLower, double * colUpper,
+ const int *column, const double *rowElements,
+ const CoinBigIndex *rowStart,const CoinBigIndex * rowStartPos,
+ const int * rowLength,
+ double *rowLower, double *rowUpper,
+ int nRows,int nCols,char * intVar,int maxpass,
+ double tolerance);
+ /// This just sets minima and maxima on rows
+ void tighten2(double *colLower, double * colUpper,
+ const int *column, const double *rowElements,
+ const CoinBigIndex *rowStart,
+ const int * rowLength,
+ double *rowLower, double *rowUpper,
+ double * minR, double * maxR, int * markR,
+ int nRows);
+ //@}
+
+ // Private member data
+
+ struct disaggregation_struct_tag ;
+ friend struct CglProbing::disaggregation_struct_tag ;
+
+ /**@name Private member data */
+ //@{
+ /// Row copy (only if snapshot)
+ CoinPackedMatrix * rowCopy_;
+ /// Column copy (only if snapshot)
+ CoinPackedMatrix * columnCopy_;
+ /// Lower bounds on rows
+ double * rowLower_;
+ /// Upper bounds on rows
+ double * rowUpper_;
+ /// Lower bounds on columns
+ double * colLower_;
+ /// Upper bounds on columns
+ double * colUpper_;
+ /// Number of rows in snapshot (or when cliqueRow stuff computed)
+ int numberRows_;
+ /// Number of columns in problem ( must == current)
+ int numberColumns_;
+ /// Tolerance to see if infeasible
+ double primalTolerance_;
+ /** Mode - 0 lazy using snapshot, 1 just unsatisfied, 2 all.
+ 16 bit set if want to extend cliques at root node
+ */
+ int mode_;
+ /** Row cuts flag
+ 0 no cuts, 1 just disaggregation type, 2 coefficient ( 3 both), 4 just column cuts
+ -n as +n but just fixes variables unless at root
+ */
+ int rowCuts_;
+ /// Maximum number of passes to do in probing
+ int maxPass_;
+ /// Log level - 0 none, 1 - a bit, 2 - more details
+ int logLevel_;
+ /// Maximum number of unsatisfied variables to probe
+ int maxProbe_;
+ /// Maximum number of variables to look at in one probe
+ int maxStack_;
+ /// Maximum number of elements in row for scan
+ int maxElements_;
+ /// Maximum number of passes to do in probing at root
+ int maxPassRoot_;
+ /// Maximum number of unsatisfied variables to probe at root
+ int maxProbeRoot_;
+ /// Maximum number of variables to look at in one probe at root
+ int maxStackRoot_;
+ /// Maximum number of elements in row for scan at root
+ int maxElementsRoot_;
+ /// Whether to include objective as constraint
+ int usingObjective_;
+ /// Number of integer variables
+ int numberIntegers_;
+ /// Number of 0-1 integer variables
+ int number01Integers_;
+ /// Number looked at this time
+ int numberThisTime_;
+ /// Total number of times called
+ int totalTimesCalled_;
+ /// Which ones looked at this time
+ int * lookedAt_;
+ /// Disaggregation cuts and for building cliques
+ typedef struct disaggregation_struct_tag {
+ int sequence; // integer variable
+ // index will be NULL if no probing done yet
+ int length; // length of newValue
+ disaggregationAction * index; // columns whose bounds will be changed
+ } disaggregation;
+ disaggregation * cutVector_;
+ /// Cliques
+ /// Number of cliques
+ int numberCliques_;
+ /// Clique type
+ CliqueType * cliqueType_;
+ /// Start of each clique
+ int * cliqueStart_;
+ /// Entries for clique
+ CliqueEntry * cliqueEntry_;
+ /** Start of oneFixes cliques for a column in matrix or -1 if not
+ in any clique */
+ int * oneFixStart_;
+ /** Start of zeroFixes cliques for a column in matrix or -1 if not
+ in any clique */
+ int * zeroFixStart_;
+ /// End of fixes for a column
+ int * endFixStart_;
+ /// Clique numbers for one or zero fixes
+ int * whichClique_;
+ /** For each column with nonzero in row copy this gives a clique "number".
+ So first clique mentioned in row is always 0. If no entries for row
+ then no cliques. If sequence > numberColumns then not in clique.
+ */
+ CliqueEntry * cliqueRow_;
+ /// cliqueRow_ starts for each row
+ int * cliqueRowStart_;
+ /// If not null and [i] !=0 then also tighten even if continuous
+ char * tightenBounds_;
+ //@}
+};
+inline int affectedInDisaggregation(const disaggregationAction & dis)
+{ return dis.affected&0x1fffffff;}
+inline void setAffectedInDisaggregation(disaggregationAction & dis,
+ int affected)
+{ dis.affected = affected|(dis.affected&0xe0000000);}
+#ifdef NDEBUG
+inline bool zeroOneInDisaggregation(const disaggregationAction & )
+{ return true;}
+#else
+inline bool zeroOneInDisaggregation(const disaggregationAction & dis)
+//{ return (dis.affected&0x80000000)!=0;}
+{ assert ((dis.affected&0x80000000)!=0); return true;}
+#endif
+inline void setZeroOneInDisaggregation(disaggregationAction & dis,bool zeroOne)
+{ dis.affected = (zeroOne ? 0x80000000 : 0)|(dis.affected&0x7fffffff);}
+inline bool whenAtUBInDisaggregation(const disaggregationAction & dis)
+{ return (dis.affected&0x40000000)!=0;}
+inline void setWhenAtUBInDisaggregation(disaggregationAction & dis,bool whenAtUB)
+{ dis.affected = (whenAtUB ? 0x40000000 : 0)|(dis.affected&0xbfffffff);}
+inline bool affectedToUBInDisaggregation(const disaggregationAction & dis)
+{ return (dis.affected&0x20000000)!=0;}
+inline void setAffectedToUBInDisaggregation(disaggregationAction & dis,bool affectedToUB)
+{ dis.affected = (affectedToUB ? 0x20000000 : 0)|(dis.affected&0xdfffffff);}
+
+//#############################################################################
+/** A function that tests the methods in the CglProbing class. The
+ only reason for it not to be a member method is that this way it doesn't
+ have to be compiled into the library. And that's a gain, because the
+ library should be compiled with optimization on, but this method should be
+ compiled with debugging. */
+void CglProbingUnitTest(const OsiSolverInterface * siP,
+ const std::string mpdDir );
+/// This just uses implication info
+class CglImplication : public CglCutGenerator {
+
+public:
+
+ /**@name Generate Cuts */
+ //@{
+ /** Generate cuts from implication table
+ Insert generated cuts into the cut set cs.
+ */
+ virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
+ const CglTreeInfo info = CglTreeInfo());
+ //@}
+
+ /**@name Constructors and destructors */
+ //@{
+ /// Default constructor
+ CglImplication ();
+
+ /// Constructor with info
+ CglImplication (CglTreeProbingInfo * info);
+
+ /// Copy constructor
+ CglImplication (
+ const CglImplication &);
+
+ /// Clone
+ virtual CglCutGenerator * clone() const;
+
+ /// Assignment operator
+ CglImplication &
+ operator=(
+ const CglImplication& rhs);
+
+ /// Destructor
+ virtual
+ ~CglImplication ();
+ /// Create C++ lines to get to current state
+ virtual std::string generateCpp( FILE * fp);
+ //@}
+ /**@name Set implication */
+ //@{
+ /// Set implication
+ inline void setProbingInfo(CglTreeProbingInfo * info)
+ { probingInfo_=info;}
+ //@}
+
+private:
+ /**@name Private member data */
+ //@{
+ /// Pointer to tree probing info
+ CglTreeProbingInfo * probingInfo_;
+ //@}
+};
+#endif