I haven't found similiar question so I apologize if it's already been asked. Anyway, here is my function:
#ifndef OPTIMALIZATION_HPP
#define OPTIMALIZATION_HPP
#include<utility>
#include<random>
#include<experimental/random>
#include<functional>
#include<experimental/functional>
#include<experimental/tuple>
#include<algorithm>
#include<type_traits>
#include<iostream>
namespace numerics{
template<
std::size_t population_size, std::size_t generations,
typename Func,
typename Compare,
typename Generator=std::default_random_engine,
template<typename>
typename RealDistribution=std::uniform_real_distribution,
template<typename>
typename IntegerDistribution=std::uniform_int_distribution,
typename ...Ts
>
auto optimize(
const Func& function, const Compare& comp,
const std::pair<Ts,Ts>&... ranges
){
constexpr std::size_t range_argument_count=sizeof...(ranges);
static_assert(range_argument_count>2,
"Function needs at least two range arguments"
);
//RANDOM NUMBER GENERATORS LAMPDA FUNCTIONS
auto real_random_generator=[&](const std::pair<auto,auto> range){
return std::bind(
RealDistribution<decltype(range.first)>(range.first,range.second),
Generator()
);
};
auto integer_random_generator=[&](const std::pair<auto,auto>& range){
return std::bind(
IntegerDistribution<decltype(range.first)>(range.first,range.second),
Generator()
);
};
//MAKING TUPLE OF GENERATORS FOR SPECIFIC RANGES ARGUMENTS
auto generator_objects=std::make_tuple(
integer_random_generator,
real_random_generator
);
auto generators=std::make_tuple(
std::get<std::is_floating_point<decltype(ranges.first)>::value> //UPDATE FOR C++17
(generator_objects)(ranges)...
);
//RANDOMIZES NUMBERS FINE!
std::cout << std::get<0>(generators)() << std::endl;
std::cout << std::get<0>(generators)() << std::endl;
//SINGLE RANDOM INDIVIDUAL GENERATOR
auto generate_random_individual=[&](const auto& gen){
auto genotype=std::experimental::apply(
[&](auto... x){
return std::make_tuple(x()...);
},
gen
);
return std::make_pair(
std::experimental::apply(function,genotype),
genotype
);
};
//RETURN THE SAME NUMBER!
auto foo=generate_random_individual(generators);
auto foo2=generate_random_individual(generators);
auto foo3=generate_random_individual(generators);
auto foo4=generate_random_individual(generators);
std::cout << std::get<0>(foo.second) << std::endl;
std::cout << std::get<0>(foo2.second) << std::endl;
std::cout << std::get<0>(foo3.second) << std::endl;
std::cout << std::get<0>(foo4.second) << std::endl;
return 1.;
}}
#endif
The most interesting part is where I randomize via function call from one of generators and it works fine (line: //RANDOMIZES NUMBERS FINE!) When I do it in function generate_random_individual (using few generator objects with specific ranges) via the very same function call on the very same object sets (so I'm not making new generators) it returns the same numbers in the last couts.
I can provide test cases if anybody wants it, I wasn't sure if I should include those.
EDIT: I'm not regenerating generators as I pass the ones already created via reference to lampda function. If I do, could you point out how can I not re-regenerate them than?
Aucun commentaire:
Enregistrer un commentaire