2025西安交大集训Day1:二分,三分,哈希,高精度,位运算,模拟退火
二分
详见2025dsfz集训Day2:二分与三分,三分在当前文章内已经重构过。
三分
三分算法详细解释
三分算法(Ternary Search)是一种用于在单峰函数(即函数在某一点左侧单调递增,右侧单调递减,或者相反)上寻找极值(最大值或最小值)的算法。它的基本思想是通过不断缩小搜索范围来逼近极值点。
算法步骤:
- 确定搜索范围:首先确定一个区间 \([left, right]\),确保极值点在这个区间内。
- 计算中间点:将区间分为三部分,计算两个中间点 \(mid1\) 和 \(mid2\):
- \(mid1 = left + (right - left) / 3\)
- \(mid2 = right - (right - left) / 3\)
- 比较函数值:比较 \(f(mid1)\) 和 \(f(mid2)\) 的大小:
- 如果 \(f(mid1) < f(mid2)\),则极值点在 \([left, mid2]\) 区间内,更新 \(right = mid2\)。
- 如果 \(f(mid1) > f(mid2)\),则极值点在 \([mid1, right]\) 区间内,更新 \(left = mid1\)。
- 如果 \(f(mid1) == f(mid2)\),则极值点在 \([mid1, mid2]\) 区间内,更新 \(left = mid1\) 和 \(right = mid2\)。
- 重复步骤2和3:直到区间 \([left, right]\) 足够小,或者达到预定的精度要求。
- 返回结果:返回 \((left + right) / 2\) 作为极值点的近似值。
举例说明:
假设我们有一个凹函数 \(f(x) = (x - 3)^2\),我们希望在区间 \([0, 6]\) 上找到最小值。
- 初始区间 \([left, right] = [0, 6]\)。
- 计算 \(mid1 = 0 + (6 - 0) / 3 = 2\),\(mid2 = 6 - (6 - 0) / 3 = 4\)。
- 计算 \(f(mid1) = (2 - 3)^2 = 1\),\(f(mid2) = (4 - 3)^2 = 1\)。
- 由于 \(f(mid1) == f(mid2)\),更新 \(left = 2\),\(right = 4\)。
- 重复步骤2和3,直到区间足够小。
最终,我们会发现最小值出现在 \(x = 3\)。
凹函数求最小值的模板代码
#include <iostream>
#include <cmath>
#include <iomanip>using namespace std;// 定义凹函数 f(x) = (x - 3)^2
double f(double x) {return (x - 3) * (x - 3);
}// 三分算法求解凹函数最小值
double ternary_search(double left, double right, double eps) {while (right - left > eps) {double mid1 = left + (right - left) / 3;double mid2 = right - (right - left) / 3;if (f(mid1) < f(mid2)) {right = mid2;} else {left = mid1;}}return (left + right) / 2;
}int main() {double left = 0.0;double right = 6.0;double eps = 1e-6; // 精度要求double result = ternary_search(left, right, eps);cout << "最小值出现在 x = " << fixed << setprecision(6) << result << endl;cout << "最小值为 f(x) = " << fixed << setprecision(6) << f(result) << endl;return 0;
}
代码解释:
- 函数 \(f(x)\):定义了我们要最小化的凹函数 \(f(x) = (x - 3)^2\)。
- \(ternary_search\) 函数:实现了三分算法,通过不断缩小搜索范围来逼近最小值点。
- \(main\) 函数:设置初始搜索区间 \([0, 6]\) 和精度要求 \(eps = 1e-6\),调用 \(ternary_search\) 函数并输出结果。
输出结果:
最小值出现在 x = 3.000000
最小值为 f(x) = 0.000000
这个结果与我们的预期一致,最小值出现在 \(x = 3\),最小值为 \(0\)。
哈希
详见我的字符串哈希学习笔记。
位运算
没啥好说的。