9

是否有任何 C# 计算引擎可以在值更改时自动重新计算依赖字段?

让我自由泳一秒钟,我在想象这样的事情..

 Field<double> quantity = Field.Create<double>("Quantity");
 Field<double> unitCost = Field.Create<double>("Unit Cost");
 Field<double> total = Field.Create<double>("Total");

 total.Calculation((q,uc) => q * uc, quantity, value);
      // would have signature something like this:
      // void Calculation<TR,T1,T1>(Func<TR,T1,T2>, Field<T1>, Field<T2>)

这将设置自动传播相关值的字段。

 quantity.Value = 5.0;
 unitCost.Value = 1.5;
 Assert.That(total.Value, Is.EqualTo(7.5));

显然这是一个简单的例子,最终用途将更类似于复杂电子表格的计算。

进一步思考如果字段/单元格支持更改通知,那将是惊人的。

4

5 回答 5

5

你看过http://ncalc.codeplex.com吗?

它是可扩展的、快速的(例如有自己的缓存),使您能够通过处理 EvaluateFunction/EvaluateParameter 事件在运行时提供自定义函数和变量。它可以解析的示例表达式:

Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");

  e.Parameters["Pi2"] = new Expression("Pi * Pi");
  e.Parameters["X"] = 10;

  e.EvaluateParameter += delegate(string name, ParameterArgs args)
    {
      if (name == "Pi")
      args.Result = 3.14;
    };

  Debug.Assert(117.07 == e.Evaluate());

它还原生处理 unicode 和许多数据类型。如果您想更改语法,它会附带一个 antler 文件。还有一个 fork 支持 MEF 加载新功能。

它还支持逻辑运算符、日期/时间字符串和 if 语句。

一个办法

您可以通过实现 INotifyPropertyChanged 然后执行类似的操作来进行自动重新计算

  • 设置字段的表达式 this.Field.Expression = new Expression("Field1+Field2");

关于类中的 notifypropertyupdated

  • 对于作为函数的每个字段(带有反射)
  • 如果它的表达式引用了更改的字段,则重新计算变量。
  • 在重新计算时,您需要处理 EvaluateParameter 事件以使用反射来查找正确的字段并提取其值(如果需要,您可以缓存以避免反射)
于 2011-02-01T16:26:52.077 回答
1

我在这里问了一个类似的问题:真正的声明性语言?

据我所知,只听说过 NCalc,我会调查一下。我有一个项目几乎可以完成您所描述的工作,然后像缓存/缓存丢弃值或模型结构的更改。将其视为数据库和 Excel 之间的交叉。您还可以定义类等并将它们链接到具有数百万图形对象的大型模型中,而不仅仅是树。客户端服务器等。还有一个模型编辑器,您可以在其中在 UI 中创建模型,这样您就可以分析所有计算如何相互构建。

你到底为什么要问?

于 2011-02-01T22:05:46.777 回答
1

我建议也看看杰斯。Jace 是用于 .NET 框架的更现代的计算引擎。它比上面提出的 NCalc 快得多。此外,它支持更多平台(.NET、WinRT、WP7 和 WP8)。

有关 Jace 的更多信息可以在 GitHub 页面上找到: https ://github.com/pieterderycke/Jace

NuGet 链接: https ://www.nuget.org/packages/Jace

于 2012-12-05T21:11:34.543 回答
1

有标量参数的计算引擎,也有更高级别的表格计算引擎,通常用于财务规划、费用和佣金计算、网络和合同计算等应用......

让我简短地解释一下。考虑以下标量公式:

1) z = f1(x,y)
2) p = f2(z,n)
3) q = f3(x,p)
...

等等。配置这样的函数和依赖树需要一个带有标量参数的计算引擎。我会(也)推荐以下链接,将这种用 c# 编写的计算引擎作为一个很好的起点: http: //www.codeproject.com/Articles/246374/A-Calculation-Engine-for-NET

如前所述,还有一些具有将表格作为参数的表格函数的计算引擎。主要原理是一样的:

1) (T4, T5) = TableFunction1(T1, T2, T3)  
2) (T7, T8) = TableFunction2(T2, T4)
...

等等。请注意,一个表函数可以返回多个表作为输出,如上所示。

这里需要注意两个关键问题:

a) 表 T7 和 T8 的值取决于表 T2 和 T4。因此,仅当输入参数T2或T4之一发生变化时,才需要通过执行函数“TableFunction2”来更新表T7和T8。

同理,只有更新了 T1、T2 或 T3 才需要更新 T4;依赖树!

b) 数据库与计算过程分离:计算引擎必须独立于任何固定的数据结构或数据库模式工作,以便与任何数据库和数据结构集成。

您可以找到我的相关文章,其中解释了这些原则:

基于规则的计算框架的逻辑架构 http://finaquant.com/logical-architecture-of-a-rule-based-calculation-framework/1053

现在,基于这些原则,正在开发一个以表格为输入和输出参数的计算引擎的 C#/.NET 库。

版主注意:以上链接如被视为自我宣传,请删除。

于 2012-12-20T11:55:13.500 回答
-1

通用规则引擎效率的问题之一是总和组的重新计算等。假设您要计算增值税的总和。在您的发票事件中,某些产品发生了变化,并且增值税从一个变为另一个。现在最简单的解决方案是重新计算所有税款。但是我们可以想象一个聪明的解决方案,我们知道在给定的组中我们需要减去增值税金额并将其添加到另一个组。另一个问题是循环。我们可以要求我们的引擎在我们输入已付款字段时计算剩余的部分付款金额。在另一种情况下,如果我们将其输入到剩余付款字段中,我们将要计算已付款字段。这可以通过虚拟字段“用户输入了哪个字段”来完成,如果在规则中取决于它

于 2018-03-11T19:58:06.853 回答