基于c++的最优化算法之一维搜索(斐波那契法+黄金分割0.618法)【完整代码】

目录

一、理论概述

二、完整源码

三、温馨提示


一、理论概述

        由于算法的理论太简单了,这里不再重复了,不清楚的小伙伴们可以去看下面的几篇博客,有详细的算法理论原理讲解

        1. https://blog.csdn.net/weixin_44044411/article/details/88091024

        2. 【优化】一维搜索方法

二、完整源码

        源码富有详细的注释,这里不再重复

2.1 斐波那契法

// 使用 斐波那契法 求函数的极小值
#include <iostream>
using namespace std;
#define A 0.0			// 索索的区间左端点
#define B 10.0			// 索索的区间右端点
#define e ((B - A)*0.03)	// 需要满足的区间精度
#define Fun12(x) (x * x - 6 * x + 2)  // 第十二题的函数表达式

int Fibonacci(int n) {	// 使用递归求斐波那契数列
	return (n < 2) ? 1 : Fibonacci(n - 1) + Fibonacci(n - 2);
}

int main() {
	cout << "// 使用 斐波那契法 求函数的极小值\n";
	int n = 1;	while (Fibonacci(n++) < 2 /e); n--;	// 满足精度的n
	double λ1 = A + (B - A) * (double)Fibonacci(n - 2) / Fibonacci(n);
	double λ2 = A + (B - A) * (double)Fibonacci(n - 1) / Fibonacci(n);
	cout <<"初始的F(n);"<< Fibonacci(n) << endl;
	double l1 = A, l2 = B;		// 迭代的两个端点值 a,b 
	while (λ2 - λ1 > e)			// 是否满足精度要求
	{
		if (Fun12(λ1) < Fun12(λ2)) {
			cout << "f(" << λ1 << ") < f(" << λ2 << ") " << endl;
			l2 = λ2;	λ2 = λ1;	λ1 = l2 + l1 - λ2;
		}
		else {
			cout << "f(" << λ1 << ") > f(" << λ2 << ") " << endl;
			l1 = λ1;	λ1 = λ2;	λ2 = l2 + l1 - λ1;
		}
		cout << "\tl1 = " << l1 << ", λ1 =" << λ1 << " , λ2= " << λ2 << ", l2 = " << l2 << endl;
	}
	cout << "极小值点:x = " << (λ2 + λ1) / 2 << "\t极小值:f(x) = " << Fun12((λ1 + λ2) / 2) << endl;
	return 0;
}

运行结果

2.2 黄金分割0.618法

// 使用 0.618法 求函数的极小值
#include <iostream>
using namespace std;
#define A 0.0			// 索索的区间左端点
#define B 10.0			// 索索的区间右端点
#define e ((B - A)*0.03)	// 需要满足的区间精度
#define Fun12(x) (x * x - 6 * x + 2)  // 第十二题的函数表达式

int Fibonacci(int n) {	// 使用递归求斐波那契数列
	return (n < 2) ? 1 : Fibonacci(n - 1) + Fibonacci(n - 2);
}

int main() {
	cout << "// 使用 0.618法 求函数的极小值\n";
	double λ1 = A + (B - A) * 0.382;double λ2 = A + (B - A) * 0.618;
	double l1 = A, l2 = B;		// 迭代的两个端点值 a,b 
	while (λ2 - λ1 > e)			// 是否满足精度要求
	{
		if (Fun12(λ1) < Fun12(λ2)) {
			cout << "f(" << λ1 << ") < f(" << λ2 << ") " << endl;
			l2 = λ2;	λ2 = λ1;	λ1 = l2 + l1 - λ2;
		}
		else {
			cout << "f(" << λ1 << ") > f(" << λ2 << ") " << endl;
			l1 = λ1;	λ1 = λ2;	λ2 = l2 + l1 - λ1;
		}
		cout << "\tl1 = " << l1 << ", λ1 =" << λ1 << " , λ2= " << λ2 << ", l2 = " << l2 << endl;
	}
	cout << "极小值点:x = " << (λ2 + λ1) / 2 << "\t极小值:f(x) = " << Fun12((λ1 + λ2) / 2) << endl;
	return 0;
} 

运行结果

三、温馨提示

        温馨提示,在使用C语言或者C++定义宏的时候,如果是复杂的表达式,最好最好使用括号将宏定义给括起来。为什么呢?别问,问就是血的教训呜呜呜

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我不是大佬zvj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值