C ++ STL随机数生成返回相同的数字

时间:2016-06-15 20:07:55

标签: c++ c++11 random stl c++14

我还没有找到类似的问题,所以如果已经被问过我会道歉。无论如何,这是我的功能:

#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

最有趣的部分是我通过函数调用从一个生成器中随机化并且它工作正常(line:// RANDOMIZES NUMBERS FINE!) 当我在函数generate_random_individual(使用少量具有特定范围的生成器对象)中通过对相同对象集的相同函数调用(因此我没有生成新生成器)时,它返回最后一个couts中的相同数字。

如果有人想要,我可以提供测试用例,我不确定是否应该包含这些测试用例。

编辑:我以此为例,如果您想知道错误的确切位置,请参阅我的回答,谢谢您的帮助。

2 个答案:

答案 0 :(得分:4)

每次要使用随机数时,都要创建新的生成器。我不知道如何为这些生成器生成种子,但它明确地为您创建的每个生成器实例使用相同的种子。您应该做的是创建所有发行版使用的单个生成器。

你可能想看看增强型随机类提供的内容,并检查一些样本。

答案 1 :(得分:2)

问题解决了 - 我忘了添加&amp;在传递我的一个功能时,即:

auto genotype=std::experimental::apply(
                    [&](auto&... x){ //THIS LINE!
                        return std::make_tuple(x()...);
                    },
                    gen
            );

因此,正如你们大多数人所说的那样,它正在复制发电机,感谢您的投入。