【发布时间】:2016-06-15 20:07:54
【问题描述】:
我没有找到类似的问题,所以如果已经被问到,我很抱歉。无论如何,这是我的功能:
#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
最有趣的部分是我通过其中一个生成器的函数调用进行随机化,它工作正常(行://RANDOMIZES NUMBERS FINE!) 当我在函数 generate_random_individual 中执行此操作时(使用具有特定范围的少数生成器对象),通过对相同对象集的相同函数调用(因此我没有制作新生成器),它在最后一个 couts 中返回相同的数字。
如果有人需要,我可以提供测试用例,我不确定是否应该包括这些。
编辑:我将此作为示例,如果您想知道错误的确切位置,请参阅我的回答,谢谢您的帮助。
【问题讨论】:
-
TL;DR;只播种一次。
-
我看不到你在哪里播种你的生成器(我可能错过了一些东西) - 如果你不播种,你总是会得到相同的序列。
-
@JesperJuhl 我必须播种吗?我正在使用随机库,我希望每次调用 generate_random_individual 时都有不同的输出。似乎这个lampda函数使用相同的生成器,因为它通过lampda调用获取那些,所以它应该返回不同的随机值(参见两个调用:std::cout (generators)()
-
你需要创建最小的个例子。
-
是的,您必须为它们播种,否则程序的每次调用都将具有相同的值。此外,您需要重用生成器并且不要重新创建它们,因为它会再次重置随机序列。
标签: c++ c++11 random stl c++14