三分法求函式極值
??類似于二分法思想,三分演算法主要應用于求解非線性函式的極值問題,是一種通過不斷迭代,求得函式極值點近似解的演算法,
??如圖所示,已知函式f(x)在點left和點right中間存在一個極值點,現在我們的任務就是找到這個極值點或者計算函式在這個區間上的極值,在這里,與二分法圖片不同的是,mid點有左右兩個(都是三等分點)
分別記為midl和midr,則易得:
m
i
d
l
x
=
l
e
f
t
x
+
r
i
g
h
t
x
?
l
e
f
t
x
3
=
2
?
l
e
f
t
x
+
r
i
g
h
t
x
3
midl_{x} = left_{x}+ \frac{right_{x} - left_{x}}{3}=\frac{2*left_{x} + right_{x}}{3}
midlx?=leftx?+3rightx??leftx??=32?leftx?+rightx??
m
i
d
r
x
=
r
i
g
h
t
x
?
r
i
g
h
t
x
?
l
e
f
t
x
3
=
l
e
f
t
x
+
2
?
r
i
g
h
t
x
3
midr_{x} = right_{x}- \frac{right_{x} - left_{x}}{3}=\frac{left_{x} + 2*right_{x}}{3}
midrx?=rightx??3rightx??leftx??=3leftx?+2?rightx??
在進行迭代的時候,計算f(midl)和f(midr)并比較大小,發現有f(midl)>f(midr),說明midr距離極值點更近,因此應該將left點進行更新,如下圖所示,

?? 在經過若干次迭代之后,right-left會越來越小,并小于一個值eps,此時結束迭代,我們可以通過調整eps的大小控制極值點求解的精度,
??值得注意的是,我們應根據所求極值點(極大值/極小值)對判斷條件應做出相應調整,即求極大值時,當f(midl) > f(midr),說明左端點距離極大值點更近,因此應該更新right,
實作上圖的代碼(C語言)如下:
double th_division(double left, double right, double eps)
{ //求解極小值點
double midl, midr;
while (right - left > eps)
{
midl = (2 * left + right) / 3;
midr = (left + 2 * right) / 3;
if (f(midl) > f(midr)) // f是需要求的函式
left = midl;
else
right = midr;
}
return midl; //回傳近似極值點
}
例題: HDOJ 2438 Turn the corner
題目傳送門
??題目大意:給定一個轉角兩端的寬度X, Y,以及汽車的長度和寬度L, D,判斷汽車能否轉過這個角(理想化轉角),
??分析:判斷汽車左側所在直線與墻邊所在直線交點位置即可,關鍵在于建立數學方程,
實作代碼:
#include <cmath>
#include <iostream>
using namespace std;
const double eps = 1e-6;
const double pi = acos(-1.0);
double x, y, l, d;
double fun(double i)
{
return (x - l * sin(i) - d / cos(i)) / tan(i);
}
int main()
{
while (~scanf("%lf%lf%lf%lf", &x, &y, &l, &d))
{
double ll = 0, rr = pi / 2, midl, midr;
while (rr - ll > eps)
{
midl = (2 * ll + rr) / 3;
midr = (ll + 2 * rr) / 3;
if (fun(midl) < fun(midr))
rr = midr;
else
ll = midl;
}
if (fun(ll) > -y)
printf("yes\n");
else
printf("no\n");
}
}
??如有錯誤還請指出,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/250220.html
標籤:其他
上一篇:Adam優化演算法理解與實作
下一篇:牛頓法、擬牛頓法
