我正在为个人图书馆编写一套学习算法。学习算法需要两件事,一个要探索的输入空间,以及一种将一个解决方案与另一个解决方案进行比较的方法。定义输入空间是最基本的数据传输,但是我很难将评级函数传递给它。
目前我的问题代码如下所示:
RankineGenerator generator(tempHotWater,tempColdWater);
int variablesSize = 2;
Range minMaxVaporizer = { tempColdWater,tempHotWater };
Range minMaxCondenser = { tempColdWater,tempHotWater };
Range minMax[] = {minMaxVaporizer, minMaxCondenser};
auto phi = [&generator] ( double * heatExchangerTemps ) -> double
{
generator.updateHeatExchangeTemps(heatExchangerTemps[0], heatExchangerTemps[1]);
generator.runSim();
return generator.getSpecificWork()/(generator.getColdWaterRelativeMass()+generator.getHotWaterRelativeMass());
};
Twiddle twiddle(variablesSize,phi,minMax,0.001);
我的构造函数 header 如下所示:
Twiddle(int size, double(*phi)(double*), Range minMax[], double minRatioDeltaPhi);
我要传递给算法“twiddle”的是“phi”lambda 函数
它不一定需要是 lambda 函数,任何内联函数都可以。
关注点:
学习算法往往是计算密集型的,因此快速的解决方案比简单的解决方案更可取。
要传递的函数需要某种方式来访问其声明范围内的一些信息。
学习算法需要通用。向它传递特定于问题的数据不是一种选择,我需要能够即插即用地解决任何问题。理想情况下,构造函数应采用如下形式:
constructor( nVars, ratingFunction(vars[nVars]), ranges[nVars], minImprovementSpeed)
更新: 看来我引起了一些困惑。抱歉。
首先,我使用的术语内联 表示在程序中间编写的函数,而不是作为一个独立的实体。不一定与同名关键字有任何关系。
其次,我要做的是传递一个可以访问某些本地数据的函数。例如这个:
double(*phi)(double*) = [](double* heatExchangerTemps) { /*do something*/ };
Twiddle twiddle(variablesSize,phi,minMax,.001);
带有构造头:
Twiddle(int size, double (*phi)(double*) , Range minMax[], double minRatioDeltaPhi);
将编译但不能访问对象“generator”。但是,当我尝试在 lambda 函数中捕获“生成器”对象时:
double(*phi)(double*) = [&generator](double* heatExchangerTemps) { /*do something*/ };
或
auto phi = [&generator] ( double * heatExchangerTemps ) -> double { /*do something*/ };
我得到一个错误。
我可以这样做:
double(*phi)(double*) = [](double* myArray)
{
Generator generator(/*stuff*/);
// do something
};
但是每次调用该函数时都会创建一个类“Generator”的新对象。考虑到此函数可能被调用 1000 多次,这并不理想。另外,现在“Twiddle”算法需要特定于生成器构造函数的信息,这违背了拥有通用算法的全部目的。
理想情况下,我需要能够访问函数内部的本地对象(在本例中为生成器),并将该函数作为构造函数的通用参数传递。
此外,它不一定必须是 lambda 函数,这正是首先想到的。
最佳答案
在摸索了几个小时后,我发现了这个:
std::function<double(double*)> phi = [&generator] ( double * heatExchangerTemps ) -> double
{ /*do someting*/ };
Twiddle twiddle(variablesSize,phi,minMax,1000000);
带有构造函数头:
Twiddle(int size, std::function<double(double*)> phi, Range minMax[], double maxResolution);
不确定这是否是最佳答案,但它似乎运作良好。
基本上我的 lambda 函数符合类型 std::function<double(double*)>
这使我能够保留 lambda 捕获功能,同时允许我的构造函数了解它接收的内容。
关于C++ 编写内联函数作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38103765/