ClpPESimplex.hpp 7.87 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 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
// Copyright (C) 2002, International Business Machines
// Corporation and others.  All Rights Reserved.
/*
   Authors

   Jeremy Omer

   Last update: june 10, 2014

 */

#ifndef ClpPESimplex_H
#define ClpPESimplex_H

#include "ClpSimplex.hpp"
#include "CoinIndexedVector.hpp"
#include "ClpPackedMatrix.hpp"
#include "CoinTime.hpp"

#include <iostream>
#include <fstream>

// #define PE_DEBUG 0

/** SHARED METHODS FOR USEFUL ALGEBRAIC OPERATIONS */

/** inner product between a coin vector and a pointer */
double PEdot(CoinIndexedVector &v1, const double *v2);

/** inner product between two coin vectors
    call the function with the sparser vector first for efficiency */
double PEdot(CoinIndexedVector &v1, CoinIndexedVector &v2);

/** compute the product x^T*[A I] for the indices "which" of [A I] */
void PEtransposeTimesSubsetAll(ClpSimplex *model, int number, const int *which,
  const double *COIN_RESTRICT x, double *COIN_RESTRICT y,
  const double *COIN_RESTRICT rowScale,
  const double *COIN_RESTRICT columnScale);

/** BASE CLASS FOR THE IMPROVED SIMPLEX
*/
class ClpPESimplex {

public:
  /** Constructor */
  ClpPESimplex(ClpSimplex *model);

  /** Destructor */
  ~ClpPESimplex();

  /** BASIC GET METHODS */
public:
  inline int coPrimalDegenerates() { return coPrimalDegenerates_; }
  inline int coDualDegenerates() { return coDualDegenerates_; }
  inline int coCompatibleCols() { return coCompatibleCols_; }
  inline int coCompatibleRows() { return coCompatibleRows_; }

  inline bool isCompatibleCol(int sequence) { return isCompatibleCol_[sequence]; }
  inline bool isCompatibleRow(int row)
  {
    assert(row >= 0 && row < numberRows_);
    return isCompatibleRow_[row];
  }

  inline ClpSimplex *clpModel() { return model_; }
  // check seems to be same model - returns false if size changed
  bool checkSize();
  /** PUBLIC METHODS RELATED TO COMPATIBILITY */
public:
  /** Updates the set of variables that are not at their bounds */
  void updatePrimalDegenerates();

  /** Updates the set of dual degenerate variables */
  void updateDualDegenerates();

  /** Identify the primal compatible columns
        The input argument is a temporary array that is needed for the Clp's BTRAN */
  void identifyCompatibleCols(int number, const int *which,
    CoinIndexedVector *spareRow2,
    CoinIndexedVector *wPrimal);

  /** Identify the dual compatible rows */
  void identifyCompatibleRows(CoinIndexedVector *spare,
    CoinIndexedVector *wDual);

  /** Update the dual compatible rows */
  void updateCompatibleRows(int sequence);

  /** DEBUG AND DISPLAY METHODS */
public:
#if PE_DEBUG >= 1
  /** Print the set of variables within their bounds */
  void printPrimalDegenerates();

  /** Print the set of primal compatible variables */
  void printCompatibleCols();

  /** Check that a nonbasic variable is indeed compatible */
  bool checkCompatibilityCol(int sequence, CoinIndexedVector *spareRow2);
#endif

  /** Check that a basic row is indeed compatible */
  bool checkCompatibilityRow(int pivotRow);

  /** Tracking the degenerate iterations after compatible pivots */
  inline double lastObjectiveValue() { return lastObjectiveValue_; }
  inline void updateLastObjectiveValue() { lastObjectiveValue_ = model_->objectiveValue(); }
  inline bool isDegeneratePivot() { return fabs(model_->objectiveValue() - lastObjectiveValue_) < model_->dualTolerance(); }
  inline bool isLastPivotCompatible() { return isLastPivotCompatible_; }
  inline void isLastPivotCompatible(bool yesOrNo) { isLastPivotCompatible_ = yesOrNo; }

  /** Start and stop the timer, and print the total recorded time */
  inline void startTimer() { timeTmp_ = CoinCpuTime(); }
  inline void stopTimer() { timeCompatibility_ += CoinCpuTime() - timeTmp_; }
  void printTimer(std::ostream &out);
  inline double timeMultRandom() { return timeMultRandom_; }
  inline double timeLinearSystem() { return timeLinearSystem_; }
  inline double timeCompatibility() { return timeCompatibility_; }

