類似の質問が見つかりませんでしたので、既に尋ねられている場合は謝ります。私は機能でそれを行うと :私は発電機のいずれかからの関数呼び出しを経由してランダム化し、それが正常に動作どこ同じ番号を返すC++ STL乱数生成
#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
最も興味深い部分がある(// NUMBERSのFINEをランダムライン:!)とにかく、ここで私の関数でありますgenerate_random_individual(特定の範囲を持つ少数のジェネレータオブジェクトを使用)を、非常に同じオブジェクトセットで同じ関数呼び出しを介して実行します(私は新しいジェネレータを作成しません)。
誰かがテストケースを望む場合は、テストケースを提供することができますが、それらを含めるべきかどうかはわかりませんでした。
編集:これは例として残していますが、正確にバグがあった場所を知りたい場合は、私の答えをご覧ください。
TL; DR;シードは一度だけ。 –
私はあなたのジェネレータを播種する場所は見ません(私は何かを見逃しているかもしれません)。あなたが種を蒔かないと、いつも同じシーケンスが得られます。 –
@JesperJuhl私はそれを播種する必要がありますか?私はランダムなライブラリを使用しており、generate_random_individualの呼び出しごとに異なる出力が必要です。このlampda関数はlampda関数を使用しているため、同じジェネレータを使用していると思われますので、異なるランダム値を返す必要があります(2つの呼び出しを参照してください:std :: cout << std::get<0>(generators)()<< std :: endl;ポストの最後の4つのコールより)。 – MostLovelyRollOnThePlanet