用户定义的框架参数应该在哪里?

时间:2015-10-27 15:40:17

标签: c++ frameworks evolutionary-algorithm

我是一个新手,我正在创建一个框架,用进化算法在C ++中进化对象。 进化算法演化对象并测试它们以获得最佳解决方案(例如,演化权重神经网络并在样本数据上进行测试,以便最终得到一个具有良好准确性的网络,而无需对其进行训练)。

我的问题是算法有很多参数(选择/交叉/变异的类型,每个的概率......),因为它是一个框架,用户应该能够轻松访问和修改它们。

当前解决方案

现在,我创建了一个这种形式的头文件parameters.h:

  PopulationManager myPop; 
  myPop.evolveIt();

用户修改静态变量TYPE_OF_MUTATION,然后我的变异函数测试TYPE_OF_MUTATION的值是什么,并调用右变异函数。

这很有效,但它有一些缺点:

  • 当我更改此标题中的参数然后调用" make"时,不会考虑任何更改,我必须调用" make clean"然后"制作"。从我看到的,它不是makefile中的问题,但它是建筑的工作原理。即使它在我更改参数时重新构建,也意味着重新编译整个项目,因为这些参数在任何地方都使用;它绝对没有效率。
  • 如果你想用不同的参数多次运行遗传算法,你必须先运行它然后保存结果,更改参数然后再运行一次等。

其他可能性

我考虑过将这些参数作为顶级函数的参数。问题是该函数会占用20个左右的参数,它看起来并不可读...

我对顶级函数的意思是,目前,进化算法只需执行此操作:

  PopulationManager myPop; 
  myPop.evolveIt(20,10,5,FLIP,9,8,2,3,TOURNAMENT,0,23,4);

如果我将参数定义为参数,我们会有类似的东西:

Select 
 STR_TO_DATE(CONCAT('2015',coldatetime,'00'),'%y','%m','%d','%H','%i','%s')
From Table1

你可以看到总是按正确的顺序定义参数会有多么神奇!

结论

我所知道的框架使您可以自己从预定义的函数构建算法,但用户不必通过所有代码逐个更改参数。

对于一组明确的项目,表明该框架将在内部使用可能是有用的。

欢迎任何关于定义这些参数的最佳方式的输入!

2 个答案:

答案 0 :(得分:0)

如果选项没有改变,我通常会使用一个结构:

Options options;
options.mutation_type = MutationType::AddConnection;
PopulationManager population(options);

然后提供一个采用这些选项的构造函数。

while

C ++ 11使这非常简单,因为它允许指定选项的默认值,因此用户只需要设置需要与默认值不同的选项。

另请注意,我为选项使用了枚举,这可确保用户只能使用正确的值。

答案 1 :(得分:0)

这是多态性的典型例子。在您提出的实现中,您正在切换常量以决定您将选择哪种多态变异算法来决定如何改变参数。在C ++中,相应的机制是模板(静态多态)或虚函数(动态多态),以选择适当的变异算法应用于参数。

模板方式的优点是一切都可以在编译时解析,并且所得到的变异算法可以完全内联,具体取决于实现。你放弃的是能够在运行时动态选择参数变异算法。

虚函数方式的优点是您可以将变异算法的选择推迟到运行时,允许它根据用户的输入或诸如此类的信息而变化。缺点是变异算法不能再内联,当你改变参数时,你需要支付虚函数调用的成本(一个额外的间接级别)。

如果您想查看“算法变异”如何工作的真实示例,请查看github上evolve.cpp存储库中的Iterated Dynamics。这是转换为C ++的C代码,因此既不使用模板也不使用虚函数。相反,它使用函数指针和开关常量来选择适当的代码。但是,这个想法是一样的。

我的建议是先看看你是否可以使用静态多态(模板)。从你最初的描述来看,你无论如何都要在编译时修复变异,所以你没有给出任何东西。

如果那只是一个原型设计阶段,并且您打算在运行时支持切换变异算法,那么请查看虚函数。正如建议的另一个答案,请避免使用类似#define常量的C风格编码,而是使用正确的枚举。

为了解决“长参数列表气味”,将所有参数打包到结构中的想法很好。通过使用builder pattern以更可读的方式构建参数结构,而不仅仅是将一堆值分配到结构中,您可以实现更高的可读性。在这个blog post中,我将构建器模式应用于Direct3D中的资源描述结构。这使我能够更直接地用合理的默认值表达这些“数据包”,并在必要时直接显示我用特殊值覆盖或替换默认值的意图。