Python 爬山算法

在本文中,让我们尝试了解爬山算法。这是人工智能领域常用的启发式搜索技术。启发式技术是选择多个选项中哪一个最能成功实现特定目标的标准。

另请阅读:分支定界搜索以及 Python 中的示例和实现

什么是爬山算法?

爬山来自深度优先搜索(生成和测试策略的一种变体)中的质量测量。这是一种优化策略,属于本地搜索家族的一部分。

这是一个相当简单的实施策略,因为我们探索了流行的第一个选项。在某些情况下,爬山是有效的,尽管更复杂的算法可能会产生更大的好处。

爬山可以通过多种解决方案来解决问题,但有些解决方案比其他解决方案更好。旅行商问题可以通过爬山来解决。找到一种能够访问每个城市的解决方案很简单,但与理想的解决方案相比,该解决方案可能会低于标准。

如果有一种技术来排列选项,以便首先探索最有希望的节点,那么搜索效率可能会提高。爬山按照深度优先的顺序遍历路径树,但选项是根据一些启发值(即从当前状态到目标状态的剩余成本的度量)排列的。

例如,在旅行推销员问题中,两个城市之间的直线(乌鸦飞翔)距离可以作为剩余距离的启发式测量。

要记住的属性

  • 本地搜索算法
  • 遵循贪婪方法
  • 没有回头路。

爬山算法的类型

简单爬山:最简单的爬山方法称为简单爬山。目标是登上这座山的最高峰。在这里,登山者的步伐和动作决定了他的移动方式。如果他认为下一步会比之前更好,或者保持在同一位置,他就会继续前进。这个搜索只是关注他之前和之后的行为。

最陡爬山:与直接的爬山搜索相反,它会比较所有后续节点并选择最接近答案的节点。因为它集中于每个节点而不仅仅是一个,所以最陡的爬山搜索与最佳优先搜索相当。

随机爬山:随机爬山时节点并不全部集中。它随机选择一个节点,然后决定是扩大它还是寻找更好的节点。

随机重启爬山:尝试和尝试方法是随机重启算法的基础。在未达到目标之前,它会迭代搜索节点并在每个阶段选择最佳候选节点。成功常常取决于山的形状。如果没有太多山脊、高原或局部最大值,那么到达那里会更容易。

爬山的简单例子

为了更好地理解这个概念,让我们尝试使用爬山算法来实现旅行推销员的问题。下面给出问题的描述。

找到必须访问的多个点和地点之间的最短路径是称为“旅行商问题”(TSP)的算法问题的目标。这里的输入是城市坐标的二维数组,输出是一个整数列表,表示按顺序排列的城市数量(从零开始)

用Python实现爬山算法

import random
import numpy as np
import networkx as nx
 
#coordinate of the points/cities
coordinate = np.array([[1,2], [30,21], [56,23], [8,18], [20,50], [3,4], [11,6], [6,7], [15,20], [10,9], [12,12]])
 
#adjacency matrix for a weighted graph based on the given coordinates
def generate_matrix(coordinate):
    matrix = []
    for i in range(len(coordinate)):
        for j in range(len(coordinate)) :      
            p = np.linalg.norm(coordinate[i] - coordinate[j])
            matrix.append(p)
    matrix = np.reshape(matrix, (len(coordinate),len(coordinate)))
    #print(matrix)
    return matrix
 
#finds a random solution   
def solution(matrix):
    points = list(range(0, len(matrix)))
    solution = []
    for i in range(0, len(matrix)):
        random_point = points[random.randint(0, len(points) - 1)]
        solution.append(random_point)
        points.remove(random_point)
    return solution
 
 
#calculate the path based on the random solution
def path_length(matrix, solution):
    cycle_length = 0
    for i in range(0, len(solution)):
        cycle_length += matrix[solution[i]][solution[i - 1]]
    return cycle_length
 
#generate neighbors of the random solution by swapping cities and returns the best neighbor
def neighbors(matrix, solution):
    neighbors = []
    for i in range(len(solution)):
        for j in range(i + 1, len(solution)):
            neighbor = solution.copy()
            neighbor[i] = solution[j]
            neighbor[j] = solution[i]
            neighbors.append(neighbor)
             
    #assume that the first neighbor in the list is the best neighbor     
    best_neighbor = neighbors[0]
    best_path = path_length(matrix, best_neighbor)
     
    #check if there is a better neighbor
    for neighbor in neighbors:
        current_path = path_length(matrix, neighbor)
        if current_path < best_path:
            best_path = current_path
            best_neighbor = neighbor
    return best_neighbor, best_path
 
 
def hill_climbing(coordinate):
    matrix = generate_matrix(coordinate)
     
    current_solution = solution(matrix)
    current_path = path_length(matrix, current_solution)
    neighbor = neighbors(matrix,current_solution)[0]
    best_neighbor, best_neighbor_path = neighbors(matrix, neighbor)
 
    while best_neighbor_path < current_path:
        current_solution = best_neighbor
        current_path = best_neighbor_path
        neighbor = neighbors(matrix, current_solution)[0]
        best_neighbor, best_neighbor_path = neighbors(matrix, neighbor)
 
    return current_path, current_solution
final_solution = hill_climbing(coordinate)
print("The solution is \n", final_solution[1])

输出

解决办法是

[2、4、8、3、7、5、0、6、9、10、1]

爬山的问题

爬山有一些问题。搜索过程可能到达一个不是解决方案的位置,但从那里开始没有任何行动可以改善情况。如果我们达到了局部最大值、高原或山脊,就会发生这种情况。

局部最大值:它是一个比它所有邻居都好但不比其他一些较远的状态好的状态,(前面可能有更好的解,这个解称为全局最大值。)从这个状态,所有的举动看起来都更糟。在这种情况下,请回溯到某个较早的状态并尝试朝不同的方向寻找解决方案。

局部最大值

高原:它是搜索空间的平坦区域,其中所有相邻状态都具有相同的值。无法确定最佳方向。在这种情况下,朝某个方向大跳并尝试到达搜索空间的新部分。它也称为平坦最大值。

高原

山脊:它是搜索空间中高于周围区域的区域,但不能通过任何一个方向的单次移动来遍历。它是一种特殊的局部最大值。这里在进行测试之前应用两个或多个规则,即同时向多个方向移动。

概括

本文深入解释了爬山算法的概念。我们了解解决著名的旅行商问题的不同类型以及算法的实现。爬山算法广泛应用于数据科学和人工智能领域。