微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以使用 Accord.Net 进行并发 cobyla 优化吗?

如何解决我可以使用 Accord.Net 进行并发 cobyla 优化吗?

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

代码运行良好,但我遇到的问题是 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 function 时,您可以“捕获”外部作用域中的变量。在内部, this 被转换为一个对象,其中所有捕获的变量都作为类中的字段。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。