import numpy as np
import matplotlib.pyplot as plt
# 計算距離和
def distance_sum(point, distances):
res = 0.
for index in range(len(point)-1):
res += distances[point[index]][point[index+1]]
return res
# 獲取選擇下一城市的權重字典
def right(begin, unvisited, matrix, distances, alpha, beta, Q):
# 計算權重
data = dict()
for end in unvisited:
data[end] = ((Q / distances[begin][end]) ** beta) * (matrix[begin][end] ** alpha)
# 權重和
s = sum(data.values())
# 權重字典
for index in unvisited:
data[index] = data[index] / s
return data
# 通過權重字典選擇下一城市
def next(right_dict):
# 獲取概率
p = np.random.random()
# 概率求和
ps = 0.
# 獲取下一座城市
last = 0
for index in right_dict:
last = index
ps += right_dict[index]
if p < ps:
return index
return last
def ACO(x, y, m=150, n=60, alpha=1, beta=5, Q=1, rho=0.1):
# 城市數量
city_num = len(x)
# 城市編號
city = [i for i in range(city_num)]
# 構造節點
points = []
for i in city:
points.append((x[i], y[i]))
# 計算間距
distances = np.zeros((city_num, city_num))
for i in range(city_num):
for j in range(city_num):
distance = (points[i][0] - points[j][0]) ** 2 + (points[i][1] - points[j][1]) ** 2
distance = np.sqrt(distance)
distances[i][j] = distance
# 初始化最優解
pg = [i for i in range(city_num)]
# 初始化信息素濃度
pheromonetable = np.ones((city_num, city_num))
# 主循環
for i in range(m):
# 每一次主循環的蟻羣路徑
paths = np.zeros((city_num, city_num))
for j in range(n):
# 起點
begin = np.random.randint(0, city_num)
# 記錄個體路徑
temp = [begin]
# 未訪問的城市列表
unvisited = city[:]
unvisited.remove(begin)
while len(unvisited) > 0:
# 計算下一個訪問的城市
rights = right(begin, unvisited, pheromonetable, distances, alpha, beta, Q)
next_city = next(rights)
# 記錄路徑
paths[begin][next_city] += 1
temp.append(next_city)
# 設置禁忌表
unvisited.remove(next_city)
# 重置起點
begin = next_city
# 更新最優解
if distance_sum(temp, distances) < distance_sum(pg, distances):
pg = temp[:]
# 更新信息素
pheromonetable *= (1 - rho)
for v in range(city_num):
for u in range(city_num):
if v != u:
pheromonetable[v][u] += (paths[v][u] * (Q / distances[v][u]))
print((i, distance_sum(pg, distances)))
return pg
# 準備數據
number = 100
x = np.round(np.random.rand(number) * 100)
y = np.round(np.random.rand(number) * 100)
plt.plot(x, y, '.')
# 轉換爲點集
points = []
for i in range(number):
points.append((x[i], y[i]))
# 蟻羣算法
pg = ACO(x, y)
# 結果可視化
xx = []
yy = []
for i in pg:
xx.append(points[i][0])
yy.append(points[i][1])
plt.plot(xx, yy)
plt.show()
plt.cla()
優化算法(四)蟻羣算法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.