搜索 —— 启发式搜索 —— 爬山法

【概述】

爬山法(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;
    }
}

 

### 近似算法与启发式算法的概念 #### 近似算法概念 近似算法旨在针对那些难以在多项式时间内获得精确解的问题提供一种能够在合理时间范围内得到接近最优解的方法。这类算法通常用于NP难问题,在这些情况下,找到确切的最佳解可能是计算上不可行的。 #### 启发式算法概念 启发式算法则是一类利用经验法则或直觉来解决问题的技术[^1]。其核心在于采用某种形式的经验性策略去探索解空间,而不是严格遵循数学证明的方式。这种方法可以快速给出满意的结果,但并不保证能找到全局最优点。 --- ### 近似算法与启发式算法的区别 #### 解的质量保障程度不同 对于近似算法而言,存在理论上的性能界限,即能够量化地说明所得解距离真实最佳解有多远;而大多数启发式方法无法提供这样的保证,尽管实践中往往可以获得不错的解答质量。 #### 设计思路差异 近似算法的设计基于严格的数学分析,试图构建一个框架使得最终结果尽可能逼近理想情况下的答案。相反,启发式方案更多依赖于具体问题特征以及过往成功案例中的模式识别来进行设计和调整[^2]。 --- ### 应用场景对比 #### 近似算法适用场合 当面对的是已知具有良好特性(比如凸函数优化)或者是已经被深入研究过的小规模实例时,可以选择使用带有明确误差边界的近似算法。此外,在一些特殊结构化的问题中,如图论里的某些组合优化难题,也有成熟的近似技术可供选用。 #### 启发式算法适用场合 对于大型、复杂且缺乏有效解析模型支持的实际工程任务,则更适合运用灵活多变的启发式手段。特别是像旅行商问题这样典型的组合爆炸型挑战,或是涉及动态变化环境的任务规划等领域,启发式搜索展现出强大的适应性和实用性。 ```python def heuristic_example(): """ 此处展示了一个简单的启发式算法示例——爬山法求解一维极值问题。 """ import numpy as np def objective_function(x): return - 3 current_solution = np.random.uniform(-5, 5) step_size = 0.1 max_iterations = 1000 for _ in range(max_iterations): neighbor = current_solution + np.random.normal(scale=step_size) if objective_function(neighbor) > objective_function(current_solution): current_solution = neighbor print(f"Heuristic solution found at x={current_solution:.4f}, f(x)={objective_function(current_solution):.4f}") heuristic_example() ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值