三分法求极值

代码如下

//可以判断极小值

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

double f(double x, const vector<double>& data) {
	int n = data.size();
	int left = 0, right = n - 1;
	while (left + 1 < right) {
		int mid = left + (right - left) / 2;
		if (x < mid) right = mid;
		else left = mid;
	}
	double x1 = left;
	double x2 = right;
	double y1 = data[left];
	double y2 = data[right];
	return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
}

double ternary_search(double left, double right, double eps, const vector<double>& data) {
	while (right - left > eps) {
		double mid1 = left + (right - left) / 3;
		double mid2 = right - (right - left) / 3;
		double f_mid1 = f(mid1, data);
		double f_mid2 = f(mid2, data);
		if (f_mid1 < f_mid2) {
			right = mid2;
		}
		else {
			left = mid1;
		}
	}
	return (left + right) / 2;
}

int main() {
	//vector<double> data = { 494.605, 459.84, 381.933, 321.128, 253.115, 213.087, 185.125, 167.345, 153.023, 141.001, 187.745, 223.045, 260.842, 344.141, 370.685 };

	vector<double> data = { 347.807, 364.69, 414.458, 459.168, 519.5, 552.838, 577.54, 587.161, 562.427, 523.519, 450.776, 425.747, 361.844, 333.258, 313.117 };

	double left = 0.0;
	double right = 14.0;
	double eps = 1e-9;

	double min_x = ternary_search(left, right, eps, data);

	cout << "min_x的值是" << "," << min_x << endl;

	double f_min_x = f(min_x, data);

	cout << "f_min_x的值是" << "," << f_min_x << endl;

	double f_left = f(left, data);
	double f_right = f(right, data);

	if (f_min_x < f_left && f_min_x < f_right) {
		cout << "函数是凹函数" << endl;
	}
	else if (f_min_x > f_left && f_min_x > f_right) {
		cout << "函数是凸函数" << endl;
	}
	else {
		cout << "函数不是凸函数也不是凹函数" << endl;
	}

	if (f_left < f_min_x && f_min_x < f_right) {
		cout << "函数是单调增的" << endl;
	}
	else if (f_left > f_min_x && f_min_x > f_right) {
		cout << "函数是单调减的" << endl;
	}
	else {
		cout << "函数不是单调增也不是单调减" << endl;
	}

	return 0;
}

如果要求极大值,把f_mid1 < f_mid2改为f_mid1 > f_mid2

问题1:如果一列数据不知道是凸还是凹,能否用三分搜索法来判定这列数据是凸或是凹?


三分搜索法(Ternary Search)主要用于在单峰函数(一个单一的极值点)上进行快速搜索,以找到极值点的位置。在这种情况下,它的效率很高。但是,三分搜索法并不能用来判定一列数据是凸函数还是凹函数。

凸函数和凹函数都有特定的定义和性质,与函数的单峰性质不同。一个函数被称为凸函数,如果其定义域内的任意两点连线上的函数值都不小于连线两端点的函数值。反之,一个函数被称为凹函数,如果其定义域内的任意两点连线上的函数值都不大于连线两端点的函数值。

判定一列数据是凸函数还是凹函数需要根据函数的定义和性质进行分析,三分搜索法并不适用于这个问题。需要对函数的变化趋势进行分析,查看其斜率的变化情况,以及二阶导数的符号,以确定函数的凸凹性质。

总而言之,三分搜索法适用于寻找单峰函数的极值点,而不适用于判定一列数据是凸函数还是凹函数。判定凸凹性质需要更深入的分析和数学推导。

问题2:三分搜索法适用于在连续函数上找到极值点,但对于离散的数据点,通常会借助图表和观察来进行分析。

参考链接1:三分查找(ternary search)及其示例_LittleMagics的博客-CSDN博客

参考链接2:百度安全验证

猜你喜欢

转载自blog.csdn.net/pingchangxin_6/article/details/132099311