用c#中的求解器翻译Excel电子表格

发布于 2025-02-13 04:48:23 字数 3881 浏览 0 评论 0原文

经过几次搜索和错误之后,我终于设法摆脱了它,并从MSF求解器那里得到了结果。

但是,这并不完美,因为我在C#代码中仍然对我有所不同。

在Excel Workbook中,我有6个求解器,相对相同。 每个选项卡只有一个求解器,但我有很多计算。

为了最好地坚持使用Excel Workbook,我每个包含一个公式的单元格创建了一种方法。 从某种意义上说,如果我给出与Excel相同的数据,我的代码有效,但是我的结果会产生相同的结果,但是求解器我有一点区别。

这是我所做的,我希望您告诉我是否有任何可以改进的方法,试图将我的方法(代表我的Excel单元)保持

两次(代表我的Excel单元)两次。 我需要拥有单元格的值来进行其他计算,似乎我无法将方法放入求解器中。

经典方法:

private double Cell_I5()
{
    double res = 0;
    res = (Math.Exp(-Var.Calc.Var4 * Var.Calc.De * M23) - 1) / (-Var.Calc.Var4 * Var.Calc.De * M23);
    return res;
}

求解器的方法:

private Term Solv_I5()
{
     Term res = 0;
     res = (Model.Exp(-Var.Calc.Var4 * Var.Calc.De * Solver_M23) - 1) / (-Var.Calc.Var4 * Var.Calc.De * Solver_M23);
     return res;
}

'M23'是双重 “ solver_m23”是一个决定 'var4'是双重和“ de”。 因此,我将返回值与“ term”一起使用,然后将所有数学功能更改为'模型',除了Math.pi是一个常数。

您可以想象,类似的方法接近60至70种方法。

我对求解器的方法:

public void StartSolver()
{
    var solver = SolverContext.GetContext();
    solver.ClearModel();
    var model = solver.CreateModel();
    //Instanciation des variables du Solver en format Real(double) Non Negative
    Solver_M22 = new Decision(Domain.RealNonnegative, "M22");
    Solver_M23 = new Decision(Domain.RealNonnegative, "M23");
    Solver_M24 = new Decision(Domain.RealNonnegative, "M24");
    Solver_M25 = new Decision(Domain.RealNonnegative, "M25");
    Solver_M26 = new Decision(Domain.RealNonnegative, "M26");

    model.AddDecision(Solver_M22);
    model.AddDecision(Solver_M23);
    model.AddDecision(Solver_M24);
    model.AddDecision(Solver_M25);
    model.AddDecision(Solver_M26);

    model.AddConstraint("M22a", Solver_M22 <= 4);
    model.AddConstraint("M22b", Solver_M22 >= 0);
    model.AddConstraint("M23a", Solver_M23 <= 2);
    model.AddConstraint("M23b", Solver_M23 >= 0.001);
    model.AddConstraint("M24a", Solver_M24 <= 2);
    model.AddConstraint("M24b", Solver_M24 >= 0);
    model.AddConstraint("M25a", Solver_M25 <= 2);
    model.AddConstraint("M25b", Solver_M25 >= 0);
    model.AddConstraint("M26a", Solver_M26 <= 2);
    model.AddConstraint("M26b", Solver_M26 >= 0.001);
    
    //Test with classical calculation methods
    double test = Cell_H33() + Cell_H23();

    //Adding Solver Methods
    model.AddGoal("SommeDesCarresDesEquartsGlobal", GoalKind.Minimize, Solv_H33() + Solv_H23());
    
    // Solve our problem
    var solution = solver.Solve();
    
    // Get our decisions
    M22 = Solver_M22.ToDouble();
    M23 = Solver_M23.ToDouble();
    M24 = Solver_M24.ToDouble();
    M25 = Solver_M25.ToDouble();
    M26 = Solver_M26.ToDouble();
    string s = solution.Quality.ToString();

    //For test
    double testSortie = Cell_H33() + Cell_H23();
    }

问题:

1) 在任何时候,我都会指出是否是线性计算。如果需要,如何指示? 在excel中,它被宣布为非线性 我看到求解器自己正在寻找最好的方法。

2) 我没有做对的事情,因为我没有相同的价值(使用Excel)?我几次检查了所有方法,也许我想念的金额,也许是什么,明天我会重新检查。

3) 除了使用经典方法进行计算之外,我还没有找到找到结果的方法。从“解决方案”对象 如果可能的话,如何从结果中提取它?

4) 这是我发现MSF C#的5个变量的结果: 0.06014756519010750 0.07283670953453890 0.07479568348101340 0.02864805010533950 0.00100000002842722

以及我发现的Excel求解器: 0.0000 0.0010 0.0141 0.0000 0.0010 有没有办法直接限制计算中的小数位数? 因为当我手动减少(计算之后)时会大大改变结果?

谢谢。

[编辑]忘记发布此消息仍在待处理。 今天早上,我再次运行了C#求解器计算,结果确实有所不同,结果差异很大。

我提醒您,我想最大程度地减少结果。 Excel = 3.92 c#= 8122.34

结果根本不可接受。

[编辑2] 我可能有一个线索:

当我进行简单的计算时,例如:

private Term Solv_I5()
{
     Term res = 0;
     res = Model.Exp(-Var.Calc.Var4 * Var.Calc.Den * Solver_M25);
     return res;
}

结果是:

{Exp(Times(-4176002161226263/70368744177664, M25))}

为什么“时间” 所有具有乘法的公式都包含时间。 对于分区,有“商”,加法“加”,但乘法”时间!!!

问题4) 我是否在“术语”中错误地做乘法? 你有主意吗?

