随机爬山是一种优化算法。它利用随机性作为搜索过程的一部分。这使得该算法适用于非线性目标函数,而其他局部搜索算法不能很好地运行。它也是一种局部搜索算法,这意味着它修改了单个解决方案并搜索搜索空间的相对局部区域,直到找到局部最优值为止。这意味着它适用于单峰优化问题或在应用全局优化算法后使用。
在本教程中,您将发现用于函数优化的爬山优化算法完成本教程后,您将知道:
-
爬山是用于功能优化的随机局部搜索算法。
-
如何在Python中从头开始实现爬山算法。
-
如何应用爬山算法并检查算法结果。
教程概述
本教程分为三个部分:他们是:
-
爬山算法
-
爬山算法的实现
-
应用爬山算法的示例
爬山算法
随机爬山算法是一种随机局部搜索优化算法。它以起始点作为输入和步长,步长是搜索空间内的距离。该算法将初始点作为当前最佳候选解决方案,并在提供的点的步长距离内生成一个新点。计算生成的点,如果它等于或好于当前点,则将其视为当前点。新点的生成使用随机性,通常称为随机爬山。这意味着该算法可以跳过响应表面的颠簸,嘈杂,不连续或欺骗性区域,作为搜索的一部分。重要的是接受具有相等评估的不同点,因为它允许算法继续探索搜索空间,例如在响应表面的平坦区域上。限制这些所谓的“横向”移动以避免无限循环也可能是有帮助的。该过程一直持续到满足停止条件,例如最大数量的功能评估或给定数量的功能评估内没有改善为止。该算法之所以得名,是因为它会(随机地)爬到响应面的山坡上,达到局部最优值。这并不意味着它只能用于最大化目标函数。这只是一个名字。实际上,通常,我们最小化功能而不是最大化它们。作为局部搜索算法,它可能会陷入局部最优状态。然而,多次重启可以允许算法定位全局最优。步长必须足够大,以允许在搜索空间中找到更好的附近点,但步幅不能太大,以使搜索跳出包含局部最优值的区域。
如果大家在学习中遇到困难,想找一个python学习交流环境,可以加入我们的python圈,裙号609616831,可领取python学习资料,会节约很多时间,减少很多遇到的难题。
爬山算法的实现
在撰写本文时,SciPy库未提供随机爬山的实现。但是,我们可以自己实现它。首先,我们必须定义目标函数和每个输入变量到目标函数的界限。目标函数只是一个Python函数,我们将其命名为Objective()。边界将是一个2D数组,每个输入变量都具有一个维度,该变量定义了变量的最小值和最大值。例如,一维目标函数和界限将定义如下:
# objective function
def objective(x):
return 0
# define range for input
bounds = asarray([[-5.0, 5.0]])
接下来,我们可以生成初始解作为问题范围内的随机点,然后使用目标函数对其进行评估。
# generate an initial point
solution = bounds[:, 0] + rand(len(bounds)) * (bounds[:, 1] - bounds[:, 0])
# evaluate the initial point
solution_eval = objective(solution)
现在我们可以遍历定义为“ n_iterations”
的算法的预定义迭代次数,例如100或1,000。
# run the hill climb
for i in range(n_iterations):
算法迭代的第一步是采取步骤。这需要预定义的“ step_size”
参数,该参数相对于搜索空间的边界。我们将采用高斯分布的随机步骤,其中均值是我们的当前点,标准偏差由“ step_size”
定义。这意味着大约99%的步骤将在当前点的(3 * step_size)
之内。
# take a step
candidate = solution + randn(len(bounds)) * step_size
我们不必采取这种方式。您可能希望使用0到步长之间的均匀分布。例如:
# take a step
candidate = solution + rand(len(bounds)) * step_size
接下来,我们需要评估具有目标函数的新候选解决方案。
# evaluate candidate point
candidte_eval = objective(candidate)
然后,我们需要检查此新点的评估结果是否等于或优于当前最佳点,如果是,则用此新点替换当前最佳点。
# check if we should keep the new point
if candidte_eval <= solution_eval:
# store the new point
solution, solution_eval = candidate, candidte_eval
# report progress
print('>%d f(%s) = %.5f' % (i, solution, solution_eval))
就是这样。我们可以将此爬山算法实现为可重用函数,该函数将目标函数的名称,每个输入变量的范围,总迭代次数和步骤作为参数,并返回找到的最佳解决方案及其评估。
# hill climbing local search algorithm
def hillclimbing(objective, bounds, n_iterations, step_size):
# generate an initial point
s