  /** Update and return the number of degenerate pivots and variables */
  inline void addDegeneratePivot() { coDegeneratePivots_++; }
  inline int coDegeneratePivots() { return coDegeneratePivots_; }
  inline void addDegeneratePivotConsecutive() { coDegeneratePivotsConsecutive_++; }
  inline void resetDegeneratePivotsConsecutive() { coDegeneratePivotsConsecutive_ = 0; }
  inline int coDegeneratePivotsConsecutive() { return coDegeneratePivotsConsecutive_; }
  void updateDualDegeneratesAvg(int coPivots);
  inline double coDualDegeneratesAvg() { return coDualDegeneratesAvg_; }
  void updatePrimalDegeneratesAvg(int coPivots);
  inline double coPrimalDegeneratesAvg() { return coPrimalDegeneratesAvg_; }
  inline double coCompatibleRowsAvg() { return coCompatibleRowsAvg_; }
  void updateCompatibleRowsAvg(int coPivots);
  inline double coCompatibleColsAvg() { return coCompatibleColsAvg_; }
  void updateCompatibleColsAvg(int coPivots);
  inline int coCompatiblePivots() { return coCompatiblePivots_; }
  inline void addCompatiblePivot() { coCompatiblePivots_++; }
  inline int coDegenerateCompatiblePivots() { return coDegenerateCompatiblePivots_; }
  inline void addDegenerateCompatiblePivot() { coDegenerateCompatiblePivots_++; }

  /* Get and update the number of compatible pivots that were done because of the priority factor */
  inline void addPriorityPivot() { coPriorityPivots_++; }
  inline int coPriorityPivots() { return coPriorityPivots_; }
  inline int doStatistics() const
  {
    return doStatistics_;
  }
  inline void setDoStatistics(int value)
  {
    doStatistics_ = value;
  }

protected:
  /** Indices of the variables that were not at one of their bounds 
        during the last update (non primal degenerate variables) */
  int coPrimalDegenerates_;
  int *primalDegenerates_;
  bool *isPrimalDegenerate_;

  /** Indices of the non basic variables with a zero reduced cost
        during the last update (ndual-degenerate variables) */
  int coDualDegenerates_;
  int *dualDegenerates_;
  bool *isDualDegenerate_;

  /** Table of booleans indicating whether each variable is primal
        compatible (true) or not (false) */
  int coCompatibleCols_;
  double *compatibilityCol_;
  bool *isCompatibleCol_;

  /** Table of booleans indicating whether each constraint is dual
        compatible (true) or not (false) */
  int coCompatibleRows_;
  double *compatibilityRow_;
  bool *isCompatibleRow_;

private:
  /** pointer to the original model that shall be solved */
  ClpSimplex *model_;

  /** tolerance used for the tests of degeneracy and compatibility (resp.) */
  double epsDegeneracy_;
  double epsCompatibility_;

  /** size of the original model */
  int numberRows_;
  int numberColumns_;

  /** w vectors that are used to identify the compatible columns and
    rows. The name w, refers to the notations of the articles on 
    positive edge */
  // now passed in CoinIndexedVector *wPrimal_;
  // now passed in CoinIndexedVector *wDual_;

  /** temporary vectors that are used to store colulns of the constraint
        matrix or random numbers */
  // not usedCoinIndexedVector *tempColumn_;
  double *tempRandom_;

  /** number of degenerate pivots and variables */
  int coPrimalDegeneratesAvg_;
  int coDualDegeneratesAvg_;
  int coCompatibleColsAvg_;
  int coCompatibleRowsAvg_;
  int coUpdateDegenerates_;
  int coIdentifyCompatibles_;
  int coDegeneratePivots_;
  int coCompatiblePivots_;
  int coDegenerateCompatiblePivots_;
  int coDegeneratePivotsConsecutive_;

  /** number of compatible pivots that were done because of the priority factor */
  int coPriorityPivots_;
  /// Do statistics
  int doStatistics_;

  /** tracking the degenerate iterations after compatible pivots */
  double lastObjectiveValue_;
  bool isLastPivotCompatible_;

  /** Timer attribute recording the additional time spent in 
        identifying compatible variables */
  double timeCompatibility_;
  double timeMultRandom_;
  double timeLinearSystem_;
  double timeTmp_;
};

#endif

/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
*/