[编辑3] 我只是看到“时代”不是一个愚蠢的术语,而是对我英语的另一个误解,对不起。

因此,这无法解决我的问题。

你能帮我吗

After several searches and mistakes on my part, I finally managed to get out of it and get a result from the MSF solver.

However, it's not perfect, because I still have a difference against me in my C# code.

In the Excel workbook I have 6 solvers, relatively identical.
Only one solver per tab, but I have a lot of calculations.

In order to best stick to the Excel workbook, I created one method per cell containing a formula.
My code works, in the sense that if I give it the same data as Excel I have the same results, but with the solver I have a little difference.

Here's what I did, and I'd like you to tell me if there's anything I can improve by trying to keep my methods (representing my Excel Cells)

Each representation of the cells is created twice.
I need to have the value of my cell to do other calculations and it seems that I can't put methods returning a double, in the solver.

Classic method:

private double Cell_I5()
{
    double res = 0;
    res = (Math.Exp(-Var.Calc.Var4 * Var.Calc.De * M23) - 1) / (-Var.Calc.Var4 * Var.Calc.De * M23);
    return res;
}

Method for the solver:

private Term Solv_I5()
{
     Term res = 0;
     res = (Model.Exp(-Var.Calc.Var4 * Var.Calc.De * Solver_M23) - 1) / (-Var.Calc.Var4 * Var.Calc.De * Solver_M23);
     return res;
}

'M23' is a double
'Solver_M23' is a Decision
'Var4' is a double as well as 'De'.
So I use the return value with "Term" and I change all the Math functions to 'Model', except Math.Pi which is a constant.

You can imagine that there are close to 60 to 70 methods involved like that.

My method for the solver:

public void StartSolver()
{
    var solver = SolverContext.GetContext();
    solver.ClearModel();
    var model = solver.CreateModel();
    //Instanciation des variables du Solver en format Real(double) Non Negative
    Solver_M22 = new Decision(Domain.RealNonnegative, "M22");
    Solver_M23 = new Decision(Domain.RealNonnegative, "M23");
    Solver_M24 = new Decision(Domain.RealNonnegative, "M24");
    Solver_M25 = new Decision(Domain.RealNonnegative, "M25");
    Solver_M26 = new Decision(Domain.RealNonnegative, "M26");

    model.AddDecision(Solver_M22);
    model.AddDecision(Solver_M23);
    model.AddDecision(Solver_M24);
    model.AddDecision(Solver_M25);
    model.AddDecision(Solver_M26);

    model.AddConstraint("M22a", Solver_M22 <= 4);
    model.AddConstraint("M22b", Solver_M22 >= 0);
    model.AddConstraint("M23a", Solver_M23 <= 2);
    model.AddConstraint("M23b", Solver_M23 >= 0.001);
    model.AddConstraint("M24a", Solver_M24 <= 2);
    model.AddConstraint("M24b", Solver_M24 >= 0);
    model.AddConstraint("M25a", Solver_M25 <= 2);
    model.AddConstraint("M25b", Solver_M25 >= 0);
    model.AddConstraint("M26a", Solver_M26 <= 2);
    model.AddConstraint("M26b", Solver_M26 >= 0.001);
    
    //Test with classical calculation methods
    double test = Cell_H33() + Cell_H23();

    //Adding Solver Methods
    model.AddGoal("SommeDesCarresDesEquartsGlobal", GoalKind.Minimize, Solv_H33() + Solv_H23());
    
    // Solve our problem
    var solution = solver.Solve();
    
    // Get our decisions
    M22 = Solver_M22.ToDouble();
    M23 = Solver_M23.ToDouble();
    M24 = Solver_M24.ToDouble();
    M25 = Solver_M25.ToDouble();
    M26 = Solver_M26.ToDouble();
    string s = solution.Quality.ToString();

    //For test
    double testSortie = Cell_H33() + Cell_H23();
    }

Questions:

1)
At no time do I indicate whether it is a linear calculation or not. How to indicate if necessary?
In Excel it is declared nonlinear
I saw that the solver was looking for the best method on its own.

2)
Is there something I'm not doing right, because I don't have the same value (with Excel)? I checked several times all the methods by one, with the amount that I missed, maybe, something, I will recheck tomorrow.

3)
Apart from doing the calculation with the classic methods, I have not found a way to find my result. From the 'solution' object
How to extract it from the result if possible?

4)
Here is the result of the 5 variables I find MSF C#:
0.06014756519010750
0.07283670953453890
0.07479568348101340
0.02864805010533950
0.00100000002842722

And what I find the Excel solver:
0.0000
0.0010
0.0141
0.0000
0.0010
Is there a way to restrict the number of decimal places directly in the calculations?
Because when I reduce manually (after calculation) that changes my result quite a bit?

Thank you.

[EDIT] Forgot to post this message it was still pending.
This morning I ran the C# solver calculation again and the result is really different with a huge difference in the result.

I remind you that I want to minimize the result.
Excel = 3.92
C#=8122.34

Result not acceptable at all.

[EDIT 2]
I may have a clue:

When I doing a simple calculation, such as:

private Term Solv_I5()
{
     Term res = 0;
     res = Model.Exp(-Var.Calc.Var4 * Var.Calc.Den * Solver_M25);
     return res;
}

the result is:

{Exp(Times(-4176002161226263/70368744177664, M25))}

Why "Times"
All formulas with multiplication contain Times.
For divisions there is 'Quotient', additions 'Plus', but multiplications 'Times !!!

Question 4)
Am I doing the multiplications wrong in a 'Term'.?
Do you have an idea?

[EDIT 3]
I just saw that "times" was not a stupid term, another misunderstanding on my part of the English language, sorry.

So that doesn't solve my problem.

Can you help me please.

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文