搜索 —— 启发式搜索 —— 爬山法
【概述】
爬山法(Hill Climbing,HC)是一种局部择优的贪心搜索算法,其本质上是梯度下降法。
该算法每次从当前的节点开始,与周围的邻接点进行比较:
- 若当前节点是最大的,那么返回当前节点,作为最大值
- 若当前节点是最小的,就用最高的邻接点替换当前节点,从而实现向山峰的高处攀爬的目的
如此循环往复,直到达到最高点为止。
但该算法的主要问题是:局部最大,即某个节点会比周围任何一个邻居都高,但只是局部最优解,并非全局最优解。
如下图,在处于当前解时,爬山法搜索到局部最优解后,就会停止搜索,因为在局部最优解这个点,无论向哪个方向小幅度的移动,都无法得到更优解
此外,其还存在以下两种问题:
- 高地问题:搜索一旦到达高地,就无法确定搜索最佳方向,会产生随机走动,使得搜索效率降低
- 山脊问题:搜索可能会在山脊的两面来回震荡,前进步伐很小
当出现以上问题后,只能随机重启爬山算法来解决。
【主要思路】
首先,随机选择一个登山的初始时间 T,这个参数是随机选择的
然后,只要当 T 大于一个边界值 EPS 时,就将当前点与其邻接点进行比较:
- 如果 res<newRes,转移答案,并记录新坐标点 pos
- 如果 res>newRes,不转移
之后,根据记录下来的新坐标点 pos,去转移状态,一般为:sta = sta + (node[pos] - sta) * T;
最后,对 T 乘以一个小于但十分接近于 1 的数 delta,以体现时间对答案的影响。
不断重复上述步骤,直到邻接点中不再有比起大的点。
int getPos(double x) {//比较答案并获取新坐标点
int pos;//新坐标点
double res = -INF;
for (int i = 1; i <= n; i++) {
double newRes = getRes(x, node[i]);//获取新状态答案
if (newRes > res) { //比较答案
res = newRes; //更新结果
pos = i; //记录新坐标点
}
}
return pos;
}
void HC(double &x,double &y) {
double T = 1;
while (T > EPS) {
int pos = getPos(x);//获取下一状态的坐标
sta = sta + (node[pos] - x) * T;//转移x状态
T *= 0.96;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY