简体   繁体   English

有没有办法限制“寻求目标”? 如果没有,您将如何处理?

[英]Is there a way to put bounds on Goal Seek? If not, how would you go about this?

I'm trying to minimize the value of the sum of the residuals squared by varying the value of De, which is found in F1. 我试图通过改变在F1中找到的De的值来最小化残差平方和的值。 I want the values of CFL Calculated to be as close as possible to the values of CFL Measured. 我希望“计算的CFL”的值尽可能接近“测量的CFL”的值。 The smaller the sum of those residuals squared, the better the fit! 这些残差的平方和越小,拟合度越好! After asking stackoverflow for some advice, I decided to use Goal Seek to minimize the sum of the residuals squared to get as close to zero as possible by varying the value of De, which I want to find the most ideal value of. 在向stackoverflow提出了一些建议之后,我决定使用Goal Seek通过改变De的值来最小化残差平方和,以使其尽可能接近零,我想找到De的最理想值。

I got this program to run perfectly, or so I thought... I found out that instead of summing every single residuals using =SUM(D2:D14) , I accidentally used =SUM(D2,D14) . 我使该程序完美运行,或者我想……我发现,我没有使用=SUM(D2:D14)对每个残差求和,而是不小心使用了=SUM(D2,D14) So I was only summing up the first and last numbers. 所以我只是总结第一个和最后一个数字。

Now that I'm trying to sum every residual squared up, I'm getting these crazy errors, and an insane value for De. 现在,我试图对所有残差平方求和,得到这些疯狂的错误以及De的疯狂值。

I know that the value of De has to be greater than zero, and less than one. 我知道De的值必须大于零且小于一。 how can I use these bounds to keep this goal seek focused within a certain range? 我如何利用这些界限将目标寻求保持在一定范围内? The answer for De in this case is about .012, if that helps. 如果有帮助,在这种情况下,De的答案约为0.012。 I keep getting the error #NUM! 我不断收到错误#NUM! in all of the residual cells. 在所有剩余的细胞中。 Is this because of overflow issues? 这是因为溢出问题吗?

If you've concluded that using Goal Seek to minimize these sums by finding the most ideal value of De will not work, how would you go about it? 如果您得出结论,使用目标寻求通过找到De的最理想值来最小化这些总和是行不通的,您将如何处理? Are there any other solvers I could use? 我还可以使用其他求解器吗?

Here is the code: 这是代码:

Option Explicit

Dim Counter As Long
Dim DeSimpleFinal As Double
Dim simpletime As Variant
Dim Tracker As Double
Dim StepAmount As Double
Dim Volume As Double
Dim SurfArea As Double
Dim pi As Double
Dim FinalTime As Variant
Dim i As Variant

Sub SimpleDeCalculationNEW()

    'This is so you can have the data and the table I'm working with!
    Counter = 13
    Volume = 12.271846
    SurfArea = 19.634954
    pi = 4 * Atn(1)
    Range("A1") = "Time(days)"
    Range("B1") = "CFL(measured)"
    Range("A2").Value = 0.083
    Range("A3").Value = 0.292
    Range("A4").Value = 1
    Range("A5").Value = 2
    Range("A6").Value = 3
    Range("A7").Value = 4
    Range("A8").Value = 5
    Range("A9").Value = 6
    Range("A10").Value = 7
    Range("A11").Value = 8
    Range("A12").Value = 9
    Range("A13").Value = 10
    Range("A14").Value = 11
    Range("B2").Value = 0.0612
    Range("B3").Value = 0.119
    Range("B4").Value = 0.223
    Range("B5").Value = 0.306
    Range("B6").Value = 0.361
    Range("B7").Value = 0.401
    Range("B8").Value = 0.435
    Range("B9").Value = 0.459
    Range("B10").Value = 0.484
    Range("B11").Value = 0.505
    Range("B12").Value = 0.523
    Range("B13").Value = 0.539
    Range("B14").Value = 0.554

    Range("H2").Value = Volume
    Range("H1").Value = SurfArea

    Range("C1") = "CFL Calculated"
    Range("D1") = "Residual Squared"
    Range("E1") = "De value"
    Range("F1").Value = 0.1

    'Inserting Equations
    Range("C2") = "=((2 * $H$1) / $H$2) * SQRT(($F$1 * A2) / PI())"
    Range("C2").Select
    Selection.AutoFill Destination:=Range("C2:C" & Counter + 1), Type:=xlFillDefault

    Range("D2") = "=((ABS(B2-C2))^2)"
    Range("D2").Select
    Selection.AutoFill Destination:=Range("D2:D" & Counter + 1), Type:=xlFillDefault

    'Summing up the residuals squared
    Range("D" & Counter + 2) = "=Sum(D2: D" & Counter + 1 & ")"

    'Goal Seek
    Range("D" & Counter + 2).GoalSeek Goal:=0, ChangingCell:=Range("F1")

    Columns("A:Z").EntireColumn.EntireColumn.AutoFit

    DeSimpleFinal = Range("F1")    
    MsgBox ("The Final Value for DeSimple is: " & DeSimpleFinal)

