CbcSymmetry.hpp

Go to the documentation of this file.
00001 /* $Id: CbcSymmetry.hpp 1033 2013-12-14 19:34:28Z pbelotti $
00002  *
00003  * Name:    Hacked from CouenneProblem.hpp
00004  * Author:  Pietro Belotti, Lehigh University
00005  *          Andreas Waechter, IBM
00006  * Purpose: define the class CouenneProblem
00007  *
00008  * (C) Carnegie-Mellon University, 2006-11.
00009  * This file is licensed under the Eclipse Public License (EPL)
00010  */
00011 /*
00012   If this is much used then we could improve build experience
00013   Download nauty - say to /disk/nauty25r9
00014   In that directory ./configure --enable-tls --enable-wordsize=32
00015   make
00016   copy nauty.a to libnauty.a
00017 
00018   In Cbc's configure 
00019   add -DCOIN_HAS_NTY to CXXDEFS
00020   add -I/disk/nauty25r9 to CXXDEFS or ADD_CXXFLAGS
00021   add -L/disk/nauty25r9 -lnauty to LDFLAGS
00022 
00023   If you wish to use Traces rather than nauty then add -DNTY_TRACES
00024 
00025   To use it is -orbit on
00026 
00027   Nauty has this -
00028 *   Permission 
00029 *   is hereby given for use and/or distribution with the exception of        *
00030 *   sale for profit or application with nontrivial military significance.    *
00031   so you can use it internally even if you are a company.
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 // when to give up (depth since last success)
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   // Symmetry Info
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   //double timeNauty () const;
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   // bool node_sort (  Node  a, Node  b);
00160   // bool index_sort (  Node  a, Node  b);
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   //int getNautyCalls() const { return nautyCalls_; }
00207   //double getNautyTime() const { return nautyTime_; }
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   //  bool isAllFixOneOrbit(const std::vector<int> &orbit) const;
00226   // bool isAllFreeOrbit(const std::vector<int> &orbit) const;
00227   //bool isAutoComputed() const { return autoComputed_; }
00228   //bool isConstraintOrbit(const std::vector<int> &orbit) const;
00229   //bool isMixedFreeZeroOrbit(const std::vector<int> &orbit) const;
00230   //void makeFree(int ix) { vstat_[ix] = FREE; }  
00231 
00232   void setWriteAutoms (const std::string &afilename);
00233   void unsetWriteAutoms();
00234 
00235 private:
00236 
00237   // The base nauty stuff
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   //static int nautyCalls_;
00263   //static double nautyTime_;
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   // File pointer for automorphism group
00272   FILE *afp_;
00273 
00274 };
00275 
00276 
00282 class CbcOrbitalBranchingObject : public CbcBranchingObject {
00283 
00284 public:
00285 
00286     // Default Constructor
00287     CbcOrbitalBranchingObject ();
00288 
00289     // Useful constructor
00290     CbcOrbitalBranchingObject (CbcModel * model,  int column,
00291                                int way,
00292                                int numberExtra, const int * extraToZero);
00293 
00294     // Copy constructor
00295     CbcOrbitalBranchingObject ( const CbcOrbitalBranchingObject &);
00296 
00297     // Assignment operator
00298     CbcOrbitalBranchingObject & operator=( const CbcOrbitalBranchingObject& rhs);
00299 
00301     virtual CbcBranchingObject * clone() const;
00302 
00303     // Destructor
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 8 Mar 2015 for Cbc by  doxygen 1.6.1