tabu keresés
Kiejtés
- IPA: [ ˈtɒbukɛrɛʃeːʃ]
Főnév
- (informatika, algoritmusok) A tabu keresés egy heurisztikus optimalizációs algoritmus, amelyet Fred Glover vezetett be 1986-ban. Az algoritmus célja, hogy lokális keresési módszerek korlátait legyőzze, például a lokális optimumokban való elakadást. Ennek érdekében tabulistát használ, amely megakadályozza, hogy az algoritmus visszatérjen korábban meglátogatott vagy nem kívánatos megoldásokhoz.
Algoritmus működése
- Inicializáció:
- Kezdeti megoldás ((s_0)) kiválasztása.
- Egy „tabulista” létrehozása, amely korlátozza a bizonyos megoldásokhoz való visszatérést.
- Paraméterek inicializálása, például a tabulista mérete és a maximális iterációk száma.
- Szomszédos megoldások generálása:
- A jelenlegi megoldásból ((s)) származtatott szomszédos megoldások halmazát ((N(s))) hozd létre.
- Legjobb szomszéd kiválasztása:
- A szomszédos megoldások közül válaszd ki a legjobbat, figyelembe véve a tabulista korlátozásait.
- Ha a megoldás tabu, de megfelel egy törekvési kritériumnak, engedélyezd.
- Frissítés:
- Frissítsd az aktuális megoldást és a tabulistát.
- A tabulista új megoldást ad hozzá, és eltávolítja a legrégebbi elemet, ha a mérete meghaladja a megengedettet.
- Megállási feltétel:
- Az algoritmus addig iterál, amíg el nem éri a maximális iterációk számát vagy egy elfogadható megoldást.
Tabulista
A tabulista a már meglátogatott megoldásokat vagy bizonyos jellemzőiket (pl. lépéseket) tárolja. Célja, hogy: - Megakadályozza a ciklusokat. - Segítsen elkerülni a lokális optimumokat.
Algoritmus Pszeudokódja
TabuSearch(s_0, max_iter, tabu_size): s = s_0 # Inicializálás kezdő megoldással best_solution = s # Kezdetben a legjobb megoldás a kezdő tabu_list = [] # Tabulista inicializálása for i = 1 to max_iter: neighbors = GenerateNeighbors(s) best_neighbor = SelectBestNeighbor(neighbors, tabu_list) if Fitness(best_neighbor) < Fitness(best_solution): best_solution = best_neighbor UpdateTabuList(tabu_list, s, tabu_size) s = best_neighbor return best_solution
Példa
Utazóügynök probléma (TSP)
Adott városok és az közöttük lévő távolságok. Találj egy minimális távolságú körutat.
Python implementáció
import random
def calculate_distance(route, distances):
"""Teljes távolság kiszámítása egy adott útvonalhoz."""
total_distance = 0
for i in range(len(route) - 1):
total_distance += distances[route[i]][route[i + 1]]
total_distance += distances[route[-1]][route[0]] # Körút
return total_distance
def generate_neighbors(route):
"""Szomszédos megoldások generálása az útvonal cseréjével."""
neighbors = []
for i in range(len(route)):
for j in range(i + 1, len(route)):
neighbor = route[:]
neighbor[i], neighbor[j] = neighbor[j], neighbor[i]
neighbors.append(neighbor)
return neighbors
def tabu_search(distances, initial_route, max_iter, tabu_size):
current_route = initial_route[:]
best_route = initial_route[:]
tabu_list = []
for _ in range(max_iter):
neighbors = generate_neighbors(current_route)
best_neighbor = None
best_distance = float('inf')
for neighbor in neighbors:
if neighbor not in tabu_list:
distance = calculate_distance(neighbor, distances)
if distance < best_distance:
best_neighbor = neighbor
best_distance = distance
if best_neighbor is None:
break
if best_distance < calculate_distance(best_route, distances):
best_route = best_neighbor
tabu_list.append(best_neighbor)
if len(tabu_list) > tabu_size:
tabu_list.pop(0)
current_route = best_neighbor
return best_route, calculate_distance(best_route, distances)
# Példa adatok
distances = {
0: {1: 10, 2: 15, 3: 20},
1: {0: 10, 2: 35, 3: 25},
2: {0: 15, 1: 35, 3: 30},
3: {0: 20, 1: 25, 2: 30}
}
initial_route = [0, 1, 2, 3]
# Tabu keresés futtatása
best_route, best_distance = tabu_search(distances, initial_route, max_iter=100, tabu_size=5)
print(f"Legjobb útvonal: {best_route}, Távolság: {best_distance}")
Kimenet:
Legjobb útvonal: [0, 1, 3, 2], Távolság: 80
C++ implementáció
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
int calculate_distance(const vector<int>& route, const vector<vector<int>>& distances) {
int total_distance = 0;
for (size_t i = 0; i < route.size() - 1; ++i) {
total_distance += distances[route[i]][route[i + 1]];
}
total_distance += distances[route.back()][route[0]];
return total_distance;
}
vector<vector<int>> generate_neighbors(const vector<int>& route) {
vector<vector<int>> neighbors;
for (size_t i = 0; i < route.size(); ++i) {
for (size_t j = i + 1; j < route.size(); ++j) {
vector<int> neighbor = route;
swap(neighbor[i], neighbor[j]);
neighbors.push_back(neighbor);
}
}
return neighbors;
}
pair<vector<int>, int> tabu_search(const vector<vector<int>>& distances, vector<int> initial_route, int max_iter, int tabu_size) {
vector<int> current_route = initial_route;
vector<int> best_route = initial_route;
vector<vector<int>> tabu_list;
for (int iter = 0; iter < max_iter; ++iter) {
auto neighbors = generate_neighbors(current_route);
vector<int> best_neighbor;
int best_distance = INT_MAX;
for (const auto& neighbor : neighbors) {
if (find(tabu_list.begin(), tabu_list.end(), neighbor) == tabu_list.end()) {
int distance = calculate_distance(neighbor, distances);
if (distance < best_distance) {
best_neighbor = neighbor;
best_distance = distance;
}
}
}
if (best_neighbor.empty()) {
break;
}
if (best_distance < calculate_distance(best_route, distances)) {
best_route = best_neighbor;
}
tabu_list.push_back(best_neighbor);
if (tabu_list.size() > tabu_size) {
tabu_list.erase(tabu_list.begin());
}
current_route = best_neighbor;
}
return {best_route, calculate_distance(best_route, distances)};
}
int main() {
vector<vector<int>> distances = {
{0, 10, 15, 20},
{10, 0, 35, 25},
{15, 35, 0, 30},
{20, 25, 30, 0}
};
vector<int> initial_route = {0, 1, 2, 3};
auto [best_route, best_distance] = tabu_search(distances, initial_route, 100, 5);
cout << "Legjobb útvonal: ";
for (int city : best_route) {
cout << city << " ";
}
cout << "\nTávolság: " << best_distance << endl;
return 0;
}
Kimenet:
Legjobb útvonal: 0 1 3 2 Távolság: 80
Előnyök
- Elkerüli a lokális optimumokat a tabulista segítségével.
- Könnyen adaptálható különböző problémákhoz.
- Hatékony kombinatorikus optimalizációs problémákra.
Hátrányok
- Paraméterérzékeny (tabulista mérete, maximális iterációk száma).
- Nagy számítási költség sok szomszédos megoldás esetén.
- Globális optimumot nem garantálja.
Összegzés
A tabu keresés egy hatékony heurisztikus algoritmus, amely jól alkalmazható összetett kombinatorikus problémák megoldására, például az utazóügynök problémára vagy ütemezési feladatokra. Bár nem garantálja a globális optimum elérését, a lokális optimumok elkerülésére kiváló módszer.
Fordítások
Tartalom
- tabu keresés - Értelmező szótár (MEK)
- tabu keresés - Etimológiai szótár (UMIL)
- tabu keresés - Szótár.net (hu-hu)
- tabu keresés - DeepL (hu-de)
- tabu keresés - Яндекс (hu-ru)
- tabu keresés - Google (hu-en)
- tabu keresés - Helyesírási szótár (MTA)
- tabu keresés - Wikidata
- tabu keresés - Wikipédia (magyar)