2012-11-28 33 views
0

我需要找到一種解決Chapman-Richards有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. 有沒有其他的方法來實現這個?

感謝您的提前回復。 kar

附錄: 對不起,我忘了提及t是時間變量。 a,b和c是解算器可以改變的參數。

+0

是't'恆定和'了','B','C'變量? –

回答

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

非常感謝您的回答,@AndersGustafsson。我會嘗試一下,並與Solver的結果進行比較。謝謝你的幫助! – user1860385

0

我解決了它與Visual Studio 2013和Visual Basic,有代碼的traslation。

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