End Sub

You're getting NUM errors because the value of F1 is going negative in your current solution -- and you are trying to take the square root of F1 in one of your expressions. 您会收到NUM个错误,因为在当前解决方案中F1的值将变为负数,并且您试图在其中一个表达式中采用F1的平方根。

Also, goal seek is, in this instance, incredibly sensitive to the particular initial starting "guess" for F1 that you are using. 同样,在这种情况下,目标搜索对您正在使用的F1的特定初始开始“猜测”非常敏感。 This will be evident if you vary the F1 initial value by a little bit on either side of the 0.1 you are using now. 如果您在现在使用的0.1的任一侧稍微改变F1初始值,这将很明显。 There are, in fact, large regions of instability in the goal seek solution, depending on the F1 value: 实际上,根据F1值,目标寻求解决方案中存在很大的不稳定区域:

目标寻求不稳定

As you brought up in your question, you are more likely to get a useable result if you can set constraints on the possible inputs to your solution search. 在提出问题时,如果可以对解决方案搜索的可能输入设置约束,则更有可能获得可用的结果。 Excel comes with an add-in called Solver that allows that, as well as offers several different search methods. Excel带有一个称为Solver的加载项,它允许这样做,并提供几种不同的搜索方法。 Solver is not loaded automatically when you first start Excel, but loading it is easy, as explained here . 求解时自动加载当你第一次启动Excel,但加载它是容易的,因为解释在这里

You ask for other solvers. 您要求其他求解器。 For alternatives and a bit of theory to help understand what's going on, have a look at Numerical Recipes (online books here ). 有关替代方法和一些理论来帮助您了解正在发生的事情,请查看数字食谱此处是在线书籍)。 Chapter 10 deals with this. 第10章讨论了这一点。 It includes ready-made code samples if you want to try something different than GoalSeek or the Solver add-in. 如果您想尝试使用不同于GoalSeek或Solver加载项的方法,它包括现成的代码示例。 Of course the code is in Fortran/C/C++ but these are readily translated into VBA (I've done this many times). 当然,代码是用Fortran / C / C ++编写的,但是它们很容易转换为VBA(我已经做过很多次了)。

The goalseek function uses a dichotomy algorithm which can be coded like this: Goaleek函数使用二分法算法,可以这样编码:

Sub dicho(ByRef target As Range, ByRef modif As Range, ByVal targetvalue As Double, ByVal a As Double, ByVal b As Double)

Dim i As Integer
Dim imax As Integer
Dim eps As Double

eps = 0.01
imax = 10
i = 0
While Abs(target.Value - targetvalue) / Abs(targetvalue) > eps And i < imax

    modif.Value = (a + b) / 2
    If target.Value - targetvalue > 0 Then
        a = (a + b) / 2
    Else
        b = (a + b) / 2
    End If
    i = i + 1
Wend
End Sub

Where a and b are you bounds. a和b是您的界线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM