我可以做并发cobyla优化使用Accord.Net?



下面的代码是我正在使用的一个最小的圆估计器的工作示例。它使用雅阁。Net的cobyla优化器。localalize方法的输入是一组点。使用优化器找到中心位置并返回。(我的实际代码有点复杂,但我省略了大多数不太相关的东西)

代码工作正常,但问题是我有static字段(我有更多的在我的实际代码)。当我同时优化多个问题时,static字段会出现问题,因为优化器可能会读取另一个线程的值。

问题是我如何使这段代码为并发代码工作?我可以放弃静态,仍然得到点内的Func<double[], double>?是否有其他方法可以规避静态对象的并发性问题?

internal class CircleLocalizer
{
private static (double, double)[] points; // I dislike these statics!
private double[] prior = { 0, 0 };
Func<double[], double> objective = x =>
{
var distancesToCenter = CircleLocalizer.points.Select(p => Distance.Euclidean(new[] { p.Item1, p.Item2 }, new[] { x[0], x[1] }));
var averageDistance = distancesToCenter.Average();
return distancesToCenter.Select(d => Math.Pow(d - averageDistance, 2)).Sum();
};
public double[] Localize((double, double) points)
{
CircleLocalizer.points = points;
Cobyla cobyla = new Cobyla(2, objective);
cobyla.Minimize(Prior);
return cobyla.Solution;
}
}

我建议将objective重写为以点为参数的常规方法:

double Objective(double[] x, (double, double)[] points){
var distancesToCenter = points.Select(p => Distance.Euclidean(new[] { p.Item1, p.Item2 }, new[] { x[0], x[1] }));
var averageDistance = distancesToCenter.Average();
return distancesToCenter.Select(d => Math.Pow(d - averageDistance, 2)).Sum();
}

并将其命名为

new Cobyla(2, x => Objective(x, points)); 

当你在编写lambda函数时,你可以在外部作用域中"捕获"变量。在内部,它被转换为一个对象,所有捕获的变量都作为类中的字段。

最新更新