Empirical
NK.h
Go to the documentation of this file.
1 
18 #ifndef EMP_EVO_NK_H
19 #define EMP_EVO_NK_H
20 
21 #include <array>
22 
23 #include "../base/vector.h"
24 #include "../tools/BitVector.h"
25 #include "../tools/math.h"
26 #include "../tools/memo_function.h"
27 #include "../tools/Random.h"
28 
29 namespace emp {
30 
48 
49  class NKLandscape {
50  private:
51  size_t N;
52  size_t K;
53  size_t state_count;
54  size_t total_count;
56 
57  public:
58  NKLandscape() : N(0), K(0), state_count(0), total_count(0), landscape() { ; }
59  NKLandscape(const NKLandscape &) = default;
60  NKLandscape(NKLandscape &&) = default;
61 
65  NKLandscape(size_t _N, size_t _K, emp::Random & random)
66  : N(_N), K(_K)
67  , state_count(emp::IntPow<size_t>(2,K+1))
68  , total_count(N * state_count)
69  , landscape(N)
70  {
71  Reset(random);
72  }
73  ~NKLandscape() { ; }
74  NKLandscape & operator=(const NKLandscape &) = delete;
75  NKLandscape & operator=(NKLandscape &&) = default;
76 
78  void Reset(emp::Random & random) {
79  emp_assert(K < 32, K);
80  emp_assert(K < N, K, N);
81 
82  // Build new landscape.
83  for ( auto & ltable : landscape) {
84  ltable.resize(state_count);
85  for (double & pos : ltable) {
86  pos = random.GetDouble();
87  }
88  }
89  }
90 
92  void Config(size_t _N, size_t _K, emp::Random & random) {
93  // Save new values.
94  N = _N; K = _K;
95  state_count = emp::IntPow<size_t>(2,K+1);
96  total_count = N * state_count;
97  landscape.resize(N);
98  Reset(random);
99  }
100 
102  size_t GetN() const { return N; }
104  size_t GetK() const { return K; }
106  size_t GetStateCount() const { return state_count; }
109  size_t GetTotalCount() const { return total_count; }
110 
113  double GetFitness(size_t n, size_t state) const {
114  emp_assert(state < state_count, state, state_count);
115  return landscape[n][state];
116  }
117 
119  double GetFitness( std::vector<size_t> states ) const {
120  emp_assert(states.size() == N);
121  double total = landscape[0][states[0]];
122  for (size_t i = 1; i < N; i++) total += GetFitness(i,states[i]);
123  return total;
124  }
125 
127  double GetFitness(BitVector genome) const {
128  emp_assert(genome.GetSize() == N, genome.GetSize(), N);
129 
130  // Use a double-length genome to easily handle wrap-around.
131  genome.Resize(N*2);
132  genome |= (genome << N);
133 
134  double total = 0.0;
135  size_t mask = emp::MaskLow<size_t>(K+1);
136  for (size_t i = 0; i < N; i++) {
137  const size_t cur_val = (genome >> i).GetUInt(0) & mask;
138  const double cur_fit = GetFitness(i, cur_val);
139  total += cur_fit;
140  }
141  return total;
142  }
143 
144  void SetState(size_t n, size_t state, double in_fit) { landscape[n][state] = in_fit; }
145 
146  void RandomizeStates(Random & random, size_t num_states=1) {
147  for (size_t i = 0; i < num_states; i++) {
148  SetState(random.GetUInt(N), random.GetUInt(state_count), random.GetDouble());
149  }
150  }
151 
152  };
153 
157 
159  private:
160  const size_t N;
161  const size_t K;
164 
165  public:
166  NKLandscapeMemo() = delete;
167  NKLandscapeMemo(const NKLandscapeMemo &) = delete;
168  NKLandscapeMemo(NKLandscapeMemo &&) = default;
169  NKLandscapeMemo(size_t _N, size_t _K, emp::Random & random)
170  : N(_N), K(_K), landscape(N), masks(N)
171  {
172  // Each position in the landscape...
173  for (size_t n = 0; n < N; n++) {
174  // ...should have its own memo_function
175  landscape[n] = [&random](const BitVector &){ return random.GetDouble(); };
176  // ...and its own mask.
177  masks[n].Resize(N);
178  for (size_t k = 0; k < K; k++) masks[n][(n+k)%N] = 1;
179  }
180  }
182  NKLandscapeMemo & operator=(const NKLandscapeMemo &) = delete;
183  NKLandscapeMemo & operator=(NKLandscapeMemo &&) = default;
184 
185  size_t GetN() const { return N; }
186  size_t GetK() const { return K; }
187 
188  double GetFitness(size_t n, const BitVector & state) const {
189  emp_assert(state == (state & masks[n]));
190  return landscape[n](state);
191  }
192  double GetFitness(const BitVector & genome) const {
193  emp_assert(genome.GetSize() == N);
194 
195  // Otherwise calculate it.
196  double total = 0.0;
197  for (size_t n = 0; n < N; n++) {
198  total += landscape[n](genome & masks[n]);
199  }
200  return total;
201  }
202  };
203 
204 }
205 
206 #endif
void Reset(emp::Random &random)
Randomize the landscape without changing the landscape size.
Definition: NK.h:78
double GetFitness(size_t n, size_t state) const
Definition: NK.h:113
double GetFitness(const BitVector &genome) const
Definition: NK.h:192
NKLandscape(size_t _N, size_t _K, emp::Random &random)
Definition: NK.h:65
double GetFitness(std::vector< size_t > states) const
Get the fitness of a whole bitstring.
Definition: NK.h:119
static constexpr TYPE IntPow(TYPE base, TYPE exp)
A fast method for calculating exponents for int types.
Definition: math.h:163
BitVector & Resize(size_t new_bits)
Resize this BitVector to have the specified number of bits.
Definition: BitVector.h:297
A versatile and non-patterned pseudo-random-number generator (Mersenne Twister).
Definition: ce_random.h:52
A drop-in replacement for std::vector<bool>, but with extra bitwise logic features.
Definition: BitVector.h:39
void Config(size_t _N, size_t _K, emp::Random &random)
Configure for new values of N and K.
Definition: NK.h:92
NKLandscape()
Definition: NK.h:58
Definition: NK.h:49
size_t GetStateCount() const
Get the number of posssible states for a given site.
Definition: NK.h:106
constexpr uint32_t GetUInt(const uint32_t max)
Definition: ce_random.h:191
NKLandscape & operator=(const NKLandscape &)=delete
void SetState(size_t n, size_t state, double in_fit)
Definition: NK.h:144
size_t GetTotalCount() const
Definition: NK.h:109
void RandomizeStates(Random &random, size_t num_states=1)
Definition: NK.h:146
constexpr double GetDouble()
Definition: ce_random.h:166
~NKLandscapeMemo()
Definition: NK.h:181
size_t GetK() const
Definition: NK.h:186
void resize(size_t new_size)
Definition: vector.h:161
Definition: NK.h:158
size_t GetN() const
Definition: NK.h:185
~NKLandscape()
Definition: NK.h:73
If we are in emscripten, make sure to include the header.
Definition: array.h:37
Build a debug wrapper emp::vector around std::vector.
Definition: vector.h:42
#define emp_assert(...)
Definition: assert.h:199
double GetFitness(size_t n, const BitVector &state) const
Definition: NK.h:188
double GetFitness(BitVector genome) const
Get the fitness of a whole bitstring (pass by value so can be modified.)
Definition: NK.h:127
size_t GetN() const
Returns N.
Definition: NK.h:102
size_t GetSize() const
How many bits do we currently have?
Definition: BitVector.h:368
size_t GetK() const
Returns K.
Definition: NK.h:104
NKLandscapeMemo(size_t _N, size_t _K, emp::Random &random)
Definition: NK.h:169