优化求解器函数
Optimize a Solver function
我正在尝试设置一个 "Solver" 函数来将 "gfc" 的值优化为零,在下面的等式中改变(并找到)变量 "fc"。给出参数。
f0 = 6
f1 = 1
k = 2
ft = 0.3
gfc = ft-((f0-fc)/k)+((f1/k)*ln((fc-f1)/(f0-f1)))
在 Excel 上求解这个函数,我找到了 fc=5.504 的值。
我假设你的意思是你想求解 fc
的值,其中 gfc
等于零。我们假设 fc
位于 f0
和 f1
之间。在那种情况下,使用问题中的常量,我们有以下基本 R 解决方案。 (另外具有此类功能的软件包包括 nleqslv 和 rootSolve。)
1) 优化 我们可以最小化 gfc^2:
gfc <- function(fc) ft-((f0-fc)/k)+((f1/k)*log((fc-f1)/(f0-f1)))
optimize(function(x) gfc(x)^2, c(f0, f1))
给予:
$minimum
[1] 5.504383
$objective
[1] 4.777981e-12
2) uniroot 或者我们可以直接使用 uniroot
:
u <- uniroot(gfc, c(f0, f1))
给予:
> u
$root
[1] 5.504386
$f.root
[1] 6.72753e-09
$iter
[1] 5
$init.it
[1] NA
$estim.prec
[1] 6.103516e-05
3)我们也可以不用像optimize
或uniroot
那样直接改写
来解决这个问题
gfc(fc) = 0
因为我们已经将 gfc 的第一个术语移动到左侧,然后在那个术语中分离出 fc,将其他所有内容都放在右侧。
fc = f0 - k*(ft + ((f1/k)*log((fc-f1)/(f0-f1))))
写成:
fc = f(fc)
我们只是迭代 f。
f <- function(fc) f0 - k*(ft + ((f1/k)*log((fc-f1)/(f0-f1))))
fc <- (f0 + f1)/2 # starting value
for(i in 1:10) fc <- f(fc)
fc
## [1] 5.504386
4) brute force 另一种方法是在许多点上评估 gfc,然后只选择 gfc^2 最小的那个。区间细分得越细,答案越准确
s <- seq(f0, f1, length = 100000)
g <- gfc(s)
s[which.min(g^2)]
## [1] 5.504395
图形
我们可以展示解决方案:
curve(gfc, f0, f1)
abline(h = 0, v = u$root, lty = 2)
axis(1, u$root, round(u$root, 3))
您可以使用 uniroot
查找函数等于零的位置:
f0 = 6
f1 = 1
k = 2
ft = 0.3
gfc = function(fc) {
ft - ((f0 - fc) / k) + ((f1 / k) * log((fc - f1) / (f0 - f1)))
}
uniroot(gfc, interval = c(f0, f1))
#> $root
#> [1] 5.504386
#>
#> $f.root
#> [1] 6.72753e-09
#>
#> $iter
#> [1] 5
#>
#> $init.it
#> [1] NA
#>
#> $estim.prec
#> [1] 6.103516e-05
我正在尝试设置一个 "Solver" 函数来将 "gfc" 的值优化为零,在下面的等式中改变(并找到)变量 "fc"。给出参数。
f0 = 6
f1 = 1
k = 2
ft = 0.3
gfc = ft-((f0-fc)/k)+((f1/k)*ln((fc-f1)/(f0-f1)))
在 Excel 上求解这个函数,我找到了 fc=5.504 的值。
我假设你的意思是你想求解 fc
的值,其中 gfc
等于零。我们假设 fc
位于 f0
和 f1
之间。在那种情况下,使用问题中的常量,我们有以下基本 R 解决方案。 (另外具有此类功能的软件包包括 nleqslv 和 rootSolve。)
1) 优化 我们可以最小化 gfc^2:
gfc <- function(fc) ft-((f0-fc)/k)+((f1/k)*log((fc-f1)/(f0-f1)))
optimize(function(x) gfc(x)^2, c(f0, f1))
给予:
$minimum
[1] 5.504383
$objective
[1] 4.777981e-12
2) uniroot 或者我们可以直接使用 uniroot
:
u <- uniroot(gfc, c(f0, f1))
给予:
> u
$root
[1] 5.504386
$f.root
[1] 6.72753e-09
$iter
[1] 5
$init.it
[1] NA
$estim.prec
[1] 6.103516e-05
3)我们也可以不用像optimize
或uniroot
那样直接改写
gfc(fc) = 0
因为我们已经将 gfc 的第一个术语移动到左侧,然后在那个术语中分离出 fc,将其他所有内容都放在右侧。
fc = f0 - k*(ft + ((f1/k)*log((fc-f1)/(f0-f1))))
写成:
fc = f(fc)
我们只是迭代 f。
f <- function(fc) f0 - k*(ft + ((f1/k)*log((fc-f1)/(f0-f1))))
fc <- (f0 + f1)/2 # starting value
for(i in 1:10) fc <- f(fc)
fc
## [1] 5.504386
4) brute force 另一种方法是在许多点上评估 gfc,然后只选择 gfc^2 最小的那个。区间细分得越细,答案越准确
s <- seq(f0, f1, length = 100000)
g <- gfc(s)
s[which.min(g^2)]
## [1] 5.504395
图形
我们可以展示解决方案:
curve(gfc, f0, f1)
abline(h = 0, v = u$root, lty = 2)
axis(1, u$root, round(u$root, 3))
您可以使用 uniroot
查找函数等于零的位置:
f0 = 6
f1 = 1
k = 2
ft = 0.3
gfc = function(fc) {
ft - ((f0 - fc) / k) + ((f1 / k) * log((fc - f1) / (f0 - f1)))
}
uniroot(gfc, interval = c(f0, f1))
#> $root
#> [1] 5.504386
#>
#> $f.root
#> [1] 6.72753e-09
#>
#> $iter
#> [1] 5
#>
#> $init.it
#> [1] NA
#>
#> $estim.prec
#> [1] 6.103516e-05