优化求解器函数

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 位于 f0f1 之间。在那种情况下,使用问题中的常量,我们有以下基本 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)我们也可以不用像optimizeuniroot那样直接改写

来解决这个问题
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