一、问题概况
路径规划数学模型的建立:
将移动机器人周围的环境用一组数据进行抽象表达,以建立二维或三维的环境模型,并得到移动机器人能够理解和分析的环境数据,是开展机器人路径规划的基本前提。栅格法是目前最常用的环境建模方法,其原理是将周围环境看成一个二维平面, 并将平面分成一个个等面积大小的具有二值信息的栅格,每个栅格中存储着周围环境信息量: 0表示无障碍物、1表示有障碍物。图4.5给出了一个栅格地图,以方便读者更好地理解栅格法。
改图引用于书《计算智能》
二、实验步骤
(1)导入必要的库:导入了NumPy和Matplotlib库,用于数组操作和绘图。
(2)定义栅格地图:通过定义一个二维NumPy数组来表示栅格地图,其中0表示可通行区域,表示障碍物。
(3)将栅格地图转换为距离矩阵:将栅格地图中的0和1转换为相应的距离值,其中0表示可通行区域,距离为0;1表示障碍物,距离设置为一个很大的值。
(4)定义蚂蚁群算法函数:定义了一个名为、ant.colony.optimization、的函数,用于实现蚂蚁群算法。该函数接受栅格地图、距离矩阵以及-些算法参数作为输入,并返回找到的最佳路径、最短距离以及迭代过程中的距离历史。
(5)运行蚂蚁群算法:调用ant.colony.optimization.函数,并传入相应的参数,包括蚂蚁数量、迭代次数、信息素权重、启发因子等。
(6)打印最佳路径和最短距离:打印出蚂蚁群算法找到的最佳路径和对应的最短距离。
(7)绘制最佳路径:使用Matplotlib库绘制栅格地图,并在上面用红色标出找到的最佳路径。
(8)绘制迭代次数与最佳距离的图表:绘制迭代次数与最佳距离之间的关系图,用于观察算法在迭代过程中最佳距离的变化。
三、实验结果
路径规划图
迭代图
机器人路径图
四、具体代码(可直接使用)
import numpy as np
import matplotlib.pyplot as plt
# 定义栅格地图
grid_map = np.array([
[0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
])
# 将栅格地图转换为距离矩阵
distances = np.array(grid_map) * 1000
# 定义蚂蚁群算法函数
def ant_colony_optimization(grid_map, distances, n_ants, n_iterations, alpha, beta, rho, Q):
# 避免除以零错误,将距离矩阵中的零值替换为一个很大的数
distances[distances == 0] = 1e6
# 初始化信息素
pheromone = np.ones(distances.shape) / distances
# 初始化最佳路径和最短距离
best_path = None
best_distance = float('inf')
# 追踪迭代次数和最佳距离
iteration_count = []
best_distance_history = []
# 迭代
for iteration in range(n_iterations):
# 初始化蚂蚁的路径集合
ant_paths = []
# 每只蚂蚁搜索路径
for _ in range(n_ants):
# 初始化蚂蚁的起始位置和已访问节点集合
current_node = (0, 0) # 初始位置在起点(0, 0)
visited = set([current_node])
path = [current_node]
# 搜索路径直到到达终点
while current_node != (grid_map.shape[0] - 1, grid_map.shape[1] - 1): # 终点在(grid_map.shape[0]-1, grid_map.shape[1]-1)
# 计算下一个节点的概率分布,排除障碍物节点
x, y = current_node
neighbors = [(x+1, y), (x-1, y), (x, y+1), (x, y-1)]
unvisited = [(nx, ny) for nx, ny in neighbors if (nx, ny) not in visited and 0 <= nx < grid_map.shape[0] and 0 <= ny < grid_map.shape[1] and grid_map[nx][ny] != 1]
if len(unvisited) == 0:
# 如果没有可选的节点,回溯到上一个节点
if len(path) == 1:
# 如果已经回溯到起点,则退出循环
break
else:
# 回溯到上一个节点
path.pop()
current_node = path[-1]
continue # 继续下一次循环
else:
probabilities = np.array([pheromone[nx][ny] ** alpha * (1 / distances[nx][ny]) ** beta for nx, ny in unvisited])
if np.sum(probabilities) == 0:
# 如果所有相邻节点的概率之和为0,则回溯到上一个节点
if len(path) == 1:
# 如果已经回溯到起点,则退出循环
break
else:
# 回溯到上一个节点
path.pop()
current_node = path[-1]
continue # 继续下一次循环
probabilities = probabilities / np.sum(probabilities)
# 根据概率选择下一个节点
next_node = unvisited[np.random.choice(len(unvisited), p=probabilities)]
# 更新当前节点、已访问的节点集合和路径
current_node = next_node
visited.add(current_node)
path.append(current_node)
# 添加路径到路径集合中
ant_paths.append(path)
# 更新全局最佳路径
for path in ant_paths:
total_distance = sum(distances[path[i][0], path[i][1]] for i in range(len(path) - 1))
if total_distance < best_distance:
best_path = path
best_distance = total_distance
# 记录最佳距离历史
iteration_count.append(iteration)
best_distance_history.append(best_distance)
# 更新信息素
pheromone *= (1 - rho)
for path in ant_paths:
for i in range(len(path) - 1):
x, y = path[i]
nx, ny = path[i + 1]
pheromone[nx][ny] += Q / distances[x][y]
return best_path, best_distance, iteration_count, best_distance_history
# 运行蚂蚁群算法
best_path, best_distance, iteration_count, best_distance_history = ant_colony_optimization(grid_map, distances, n_ants=50, n_iterations=500, alpha=1, beta=7, rho=0.3, Q=1)
# 打印最佳路径和最短距离
print("Best Path:", best_path)
print("Best Distance:", best_distance)
# 绘制最佳路径
plt.imshow(grid_map, cmap='Greys', origin='lower')
plt.plot([j for _, j in best_path], [i for i, _ in best_path], marker='o', color='red')
plt.title('Best Path')
plt.xlabel('Y')
plt.ylabel('X')
plt.grid(True)
plt.show()
# 绘制迭代次数与最佳距离的图表
plt.plot(iteration_count, best_distance_history)
plt.title('Iteration vs. Best Distance')
plt.xlabel('Iteration')
plt.ylabel('Best Distance')
plt.grid(True)
plt.show()