00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <cassert>
00012 #include <cmath>
00013 #include "Nauty.h"
00014 #include <iostream>
00015 #include <algorithm>
00016 #include <map>
00017 #include <set>
00018 #include "CoinTime.hpp"
00019
00020
00021
00022 int Nauty::nautyCalls_ = 0;
00023 double Nauty::nautyTime_ = 0.0;
00024
00025 Nauty::Nauty(int vertices)
00026 {
00027
00028 n_ = vertices;
00029 m_ = (n_ + WORDSIZE - 1)/WORDSIZE;
00030
00031
00032
00033
00034 nauty_check (WORDSIZE, m_, n_, NAUTYVERSIONID);
00035
00037
00038 #define MULTIPLIER 2
00039
00040 G_ = (graph *) malloc(MULTIPLIER * m_ * n_ * sizeof(int));
00041 lab_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int));
00042 ptn_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int));
00043 active_ = NULL;
00044 orbits_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int));
00045 options_ = (optionblk *) malloc(MULTIPLIER * sizeof(optionblk));
00046 stats_ = (statsblk *) malloc(MULTIPLIER * sizeof(statsblk));
00047 worksize_ = 100*m_;
00048 workspace_ = (setword *) malloc(MULTIPLIER * worksize_*sizeof(setword));
00049 canonG_ = NULL;
00050 if (G_ == 0 || lab_ == 0 || ptn_ == 0 ||
00051 orbits_ == 0 || options_ == 0 || stats_ == 0 ||
00052 workspace_ == 0) assert(0);
00053
00054
00055 memset(G_, 0, m_*n_*sizeof(int));
00056 memset(lab_, 0, n_*sizeof(int));
00057 memset(ptn_, 0, n_*sizeof(int));
00058 memset(orbits_, 0, n_*sizeof(int));
00059 memset(workspace_, 0, worksize_*sizeof(setword));
00060
00061
00062 options_->getcanon = FALSE;
00063 options_->digraph = FALSE;
00064 options_->writeautoms = FALSE;
00065 options_->writemarkers = FALSE;
00066 options_->defaultptn = TRUE;
00067 options_->cartesian = FALSE;
00068 options_->linelength = 78;
00069 options_->outfile = NULL;
00070 options_->userrefproc = NULL;
00071 options_->userautomproc = NULL;
00072 options_->userlevelproc = NULL;
00073 options_->usernodeproc = NULL;
00074
00075 options_->invarproc = NULL;
00076 options_->tc_level = 100;
00077 options_->mininvarlevel = 0;
00078 options_->maxinvarlevel = 1;
00079 options_->invararg = 0;
00080 options_->dispatch = &dispatch_graph;
00081
00082 for (int j = 0; j < n_; j++) {
00083 set *gv = GRAPHROW(G_, j, m_);
00084 EMPTYSET(gv, m_);
00085 }
00086
00087 vstat_ = new int[n_];
00088 clearPartitions();
00089 afp_ = NULL;
00090 }
00091
00092 Nauty::~Nauty()
00093 {
00094 if (G_) free(G_);
00095 if (lab_) free(lab_);
00096 if (ptn_) free(ptn_);
00097 if (active_) free(active_);
00098 if (orbits_) free(orbits_);
00099 if (options_) free(options_);
00100 if (stats_) free(stats_);
00101 if (workspace_) free(workspace_);
00102 if (canonG_) free(canonG_);
00103
00104 if (vstat_) delete [] vstat_;
00105 }
00106
00107 void
00108 Nauty::addElement(int ix, int jx)
00109 {
00110
00111
00112 assert(ix < n_ && jx < n_);
00113 if(ix != jx){
00114 set *gv = GRAPHROW(G_, ix, m_);
00115 ADDELEMENT(gv, jx);
00116 set *gv2 = GRAPHROW(G_, jx, m_);
00117 ADDELEMENT(gv2, ix);
00118 autoComputed_ = false;
00119 }
00120 }
00121
00122 void
00123 Nauty::clearPartitions()
00124 {
00125 for (int j = 0; j < n_; j++) {
00126 vstat_[j] = 1;
00127
00128 }
00129
00130 autoComputed_ = false;
00131 }
00132
00133 void
00134 Nauty::computeAuto()
00135 {
00136
00137
00138
00139 double startCPU = CoinCpuTime ();
00140
00141 options_->defaultptn = FALSE;
00142
00143
00144
00145 int ix = 0;
00146
00147 for( int color = 1; color <= n_; color++){
00148 for (int j = 0; j < n_; j++) {
00149 if (vstat_[j] == color) {
00150 lab_[ix] = j;
00151 ptn_[ix] = color;
00152 ix++;
00153 }
00154 }
00155 if (ix > 0) ptn_[ix-1] = 0;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 assert(ix == n_);
00165
00166
00167
00168
00169 nauty(G_, lab_, ptn_, active_, orbits_, options_,
00170 stats_, workspace_, worksize_, m_, n_, canonG_);
00171 autoComputed_ = true;
00172
00173 double endCPU = CoinCpuTime ();
00174
00175 nautyCalls_++;
00176 nautyTime_ += endCPU - startCPU;
00177
00178 if (afp_) fflush(afp_);
00179 }
00180
00181 void
00182 Nauty::deleteElement(int ix, int jx)
00183 {
00184
00185 assert(ix < n_ && jx < n_);
00186 set *gv = GRAPHROW(G_, ix, m_);
00187 if (ISELEMENT(gv, jx)) {
00188 DELELEMENT(gv, jx);
00189 }
00190 autoComputed_ = false;
00191 }
00192
00193 double
00194 Nauty::getGroupSize() const
00195 {
00196 if (!autoComputed_) return -1.0;
00197 return( stats_->grpsize1 * pow(10.0, (double) stats_->grpsize2) );
00198 }
00199
00200 int
00201 Nauty::getNumGenerators() const
00202 {
00203 if (!autoComputed_) return -1;
00204 return(stats_->numgenerators);
00205 }
00206
00207 int
00208 Nauty::getNumOrbits() const
00209 {
00210 if (!autoComputed_) return -1;
00211 return(stats_->numorbits);
00212 }
00213
00214 std::vector<std::vector<int> >
00215 *Nauty::getOrbits() const
00216 {
00217 std::vector<std::vector<int> > *orb = new std::vector<std::vector<int> >;
00218 if (!autoComputed_) return orb;
00219 orb -> resize(getNumOrbits());
00220 std::multimap<int, int> orbmap;
00221 std::set<int> orbkeys;
00222 for (int j = 0; j < n_; j++) {
00223 orbkeys.insert(orbits_[j]);
00224 orbmap.insert(std::make_pair(orbits_[j], j));
00225 }
00226
00227 int orbix = 0;
00228 for (std::set<int>::iterator it = orbkeys.begin();
00229 it != orbkeys.end(); ++it) {
00230 std::multimap<int, int>::iterator pos;
00231 for (pos = orbmap.lower_bound(*it);
00232 pos != orbmap.upper_bound(*it); ++pos) {
00233 (*orb)[orbix].push_back(pos->second);
00234 }
00235 orbix++;
00236 }
00237
00238 assert(orbix == getNumOrbits());
00239 return orb;
00240 }
00241
00242 void
00243 Nauty::getVstat(double *v, int nv)
00244 {
00245 assert(nv == n_);
00246 memcpy(v, vstat_, nv * sizeof(VarStatus));
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 void
00302 Nauty::setWriteAutoms(const std::string &fname)
00303 {
00304 afp_ = fopen(fname.c_str(), "w");
00305 options_->writeautoms = TRUE;
00306 options_->writemarkers = FALSE;
00307 options_->outfile = afp_;
00308
00309 }
00310
00311 void
00312 Nauty::unsetWriteAutoms()
00313 {
00314 fclose(afp_);
00315 options_->writeautoms = FALSE;
00316 }
00317