問題描述:
給定函數,設計fibnacci算法,進退算法分別求在區間[0,3]上的極小值區間,要求區間長度不大於原始區間的
Fibnacci算法:
算法設計:
給定區間以及精度,函數
①預處理出一定數量的斐波那契數列,然後根據求解區間和求解精度得到計算次數n。因爲我們設定間隔兩個單位區間長度的時候結束,所以
②令
③判斷是否小於等於,如果是,則結束計算,得到結果區間,否則比較和
的大小,若,跳到④,否則跳到⑤。
④令.跳到③
⑤令.跳到③
代碼實現:
#include<bits/stdc++.h>
using namespace std;
int fib[40];
double f(double x){
return x*(x-1)+2;
}
void init(){
fib[0] = 1; fib[1] = 1; for(int i = 2; i < 40; ++i) fib[i] = fib[i-1] + fib[i-2];
}
void sol(double l, double r, double eps){
int s = 2*(r-l)/eps+1;
int n = 0;
while(fib[n+1] <= s) ++n;//獲取迭代次數
double lmid = r - (double)fib[n]/fib[n+1] * (r-l);
double rmid = l + (double)fib[n]/fib[n+1] * (r-l);
int ca = 0;
while(r-l > eps){
cout<<setprecision(4)<<fixed<<"test"<<++ca<<": l = "<<l<<" r = "<<r<<" lmid = "<<lmid<<" rmid:"<<rmid;
cout<<" f(lmid) = "<<f(lmid)<<" f(rmid) = "<<f(rmid)<<endl<<endl;
if(f(lmid) > f(rmid)){
l = lmid;
lmid = rmid;
rmid = l + r - lmid;
}
else{
r = rmid;
rmid = lmid;
lmid = l + r - rmid;
}
}
cout<<"\n result : \nl:"<<l<<" r:"<<r<<endl;
}
int main()
{
init();
double l, r;cout<<"輸入搜索區間:"; cin>>l>>r;
sol(l, r, (r-l)*0.09);
}
進退法:
ps: 這裏寫的進退法經過修改,在找到單峯但是不滿足精度的時候通過減少步長來繼續下降。不知道還算不算進退法:D
算法設計:
給定初始點,精度和函數,初始步長
①先確定很小的步數,比較和來確定下降方向,若,令,若,令,否則可確定爲滿足條件的區間,結束算法。
②令.如果,轉③,否則如果,已經找到滿足條件單峯區間,結束算法。如果,轉④
③令。轉②
④令。轉②
代碼實現:
#include<bits/stdc++.h>
using namespace std;
double f(double x){
return x*(x-1)+2;
}
void sol(double x0, double eps, double h0){
double dx = eps/100;
double x1, x2;
if(f(x0) < f(x0 + dx) && f(x0) < f(x0 - dx)) {
cout<<"結果區間爲:["<<x0-dx<<","<<x0+dx<<"]\n";return;
}
else if(f(x0) > f(x0 + dx)) dx = h0;
else dx = -h0;
int num = 0;
while(1){
num++;
x1 = x0 + dx; x2 = x1 + dx;
cout<<setprecision(3)<<fixed<<"x0 = "<<x0<<"\tx1 = "<<x1<<"\tx2 = "<<x2;
cout<<"\tf(x0) = "<<f(x0)<<"\tf(x1) = "<<f(x1)<<"\tf(x2) = "<<f(x2)<<endl;
if(f(x0) > f(x1) && f(x1) > f(x2)){
x0 = x1;
dx = dx*2.0;
continue;
}
else{
if(abs(x2-x0) > eps){
dx = dx/2.0;
}
else{
cout<<"迭代次數:"<<num<<endl;
cout<<"結果區間爲:["<<min(x0,x2)<<","<<max(x0, x2)<<"]\n";return;
}
}
}
}
int main()
{
double x0, e, h0;
cout<<"輸入初始點:";cin>>x0;
cout<<"輸入需求區間精度:";cin>>e;
cout<<"輸入初始步長:";cin>>h0;
sol(x0, e, 0.1);
}