1

我需要找到一种方法来解决具有 3 个参数的 Chapman-Richards。方程是

F=a(1-EXP(-bt)) power c

这是一个非线性问题。目标是最小化误差,约束是 3 个变量必须 >= 0.0001。我们当前的实现使用 Excel 和 Solver 插件(GRG 非线性方法)。但是现在,我们需要在不使用 Excel 的情况下实现这一切。

我的问题是: 1. 是否可以使用 MS Solver Foundation 来解决这个问题?我已经阅读了一些文档并了解 MS Solver Foundation 使用 Nelder Mead Solver 或混合局部搜索求解器来解决非线性问题。有谁知道我的特定问题是否可以使用这些方法解决?而且,结果是否与使用 Excel 的 Solver 插件的 GRG 非线性方法相同?

  1. 如果没有,是否可以实现Excel Solver的GRG非线性方法?

  2. 还有其他方法可以实现吗?

感谢您提前回复。卡尔

附录:对不起,我忘了说 t 是时间变量。a、b 和 c 是求解器可以更改的参数。

4

2 回答 2

0

我用 Visual Studio 2013 和 Visual Basic 解决了它,有代码的翻译。

Private Sub NelderMead()
    Dim Solver As New Microsoft.SolverFoundation.Solvers.NelderMeadSolver

    Dim objId As Integer
    Solver.AddRow("obj", objId)
    Solver.AddGoal(objId, 0, True)

    Dim aId, bId, cId As Integer
    Solver.AddVariable("a", aId)
    Solver.AddVariable("b", bId)
    Solver.AddVariable("c", cId)

    Solver.SetLowerBound(aId, 0.001)
    Solver.SetLowerBound(bId, 0.001)
    Solver.SetLowerBound(cId, 0.001)

    Solver.FunctionEvaluator = AddressOf FunctionValue

    Dim Par As New Microsoft.SolverFoundation.Solvers.NelderMeadSolverParams
    Dim Solucion = Solver.Solve(Par)

    Debug.Print(Solucion.Result)
End Sub

Function FunctionValue(Model As Microsoft.SolverFoundation.Services.INonlinearModel, _
                       rowVid As Integer, _
                       Values As Microsoft.SolverFoundation.Services.ValuesByIndex, _
                       newValues As Boolean) As Object
    Dim a, b, c As Double

    a = Values(Model.GetIndexFromKey("a"))
    b = Values(Model.GetIndexFromKey("b"))
    c = Values(Model.GetIndexFromKey("c"))

    Return a * Math.Pow(1.0 - Math.Exp(-b * t), c)
End Function
于 2015-01-16T23:36:16.180 回答
0

是的,可以使用Solver Foundation 中的Nelder-Mead求解器来完成。这是 C# 中的一些示例代码。只需确保您引用了Microsoft.Solver.Foundation程序集。

    private const double t = 1.0;

    public static void Main()
    {
        var solver = new NelderMeadSolver();

        // Objective function.
        int objId;
        solver.AddRow("obj", out objId);
        solver.AddGoal(objId, 0, true);

        // Define variables.
        int aId, bId, cId;
        solver.AddVariable("a", out aId);
        solver.AddVariable("b", out bId);
        solver.AddVariable("c", out cId);

        // Define bounds.
        solver.SetLowerBound(aId, 0.001);
        solver.SetLowerBound(bId, 0.001);
        solver.SetLowerBound(cId, 0.001);

        // Assign objective function delegate.
        solver.FunctionEvaluator = FunctionValue;

        // Solve.
        var param = new NelderMeadSolverParams();
        var solution = solver.Solve(param);

        Console.WriteLine("The Result is " + solution.Result + ".");
        Console.WriteLine("The minimium objective value is " + 
                          solution.GetValue(objId) + ".");
        Console.WriteLine("a = " + solution.GetValue(aId) + ".");
        Console.WriteLine("b = " + solution.GetValue(bId) + ".");
        Console.WriteLine("c = " + solution.GetValue(cId) + ".");

        Console.ReadKey();
    }

    private static double FunctionValue(INonlinearModel model, int rowVid,
         ValuesByIndex values, bool newValues)
    {
        var a = values[model.GetIndexFromKey("a")];
        var b = values[model.GetIndexFromKey("b")];
        var c = values[model.GetIndexFromKey("c")];

        return a * Math.Pow(1.0-Math.Exp(-b * t), c);
    }
于 2012-11-29T14:11:11.623 回答