目录
一、理论概述
由于算法的理论太简单了,这里不再重复了,不清楚的小伙伴们可以去看下面的几篇博客,有详细的算法理论原理讲解
1. https://blog.csdn.net/weixin_44044411/article/details/88091024
二、完整源码
源码富有详细的注释,这里不再重复
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++定义宏的时候,如果是复杂的表达式,最好最好使用括号将宏定义给括起来。为什么呢?别问,问就是血的教训呜呜呜