5 #ifndef ROCKY_ZAGROS_SCONTAINER_GUARD
6 #define ROCKY_ZAGROS_SCONTAINER_GUARD
21 #include<rocky/zagros/system.h>
22 #include<rocky/utils.h>
30 template<
typename T_e,
int T_dim>
37 n_particles_ = n_particles;
38 group_size_ = group_size;
40 int n_particles()
const{
43 int group_size()
const{
47 return n_particles() / group_size();
50 std::vector<std::vector<T_e>> particles;
52 std::vector<T_e> values;
55 std::fill(values.begin(), values.end(), std::numeric_limits<T_e>::max());
59 particles.resize(n_particles());
60 for(
int p=0; p<n_particles(); ++p)
61 particles[p].resize(T_dim);
62 values.resize(n_particles());
72 return particles[p].data();
81 return p / group_size();
90 return particles[g * group_size()].data();
99 int group_s = g * group_size();
100 int group_e = group_s + group_size();
101 if (g == n_groups() - 1)
102 group_e = n_particles();
103 return std::make_pair(group_s, group_e);
121 std::set<int> indices_set;
122 int max_iters = 10 * n;
125 indices_set.insert(weighted_dist(rocky::utils::random::prng()));
127 }
while((indices_set.size() < n) && (iters < max_iters));
129 if(indices_set.size() < n){
130 std::uniform_int_distribution uniform_dist(0, n_particles()-1);
132 indices_set.insert(uniform_dist(rocky::utils::random::prng()));
133 }
while(indices_set.size() < n);
136 for(
auto index: indices_set)
137 indices[i++] = index;
147 auto el = indices.begin();
148 auto result = std::make_pair(*el, *(std::next(el)));
159 std::uniform_int_distribution<> dist(group_rng.first, group_rng.second-1);
160 return dist(rocky::utils::random::prng());
168 std::uniform_int_distribution<> dist(0, T_dim-1);
169 return dist(rocky::utils::random::prng());
176 return sizeof(T_e) * (n_particles() * (T_dim + 1));
183 T_e best = *std::min_element(values.begin(), values.end());
192 auto min_el = std::min_element(values.begin(), values.end());
193 int index =
static_cast<int>(min_el - values.begin());
195 return std::make_pair(best, index);
206 tbb::parallel_for(rng_start, rng_end, [&](
int p){
207 T_e obj = problem->objective(this->
particle(p));
208 this->values[p] = obj;
237 auto comp_values = [
this](
int x,
int y){
238 return this->values[x] < this->values[y];
240 std::vector<int> all_ind(n_particles());
241 std::iota(all_ind.begin(), all_ind.end(), 0);
242 std::sort(all_ind.begin(), all_ind.end(), comp_values);
243 std::copy(all_ind.data(), all_ind.data()+k, indices);
252 auto comp_values = [
this](
int x,
int y){
253 return this->values[x] > this->values[y];
255 std::vector<int> all_ind(n_particles());
256 std::iota(all_ind.begin(), all_ind.end(), 0);
257 std::sort(all_ind.begin(), all_ind.end(), comp_values);
258 std::copy(all_ind.data(), all_ind.data()+k, indices);
268 std::vector<int> src_ind(cnt->n_particles());
269 std::vector<int> des_ind(n_particles());
270 cnt->
best_k(src_ind.data(), cnt->n_particles());
271 worst_k(des_ind.data(), n_particles());
272 int src_i=0, des_i=0;
274 while((src_i < cnt->n_particles()) && (des_i < n_particles())){
276 src_b = cnt->values[src_ind[src_i]];
277 des_w = values[des_ind[des_i]];
281 std::copy(cnt->particles[src_ind[src_i]].begin(),
282 cnt->particles[src_ind[src_i]].end(),
283 particles[des_ind[des_i]].begin());
285 values[des_ind[des_i]] = cnt->values[src_ind[src_i]];
296 std::vector<T_e> weights;
297 T_e max_el = *std::max_element(values.begin(), values.end());
298 if(max_el == std::numeric_limits<T_e>::max())
299 weights.assign(values.size(), 1.0);
301 T_e min_el = *std::min_element(values.begin(), values.end());
306 weights.resize(n_particles());
307 for(
int p=0; p<n_particles(); p++)
308 weights[p] = max_el - (shift + values[p]);
311 std::discrete_distribution<int> sampling_dist(weights.begin(), weights.end());
312 return sampling_dist;