CbcSymmetry.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef CBC_SYMMETRY_HPP
00034 #define CBC_SYMMETRY_HPP
00035 extern "C" {
00036 #include "nauty.h"
00037 #include "nausparse.h"
00038 #ifdef NTY_TRACES
00039 #include "traces.h"
00040 #endif
00041 }
00042
00043 #include <vector>
00044 #include <map>
00045 #include <string.h>
00046
00047 #include "CbcModel.hpp"
00048
00049 class OsiObject;
00050
00051 #ifndef NTY_BAD_DEPTH
00052 #define NTY_BAD_DEPTH 10
00053 #endif
00054 class CbcNauty;
00055
00056 class Node{
00057 int index;
00058 double coeff;
00059 double lb;
00060 double ub;
00061 int color;
00062 int code;
00063 int sign;
00064 public:
00065 void node(int, double, double, double, int, int);
00066 inline void color_vertex (register int k) {color = k;}
00067 inline int get_index () const {return index;}
00068 inline double get_coeff () const {return coeff;}
00069 inline double get_lb () const {return lb;}
00070 inline double get_ub () const {return ub;}
00071 inline int get_color () const {return color;}
00072 inline int get_code () const {return code;}
00073 inline int get_sign () const {return sign;}
00074 inline void bounds(register double a, register double b){ lb = a; ub = b;}
00075 };
00076
00077 #define COUENNE_HACKED_EPS 1.e-07
00078 #define COUENNE_HACKED_EPS_SYMM 1e-8
00079 #define COUENNE_HACKED_EXPRGROUP 8
00080
00081 struct myclass0 {
00082 inline bool operator() (register const Node &a, register const Node &b) {
00083
00084 return (( a.get_code () < b.get_code ()) ||
00085 (( a.get_code () == b.get_code () &&
00086 (( a.get_coeff () < b.get_coeff () - COUENNE_HACKED_EPS_SYMM) ||
00087 (( fabs (a.get_coeff () - b.get_coeff ()) < COUENNE_HACKED_EPS_SYMM) &&
00088 (( a.get_lb () < b.get_lb () - COUENNE_HACKED_EPS_SYMM) ||
00089 (( fabs (a.get_lb () - b.get_lb ()) < COUENNE_HACKED_EPS_SYMM) &&
00090 (( a.get_ub () < b.get_ub () - COUENNE_HACKED_EPS_SYMM) ||
00091 (( fabs (a.get_ub () - b.get_ub ()) < COUENNE_HACKED_EPS_SYMM) &&
00092 (( a.get_index () < b.get_index ())))))))))));
00093
00094 }
00095 } ;
00096
00097
00098 struct myclass {
00099 inline bool operator() (register const Node &a, register const Node &b) {
00100 return (a.get_index() < b.get_index() );
00101 }
00102 };
00103
00104 struct less_than_str {
00105 inline bool operator() (register const char *a, register const char *b) const
00106 {return strcmp (a, b) < 0;}
00107 };
00108
00114 class CbcSymmetry {
00115
00116 public:
00117
00120
00121 CbcSymmetry ();
00122
00124 CbcSymmetry (const CbcSymmetry &);
00125
00127 CbcSymmetry & operator=(const CbcSymmetry& rhs);
00128
00130 ~CbcSymmetry ();
00132
00133
00134
00135 std::vector<int> *Find_Orbit(int) const;
00136
00137 myclass0 node_sort;
00138 myclass index_sort;
00139
00140 void Compute_Symmetry() const;
00141 int statsOrbits(CbcModel * model, int type) const;
00142
00143 void Print_Orbits() const;
00144 void fillOrbits();
00146 int orbitalFixing(OsiSolverInterface * solver);
00147 inline int * whichOrbit()
00148 { return numberUsefulOrbits_ ? whichOrbit_ : NULL;}
00149 inline int numberUsefulOrbits() const
00150 { return numberUsefulOrbits_;}
00151 inline int numberUsefulObjects() const
00152 { return numberUsefulObjects_;}
00153 int largestOrbit(const double * lower, const double * upper) const;
00154 void ChangeBounds (const double * lower, const double * upper,
00155 int numberColumns,bool justFixedAtOne) const;
00156 inline bool compare (register Node &a, register Node &b) const;
00157 CbcNauty *getNtyInfo () {return nauty_info_;}
00158
00159
00160
00161
00163 void setupSymmetry (const OsiSolverInterface & solver);
00164 private:
00165 mutable std::vector<Node> node_info_;
00166 mutable CbcNauty *nauty_info_;
00167 int numberColumns_;
00168 int numberUsefulOrbits_;
00169 int numberUsefulObjects_;
00170 int * whichOrbit_;
00171 };
00172
00173 class CbcNauty
00174 {
00175
00176 public:
00177 enum VarStatus { FIX_AT_ZERO, FIX_AT_ONE, FREE };
00178
00181 private:
00183 CbcNauty ();
00184 public:
00186 CbcNauty (int n, const size_t * v, const int * d, const int * e);
00187
00189 CbcNauty (const CbcNauty &);
00190
00192 CbcNauty & operator=(const CbcNauty& rhs);
00193
00195 ~CbcNauty ();
00197
00198 void addElement(int ix, int jx);
00199 void clearPartitions();
00200 void computeAuto();
00201 void deleteElement(int ix, int jx);
00202 void color_node(int ix, int color) { vstat_[ix] = color; }
00203 void insertRHS(int rhs , int cons) {constr_rhs.insert( std::pair<int,int>(rhs,cons));}
00204
00205 double getGroupSize() const;
00206
00207
00208
00209 int getN() const { return n_; }
00210
00211 int getNumGenerators() const;
00212 int getNumOrbits() const;
00213
00215 std::vector<std::vector<int> > *getOrbits() const;
00216
00217 void getVstat(double *v, int nv);
00218 inline bool isSparse() const
00219 { return GSparse_ != NULL;}
00220 inline int errorStatus() const
00221 { return stats_->errstatus;}
00225
00226
00227
00228
00229
00230
00231
00232 void setWriteAutoms (const std::string &afilename);
00233 void unsetWriteAutoms();
00234
00235 private:
00236
00237
00238 graph *G_;
00239 sparsegraph *GSparse_;
00240 int *lab_;
00241 int *ptn_;
00242 set *active_;
00243 int *orbits_;
00244 #ifndef NTY_TRACES
00245 optionblk *options_;
00246 statsblk *stats_;
00247 #else
00248 TracesOptions *options_;
00249 TracesStats *stats_;
00250 #endif
00251 setword *workspace_;
00252 int worksize_;
00253 int m_;
00254 int n_;
00255 size_t nel_;
00256 graph *canonG_;
00257
00258 bool autoComputed_;
00259
00260 int *vstat_;
00261
00262
00263
00264
00265 std::multimap<int,int> constr_rhs;
00266 std::multimap<int,int>::iterator it;
00267
00268 std::pair<std::multimap<int,int>::iterator,
00269 std::multimap<int,int>::iterator> ret;
00270
00271
00272 FILE *afp_;
00273
00274 };
00275
00276
00282 class CbcOrbitalBranchingObject : public CbcBranchingObject {
00283
00284 public:
00285
00286
00287 CbcOrbitalBranchingObject ();
00288
00289
00290 CbcOrbitalBranchingObject (CbcModel * model, int column,
00291 int way,
00292 int numberExtra, const int * extraToZero);
00293
00294
00295 CbcOrbitalBranchingObject ( const CbcOrbitalBranchingObject &);
00296
00297
00298 CbcOrbitalBranchingObject & operator=( const CbcOrbitalBranchingObject& rhs);
00299
00301 virtual CbcBranchingObject * clone() const;
00302
00303
00304 virtual ~CbcOrbitalBranchingObject ();
00305
00306 using CbcBranchingObject::branch ;
00308 virtual double branch();
00311 virtual void fix(OsiSolverInterface * solver,
00312 double * lower, double * upper,
00313 int branchState) const ;
00314
00318 virtual void previousBranch() {
00319 CbcBranchingObject::previousBranch();
00320 }
00321
00322 using CbcBranchingObject::print ;
00325 virtual void print();
00326
00328 virtual CbcBranchObjType type() const {
00329 return SoSBranchObj;
00330 }
00331
00339 virtual int compareOriginalObject(const CbcBranchingObject* brObj) const;
00340
00349 virtual CbcRangeCompare compareBranchingObject
00350 (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false);
00351
00352 private:
00354 int column_;
00356 int numberOther_;
00358 int numberExtra_;
00360 int * fixToZero_;
00361 };
00362
00363 #endif