C# 的计算引擎之类的东西?

发布于 2024-10-15 02:08:01 字数 733 浏览 7 评论 0原文

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));

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

进一步思考,如果字段/单元格支持更改通知,那就太棒了。

Is there any calculation engine for C# that can automatically recalculate dependent fields when a value changes?

Let me freestyle for a second, I'm imagining something like this..

 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>)

This would set up fields that auto-propagate dependent values.

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

Obviously this is a simple example, the end uses would be much more akin to the calculations of a complex spreadsheet.

Thinking further it would be amazing if the field/cells would support change notification.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

狼性发作 2024-10-22 02:08:01

您看过 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 &许多本地数据类型。如果您想更改语法,它会附带一个鹿角文件。还有一个支持 MEF 加载新功能的 fork。

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

解决方案

您可以通过实现 INotifyPropertyChanged 然后执行诸如

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

来自动重新计算。在类中的notifypropertyupdated 上,

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

Have you seen http://ncalc.codeplex.com ?

It's extensible, fast (e.g. has its own cache) enables you to provide custom functions and varaibles at run time by handling EvaluateFunction/EvaluateParameter events. Example expressions it can parse:

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());

It also handles unicode & many data type natively. It comes with an antler file if you want to change the grammer. There is also a fork which supports MEF to load new functions.

It also supports logical operators, date/time's strings and if statements.

a solution

You could possibly do automatic recalculation by implementing INotifyPropertyChanged then doing something like

  • set a field's expression this.Field.Expression = new Expression("Field1+Field2");

On notifypropertyupdated in the class

  • for each field (with reflection) that is a Function
  • if it's expression refers to the changed field then recalculate the variable.
  • on recalculation you'd need to handle the EvaluateParameter event to use reflection to find the right field and extract its value (you could cache to avoid reflection if needed)
王权女流氓 2024-10-22 02:08:01

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

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

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/ological-architecture-of -a-rule-based-calculation-framework/1053

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

版主注意:如属自我推销,请删除以上链接。

There are calculation engines for scalar parameters, and there are higher-level calculation engines for tables, typically used for applications like financial planning, fee and commission calculations, network and contract computations...

Let me explain this shortly. Consider following formulas for scalars:

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

and so on. Configuring such functions and dependency trees requires a calculation engine with scalar parameters. I would (also) recommend following link for such a calculation engine written in c# as a good starting point:
http://www.codeproject.com/Articles/246374/A-Calculation-Engine-for-NET

As mentioned, there are also calculation engines with table functions that take tables as parameters. The main principle is but the same:

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

and so on. Note that a table function can return multiple tables as outputs, as shown above.

There two key issues to be observed here:

a) The values of tables T7 and T8 depend on tables T2 and T4. Therefore, the tables T7 and T8 need to be updated by executing the function "TableFunction2" only if there is a change in one of the input parameters T2 or T4.

Similarly, T4 need to be updated only if T1, T2 or T3 is updated; dependency tree!

b) Separation of database from the calculation process: The calculation engine must work independent of any fixed data structure or database schema so that it can be integrated with any database and data structure.

You can find my related article where these principles are explained at:

Logical Architecture of a Rule-Based Calculation Framework
http://finaquant.com/logical-architecture-of-a-rule-based-calculation-framework/1053

Now, a C#/.NET library for a calculation engine with tables as input and output parameters is being developed based on these principles.

Note to moderators: Please delete the link above if it is counted as self-promotion.

甜柠檬 2024-10-22 02:08:01

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

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

你到底为什么问?

I asked a similar question here: Truly declarative language?

As far as I know not, only just heard about NCalc, I'll look into it. I have a project that does pretty much what you describe and then some like caching/ cache dropping on changes to values or model structure. Think f it as a crossover between a database and Excel. You can also define classes etc and link them together into large models with millions of objects in graphs, not just trees. Client server etc. Also there's a model editor where you create models in a UI so you can analyse how all the calculations build on each other.

Why exactly are you asking?

痴骨ら 2024-10-22 02:08:01

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

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

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

I would recommend to also give a look at Jace. Jace is a more modern calculation engine for the .NET framework. It is a lot faster then the above proposed NCalc. Furthermore it supports more platforms (.NET, WinRT, WP7 and WP8).

More information about Jace can be found on the GitHub page:
https://github.com/pieterderycke/Jace

NuGet link:
https://www.nuget.org/packages/Jace

浪漫人生路 2024-10-22 02:08:01

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

One of problems with generic rule engine efficiency is recalculation of sums groups etc. Imagine that you want to calculates sum of VAT taxes. In your invoice event appeared that some product changed and vat changed from one to another. Now the simples solution is to recalculate all taxes. But we could imagine smart solution that we know that in given group we need to subtract vat amount and add it to another group.
Another problem is cycles. We can have demand that our engine would calculate part of remaining to pay amount when we enter it into paid field. And in another case we would want to calculate paid field if we enter it into remaining to pay field. This could be done by virtual field "which field was entered by user" and if depending on it in the rule

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文