solving the Chapman-Richards equation

社会主义新天地 提交于 2020-01-05 06:29:15

问题


I need to find a way to solve the Chapman-Richards with 3 parameters. The equation is

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

It is a nonlinear problem. The goal is to minimize the error and the constraints are that the 3 variables must be >= 0.0001. Our current implementation uses Excel and the Solver plugin (GRG nonlinear method). But now, we need to implement all this without making use of Excel.

My questions are: 1. Is it possible to use MS Solver Foundation to solve this problem? I have read some docs and understand that MS Solver Foundation uses either the Nelder Mead Solver or the hybrid local search solver to solve nonlinear problems. Does anyone know if my particular problem can be solved using these methods? And, will the results be same as using GRG nonlinear method of Excel's Solver addin?

  1. If not, is it possible to implement the GRG nonlinear method of Excel Solver?

  2. Is there any other way to implement this?

Thanks for your replies in advance. kar

Addendum: Sorry, I forgot to mention that t is the time variable. a, b, and c are the parameters which can be changed by the solver.


回答1:


Yes, it can be done with the Nelder-Mead solver in Solver Foundation. Here is some example code in C#. Just make sure you reference the Microsoft.Solver.Foundation assembly.

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



回答2:


I solved it with Visual Studio 2013 and Visual Basic, there is the traslation of the code.

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


来源:https://stackoverflow.com/questions/13609265/solving-the-chapman-richards-equation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!