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;