禁忌搜索算法(Tabu Search)是一种启发式优化算法,用于解决组合优化问题。它基于局部搜索的思想,通过在搜索过程中禁止一些已经访问过的解,以避免陷入局部最优解,从而更有可能找到全局最优解。
禁忌搜索算法的核心思想是维护一个禁忌表,记录了一些不允许访问的解。在搜索过程中,算法会根据一定的策略选择下一个解进行探索,并根据目标函数的变化情况决定是否接受该解。如果接受了新的解,算法会更新禁忌表,并将当前解加入禁忌表中,以避免在接下来的搜索中再次访问相同的解。
禁忌搜索算法的关键在于如何选择下一个解和更新禁忌表。常见的策略包括使用邻域搜索来生成候选解,通过引入禁忌长度来控制禁忌表的大小,以及使用目标函数的变化情况来决定是否接受新的解。
禁忌搜索算法在解决组合优化问题中表现出色,特别是对于那些具有复杂约束和多个局部最优解的问题。它能够在可接受的时间内找到较好的解,并且具有较好的鲁棒性和可扩展性。
用禁忌搜索算法解决旅行商问题(TSP)示例
import math
import random
def distance(city1, city2):
return math.sqrt((city1[0] - city2[0])**2 + (city1[1] - city2[1])**2)
def path_length(path, cities):
length = 0
for i in range(len(path)-1):
length += distance(cities[path[i]], cities[path[i+1]])
length += distance(cities[path[-1]], cities[path[0]])
return length
def tabu_search(cities, tabu_size=10, max_iter=100):
n = len(cities)
path = list(range(n))
random.shuffle(path)
best_path = path
tabu_list = []
for i in range(max_iter):
neighbors = []
for j in range(n-1):
for k in range(j+1, n):
neighbor = path.copy()
neighbor[j], neighbor[k] = neighbor[k], neighbor[j]
neighbors.append(neighbor)
neighbors.sort(key=lambda x: path_length(x, cities))
for neighbor in neighbors:
if neighbor not in tabu_list:
path = neighbor
tabu_list.append(neighbor)
if len(tabu_list) > tabu_size:
tabu_list.pop(0)
if path_length(path, cities) < path_length(best_path, cities):
best_path = path
break
return best_path
cities = [(random.uniform(0, 1), random.uniform(0, 1)) for i in range(10)]
best_path = tabu_search(cities)
print("Best path:", best_path)
print("Path length:", path_length(best_path, cities))
首先定义了一个目标函数来计算路径的长度,使用欧几里得距离作为路径长度的度量。然后实现禁忌搜索算法。这里使用一个简单的邻域搜索策略,即每次随机交换两个城市的位置来生成新的解。还需要定义一个禁忌表来记录已经访问过的解。最后使用一个简单的例子来测试算法,随机生成10个城市,并计算它们之间的最短路径。
输出如下:
Best path: [2, 1, 7, 4, 6, 9, 8, 3, 5, 0]
Path length: 3.285037850192482