为STL随机数生成器编写Factory方法 [英] Writing a Factory method for STL random number generators

查看:160
本文介绍了为STL随机数生成器编写Factory方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过配置文件提供一个界面,供我的用户选择他们所使用的某些参数的分布.为此,我想使用STL随机数生成器算法.

I'm trying to provide an interface — through a config file — for my users to choose a distribution for some of the parameters that they are using. I would like to use STL random number generator algorithms for this purpose.

让我们假设我的程序从命令行读取JSON.对于下面提供的JSON,程序需要意识到,它应该从正态分布中产生一个具有给定均值和标准差的随机数. (我使用与STL库相同的参数名称来进行清除.)

Let's assume that my program reads a JSON from a command line. For the JSON provided below, the program needs to realize that it should generate a random number from the normal distribution with given mean and standard variation. (I'm using the same parameter names as STL library for clearance.)

{
    "dist": "normal_distribution",
    "mean": 0.1,
    "stddev": 0.5
}

到目前为止,我可以轻松解析JSON,并使用每个发行版的param_type初始化发行版.我使用名称来决定要确定param_type和分布的分布.

So far, I can parse the JSON easily, and use each distribution's param_type to initialize the distribution. I use the name to decide which distribution to decide the param_type and the distribution.

我不知道如何很好地实现这一目标.我知道我应该为此提供某种工厂方法,传递JSON并吐出一个函数或一个类.如果我想返回一个类的实例,比方说生成器的unique_ptr,则需要定义一个抽象类,例如RandDist,并编写某种适配器以合并我的输入,.....通常,该类不需要太多,只需gen()方法就足够了.

What I don't know is how to implement this nicely. I know that I should provide some sort of factory method for this, pass the JSON, and spit out a function or a class. If I want to return an instance of a class, let's say a unique_ptr of the generator, I need to define an abstract class, e.g., RandDist and write some sort of adaptor to incorporate my input, .... I generally don't need a lot from the class, just a gen() method should be enough.

我想知道是否有人对此有所想法.或者,如果有人知道可以做到这一点的图书馆.

I'm wondering if anyone have thoughts on this. Or, if anyone knows a library that can do this.

P.S.输入不必是JSON对象,任何哈希表本身都可以工作.

P.S. Input doesn't have to be a JSON object, any hash table would work per se.

推荐答案

我试图将样板保持在最低限度.假设:

I've tried to keep the boilerplate to a bare minimum. Assumptions:

  • 您已经预先知道了生成器的类型(如果您还需要动态生成器,则可以轻松切换)

  • You know the type of your generator in advance (that's easily switchable if you need your generators to be dynamic as well)

所有发行版均生成double(由于API必须返回 something 具体的对象才能正常使用,因此已被广泛使用)

All of the distributions generate doubles (that's pretty much baked in since the API has to return something concrete to be decently usable)

所有发行版都可以通过double参数进行构造(也可以通过代理对象进行调整,但是取决于您的实际JSON库,该工作可能已经在此处完成)

All of the distributions are constructible from double parameters (that's tweakable as well with a proxy object, but depending on your actual JSON library the work may already be done there)

我使用了GCC预处理程序扩展来处理零参数的情况,但是可以肯定地将宏重写为不需要它.

I've used a GCC preprocessor extension to handle the zero-parameter case, but the macro can certainly be rewritten to not need it.

using Generator = std::mt19937;
using Distribution = std::function<double(Generator &)>;
using Json = std::map<std::string, std::string>;

template <class DistributionType, class... Parameters>
Distribution make_distribution_impl(Json const &json, Parameters... parameters) {
    return DistributionType{std::stod(json.at(parameters))...};
}

Distribution make_distribution(Json const &json) {
    auto const &distributionName = json.at("dist");

    #define generate_distribution_factory(name_, ...) \
        if(distributionName == #name_) \
            return make_distribution_impl<std::name_<double>>(json, ## __VA_ARGS__)

    generate_distribution_factory(uniform_real_distribution, "a", "b");
    generate_distribution_factory(normal_distribution, "mean", "stddev");
    // ...

    #undef generate_distribution_factory

    throw std::runtime_error{"Unknown distribution " + distributionName};
}

在Wandbox上观看

这篇关于为STL随机数生成器编写Factory方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