不断更新中......
一、
爬山算法:爬山算法是一种简单的贪心搜索算法,该算法每次从当前位置的临近空间中选择一个最优解作为当前解,直到达到一个局部最优解。爬山算法可以类比成一个有失忆的人在浓雾中爬山。这里就揭示了爬山算法的两个问题:
失忆:就是说这个人不记得他去过什么地方,他只记得他现在所处的位置,以及周边的情况(因为有浓雾,所以他只能看到最近的周边的情况)。所以说他在任何时候只存储一个当前的状态,之前的所有的状态全部不记得了。那么我们就可以看出爬山算法非常依赖于这个初始状态(如果初始状态距离全局最值点很近的话,是更容易搜索到全局最值点的)。
浓雾:当他走到一个局部最值点时,因为他看见远处是否还有更大的最值点,所以就把当前这个局部最值点返回给你(爬山算法的返回是返回一个状态而不是一个路径,这个状态就是一个局部最值点)。
爬山算法的输入是定义的两个局部变量,一个是当前状态(当前结点),还有一个就是用来存储邻居结点的neighbor。我们从初始结点(也就是我们的当前结点)出发,开始往前爬山(往前搜索)。首先根据当前结点能够产生多少个后续结点,然后在这些后续结点中选择一个最大值(这个值是用你所定义的评估函数评估出来的)的后续结点,并将它放进neighbor中,然后将后续结点的值与当前结点的值进行比较,如果发现当前结点的值比后续结点的值要大,那么就意味着当前结点就是一个局部最值点了,所以就不用动了,把当前结点对应的状态返回即可。但是如果当前结点的值比后续结点的值要小,那么就往前走。这样一步一步地进行迭代,直到走到一个局部最值点。
所以说,爬山算法的主要缺点是可能会陷入局部最优解,而不一定能搜索到全局最优解。当然有一种办法就是多运行几次爬山搜索算法,每一次都使用不同的初始状态,然后从里面挑一个最大的值作为这个问题的解。
在某个给定的定义域X内,求函数f(x)对应的最优值。这里假设求最小值:
如果X是离散有限取值,那么可以通过穷取法获得问题的最优解;
如果X是连续的,且f(x)是凸的,那么可以通过梯度下降等方法获得最优解;
如果X是连续的,但是f(x)是非凸的,虽说也可以通过梯度下降找到局部最优解但不一定找到全局最优解。
优点:
①避免遍历,采用启发式搜索策略,效率更高
(启发式搜索:在状态空间中进行搜索并对每一个搜索的位置进行评估,从而得到最好的位置)
(状态空间:用来描述一个问题的全部状态以及这些状态之间的相互关系)
缺点:
①因为不是全面搜索,所以结果可能只是局部最优解,而不是全局最优解
②如果到达高地(平顶),那么就无法确定最佳搜索方向,会产生随机走动,使得搜索效率降低
③搜索可能会在山脊的两面来回振荡,前进步伐很小
# 我的代码
# @Time : 2019/11/14 下午 3:09
'''
问题:设方程y=x1+x2-x3,
x1是区间[-2,5]中的整数,
x2是区间[2,6]中的整数,
x3是区间[-5,2]中的整数,
使用爬山法,找到使得y取值最小的解
'''
import numpy as np
y = 10000
list_mid = list()
list_x = np.zeros(3)
for x1 in range(-10, 6):
for x2 in range(2, 7):
for x3 in range(-5, 9):
s = x1+x2-x3
list_mid.append([x1, x2, x3]) #把每种搜索都记录下来
if s < y:
y = s
list_x = [x1, x2, x3] #最优搜索选择
continue
else:
continue
if s < y:
print(s)
else:
print(y)
print(list_x)
print(list_mid)