Topologisk sorteringsalgoritme: Python, C++ Eksempel
โก Smart opsummering
Topologisk sortering ordner noderne i en rettet acyklisk graf, sรฅ hver node vises fรธr dem, den peger pรฅ, ved hjรฆlp af Kahns algoritme til gentagne gange at vรฆlge noder med nul ingrad.

Hvad er topologisk sorteringsalgoritme?
Topologisk sortering er ogsรฅ kendt som Kahns algoritme og er en populรฆr sorteringsalgoritme. Ved at bruge en rettet graf som input sorterer Topologisk sortering noderne, sรฅ hver af dem vises fรธr den, den peger pรฅ.
Denne algoritme anvendes pรฅ en DAG (Directed Acyclic Graph), sรฅ hver node vises i det ordnede array fรธr alle andre noder, den peger pรฅ. Denne algoritme fรธlger visse regler gentagne gange, indtil sorteringen er fuldfรธrt.
For at forenkle, se pรฅ fรธlgende eksempel:
Instrueret graf
Her kan vi se, at "A" ikke har nogen ingrad. Ingrad betyder den kant, der peger pรฅ en node. "B" og "C" har en forudsรฆtning for "A", hvorefter "E" har en forudsรฆtning for "D"- og "F"-noder. Nogle af noderne er afhรฆngige af andre noder.
Her er en anden reprรฆsentation af ovenstรฅende graf:
Afhรฆngighed af hver node (lineรฆr rรฆkkefรธlge)
Sรฅ nรฅr vi sender DAG (Directed Acyclic Graph) til den topologiske sortering, vil det give os en matrix med lineรฆr rรฆkkefรธlge, hvor det fรธrste element ikke har nogen afhรฆngighed.
Her er trinnene til at gรธre dette:
Trin 1) Find noden med nul indgรฅende kanter, en node med nul grader.
Trin 2) Gem den nul-i-graders-node i en kรธ eller stak, og fjern noden fra grafen.
Trin 3) Slet derefter den udgรฅende kant fra den node. Dette vil mindske antallet af grader for den nรฆste node.
Topologisk rรฆkkefรธlge krรฆver, at grafens datastruktur ikke har nogen cyklus. En graf vil blive betragtet som en DAG, hvis den opfylder disse krav:
- En eller flere noder med en indegree-vรฆrdi pรฅ nul.
- Grafen indeholder ingen cyklus.
Sรฅ lรฆnge der er noder i grafen, og grafen stadig er en DAG, vil vi kรธre de ovenstรฅende tre trin. Ellers vil algoritmen falde ind i den cykliske afhรฆngighed, og Kahns algoritme vil ikke vรฆre i stand til at finde en node med nul in-grad.
Sรฅdan fungerer topologisk sortering
Her vil vi bruge "Kahns algoritme" til den topologiske sortering. Lad os sige, at vi har fรธlgende graf:
Her er trinnene til Kahns algoritme:
Trin 1) Beregn indegreen eller indgรฅende kant af alle noder i grafen.
Bemรฆrk:
- Indegree betyder de rettede kanter, der peger pรฅ noden.
- Outdegree betyder de rettede kanter, der kommer fra en node.
Her er ingraden og outgraden af โโovenstรฅende graf:
Trin 2) Find knuden med nul ingrader eller nul indgรฅende kanter. Knuden med nul ingrader betyder, at der ikke er nogen kanter, der peger mod knuden. Knude "A" har nul ingrader, hvilket betyder, at der ikke er nogen kant, der peger mod knude "A". Sรฅ vi vil udfรธre fรธlgende handlinger:
- Fjern denne node og dens udadgรฅende kanter (udgรฅende kanter).
- Placer noden i kรธen for bestilling.
- Opdater antallet af grader for nabonoden til "A".
Trin 3) Vi skal finde en node med en indegradsvรฆrdi pรฅ nul. I dette eksempel har "B" og "C" nul indegrad. Her kan vi tage en af โโdisse to. Lad os tage "B" og slette den fra grafen. Derefter opdatere indegradsvรฆrdierne for de andre noder. Efter at have udfรธrt disse operationer, vil vores graf og kรธ se sรฅledes ud:
Trin 4) Knudepunktet โCโ har ingen indgรฅende kant. Sรฅ vi fjerner knudepunktet โCโ fra grafen og sรฆtter det i kรธen. Vi kan ogsรฅ slette den kant, der er udgรฅende fra โCโ. Nu vil vores graf se sรฅdan ud:
Trin 5) Vi kan se, at noderne "D" og "F" har ingraden nul. Vi tager en node og sรฆtter den i kรธen. Lad os fรธrst fjerne "D". Sรฅ vil ingradantallet for node "E" vรฆre 1. Nu vil der ikke vรฆre nogen node fra D til E. Vi skal gรธre det samme for node "F", og vores resultat vil vรฆre som fรธlger:
Trin 6) Indgraden (indgรฅende kanter) og udgraden (udgรฅende kanter) for knudepunktet "E" blev nul. Sรฅ vi har opfyldt alle forudsรฆtningerne for knudepunktet "E". Her sรฆtter vi "E" i slutningen af โโkรธen. Sรฅ vi har ingen knudepunkter tilbage, og algoritmen slutter her.
Kaldenavn Code til topologisk sortering
Her er pseudokoden for den topologiske sortering, mens Kahns algoritme bruges.
function TopologicalSort( Graph G ): for each node in G: calculate the indegree start = Node with 0 indegree G.remove(start) topological_list = [start] while node with 0 indegree present: topological_list.append(node) G.remove(node) // Update indegree of present nodes return topological_list
Topologisk sortering kan ogsรฅ implementeres ved hjรฆlp af DFS (Dybde fรธrste sรธgning) metode. Den tilgang er dog den rekursive metode. Kahns algoritme er mere effektiv end DFS-tilgangen.
C++ Implementering af Topologisk Sortering
#include<bits/stdc++.h> using namespace std; class graph{ int vertices; list<int> *adjecentList; public: graph(int vertices){ this->vertices = vertices; adjecentList = new list<int>[vertices]; } void createEdge(int u, int v){ adjecentList[u].push_back(v); } void TopologicalSort(){ // filling the vector with zero initially vector<int> indegree_count(vertices,0); for(int i=0;i<vertices;i++){ list<int>::iterator itr; for(itr=adjecentList[i].begin(); itr!=adjecentList[i].end();itr++){ indegree_count[*itr]++; } } queue<int> Q; for(int i=0; i<vertices;i++){ if(indegree_count[i]==0){ Q.push(i); } } int visited_node = 0; vector<int> order; while(!Q.empty()){ int u = Q.front(); Q.pop(); order.push_back(u); list<int>::iterator itr; for(itr=adjecentList[u].begin(); itr!=adjecentList[u].end();itr++){ if(--indegree_count[*itr]==0){ Q.push(*itr); } } visited_node++; } if(visited_node!=vertices){ cout<<"There's a cycle present in the Graph.\nGiven graph is not DAG"<<endl; return; } for(int i=0; i<order.size();i++){ cout<<order[i]<<"\t"; } } }; int main(){ graph G(6); G.createEdge(0,1); G.createEdge(0,2); G.createEdge(1,3); G.createEdge(1,5); G.createEdge(2,3); G.createEdge(2,5); G.createEdge(3,4); G.createEdge(5,4); G.TopologicalSort(); }
Produktion
0 1 2 3 5 4
Python Implementering af Topologisk Sortering
from collections import defaultdict class graph: def __init__(self, vertices): self.adjacencyList = defaultdict(list) self.Vertices = vertices # No. of vertices # function to add an edge to adjacencyList def createEdge(self, u, v): self.adjacencyList[u].append(v) # The function to do Topological Sort. def topologicalSort(self): total_indegree = [0]*(self.Vertices) for i in self.adjacencyList: for j in self.adjacencyList[i]: total_indegree[j] += 1 queue = [] for i in range(self.Vertices): if total_indegree[i] == 0: queue.append(i) visited_node = 0 order = [] while queue: u = queue.pop(0) order.append(u) for i in self.adjacencyList[u]: total_indegree[i] -= 1 if total_indegree[i] == 0: queue.append(i) visited_node += 1 if visited_node != self.Vertices: print("There's a cycle present in the Graph.\nGiven graph is not DAG") else: print(order) G = graph(6) G.createEdge(0,1) G.createEdge(0,2) G.createEdge(1,3) G.createEdge(1,5) G.createEdge(2,3) G.createEdge(2,5) G.createEdge(3,4) G.createEdge(5,4) G.topologicalSort()
Produktion
[0, 1, 2, 3, 5, 4]
Cykliske grafer af topologisk sorteringsalgoritme
En graf, der indeholder en cyklus, kan ikke topologisk ordnes, da den cykliske graf har afhรฆngigheden pรฅ en cyklisk mรฅde. Se for eksempel denne graf:
Denne graf er ikke en DAG (Directed Acyclic Graph), fordi A, B og C skaber en cyklus. Hvis du bemรฆrker det, er der ingen node med nul vรฆrdi i grader. Ifรธlge Kahns algoritme, hvis vi analyserer ovenstรฅende graf:
- Find en node med nul grader (ingen indgรฅende kanter).
- Fjern den node fra grafen og skub den til kรธen. I ovenstรฅende graf er der dog ingen node med nul grader i in-grader. Hver node har en graders vรฆrdi stรธrre end 0.
- Returner en tom kรธ, da den ikke kunne finde nogen node med nul grader i grader.
Vi kan detektere cyklusser ved hjรฆlp af den topologiske rรฆkkefรธlge med fรธlgende trin:
Trin 1) Udfรธr topologisk sortering.
Trin 2) Beregn det samlede antal elementer i den topologisk sorterede liste.
Trin 3) Hvis antallet af elementer er lig med det samlede antal hjรธrner, er der ingen cyklus.
Trin 4) Hvis det ikke er lig med antallet af hjรธrner, er der mindst รฉn cyklus i den givne grafdatastruktur.
Kompleksitetsanalyse af topologisk sort
Der er to typer kompleksitet i algoritmer. De er:
- Tidskompleksitet
- Rumkompleksitet
Disse kompleksiteter er reprรฆsenteret med en funktion, der giver en generel kompleksitet.
Tidskompleksitet: Al tidskompleksitet er den samme for topologisk sortering. Der er vรฆrst tรฆnkelige, gennemsnitlige og bedste tรฆnkelige scenarier for tidskompleksitet. Tidskompleksiteten for topologisk sortering er O(E + V), hvor E stรฅr for antallet af kanter i grafen, og V stรฅr for antallet af hjรธrner i grafen.
Lad os bryde igennem denne kompleksitet:
Trin 1) I begyndelsen vil vi beregne alle graderne. For at gรธre det skal vi gรฅ gennem alle kanterne, og til at begynde med vil vi tildele alle V vertex-grader til nul. Sรฅ de trinvise trin, vi gennemfรธrer, vil vรฆre O(V+E).
Trin 2) Vi finder noden med nul indegree vรฆrdi. Vi skal sรธge fra toppunktets V-nummer. Sรฅ de gennemfรธrte trin vil vรฆre O (V).
Trin 3) For hver knude med nul grader, vil vi fjerne denne node og formindske indegreen. Det vil tage at udfรธre denne operation for alle noderne O(E).
Trin 4) Til sidst vil vi kontrollere, om der er nogen cyklus eller ej. Vi vil kontrollere, om det samlede antal elementer i det sorterede array er lig med det samlede antal noder. Det vil tage O (1).
Sรฅ dette var de individuelle tidskompleksiteter for hvert trin i den topologiske sortering eller topologiske ordning. Vi kan sige, at tidskompleksiteten fra ovenstรฅende beregning vil vรฆre O(V + E); her betyder O kompleksitetsfunktionen.
Rumkompleksitet: Vi havde brug for O(V)-rum til at kรธre den topologiske sorteringsalgoritme. Her er de trin, hvor vi havde brug for pladsen til programmet:
- Vi var nรธdt til at beregne alle de grader af noder, der er til stede i grafen. Da grafen har i alt V-noder, er vi nรธdt til at skabe en matrix af stรธrrelse V. Sรฅ den nรธdvendige plads var O (V).
- En kรธdatastruktur blev brugt til at lagre noden med nul indegree. Vi fjernede noderne med nul indegree fra den originale graf og placerede dem i kรธen. Til dette var den nรธdvendige plads O (V).
- Arrayet hedder "orden", som gemte noderne i topologisk rรฆkkefรธlge. Det krรฆvede ogsรฅ O (V) rum.
Dette var de individuelle rumkompleksiteter. Sรฅ vi er nรธdt til at maksimere disse rum i lรธbetid. Rumkompleksitet stรฅr for O(V), hvor V stรฅr for antallet af hjรธrner i grafen.
Anvendelse af topologisk sort
Der er en enorm anvendelse for topologisk sortering. Her er nogle af dem:
- Det bruges nรฅr en Operating system skal udfรธre ressourceallokeringen.
- Find en cyklus i grafen. Vi kan validere, om grafen er en DAG eller ej, med topologisk sortering.
- Sรฆtningsrรฆkkefรธlge i autofuldfรธrelsesapps.
- Det bruges til at detektere blokeringer.
- Forskellige typer planlรฆgning eller kursusplanlรฆgning bruger topologisk sortering.
- Lรธsning af afhรฆngigheder. For eksempel, hvis du prรธver at installere en pakke, kan den pakke muligvis ogsรฅ have brug for andre pakker. Topologisk bestilling finder ud af alle de nรธdvendige pakker for at installere den aktuelle pakke.
- Linux bruger den topologiske sortering i "apt" til at kontrollere pakkernes afhรฆngighed.











