CglDuplicateRow.hpp 5.49 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
// $Id$
// 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).

#ifndef CglDuplicateRow_H
#define CglDuplicateRow_H

#include <string>

#include "CglCutGenerator.hpp"
class CglStored;

/** DuplicateRow Cut Generator Class */
class CglDuplicateRow : public CglCutGenerator {
 
public:
    
  
  /**@name Generate Cuts */
  //@{
  /** Fix variables and find duplicate/dominated rows for the model of the 
      solver interface, si.

      This is a very simple minded idea but I (JJF) am using it in a project so thought
      I might as well add it.  It should really be called before first solve and I may
      modify CBC to allow for that.

      This is designed for problems with few rows and many integer variables where the rhs
      are <= or == and all coefficients and rhs are small integers.

      If effective rhs is K then we can fix all variables with coefficients > K to their lower bounds
      (effective rhs just means original with variables with nonzero lower bounds subtracted out).

      If one row is a subset of another and the effective rhs are same we can fix some variables
      and then the two rows are identical.

      The generator marks identical rows so can be taken out in solve
  */
  virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
			     const CglTreeInfo info = CglTreeInfo());
private:
  /// Does work for modes 1,2
  void generateCuts12( const OsiSolverInterface & si, OsiCuts & cs,
		       const CglTreeInfo info = CglTreeInfo());
  /// Does work for mode 4
  void generateCuts4( const OsiSolverInterface & si, OsiCuts & cs,
		       const CglTreeInfo info = CglTreeInfo());
  /// Does work for mode 8
  void generateCuts8( const OsiSolverInterface & si, OsiCuts & cs,
		       const CglTreeInfo info = CglTreeInfo());
public:
  /** Fix variables and find duplicate/dominated rows for the model of the 
      solver interface, si.

      This is a very simple minded idea but I (JJF) am using it in a project so thought
      I might as well add it.  It should really be called before first solve and I may
      modify CBC to allow for that.

      This is designed for problems with few rows and many integer variables where the rhs
      are <= or == and all coefficients and rhs are small integers.

      If effective rhs is K then we can fix all variables with coefficients > K to their lower bounds
      (effective rhs just means original with variables with nonzero lower bounds subtracted out).

      If one row is a subset of another and the effective rhs are same we can fix some variables
      and then the two rows are identical.

      This version does deletions and fixings and may return stored cuts for
      dominated columns 
  */
  CglStored * outDuplicates( OsiSolverInterface * solver);

  //@}

  /**@name Get information on size of problem */
  //@{
  /// Get duplicate row list, -1 means still in, -2 means out (all fixed), k>= means same as row k 
  inline const int * duplicate() const
  { return duplicate_;}
  /// Size of dynamic program
  inline int sizeDynamic() const
  { return sizeDynamic_;}
  /// Number of rows in original problem
  inline int numberOriginalRows() const
  { return matrix_.getNumRows();}
  //@}

  /**@name Get information on size of problem */
  //@{
  /// logLevel
  inline int logLevel() const
  { return logLevel_;}
  inline void setLogLevel(int value)
  { logLevel_ = value;}
  //@}


  /**@name We only check for duplicates amongst rows with effective rhs <= this */
  //@{
  /// Get
  inline int maximumRhs() const
  { return maximumRhs_;}
  /// Set
  inline void setMaximumRhs(int value)
  { maximumRhs_=value;}
  //@}

  /**@name We only check for dominated amongst groups of columns whose size <= this */
  //@{
  /// Get
  inline int maximumDominated() const
  { return maximumDominated_;}
  /// Set
  inline void setMaximumDominated(int value)
  { maximumDominated_=value;}
  //@}
  /**@name gets and sets */
  //@{
  /// Get mode
  inline int mode() const
  { return mode_;}
  /// Set mode
  inline void setMode(int value)
  { mode_=value;}
  //@}

  /**@name Constructors and destructors */
  //@{
  /// Default constructor 
  CglDuplicateRow ();
 
  /// Useful constructor 
  CglDuplicateRow (OsiSolverInterface * solver);
 
  /// Copy constructor 
  CglDuplicateRow (
    const CglDuplicateRow & rhs);

  /// Clone
  virtual CglCutGenerator * clone() const;

  /// Assignment operator 
  CglDuplicateRow &
    operator=(
    const CglDuplicateRow& rhs);
  
  /// Destructor 
  virtual
    ~CglDuplicateRow ();
  /// Create C++ lines to get to current state
  virtual std::string generateCpp( FILE * fp);

  /// This can be used to refresh any information
  virtual void refreshSolver(OsiSolverInterface * solver);
  //@}
      
protected:
  

  // Protected member data

  /**@name Protected member data */
  //@{
  /// Matrix
  CoinPackedMatrix matrix_;
  /// Matrix by row
  CoinPackedMatrix matrixByRow_; 
  /// Possible rhs (if 0 then not possible)
  int * rhs_;
  /// Marks duplicate rows
  int * duplicate_;
  /// To allow for <= rows
  int * lower_;
  /// Stored cuts if we found dominance cuts
  CglStored * storedCuts_;
  /// Check dominated columns if less than this number of candidates
  int maximumDominated_;
  /// Check duplicates if effective rhs <= this
  int maximumRhs_;
  /// Size of dynamic program
  int sizeDynamic_;
  /// 1 do rows, 2 do columns, 3 do both
  int mode_;
  /// Controls print out
  int logLevel_;
  //@}
};
#endif