diff options
-rw-r--r-- | cacount.cpp | 54 |
1 files changed, 23 insertions, 31 deletions
diff --git a/cacount.cpp b/cacount.cpp index ecf0f38..882e4a6 100644 --- a/cacount.cpp +++ b/cacount.cpp @@ -7,8 +7,8 @@ #include <functional> #include <iostream> #include <list> -#include <map> -#include <set> +#include <unordered_map> +#include <unordered_set> #include <thread> #include <boost/integer.hpp> @@ -106,41 +106,33 @@ State canonize(State s) { void cycleStat(Trans &t, Trans &c, pbitset &reachable) { struct Stat { - State basin, len, eden, cycleRed; - explicit Stat() : basin(0), len(0), eden(0), cycleRed(0) {} + State basin, len, eden; + StateIter totalBasin; + explicit Stat() : basin(0), len(0), eden(0), totalBasin(0) {} }; - map<State, StateIter> cycp; - vector<Stat> cycs; + unordered_map<State, Stat> cycStat; + unordered_set<State> redCycleCounted; // Is this cycle the canonical one? // How big is the basin of attraction? // How many garden of eden states does it contain? { PerfPrinter perfPrinter((string) "cycle count"); iterState([&](State s) { - auto cyc = c[s]; - auto i = cycp.find(cyc); - if (i == cycp.end()) { - if (cyc == canonize(cyc)) { - cycs.emplace_back(); - i = cycp.insert(make_pair(cyc, cycs.size() - 1)).first; - }else{ - i = cycp.insert(make_pair(cyc, nullState)).first; - } - } - auto si = i->second; - - if (si != nullState) { - cycs[si].basin++; - if (!reachable[s]) - cycs[si].eden++; - } - }, (string) "basin & eden"); } + auto cyc = c[s]; + auto canonCyc = canonize(cyc); + auto &stat = cycStat[canonCyc]; + stat.totalBasin++; + if (cyc == canonCyc) { + stat.basin++; + if (!reachable[s]) + stat.eden++; + } + }, (string) "basin & eden"); } // how long is the cycle, what is the actual minimal state { PerfPrinter perfPrinter((string) "cycle length"); - for (auto i : cycp) { - if (i.second == nullState) continue; - auto &stat = cycs[i.second]; + for (auto &i : cycStat) { + Stat &stat = i.second; State cur, start; cur = start = t[i.first]; do { @@ -151,11 +143,11 @@ void cycleStat(Trans &t, Trans &c, pbitset &reachable) { }} // print it - for (auto i : cycp) { - if (i.second == nullState) continue; - auto &s = cycs[i.second]; + for (auto &i : cycStat) { + auto &s = i.second; + assert(s.totalBasin % s.basin == 0); cout << bitset<logState>(i.first) << "\t" - << s.cycleRed << "\t" + << (s.totalBasin / s.basin) << "\t" << s.len << "\t" << s.basin << "\t" << s.eden << "\t" |