求凸函数极值 CSF迭代法(雾)
簡介
本算法用來求解凸函數極值點的問題,由我在寫ACM習題時想到,在網上并未找到這樣的算法,拿出來給大家分享一下,如果網上沒有的話,我決定給它起名叫做 CSF迭代法,如果這個算法早已經存在,那就當看個笑話吧。
by 蔡少斐 西安交大 軟件53
算法步驟
先從定義域[l,r]中等差地取出n個點,x1,x2,...,xn。
x1=l+(r?l)n+1,xi=xi?1+r?ln+1
計算f(x1),...,f(xn),挑選出使得f(xt)最大的點xt。
把定義域縮小到[xt?1,xt+1],執行2。
x0=l,xn+1=r
輸出xt
算法證明
用反證法:假設存在一次迭代,使得極值點不在[xt?1,xt+1]里面,那么設這個極值點為xp,并且有xp>xt+1,那么可以知道區間[xt?1,xt+1]是單調遞增的。也就是說f(xt+1)>f(xt),因此我們在算法的第2個步驟時將選擇xt+1而不是xt,矛盾。
因而極值一定在我們所迭代的區間內。
算法復雜度分析
設區間長度為len,劃分粒度為n,精度要求為eps,遞歸深度為dep
可以列出遞歸方程如下:
T(len)=n+T(len(n+1)/2)
其中滿足方程:
(2n+1)deplen=eps
解得:
O(len)=nlogepslen2n+1
特殊性
如果令劃分粒度n=2的話,等價于三分算法。
算法實現
double csf(double l,double r,int n = 2,double eps = 0.001){ static const double INF = 1e9;double x;while(r - l > eps){double step = (r-l)/(n+1);double mx = -INF;for(double i = l+step;i < r;i += step) if(mx < f(i)) mx = f(i),x = i;l = x-step;r = x+step;}return x; }參數分析
函數總共有4個參數l,r,n,eps,其中有3個參數l,r,eps都是給定的。
總是選取l=?10000000,r=10000000
當選取eps=0.001時候
當選取eps=0.000001的時候
結論
n選取4或6<script type="math/tex" id="MathJax-Element-37">6</script>的時候函數效果較好。
實驗代碼
#include <bits/stdc++.h> using namespace std; double f(double x){return -(x-5)*(x-786); } int cnt; double csf(double l,double r,int n = 2,double eps = 0.001){ static const double INF = 1e9;double x;while(r - l > eps){double step = (r-l)/(n+1);double mx = -INF;for(double i = l+step;i < r;i += step) if(mx < f(i)) mx = f(i),x = i,cnt++;l = x-step;r = x+step;}return x; } int main(){freopen("1.csv","w",stdout);for(int i = 2;i <= 100;i+=1) {cnt = 0;double x = csf(-10000000,10000000,i,0.000001);printf("%d,%d\n",i,cnt);}return 0; }總結
以上是生活随笔為你收集整理的求凸函数极值 CSF迭代法(雾)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《先驱者》游戏开发商正和微软 Xbox
- 下一篇: codeforces National