Kahn-algoritmus
Kiejtés
- IPA: [ ˈkɒxnɒlɡoritmuʃ]
Főnév
- (matematika) A Kahn-algoritmus egy széles körben használt módszer a topologikus rendezés elvégzésére irányított, körmentes gráfokon (DAG - Directed Acyclic Graph). A topologikus rendezés egy olyan sorrend, amelyben a gráf csúcsai elrendezhetők úgy, hogy minden irányított él ( (u, v) ) esetén ( u ) mindig ( v ) előtt szerepel a sorrendben.
Fő ötlet
Az algoritmus az indegree (bejövő élek száma) fogalmát használja: 1. Azokat a csúcsokat választja ki, amelyeknek nincs bejövő élük (indegree = 0). 2. Ezeket a csúcsokat a sorrendbe helyezi, majd eltávolítja őket a gráfból. 3. A folyamatot addig ismétli, amíg az összes csúcsot feldolgozza, vagy megáll, ha kör található a gráfban.
Algoritmus lépései
1. Indegree kiszámítása
- Minden csúcsra meghatározzuk a bejövő élek számát.
2. Indegree = 0 csúcsok hozzáadása a várakozási sorhoz
- Egy olyan adatszerkezetbe helyezzük a csúcsokat (például sorba vagy verembe), amelyeknek nincs bejövő élük.
3. Iteráció
- Amíg a várakozási sor nem üres:
- Vegyük ki a sor első elemét, és adjuk hozzá a topologikus sorrendhez.
- Távolítsuk el a gráfhoz tartozó éleit, és frissítsük a bejövő élek számát.
- Ha egy csúcs bejövő élei 0-ra csökkennek, adjuk hozzá a várakozási sorhoz.
4. Ellenőrzés
- Ha minden csúcs feldolgozásra került, a gráf topologikusan rendezett.
- Ha maradnak csúcsok bejövő élekkel, a gráf kör tartalmaz.
Idő- és tárkomplexitás
- Időbonyolultság: ( O(V + E) ), ahol ( V ) a csúcsok és ( E ) az élek száma.
- Tárbonyolultság: ( O(V + E) ) az adatszerkezetek tárolására.
Pszeudokód
KahnAlgorithm(graph): indegree = [0] * len(graph) for u in graph: for v in graph[u]: indegree[v] += 1 queue = [] for i in range(len(indegree)): if indegree[i] == 0: queue.append(i) topo_order = [] while queue: u = queue.pop(0) topo_order.append(u) for v in graph[u]: indegree[v] -= 1 if indegree[v] == 0: queue.append(v) if len(topo_order) != len(graph): return "Kör található a gráfban!" return topo_order
Python implementáció
from collections import deque
def kahn_topological_sort(graph):
# Indegree kiszámítása
indegree = {node: 0 for node in graph}
for u in graph:
for v in graph[u]:
indegree[v] += 1
# Indegree = 0 csúcsok hozzáadása a sorhoz
queue = deque([node for node in graph if indegree[node] == 0])
topo_order = []
while queue:
u = queue.popleft()
topo_order.append(u)
for v in graph[u]:
indegree[v] -= 1
if indegree[v] == 0:
queue.append(v)
# Ellenőrzés, hogy körmentes-e a gráf
if len(topo_order) != len(graph):
return "Kör található a gráfban!"
return topo_order
# Példa gráf
graph = {
0: [1, 2],
1: [3],
2: [3],
3: [4],
4: []
}
print("Topologikus sorrend:", kahn_topological_sort(graph))
Kimenet:
Topologikus sorrend: [0, 1, 2, 3, 4]
C++ implementáció
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;
vector<int> kahn_topological_sort(unordered_map<int, vector<int>>& graph, int V) {
vector<int> indegree(V, 0);
// Indegree kiszámítása
for (const auto& [u, neighbors] : graph) {
for (int v : neighbors) {
indegree[v]++;
}
}
// Indegree = 0 csúcsok hozzáadása a sorhoz
queue<int> q;
for (int i = 0; i < V; ++i) {
if (indegree[i] == 0) {
q.push(i);
}
}
vector<int> topo_order;
while (!q.empty()) {
int u = q.front();
q.pop();
topo_order.push_back(u);
for (int v : graph[u]) {
indegree[v]--;
if (indegree[v] == 0) {
q.push(v);
}
}
}
// Ellenőrzés, hogy körmentes-e a gráf
if (topo_order.size() != V) {
cout << "Kör található a gráfban!" << endl;
return {};
}
return topo_order;
}
int main() {
unordered_map<int, vector<int>> graph = {
{0, {1, 2}},
{1, {3}},
{2, {3}},
{3, {4}},
{4, {}}
};
int V = 5;
vector<int> topo_order = kahn_topological_sort(graph, V);
cout << "Topologikus sorrend: ";
for (int node : topo_order) {
cout << node << " ";
}
cout << endl;
return 0;
}
Kimenet:
Topologikus sorrend: 0 1 2 3 4
Alkalmazások
- Feladatütemezés:
- Függőségek kezelése, például projektek vagy feladatok sorrendjének meghatározása.
- Verziókezelés:
- Kód függőségek sorrendjének meghatározása.
- Gráf algoritmusok:
- Körök keresése irányított gráfokban.
- Fordítóprogramok:
- Kódkomponensek (osztályok, függvények) sorrendjének meghatározása.
Összegzés
A Kahn-algoritmus egy hatékony és egyszerű módszer a topologikus rendezésre irányított, körmentes gráfokon. Az (O(V + E)) időbonyolultsága miatt nagy gráfok esetén is hatékony, és széles körben alkalmazható valós problémák megoldására, például feladatütemezésre és függőségkezelésre. Az algoritmus körök detektálására is használható, ami különösen hasznos hibakeresési és rendszerelemzési feladatokban.
- Kahn-algoritmus - Értelmező szótár (MEK)
- Kahn-algoritmus - Etimológiai szótár (UMIL)
- Kahn-algoritmus - Szótár.net (hu-hu)
- Kahn-algoritmus - DeepL (hu-de)
- Kahn-algoritmus - Яндекс (hu-ru)
- Kahn-algoritmus - Google (hu-en)
- Kahn-algoritmus - Helyesírási szótár (MTA)
- Kahn-algoritmus - Wikidata
- Kahn-algoritmus - Wikipédia (magyar)