我是个新手,我正在创建一个框架,用进化算法在C++中进化对象。一种进化算法对对象进行进化并对其进行测试以获得最佳解(例如,进化权重神经网络并对样本数据进行测试,从而最终得到精度较高的网络,而无需对其进行训练)。
我的问题是算法有很多参数(选择/交叉/变异的类型,每个参数的概率.)由于它是一个框架,用户应该能够轻松地访问和修改它们。
电流溶液
现在,我创建了这个表单的头文件参数.h:
// DON'T CHANGE THESE PARAMETERS
//mutation type
#define FLIP 1
#define ADD_CONNECTION 2
#define RM_CONNECTION 3
// USER DEFINED
static const int TYPE_OF_MUTATION = FLIP; 用户修改静态变量TYPE_OF_MUTATION,然后我的变异函数测试TYPE_OF_MUTATION的值,并调用正确的突变函数。
这很好,但是它有一些缺点:
其他可能性
我想把这些参数作为顶层函数的参数。问题是这个函数需要20个左右的参数,看起来不太容易读.
关于顶级函数,我的意思是,目前,进化算法只是通过这样做来运行:
PopulationManager myPop;
myPop.evolveIt();如果我将参数定义为参数,我们将得到如下内容:
PopulationManager myPop;
myPop.evolveIt(20,10,5,FLIP,9,8,2,3,TOURNAMENT,0,23,4);您可以看到,总是按照正确的顺序定义参数是多么糟糕!
结论
我所知道的框架使您可以通过预定义的函数自己构建算法,但是用户不应该一个一个地修改所有代码来更改参数。
指出这一框架将在内部用于确定的一组项目可能是有用的。
任何关于定义这些参数的最佳方法的输入都是欢迎的!
发布于 2015-10-27 19:34:01
如果选项没有改变,我通常使用结构来实现:
enum class MutationType {
Flip,
AddConnection,
RemoveConnection
};
struct Options {
// Documentation for mutation_type.
MutationType mutation_type = MutationType::Flip;
// Documentation for integer option.
int integer_option = 10;
};然后提供接受这些选项的构造函数。
Options options;
options.mutation_type = MutationType::AddConnection;
PopulationManager population(options);C++11使这非常容易,因为它允许为选项指定默认值,因此用户只需要设置与默认选项不同的选项。
还请注意,我对选项使用了枚举,这确保了用户只能使用正确的值。
发布于 2015-10-27 23:00:47
这是一个典型的多态示例。在您建议的实现中,您需要打开常量来决定选择哪种多态变异算法来决定如何修改参数。在C++中,相应的机制是模板(静态多态)或虚拟函数(动态多态),以选择适用于参数的适当的变异算法。
模板方法的优点是在编译时一切都是可解决的,所产生的变异算法可以完全内联,这取决于实现。您放弃的是在运行时动态选择参数变异算法的能力。
虚拟函数方法的优点是,您可以将变异算法的选择推迟到运行时,允许根据用户输入或其他什么内容进行更改。缺点是,变异算法不能再内联,并且当您改变参数时,您需要支付虚拟函数调用(额外的间接级别)的费用。
如果您想要看到“算法突变”如何工作的真实示例,请查看我在github上的迭代动力学存储库中的迭代动力学。这是转换成C++的C代码,所以它既不使用模板,也不使用虚拟函数。相反,它使用函数指针和开关常量来选择适当的代码。然而,这个想法是一样的。
我的建议是先看看是否可以使用静态多态(模板)。根据你最初的描述,你是在编译时修复突变的,所以你不会放弃任何东西。
如果这只是一个原型化阶段,并且您打算在运行时支持突变算法的切换,那么就看一下虚拟函数。另一个建议的答案是,请避免使用C风格的编码,比如#define常量,而使用适当的枚举。
为了解决“长参数列表气味”的问题,将所有参数打包到一个结构中是一个很好的想法。在此基础上,您可以通过使用建造者模式以更易读的方式构建参数结构来实现更高的可读性,而不仅仅是将一组值分配到结构中。在这个博客帖子中,我将构建器模式应用于Direct3D中的资源描述结构。这使我能够更直接地用合理的默认值表示这些“数据袋”,并在必要时直接显示我的意图,即用特殊值覆盖或替换默认值。
https://stackoverflow.com/questions/33372306
复制相似问题