2

実験値と理論値の誤差を最小限に抑えるために、Excel で 3 つのパラメーターを最適化しようとしています。for ループで、一度に 1 つずつ、各パラメーターに Solver を使用します。ただし、実験値と理論値の誤差が目標値よりも小さくなるまで、このソルバー for ループ (ループ内のループ) を繰り返したいと考えています。

私の実験値は$K25です。
私の理論値 (モデル方程式に基づいて計算) は$J$25です。
最適化する必要がある私のパラメーターは$C$4、、、$C$5$C$6

次の VBA コードを実行すると、、、のパラメーター が初期値から変更さ$C$4れません。ただし、マクロはエラーなしで正常にコンパイルされます。誰か助けてくれませんか?$C$5$C$6

コードは次のとおりです。

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
4

2 に答える 2

1

あなたが探しているのはまさにソルバーがすべきことなので、VBAでこれを行う必要があるかどうかはわかりません-他の何かが最大化/最小化されるようにパラメータのセットを変更してください!

したがって、必要なのは、数式=ABS(J25-K25)を別のセルに挿入することだけです。このセルには、実験値と理論値の間のデルタが表示されます。次に、3つのパラメーターを変更してこのセルを最小化するようにソルバーを設定します。これで、完了です。([可変セルを変更する]フィールドに複数のセルを指定できることに注意してください!)

あなたがあなたのアプローチに固執したい場合のために、ここに構文的に正しいコードがあります。私はそれをテストしていないことに注意してください-しかし、コードを調べることによって見つけた間違いを修正しただけです。うまくいけば、それは良い出発点になるでしょう。実際、このアプローチを見ると、各実行で最適化される変数は1つだけであるため、間違った結果になると確信しています。したがって、2つまたは3つのパラメーターの組み合わせから生じる影響を調べることはありません。 !!

とにかく、ここにあなたのコードがあります:

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
于 2013-02-20T20:09:58.227 に答える