Оптимизировать функцию Солвера - PullRequest
2 голосов
/ 04 июля 2019

Я пытаюсь настроить функцию «Солвер», чтобы оптимизировать значение «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.

Ответы [ 2 ]

2 голосов
/ 04 июля 2019

Вы можете использовать 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
2 голосов
/ 04 июля 2019

Я предполагаю, что вы имеете в виду, что вы хотите найти значение 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 в LHS, а затем изолировали fc в этом термине, поместив все остальное в RHS.

 fc = f0 - k*(ft + ((f1/k)*log((fc-f1)/(f0-f1))))

Запись этого как:

fc = f(fc)

мы просто итерируем е.

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) Грубая сила Другой подход - оценить 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))

enter image description here

...