目次
1. タブーアルゴリズムの概念
タブー検索は、人間の知能をシミュレートする最適化アルゴリズムです。人間の記憶の機能を模倣します問題を解決する過程でタブーな手法が使われ、探索された局所最適解をマークします。を繰り返してみてください同じ検索を繰り返さないようにする(ただし、完全に排除されるわけではありません)より広い検索間隔を取得し、全体的な最適解を見つけるのに役立ちます。
2. 関連用語の説明
1.タブーオブジェクト(タブーオブジェクト、TO)
タブーリストで禁止されている可変要素を指します。
たとえば、巡回セールスマン問題 (TSP) では、交換された都市ペアをタブー オブジェクトとして使用でき、経路の全長もタブー オブジェクトとして使用できます。
2.タブーリスト(タブーリスト、TL)
タブーオブジェクトを保存(記憶)するために使用されるテーブル。それがタブー検索を行うための大前提となります。タブ テーブル自体の容量には制限があり、そのサイズは保存されるタブ オブジェクトの数に影響し、アルゴリズムのパフォーマンスに影響します。
3. タブー在職期間 (TT)
禁忌期間とも呼ばれ、禁忌対象を選択できない期間を指します。
タブー期間が短すぎるとサイクルが発生しやすく、局所最適から抜け出すことができなくなります。
緊急期限が長すぎると、計算時間が過度に長くなる可能性があります。
4. 吸引基準 (AC)
恩赦規則とも呼ばれます。すべてのオブジェクトがタブー化されている場合、最もパフォーマンスの高い禁止オブジェクトを禁止解除することも、オブジェクトの禁止解除により目標値が大幅に向上する場合には恩赦ルールを使用することもできます。
5. 終了基準
3つの方法:
-
反復ステップの最大数を指定します。
-
オブジェクトの最大タブー周波数を設定します。
-
フィット値の偏差範囲を設定します。
3. アルゴリズムの基本的な流れ
4.TSP問題
巡回セールスマン問題は 4 つの都市 (a、b、c、d) の問題であることが知られており、都市間の距離は行列 D で示されます。便宜上、近隣マップは次のように定義されていると仮定します。 2つの都市を交換し、始点と終点の都市はすべてaです。タブー検索アルゴリズムを使用して、この問題を解決する過去 3 世代のプロセスと主な手順を分析してください。
主な手順:
Pythonコード
1. パッケージをインポートします。
import time
import numpy as np
import random
2. タブーアルゴリズムのパラメータ値を設定します。
タブーの長さは 2 です。
# m城市个数 best全局最优 tl初始禁忌长度
# time 迭代次数, spe特赦值
# tabu禁忌表
# best_way 最优解 now_way当前解
# dis两点距离
global m, best, tl
global time, spe
best = 4.0
m= 4
tl = 2
spe= 2
time = 100
tabu = [[0] * (m) for i in range(m)]
best_way =[0] * m
now_way = [0] * m
dis = [[0] * (m) for i in range(m)]
3. 初期解を生成します。
def rand(g):
vis = [0]*m
for i in range(m):
vis[i] = 0;
g[0] = 0 # 必定要从第一个城市a出发
vis[0] = 1
on = 1
while on < m:
te = random.randint(1, m - 1) # 随机选择一个城市
if(vis[te] == 0):
vis[te] = 1
g[on] = te
on += 1
4. 解 t の経路長を計算します。
def get_value(t):
ans = 0.0
for i in range(1, m):
ans += dis[t[i-1]][t[i]]
ans += dis[t[i-1]][t[i]]
return ans
5. 現在の解を最適解配列にコピーします。
def cop(a,b):
for i in range(m):
a[i] = b[i]
6. タブー テーブルを初期化し、初期解のパス値を計算します。
def init():
global best
for i in range(m):
for j in range(m):
tabu[i][j] = 0 #初始化禁忌表
rand(now_way) #生成初始解作为当前解
now = get_value(now_way)
cop(best_way, now_way)
best = now
7. タブーアルゴリズム。
def slove():
global best, now
temp = [0] * m # 中间变量记录交换结果
a = 0 # 记录交换城市下标
b = 0
ob_way = [0] * m
cop(ob_way, now_way)
ob_value = get_value(now_way) # 暂存邻域最优解
for i in range(1, m): # 搜索所有邻域
for j in range(1, m):
if(i + j >= m): break;
if(i == j): continue;
cop(temp, now_way)
temp[i], temp[i + j] = temp[i + j], temp[i]
value = get_value(temp)
if(value <= best and tabu[i][i + j] < spe): # 如果优于全局最优且禁忌长度小于特赦值
cop(best_way, temp)
best = value
a = i
b = i + j #更新全局最优且接受新解
cop(ob_way, temp)
ob_value = value
elif(tabu[i][i + j] == 0 and value < ob_value): # 如果优于邻域中的最优解则接受新解
cop(ob_way, temp)
ob_value = value
a = i
b = i + j
cop(now_way, ob_way) # 更新当前解
for i in range(m): # 更新禁忌表
for j in range(m):
if(tabu[i][j] > 0):
tabu[i][j] -= 1
tabu[a][b] = tl #重置a,b两个交换城市的禁忌值
8.主な機能:
if __name__ == '__main__':
dis = np.array([[0, 1, 0.5, 1],
[1, 0, 1, 1],
[1.5, 5, 0, 1],
[1, 1, 1, 0]])
init() # 数据初始化
for i in range(time): # 控制迭代次数
slove()
print("路线总长度: ", round(best,3)) # 打印最优解距离保留三位小数
print("具体路线: ", best_way)
9. 実行結果:
終わり