2-Opt算法
2-Opt算法通过交换路径中的两个边缘(即两个城市之间的连接)来改进当前的解决方案。具体来说,算法会考虑路径中的任意两个非相邻城市,如果将它们之间的路径进行反转(即交换它们的位置),能够减少总旅行距离,那么就会进行这样的交换。
效率:100个随机点位,时间基本在1s以内
结果:运行时间 0.6875s
代码如下
import numpy as np
import matplotlib.pyplot as plt
import random
import time
def generate_random_points(n, seed=None):
if seed is not None:
random.seed(seed)
points = np.random.rand(n, 2) * 100
return points
def distance_matrix(points):
n = len(points)
dist_matrix = np.zeros((n, n))
for i in range(n):
for j in range(i + 1, n):
dist = np.sqrt(np.sum((points[i] - points[j]) ** 2))
dist_matrix[i, j] = dist
dist_matrix[j, i] = dist
return dist_matrix
def nearest_neighbor_algorithm(dist_matrix, start_index=0):
n = len(dist_matrix)
unvisited = set(range(n))
unvisited.remove(start_index)
path = [start_index]
while unvisited:
last_point = path[-1]
nearest = min(unvisited, key=lambda x: dist_matrix[last_point, x])
path.append(nearest)
unvisited.remove(nearest)
return path
def total_distance(dist_matrix, path):
dist = 0
for i in range(len(path) - 1):
dist += dist_matrix[path[i], path[i + 1]]
return dist
def two_opt_swap(path, i, k):
new_path = path[:i] + path[i:k + 1][::-1] + path[k + 1:]
return new_path
def two_opt_algorithm(dist_matrix, path):
best_path = path
improved = True
while improved:
improved = False
for i in range(1, len(best_path) - 2):
for k in range(i + 1, len(best_path) - 1):
new_path = two_opt_swap(best_path, i, k)
if total_distance(dist_matrix, new_path) < total_distance(dist_matrix, best_path):
best_path = new_path
improved = True
return best_path
def plot_path(points, path, title="Path Visualization"):
plt.figure(figsize=(10, 6))
for i in range(len(path) - 1):
plt.plot([points[path[i]][0], points[path[i + 1]][0]], [points[path[i]][1], points[path[i + 1]][1]], 'bo-')
plt.plot(points[:, 0], points[:, 1], 'ro')
plt.plot(points[path[0]][0], points[path[0]][1], 'go', markersize=10, label='Start Point')
plt.plot(points[path[-1]][0], points[path[-1]][1], 'mo', markersize=10, label='End Point')
plt.legend()
plt.title(title)
plt.xlabel('X-coordinate')
plt.ylabel('Y-coordinate')
plt.grid(True)
plt.show()
num_points = 100
start_point = np.array([0, 0])
points = generate_random_points(num_points, seed=42)
points = np.vstack((start_point, points))
start_time = time.time()
dist_matrix = distance_matrix(points)
initial_path = nearest_neighbor_algorithm(dist_matrix, start_index=0)
optimized_path = two_opt_algorithm(dist_matrix, initial_path)
end_time = time.time()
execution_time = end_time - start_time
print(f"Number of Points: {num_points}")
print(f"Initial Path: {initial_path}")
print(f"Optimized Path: {optimized_path}")
print(f"Total Distance: {total_distance(dist_matrix, optimized_path):.2f}")
print(f"Execution Time: {execution_time:.4f} seconds")
plot_path(points, optimized_path, title="2-Opt Algorithm Path")