斐波那契(Fibonacci)迭代法求解函数极值(附代码)

目录

Fibonacci数列:

迭代公式:

算法步骤:

例题

C++代码:


Fibonacci数列又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,Fibonacci迭代法可以求解函数零点、函数极值等,本文用c++语言实现Fibonacci迭代法求解函数极值。

Fibonacci数列:

                                     \left\{\begin{matrix} F_{0}=F{1}=1\\ F_{i+1}=F_{i-1}+F_{i},i=1,2,... \end{matrix}\right.

迭代公式:

                        \left\{\begin{matrix} \lambda _{k}=a_{k}+\frac{F_{n-k-1}}{F_{n-k+1}}(b_{k}-a_{k}),k=1,2,...,n-1\\ \mu _{k}=a_{k}+\frac{F_{n-k}}{F_{n-k+1}}(b_{k}-a_{k}),k=1,2,...,n-1 \end{matrix}\right.

算法步骤:

step1.给定初始搜索区间[a_{1},b_{1}]和允许误差\varepsilon,辨别系数\delta> 0,求解迭代次数n,使

                                        F_{n}\geqslant \frac{b_{1}-a_{1}}{\varepsilon }

step2.计算初始值

                                \left\{\begin{matrix} \lambda _{1}=a_{1}+\frac{F_{n-2}}{F_{n}}(b_{1}-a_{1})\\\mu _{1}=a_{1}+\frac{F_{n-1}}{F_{n}}(b _{1}-a_{1})\\f_{\lambda }=f(\lambda _{1})\\f_{\mu }=f(\mu _{1}) \end{matrix}\right.

step3.开始循环k=k+1,转step4,若k>=n-2则退出循环,转step7.

step4 判断f_{\lambda }<f_{\mu }?,是转step5,否转step6;

step5.令

               a_{k+1}=a_{k},b_{k+1}=\mu _{k},\mu _{k+1}=\lambda _{k},f_{\mu }=f_{\lambda }

               \lambda _{k+1}=a_{k+1}+\frac{F_{n-k-2}}{F_{n-k}}(b_{k+1}-a_{k+1})

               f_{\lambda }=f(\lambda _{k +1})

step6.令

               a_{k+1}=\lambda _{k},b_{k+1}=b _{k},\lambda _{k+1}=\mu _{k},f_{\lambda }=f_{\mu }

               \mu _{k+1}=a_{k+1}+\frac{F_{n-k-1}}{F_{n-k}}(b_{k+1}-a_{k+1})

               f_{\mu }=f(\mu _{k +1})

step7.令

          \lambda _{n}=\lambda _{n-1}\mu _{n}=\lambda _{n-1}+\delta

          判断f_{\lambda_{n} }<f_{\mu_{n} }?,是,极小点所在的区间为[a _{n-1},\mu _{n}];否,极小点所在的区间为[\lambda _{n},b _{n-1}]

          极值点为:                                                                   

                         f_{min}=(f_a_{n} +f_b_{n})/2

例题

求解函数f(x)=x^{2}-x+2在区间[-1,3]上的极小点,要求求解的区间不大于原始区间长度的0.0008倍。

程序求解结果如图:

 

C++代码:

#include <iostream>
#include <vector>
#include <iomanip> 
using namespace std;
double fx(double x)
{
	double fx;
	fx = pow(x, 2) - x + 2;
	return fx;
}
int main()
{
	double epsilon = 0.08, f_min;
	vector<double>fn(2);
	fn[0] = 1; fn[1] = 1;
	int i;
	double a_fib = -1.0, b_fib = 3.0, f_lambda = 0, f_mu = 0;
	for (i = 2; fn[i - 1] < 1.0 / epsilon; i++)
	{
		fn.push_back(fn[i - 2] + fn[i - 1]);
	}
	int n_fib = i - 1;
	cout <<"n取值:    "<< n_fib <<endl << endl;
	double lambda = a_fib + (fn[n_fib - 2] / fn[n_fib])*(b_fib - a_fib), mu = a_fib + (fn[n_fib -1] / fn[n_fib])*(b_fib - a_fib);
	f_lambda = fx(lambda);
	f_mu = fx(mu);
	cout << "区间迭代:  " <<  endl;
	for (int i = 0; i < n_fib-2; i++)
	{
		if ( f_lambda<f_mu)
		{
			a_fib = a_fib, b_fib = mu, mu = lambda, f_mu = f_lambda;
			lambda = a_fib + (fn[n_fib - i - 3] / fn[n_fib-1 - i])*(b_fib - a_fib);
			f_lambda = fx(lambda);
		}
		else
		{
			a_fib = lambda, b_fib = b_fib, lambda = mu, f_lambda = f_mu;
			mu = a_fib + (fn[n_fib - i - 2] / fn[n_fib -1-i])*(b_fib - a_fib);
			f_mu = fx(mu);
		}
		cout << fixed << setw(12) << setprecision(5) << a_fib << fixed << setw(12) << setprecision(5) << lambda << fixed << setw(12) << setprecision(5) << mu << fixed << setw(12) << setprecision(5) << b_fib << endl;
	}
	mu = lambda + 0.001;
	f_mu = fx(mu);
	if (f_lambda < f_mu)
	{
		a_fib = a_fib, b_fib = mu,f_min=0.5*(fx(a_fib)+fx(b_fib));
	}
	else 
	{
		a_fib = lambda, b_fib = b_fib, f_min = 0.5*(fx(a_fib) + fx(b_fib));

	}
	cout << endl << "极小值区间:" << fixed << setw(9) << setprecision(5) << a_fib << fixed << setw(12) << setprecision(5) << b_fib << endl;
	cout << "极小值:  " << fixed << setw(12) << setprecision(5) << f_min << endl;
}

 

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值