在 C# 中组合委托(和积算法)

Combining delegates in C# (Sum-Product Algorithm)

我目前正在为离散变量实施信念传播。

消息是函数。我需要能够使用乘积和求和来组合它们以生成新函数。

我目前有一个使用委托的基本实现,但我想知道是否有更好的方法来处理这个问题。我还担心这将如何使用代表进行扩展。

这是我的实现示例:

public Func<double, double> ProductFunc(List<Func<double, double>> messages)
{
    // Construct the product of the message functions
    Func<double, double> productFunc = delegate(double x)
    {
        double productValue = 1.0;
        foreach(Func<double, double> message in messages)
        {
            productValue *= message(x);
        }
        return productValue;
    };

    return productFunc;

}

有没有更有效的方法来实现?

您拥有的代码实际上做您想要的吗?

我问,因为规范不是很清楚。您拥有的代码捕获对 List<Func<double, double>> 对象的引用,以及 returns 一个 Func<double, double> 委托,它将在调用委托时按原样 枚举列表(与调用方法时使用的列表相反)。

也许这就是您想要的。它与整个过程中使用的延迟执行一致。 LINQ。但这确实意味着调用者要么打算更改列表将更改返回委托的评估,要么必须非常小心不要更改列表。

如果您想要实现的是捕获调用时存在的数学关系,您可能更希望该方法看起来像这样:

public Func<double, double> ProductFunc(List<Func<double, double>> messages)
{
    Func<double, double> productFunc = x => 1.0;

    foreach (Func<double, double> message in messages)
    {
        Func<double, double> currentFunc = productFunc;

        productFunc = x => currentFunc(x) * message(x);
    }

    return productFunc;
}

在我看来,哪种方式都可以。这仅取决于您实际希望代码具有的行为。你的问题中没有足够的上下文让我知道。

I'm also concerned about how this will scale using delegates

它应该可以正常缩放。无论如何,您已经在使用委托。以任何一种方式组合它们都不太可能导致不当的性能问题,并且在任何情况下代码都按原样正确表达。如果您 运行 遇到 特定的 性能问题,导致代码无法满足某些 objective 可衡量的性能目标,那么您可以考虑将代码调整为解决这个问题(并可能在此过程中至少失去一些表现力)。