01の概要
貪欲ランダム適応検索、貪欲ランダム適応検索(GRAS)は、アルゴリズムの各反復において、メタヒューリスティックマルチ開始組合せ最適化問題であり、主に2つのフェーズで構成:構成(構造)及びローカル検索(検索)ローカル。コンフィギュレーション(構成)の段階では、主に、それははるかに局所最適解を見つけるまで、最初の実行可能な解決策が局所近傍検索で配置された後に実行可能なソリューションを生成するために使用されます。
02全体的な枠組み
実際には、前述したように、他のアルゴリズムに対するアルゴリズムの全体のフレームワークは非常に簡単です、我々は次の擬似コードの全体を見ることができます。
GRASは、主に二つの部分から構成されています。
- Greedy_Randomized_Construction:いくつかのランダムな要因は、最初の実行可能解の構成を追加、貪欲に基づきます。
- ローカル検索:あなたは局所最適解を見つけるまで、最初の実行可能な解決策は、近傍探索の上に構築されます。
もっとその後、いくつかの単語を言います:
修理一体何?
、修理ソリューションのため、修理作業を追加して、次のローカル検索を続けることができることを確認するために、その実現可能性を確保するためにのでたまに溶液に加え、ランダムな要因に起因して、生成されたGreedy_Randomized_Constructionフェーズは、常に実行可能な解決ではありません。その適応(アダプティブ)が行うと言うことではありませんか?私はどのように適応プロセスが表示されませんか?
しかし、この後者の具体例を詳細に述べると、待ってください。
03あなたの例を与えます
我々はより深くアルゴリズムを理解することができるようにするために、我々は皆のための詳細なプロセスのアルゴリズムを説明するための簡単な例を与えます。
まあ、私は(タン寿、読み取ることができないと私に聞かないでください)我々はすべての上記の問題を理解すると信じています。これらの問題については、来る、のはGRASでそれを解決するためにステップバイステップで聞かせて、小さなシリーズは密接の足跡を追った......
何度も強調し、GRASは2つの部分で構成されていますGreedy_Randomized_Constructionとローカル検索、特定の問題を解決するときに、二つの部分の設計を完了し、その後、セクションIIに示されているフレームワークに基づいてそれを取ります。
3.1 Greedy_Randomized_Construction
ここでは古いルール、誰もが参照するための最初の擬似コードは、その後、私たちは結局、アルゴリズムのために、擬似コードの役割は自明である、説明します。
- 1行目は、開始液が空のセットです。
- 例えば1,2,3などのライン2、初期の候補要素のセット、候補要素はここにある溶液中に要素を指す(すなわち、現在の解が存在する)、.......
- 行3は、関数fの溶液に、計算要素xを評価するための候補セットの各要素は、変更delta_xの目標量を引き起こします。
- ライン5は、delta_x各要素に従ってソート、部分は、好ましくは、候補要素RCLテーブルを選択された(貪欲がここで反射されます)。
- 6行目、RCL中の溶液に、ランダムに選択された要素。(ランダムアルゴリズム)
- 各要素は、デルタ値を算出するため、候補要素のセットを更新し、8,9行は、再評価します。(ここでは具体化適応アルゴリズム)
私は上記のような詳細な説明の後、我々はすべてそれを知っていると信じています!
3.2ローカル検索
コンテンツについてのローカル検索用語、私は私がそれを言うために多くのものを持っていない、我々はあまりにも長い間、ヒューリスティックを学ぶと信じて:
私たちは、単に擬似コード、近所のデザインの主オペレータを見て、その後、近所の内側にある検索これまでの局所最適解を見つけることができます。近所で検索し、最高の改善や戦略の2つの方法を最初に改善され、次回は、あなたがそれに関連する概念のいくつかを理解し、テーマ別言うそこにあります。
Greedy_Randomized_Constructionに04より
以前の私たちは、それはそれはもう少し貪欲成分である、ある、Greedy_Randomized_Constructionは、それが2 Greedy_Randomizedの組み合わせは、その後、確かに重量配分の問題があるがあるため、初期解を生成するために使用される、と述べましたか?ランダム化成分または良いよりも少し?そのため、解に至る過程でいくつかの男無理な力を防止するため、これらの二つの弟の量を調節するために、我々は、パラメータαを導入し、あまり良くないです。
他の部分を見ることができると言うではない、上記パラメータαは、主にRCLの長さを制御します。
- α= 0、貪欲純粋は、唯一最良の候補要素を選択した場合。
- α= 1、純粋にランダムな、候補となる全ての要素をランダムに選択することができる場合。
05コードの実装
限られ、小さなシリーズのエネルギーに、皆のためでなく、TSPのためのGitHubから良いアルゴリズムを感じるを探して、ゼロから再びそれを書いていません。しかし、確かに、Pythonの書き込みアルゴリズムの速度は、それが建築と速度の他の側面があるかのアルゴリズムは、大規模最適化アルゴリズムMathWorks社のMATLABやPythonを書くためにあなたをお勧めしませんか、非常に遅いです。
結果は以下の通りであります:
コード例および関連の業績は、公開番号[プログラム]猿の音、舞台裏の返信に注意してください:GRAS、あなたがダウンロードすることができます
############################################################################
# Created by: Prof. Valdecy Pereira, D.Sc.
# UFF - Universidade Federal Fluminense (Brazil)
# email: [email protected]
# Course: Metaheuristics
# Lesson: Local Search-GRASP
# Citation:
# PEREIRA, V. (2018). Project: Metaheuristic-Local_Search-GRASP, File: Python-MH-Local Search-GRASP.py, GitHub repository: <https://github.com/Valdecy/Metaheuristic-Local_Search-GRASP>
############################################################################
# Required Libraries
import pandas as pd
import random
import numpy as np
import copy
import os
from matplotlib import pyplot as plt
# Function: Tour Distance
def distance_calc(Xdata, city_tour):
distance = 0
for k in range(0, len(city_tour[0])-1):
m = k + 1
distance = distance + Xdata.iloc[city_tour[0][k]-1, city_tour[0][m]-1]
return distance
# Function: Euclidean Distance
def euclidean_distance(x, y):
distance = 0
for j in range(0, len(x)):
distance = (x.iloc[j] - y.iloc[j])**2 + distance
return distance**(1/2)
# Function: Initial Seed
def seed_function(Xdata):
seed = [[],float("inf")]
sequence = random.sample(list(range(1,Xdata.shape[0]+1)), Xdata.shape[0])
sequence.append(sequence[0])
seed[0] = sequence
seed[1] = distance_calc(Xdata, seed)
return seed
# Function: Build Distance Matrix
def buid_distance_matrix(coordinates):
Xdata = pd.DataFrame(np.zeros((coordinates.shape[0], coordinates.shape[0])))
for i in range(0, Xdata.shape[0]):
for j in range(0, Xdata.shape[1]):
if (i != j):
x = coordinates.iloc[i,:]
y = coordinates.iloc[j,:]
Xdata.iloc[i,j] = euclidean_distance(x, y)
return Xdata
# Function: Tour Plot
def plot_tour_distance_matrix (Xdata, city_tour):
m = Xdata.copy(deep = True)
for i in range(0, Xdata.shape[0]):
for j in range(0, Xdata.shape[1]):
m.iloc[i,j] = (1/2)*(Xdata.iloc[0,j]**2 + Xdata.iloc[i,0]**2 - Xdata.iloc[i,j]**2)
m = m.values
w, u = np.linalg.eig(np.matmul(m.T, m))
s = (np.diag(np.sort(w)[::-1]))**(1/2)
coordinates = np.matmul(u, s**(1/2))
coordinates = coordinates.real[:,0:2]
xy = pd.DataFrame(np.zeros((len(city_tour[0]), 2)))
for i in range(0, len(city_tour[0])):
if (i < len(city_tour[0])):
xy.iloc[i, 0] = coordinates[city_tour[0][i]-1, 0]
xy.iloc[i, 1] = coordinates[city_tour[0][i]-1, 1]
else:
xy.iloc[i, 0] = coordinates[city_tour[0][0]-1, 0]
xy.iloc[i, 1] = coordinates[city_tour[0][0]-1, 1]
plt.plot(xy.iloc[:,0], xy.iloc[:,1], marker = 's', alpha = 1, markersize = 7, color = 'black')
plt.plot(xy.iloc[0,0], xy.iloc[0,1], marker = 's', alpha = 1, markersize = 7, color = 'red')
plt.plot(xy.iloc[1,0], xy.iloc[1,1], marker = 's', alpha = 1, markersize = 7, color = 'orange')
return
# Function: Tour Plot
def plot_tour_coordinates (coordinates, city_tour):
coordinates = coordinates.values
xy = pd.DataFrame(np.zeros((len(city_tour[0]), 2)))
for i in range(0, len(city_tour[0])):
if (i < len(city_tour[0])):
xy.iloc[i, 0] = coordinates[city_tour[0][i]-1, 0]
xy.iloc[i, 1] = coordinates[city_tour[0][i]-1, 1]
else:
xy.iloc[i, 0] = coordinates[city_tour[0][0]-1, 0]
xy.iloc[i, 1] = coordinates[city_tour[0][0]-1, 1]
plt.plot(xy.iloc[:,0], xy.iloc[:,1], marker = 's', alpha = 1, markersize = 7, color = 'black')
plt.plot(xy.iloc[0,0], xy.iloc[0,1], marker = 's', alpha = 1, markersize = 7, color = 'red')
plt.plot(xy.iloc[1,0], xy.iloc[1,1], marker = 's', alpha = 1, markersize = 7, color = 'orange')
return
# Function: Rank Cities by Distance
def ranking(Xdata, city = 0):
rank = pd.DataFrame(np.zeros((Xdata.shape[0], 2)), columns = ['Distance', 'City'])
for i in range(0, rank.shape[0]):
rank.iloc[i,0] = Xdata.iloc[i,city]
rank.iloc[i,1] = i + 1
rank = rank.sort_values(by = 'Distance')
return rank
# Function: RCL
def restricted_candidate_list(Xdata, greediness_value = 0.5):
seed = [[],float("inf")]
sequence = []
sequence.append(random.sample(list(range(1,Xdata.shape[0]+1)), 1)[0])
for i in range(0, Xdata.shape[0]):
count = 1
rand = int.from_bytes(os.urandom(8), byteorder = "big") / ((1 << 64) - 1)
if (rand > greediness_value and len(sequence) < Xdata.shape[0]):
next_city = int(ranking(Xdata, city = sequence[-1] - 1).iloc[count,1])
while next_city in sequence:
count = np.clip(count+1,1,Xdata.shape[0]-1)
next_city = int(ranking(Xdata, city = sequence[-1] - 1).iloc[count,1])
sequence.append(next_city)
elif (rand <= greediness_value and len(sequence) < Xdata.shape[0]):
next_city = random.sample(list(range(1,Xdata.shape[0]+1)), 1)[0]
while next_city in sequence:
next_city = int(random.sample(list(range(1,Xdata.shape[0]+1)), 1)[0])
sequence.append(next_city)
sequence.append(sequence[0])
seed[0] = sequence
seed[1] = distance_calc(Xdata, seed)
return seed
# Function: 2_opt
def local_search_2_opt(Xdata, city_tour):
tour = copy.deepcopy(city_tour)
best_route = copy.deepcopy(tour)
seed = copy.deepcopy(tour)
for i in range(0, len(tour[0]) - 2):
for j in range(i+1, len(tour[0]) - 1):
best_route[0][i:j+1] = list(reversed(best_route[0][i:j+1]))
best_route[0][-1] = best_route[0][0]
best_route[1] = distance_calc(Xdata, best_route)
if (best_route[1] < tour[1]):
tour[1] = copy.deepcopy(best_route[1])
for n in range(0, len(tour[0])):
tour[0][n] = best_route[0][n]
best_route = copy.deepcopy(seed)
return tour
# Function: GRASP
def greedy_randomized_adaptive_search_procedure(Xdata, city_tour, iterations = 50, rcl = 25, greediness_value = 0.5):
count = 0
best_solution = copy.deepcopy(city_tour)
while (count < iterations):
rcl_list = []
for i in range(0, rcl):
rcl_list.append(restricted_candidate_list(Xdata, greediness_value = greediness_value))
candidate = int(random.sample(list(range(0,rcl)), 1)[0])
city_tour = local_search_2_opt(Xdata, city_tour = rcl_list[candidate])
while (city_tour[0] != rcl_list[candidate][0]):
rcl_list[candidate] = copy.deepcopy(city_tour)
city_tour = local_search_2_opt(Xdata, city_tour = rcl_list[candidate])
if (city_tour[1] < best_solution[1]):
best_solution = copy.deepcopy(city_tour)
count = count + 1
print("Iteration =", count, "-> Distance =", best_solution[1])
print("Best Solution =", best_solution)
return best_solution
######################## Part 1 - Usage ####################################
X = pd.read_csv('Python-MH-Local Search-GRASP-Dataset-01.txt', sep = '\t') #17 cities = 1922.33
seed = seed_function(X)
lsgrasp = greedy_randomized_adaptive_search_procedure(X, city_tour = seed, iterations = 5, rcl = 5, greediness_value = 0.5)
plot_tour_distance_matrix(X, lsgrasp) # Red Point = Initial city; Orange Point = Second City # The generated coordinates (2D projection) are aproximated, depending on the data, the optimum tour may present crosses.
Y = pd.read_csv('Python-MH-Local Search-GRASP-Dataset-02.txt', sep = '\t') # Berlin 52 = 7544.37
X = buid_distance_matrix(Y)
seed = seed_function(X)
lsgrasp = greedy_randomized_adaptive_search_procedure(X, city_tour = seed, iterations = 10, rcl = 15, greediness_value = 0.5)
plot_tour_coordinates (Y, lsgrasp) # Red Point = Initial city; Orange Point = Second City