我需要找到一种方法来解决Chapman-Richards的3个参数。等式是
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非线性方法相同?
如果没有,是否可以实现Excel Solver的GRG非线性方法?
还有其他方法可以实现吗?
感谢您提前回复。 KAR
附录: 对不起,我忘了提到t是时间变量。 a,b和c是解算器可以更改的参数。
答案 0 :(得分: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);
}
答案 1 :(得分: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