Nauty.cpp
Go to the documentation of this file.
1 /* $Id: Nauty.cpp 928 2012-11-30 15:37:18Z stefan $
2  *
3  * Name: Nauty.cpp
4  * Authors: Jim Ostrowski
5  * Purpose: Branching with symmetry -- implementation of the Nauty object
6  * Date: October 13, 2010
7  *
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include <cassert>
12 #include <cmath>
13 #include "Nauty.h"
14 #include <iostream>
15 #include <algorithm>
16 #include <map>
17 #include <set>
18 #include "CoinTime.hpp"
19 //#include "OrbitalOptions.h"
20 //extern OrbitalOptions *options;
21 
22 int Nauty::nautyCalls_ = 0;
23 double Nauty::nautyTime_ = 0.0;
24 
25 Nauty::Nauty(int vertices)
26 {
27 
28  n_ = vertices;
29  m_ = (n_ + WORDSIZE - 1)/WORDSIZE;
30 
31  //printf ("size of long = %d (%d)\nwordsize = %d\nn,m = %d,%d\n",
32  // SIZEOF_LONG, sizeof (long), WORDSIZE, n_, m_);
33 
34  nauty_check (WORDSIZE, m_, n_, NAUTYVERSIONID);
35 
37 
38 #define MULTIPLIER 2
39 
40  G_ = (graph *) malloc(MULTIPLIER * m_ * n_ * sizeof(int));
41  lab_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int));
42  ptn_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int));
43  active_ = NULL;
44  orbits_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int));
45  options_ = (optionblk *) malloc(MULTIPLIER * sizeof(optionblk));
46  stats_ = (statsblk *) malloc(MULTIPLIER * sizeof(statsblk));
47  worksize_ = 100*m_;
48  workspace_ = (setword *) malloc(MULTIPLIER * worksize_*sizeof(setword));
49  canonG_ = NULL;
50  if (G_ == 0 || lab_ == 0 || ptn_ == 0 ||
51  orbits_ == 0 || options_ == 0 || stats_ == 0 ||
52  workspace_ == 0) assert(0);
53 
54  // Zero allocated memory
55  memset(G_, 0, m_*n_*sizeof(int));
56  memset(lab_, 0, n_*sizeof(int));
57  memset(ptn_, 0, n_*sizeof(int));
58  memset(orbits_, 0, n_*sizeof(int));
59  memset(workspace_, 0, worksize_*sizeof(setword));
60 
61  // Set the options you want
62  options_->getcanon = FALSE;
63  options_->digraph = FALSE;
64  options_->writeautoms = FALSE;
65  options_->writemarkers = FALSE;
66  options_->defaultptn = TRUE;
67  options_->cartesian = FALSE;
68  options_->linelength = 78;
69  options_->outfile = NULL;
70  options_->userrefproc = NULL;
71  options_->userautomproc = NULL;
72  options_->userlevelproc = NULL;
73  options_->usernodeproc = NULL;
74  // options_->usertcellproc = NULL;
75  options_->invarproc = NULL;
76  options_->tc_level = 100;
77  options_->mininvarlevel = 0;
78  options_->maxinvarlevel = 1;
79  options_->invararg = 0;
80  options_->dispatch = &dispatch_graph;
81  // Make an empty graph
82  for (int j = 0; j < n_; j++) {
83  set *gv = GRAPHROW(G_, j, m_);
84  EMPTYSET(gv, m_);
85  }
86 
87  vstat_ = new int[n_];
89  afp_ = NULL;
90  }
91 
93 {
94  if (G_) free(G_);
95  if (lab_) free(lab_);
96  if (ptn_) free(ptn_);
97  if (active_) free(active_);
98  if (orbits_) free(orbits_);
99  if (options_) free(options_);
100  if (stats_) free(stats_);
101  if (workspace_) free(workspace_);
102  if (canonG_) free(canonG_);
103 
104  if (vstat_) delete [] vstat_;
105 }
106 
107 void
108 Nauty::addElement(int ix, int jx)
109 {
110  // Right now die if bad index. Can throw exception later
111  //printf("addelement %d %d \n", ix, jx);
112  assert(ix < n_ && jx < n_);
113  if(ix != jx){ //No Loops
114  set *gv = GRAPHROW(G_, ix, m_);
115  ADDELEMENT(gv, jx);
116  set *gv2 = GRAPHROW(G_, jx, m_);
117  ADDELEMENT(gv2, ix);
118  autoComputed_ = false;
119  }
120 }
121 
122 void
124 {
125  for (int j = 0; j < n_; j++) {
126  vstat_[j] = 1;
127  //printf("vstat %d = %d", j, vstat_[j]);
128  }
129 
130  autoComputed_ = false;
131 }
132 
133 void
135 {
136 
137  // if (autoComputed_) return;
138 
139  double startCPU = CoinCpuTime ();
140 
141  options_->defaultptn = FALSE;
142 
143  // Here we only implement the partitions
144  // [ fix1 | fix0 (union) free | constraints ]
145  int ix = 0;
146 
147  for( int color = 1; color <= n_; color++){
148  for (int j = 0; j < n_; j++) {
149  if (vstat_[j] == color) {
150  lab_[ix] = j;
151  ptn_[ix] = color;
152  ix++;
153  }
154  }
155  if (ix > 0) ptn_[ix-1] = 0;
156  }
157 
158  /*
159  for (int j = 0; j < n_; j++)
160  printf("ptn %d = %d lab = %d \n", j, ptn_[j], lab_[j]);
161  */
162 
163  // Should be number of columns
164  assert(ix == n_);
165  // Now the constraints if needed
166 
167  // Compute Partition
168 
169  nauty(G_, lab_, ptn_, active_, orbits_, options_,
171  autoComputed_ = true;
172 
173  double endCPU = CoinCpuTime ();
174 
175  nautyCalls_++;
176  nautyTime_ += endCPU - startCPU;
177  // Need to make sure all generators are written
178  if (afp_) fflush(afp_);
179 }
180 
181 void
182 Nauty::deleteElement(int ix, int jx)
183 {
184  // Right now die if bad index. Can throw exception later
185  assert(ix < n_ && jx < n_);
186  set *gv = GRAPHROW(G_, ix, m_);
187  if (ISELEMENT(gv, jx)) {
188  DELELEMENT(gv, jx);
189  }
190  autoComputed_ = false;
191 }
192 
193 double
195 {
196  if (!autoComputed_) return -1.0;
197  return( stats_->grpsize1 * pow(10.0, (double) stats_->grpsize2) );
198 }
199 
200 int
202 {
203  if (!autoComputed_) return -1;
204  return(stats_->numgenerators);
205 }
206 
207 int
209 {
210  if (!autoComputed_) return -1;
211  return(stats_->numorbits);
212 }
213 
214 std::vector<std::vector<int> >
216 {
217  std::vector<std::vector<int> > *orb = new std::vector<std::vector<int> >;
218  if (!autoComputed_) return orb;
219  orb -> resize(getNumOrbits());
220  std::multimap<int, int> orbmap;
221  std::set<int> orbkeys;
222  for (int j = 0; j < n_; j++) {
223  orbkeys.insert(orbits_[j]);
224  orbmap.insert(std::make_pair(orbits_[j], j));
225  }
226 
227  int orbix = 0;
228  for (std::set<int>::iterator it = orbkeys.begin();
229  it != orbkeys.end(); ++it) {
230  std::multimap<int, int>::iterator pos;
231  for (pos = orbmap.lower_bound(*it);
232  pos != orbmap.upper_bound(*it); ++pos) {
233  (*orb)[orbix].push_back(pos->second);
234  }
235  orbix++;
236  }
237 
238  assert(orbix == getNumOrbits());
239  return orb;
240 }
241 
242 void
243 Nauty::getVstat(double *v, int nv)
244 {
245  assert(nv == n_);
246  memcpy(v, vstat_, nv * sizeof(VarStatus));
247 }
248 
249 /*
250 bool
251 Nauty::isAllFixOneOrbit(const std::vector<int> &orbit) const
252 {
253 
254  for(std::vector<int>::const_iterator it = orbit.begin();
255  it != orbit.end(); ++it) {
256  if (*it >= n_) return false;
257  if (vstat_[*it] != FIX_AT_ONE) return false;
258  }
259  return true;
260 }
261 
262 bool
263 Nauty::isAllFreeOrbit(const std::vector<int> &orbit) const
264 {
265  for(std::vector<int>::const_iterator it = orbit.begin();
266  it != orbit.end(); ++it) {
267  if (*it >= n_) return false;
268  if (vstat_[*it] != FREE) return false;
269  }
270  return true;
271 }
272 
273 bool
274 Nauty::isConstraintOrbit(const std::vector<int> &orbit) const
275 {
276  for(std::vector<int>::const_iterator it = orbit.begin();
277  it != orbit.end(); ++it) {
278  if (*it >= n_) return true;
279  }
280  return false;
281 
282 }
283 
284 bool
285 Nauty::isMixedFreeZeroOrbit(const std::vector<int> &orbit) const
286 {
287  bool containsFree = false;
288  bool containsZero = false;
289 
290  for(std::vector<int>::const_iterator it = orbit.begin();
291  it != orbit.end(); ++it) {
292  if (*it >= n_) return false;
293  if (vstat_[*it] == FREE) containsFree = true;
294  if (vstat_[*it] == FIX_AT_ZERO) containsZero = true;
295  if (containsFree && containsZero) break;
296  }
297  return (containsFree && containsZero);
298 }
299 */
300 
301 void
302 Nauty::setWriteAutoms(const std::string &fname)
303 {
304  afp_ = fopen(fname.c_str(), "w");
305  options_->writeautoms = TRUE;
306  options_->writemarkers = FALSE;
307  options_->outfile = afp_;
308 
309 }
310 
311 void
313 {
314  fclose(afp_);
315  options_->writeautoms = FALSE;
316 }
317 
static double nautyTime_
Definition: Nauty.h:89
void computeAuto()
Definition: Nauty.cpp:134
#define MULTIPLIER
pos
position where the operator should be printed when printing the expression
std::multimap< int, int >::iterator it
Definition: Nauty.h:92
int * lab_
Definition: Nauty.h:72
void addElement(int ix, int jx)
Definition: Nauty.cpp:108
statsblk * stats_
Definition: Nauty.h:77
optionblk * options_
Definition: Nauty.h:76
int * vstat_
Definition: Nauty.h:86
VarStatus
Definition: Nauty.h:27
void getVstat(double *v, int nv)
Definition: Nauty.cpp:243
static char * j
Definition: OSdtoa.cpp:3622
void deleteElement(int ix, int jx)
Definition: Nauty.cpp:182
int * orbits_
Definition: Nauty.h:75
int m_
Definition: Nauty.h:80
void clearPartitions()
Definition: Nauty.cpp:123
setword * workspace_
Definition: Nauty.h:78
int getNumGenerators() const
Definition: Nauty.cpp:201
void unsetWriteAutoms()
Definition: Nauty.cpp:312
int * ptn_
Definition: Nauty.h:73
bool autoComputed_
Definition: Nauty.h:84
int getNumOrbits() const
Definition: Nauty.cpp:208
set * active_
Definition: Nauty.h:74
FILE * afp_
Definition: Nauty.h:98
void setWriteAutoms(const std::string &afilename)
Methods to classify orbits.
Definition: Nauty.cpp:302
graph * canonG_
Definition: Nauty.h:82
int worksize_
Definition: Nauty.h:79
~Nauty()
Definition: Nauty.cpp:92
int n_
Definition: Nauty.h:81
double getGroupSize() const
Definition: Nauty.cpp:194
graph * G_
Definition: Nauty.h:71
static int nautyCalls_
Definition: Nauty.h:88
std::vector< std::vector< int > > * getOrbits() const
Returns the orbits in a &quot;convenient&quot; form.
Definition: Nauty.cpp:215