在Excel中使用Solver的VBAmacros优化不返回最佳variables

我试图在Excel中优化三个参数,以最小化实验值和理论值之间的误差。 我使用求解器为每个参数,一个一个,在一个for循环。 但是,我想迭代这个求解器的循环(循环内的循环),直到实验值的误差和理论值小于某个目标值。

我的实验值是$K25
我的理论价值(根据我的模型方程计算)是$J$25
我需要优化的参数是$C$4$C$5$C$6

当我运行下面的VBA代码时, $C$4$C$5$C$6不会改变它们的初始值。 但是,macros编译没有错误。 有人可以帮我从这里出去吗?

这里是代码:

 Sub Macro3() Application.ScreenUpdating = False SolverReset Dim j As Integer For j = 1 To 100 Step 1 If "$J$25" > "$K$25" Then Dim i As Integer, s As String For i = 4 To 6 Step 1 s = Format(i, "0") SolverOk SetCell:="$J$25", MaxMinVal:=2, ValueOf:=0, ByChange:="$C$" & s, Engine:= _ 1, EngineDesc:="GRG Nonlinear" SolverOptions MaxTime:=0, Iterations:=1000000, Precision:=0.000001, Convergence _ :=0.00001, StepThru:=False, Scaling:=True, AssumeNonNeg:=True, Derivatives:=1 SolverOptions PopulationSize:=100, RandomSeed:=0, MutationRate:=0.075, Multistart _ :=False, RequireBounds:=True, MaxSubproblems:=0, MaxIntegerSols:=0, _ IntTolerance:=1, SolveWithout:=False, MaxTimeNoImp:=30 SolverOk SetCell:="$J$25", MaxMinVal:=2, ValueOf:=0, ByChange:="$C$" & s, Engine:= _ 1, EngineDesc:="GRG Nonlinear" SolverSolve (True) SolverReset Next i End If Next j Application.ScreenUpdating = True End Sub 

我不确定你需要在VBA中这样做,因为你正在寻找的东西正是Solver应该做的 – 修改一组参数,以便其他的东西被最大化/最小化!

因此,您只需在另一个单元格中插入公式=ABS(J25-K25) 。 这个单元格会显示你的实验值和理论值之间的差值。 现在设置你的Solver,通过改变你的三个参数来最小化这个单元格 – 你就完成了! (请注意,您可以在“通过更改variables单元格”字段中提供多个单元格!)

如果你想坚持你的方法,这里是语法正确的代码。 请注意,我没有对它进行testing – 但只是通过查看代码来纠正我可以发现的错误。 这将是一个很好的起点。 事实上,看着这种方法,我相信你最终会得到错误的结果,因为每个运行只优化一个variables – 因此,你将永远不会看到由两个或三个参数!

无论如何,这是你的代码:

 Sub RunSolver() Dim j As Integer, i As Integer Application.ScreenUpdating = False SolverReset For j = 1 To 100 Application.Statusbar = j & "/100" If Range("$J$25") > Range("$K$25") Then For i = 4 To 6 SolverOk SetCell:=Range("$J$25"), MaxMinVal:=2, ValueOf:=0, ByChange:=Range("$C$" & i), Engine:= _ 1, EngineDesc:="GRG Nonlinear" SolverOptions MaxTime:=0, Iterations:=1000000, Precision:=0.000001, Convergence _ :=0.00001, StepThru:=False, Scaling:=True, AssumeNonNeg:=True, Derivatives:=1 SolverOptions PopulationSize:=100, RandomSeed:=0, MutationRate:=0.075, Multistart _ :=False, RequireBounds:=True, MaxSubproblems:=0, MaxIntegerSols:=0, _ IntTolerance:=1, SolveWithout:=False, MaxTimeNoImp:=30 SolverSolve (True) SolverReset Next i End If Next j Application.StatusBar = False Application.ScreenUpdating = True End Sub 

你可以仔细检查你的代码行:

 Engine:= 1, EngineDesc:="GRG Nonlinear" 

根据MS文档 :

  • 1为Simplex LP方法,
  • 2为GRG非线性方法,或者
  • 3为进化方法。

很可能,您的目标函数是非线性的 ,因为您在EngineDesc参数下提到它,所以您认为您正在使用GRG非线性求解器。 这是不正确的。 这只是一个描述参数。

你实际使用的求解器是Simplex LP ,其值为1

更改为2以使用GRG非线性求解器