我正在为个人图书馆编写一套学习算法。学习算法需要两件事,一个可以探索的输入空间,以及一种将一种解决方案与另一种解决方案进定义输入空间是最基本的数据传输,但是我很难将其传递给评级函数。
目前我的问题代码如下:
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);
我的构造函数标题如下:
Twiddle(int size, double(*phi)(double*), Range minMax[], double minRatioDeltaPhi);
" phi" lambda函数是我试图传递给算法的函数" twiddle"
它不一定需要是lambda函数,任何内联函数都可以。
关注点:
学习算法往往是计算密集型的,因此快速解决方案比简单的解决方案更可取。
要传递的函数需要某种方式来访问声明它的声明范围内的一些信息。
学习算法需要具有普遍性。传递问题特定数据不是一个选项,我需要能够插入和播放任何问题。理想情况下,构造函数应采用如下形式:
constructor( nVars, ratingFunction(vars[nVars]), ranges[nVars], minImprovementSpeed)
更新 我似乎引起了一些混乱。道歉。
首先,我使用术语 inline 表示在程序中间而不是作为独立实体编写的函数。不一定与同名关键字有任何关系。
其次我要做的是传递一个能够访问某些本地数据的函数。例如:
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"算法需要特定于Generator构造函数的信息,这违背了具有通用算法的整个目的。
理想情况下,我需要能够在函数内部访问本地对象(在本例中为生成器),并将该函数作为构造函数的泛型参数传递。
它也不一定必须是一个lambda函数,这才是最初想到的。
答案 0 :(得分:1)
经过几个小时的探索后,我发现了这个:
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捕获功能,同时允许我的构造函数理解它接收的内容。