Breadth First Search (BFS) je základom algoritmus prechodu grafu . Zahŕňa návštevu všetkých pripojených uzlov grafu spôsobom úroveň po úrovni. V tomto článku sa pozrieme na koncept BFS a ako ho možno efektívne aplikovať na grafy
pokladňa pomocou git
Obsah
- Breadth First Search alebo BFS pre graf
- Vzťah medzi BFS pre graf a BFS pre strom
- Breadth First Search (BFS) pre grafový algoritmus
- Ako funguje algoritmus BFS?
- Implementácia BFS pre Graph pomocou Adjacency List
- Zložitosť algoritmu BFS (Breadth-First Search).
- Aplikácie BFS v grafoch
- Problémy pri prvom hľadaní šírky alebo BFS pre graf
- Časté otázky o šírke prvého vyhľadávania (BFS) pre graf
Breadth First Search (BFS) pre graf:
Breadth First Search (BFS) je algoritmus prechodu grafu, ktorý skúma všetky vrcholy v grafe v aktuálnej hĺbke pred prechodom na vrcholy na ďalšej úrovni hĺbky. Začína v určenom vrchole a navštevuje všetkých svojich susedov a potom prejde na ďalšiu úroveň susedov. BFS sa bežne používa v algoritmoch na hľadanie ciest, pripojených komponentov a problémov s najkratšou cestou v grafoch.
Vzťah medzi BFS pre graf a BFS pre strom:
Breadth-First Traversal (BFS) pre graf je podobný Prechod stromu do šírky .
Jediným háčikom je, že na rozdiel stromy , grafov môže obsahovať cykly, takže sa môžeme opäť dostať do toho istého uzla. Aby sme sa vyhli spracovaniu uzla viac ako raz, rozdeľujeme vrcholy do dvoch kategórií:
- Navštívil a
- Nenavštívené.
Na označenie navštívených vrcholov sa používa boolovské navštívené pole. Pre jednoduchosť sa predpokladá, že všetky vrcholy sú dosiahnuteľné z počiatočného vrcholu. BFS používa a Breadth First Search (BFS) pre grafový algoritmus:
Poďme diskutovať o algoritme pre BFS:
- Inicializácia: Zaraďte počiatočný uzol do frontu a označte ho ako navštívený.
- Prieskum: Kým rad nie je prázdny:
- Vyraďte uzol z frontu a navštívte ho (napr. vytlačte jeho hodnotu).
- Pre každého nenavštíveného suseda vyradeného uzla:
- Zaraďte suseda do frontu.
- Označte suseda ako navštíveného.
- Ukončenie: Opakujte krok 2, kým nebude front prázdny.
Tento algoritmus zaisťuje, že všetky uzly v grafe sú navštívené v šírke, začínajúc od počiatočného uzla.
Ako funguje algoritmus BFS?
Počnúc od koreňa sa najprv navštívia všetky uzly na určitej úrovni a potom sa prejdú uzly ďalšej úrovne, až kým sa nenavštívia všetky uzly.
Na tento účel sa používa rad. Všetky susedné nenavštívené uzly aktuálnej úrovne sa zaradia do frontu a uzly aktuálnej úrovne sa označia ako navštívené a vypustené z frontu.
Ilustrácia:
Poďme pochopiť fungovanie algoritmu pomocou nasledujúceho príkladu.
Krok 1: Na začiatku sú front a navštívené polia prázdne.
Front a navštívené polia sú spočiatku prázdne.
Krok 2: Zaradiť uzol 0 do fronty a označiť ho ako navštívený.
Zaradiť uzol 0 do fronty a označiť ho ako navštívený.
Krok 3: Odstráňte uzol 0 z prednej časti frontu a navštívte nenavštívených susedov a zaraďte ich do frontu.
Odstráňte uzol 0 z prednej časti frontu a navštívili nenavštívených susedov a zatlačte do frontu.
Krok 4: Odstráňte uzol 1 z prednej časti frontu a navštívte nenavštívených susedov a zaraďte ich do frontu.
Odstráňte uzol 1 z prednej časti frontu a navštívili nenavštívených susedov a zatlačte
Krok 5: Odstráňte uzol 2 z prednej časti frontu a navštívte nenavštívených susedov a zatlačte ich do frontu.
Odstráňte uzol 2 z prednej časti frontu a navštívte nenavštívených susedov a zatlačte ich do frontu.
Krok 6: Odstráňte uzol 3 z prednej časti frontu a navštívte nenavštívených susedov a zatlačte ich do frontu.
Ako vidíme, že sú navštívení všetci susedia uzla 3, prejdite na ďalší uzol, ktorý je v prednej časti frontu.nginxOdstráňte uzol 3 z prednej časti frontu a navštívte nenavštívených susedov a zatlačte ich do frontu.
Kroky 7: Odstráňte uzol 4 z prednej časti frontu a navštívte nenavštívených susedov a zaraďte ich do frontu.
Ako vidíme, že sú navštívení všetci susedia uzla 4, prejdite na ďalší uzol, ktorý je v prednej časti frontu.Odstráňte uzol 4 z prednej časti frontu a navštívte nenavštívených susedov a zaraďte ich do frontu.
Teraz sa front vyprázdni, takže ukončite tento proces opakovania.
zablokované kontakty
Implementácia BFS pre Graph pomocou zoznamu susediacich krajín:
C++ #include #include #include using namespace std; // Function to perform Breadth First Search on a graph // represented using adjacency list void bfs(vector>& adjList, int startNode, vector & navštívené) { // Vytvorenie frontu pre front BFS q; // Označiť aktuálny uzol ako navštívený a zaradiť ho do frontu[startNode] = true; q.push(startNode); // Iterácia cez front while (!q.empty()) { // Dequeue vrchol z frontu a vytlačí ho int currentNode = q.front(); q.pop(); cout<< currentNode << ' '; // Get all adjacent vertices of the dequeued vertex // currentNode If an adjacent has not been visited, // then mark it visited and enqueue it for (int neighbor : adjList[currentNode]) { if (!visited[neighbor]) { visited[neighbor] = true; q.push(neighbor); } } } } // Function to add an edge to the graph void addEdge(vector>& adjList, int u, int v) { adjList[u].push_back(v); } int main() { // Počet vrcholov v grafe int vrcholov = 5; // Reprezentácia zoznamu susediacich vektorov grafu> adjList(vertices); // Pridanie hrán do grafu addEdge(adjList, 0, 1); addEdge(adjList, 0, 2); addEdge(adjList, 1, 3); addEdge(adjList, 1, 4); addEdge(adjList, 2, 4); // Označte všetky vrcholy ako nenavštívený vektor navštívené(vrcholy, nepravda); // Vykonajte prechod BFS od vrcholu 0 cout<< 'Breadth First Traversal starting from vertex ' '0: '; bfs(adjList, 0, visited); return 0; }>
C #include #include #define MAX_VERTICES 100 // Structure to represent a node in adjacency list struct Node { int data; struct Node* next; }; // Function to create a new node struct Node* createNode(int data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->dáta = dáta; newNode->next = NULL; return newNode; } // Funkcia na pridanie hrany do grafu void addEdge(struct Node* adjList[], int u, int v) { struct Node* newNode = createNode(v); newNode->next = adjList[u]; adjList[u] = newNode; } // Funkcia na vykonanie šírky prvého vyhľadávania v grafe // reprezentovanom pomocou zoznamu susediacich void bfs(struct Node* adjList[], int vertices, int startNode, int visited[]) { // Vytvorenie frontu pre BFS int queue[ MAX_VERTICES]; vnútorné predné = 0, zadné = 0; // Označiť aktuálny uzol ako navštívený a zaradiť ho do frontu[startNode] = 1; fronta[zadny++] = startNode; // Iterácia cez front while (front != zadný) { // Dequeue a vertex from queue and print it int currentNode = queue[front++]; printf('%d ', aktuálnyUzol); // Získanie všetkých susedných vrcholov odradeného vrcholu // currentNode Ak susedný uzol nebol navštívený, // potom ho označte ako navštívený a zaraďte ho do frontu struct Node* temp = adjList[currentNode]; while (temp != NULL) { int sused = temp->data; if (!navštívil[sused]) { navštívil[sused] = 1; front[zadný++] = sused; } temp = temp->ďalší; } } } int main() { // Počet vrcholov v grafe int vrcholov = 5; // Reprezentácia zoznamu susediacich štruktúr grafu Node* adjList[vertices]; pre (int i = 0; i< vertices; ++i) adjList[i] = NULL; // Add edges to the graph addEdge(adjList, 0, 1); addEdge(adjList, 0, 2); addEdge(adjList, 1, 3); addEdge(adjList, 1, 4); addEdge(adjList, 2, 4); // Mark all the vertices as not visited int visited[vertices]; for (int i = 0; i < vertices; ++i) visited[i] = 0; // Perform BFS traversal starting from vertex 0 printf( 'Breadth First Traversal starting from vertex 0: '); bfs(adjList, vertices, 0, visited); return 0; }>
Java import java.util.LinkedList; import java.util.Queue; // Class to represent a graph using adjacency list class Graph { int vertices; LinkedList [] adjList; @SuppressWarnings('unchecked') Graph(int vertices) { this.vertices = vertices; adjList = new LinkedList[vrcholy]; pre (int i = 0; i< vertices; ++i) adjList[i] = new LinkedList(); } // Function to add an edge to the graph void addEdge(int u, int v) { adjList[u].add(v); } // Function to perform Breadth First Search on a graph // represented using adjacency list void bfs(int startNode) { // Create a queue for BFS Queue fronta = new LinkedList(); boolean[] navštívené = new boolean[vertices]; // Označiť aktuálny uzol ako navštívený a zaradiť ho do frontu[startNode] = true; queue.add(startNode); // Iterácia frontu while (!queue.isEmpty()) { // Vyradí vrchol z frontu a vytlačí ho int currentNode = queue.poll(); System.out.print(currentNode + ' '); // Získanie všetkých susedných vrcholov vyradeného // vrcholu currentNode Ak sused // nebol navštívený, potom ho označte ako navštívený a // zaraďte ho do frontu pre (int sused : adjList[currentNode]) { if (!visited[neighbor] ) { navštívený[sused] = true; queue.add(neighbor); } } } } } public class Main { public static void main(String[] args) { // Počet vrcholov v grafe int vertices = 5; // Vytvorenie grafu Graf grafu = new Graph(vertices); // Pridanie hrán do grafu graph.addEdge(0, 1); graph.addEdge(0, 2); graph.addEdge(1, 3); graph.addEdge(1, 4); graph.addEdge(2, 4); // Vykonanie prechodu BFS počnúc vrcholom 0 System.out.print( 'Breadth First Traversal od vrcholu 0: '); graf.bfs(0); } }>
Python3 from collections import deque # Function to perform Breadth First Search on a graph # represented using adjacency list def bfs(adjList, startNode, visited): # Create a queue for BFS q = deque() # Mark the current node as visited and enqueue it visited[startNode] = True q.append(startNode) # Iterate over the queue while q: # Dequeue a vertex from queue and print it currentNode = q.popleft() print(currentNode, end=' ') # Get all adjacent vertices of the dequeued vertex # If an adjacent has not been visited, then mark it visited and enqueue it for neighbor in adjList[currentNode]: if not visited[neighbor]: visited[neighbor] = True q.append(neighbor) # Function to add an edge to the graph def addEdge(adjList, u, v): adjList[u].append(v) def main(): # Number of vertices in the graph vertices = 5 # Adjacency list representation of the graph adjList = [[] for _ in range(vertices)] # Add edges to the graph addEdge(adjList, 0, 1) addEdge(adjList, 0, 2) addEdge(adjList, 1, 3) addEdge(adjList, 1, 4) addEdge(adjList, 2, 4) # Mark all the vertices as not visited visited = [False] * vertices # Perform BFS traversal starting from vertex 0 print('Breadth First Traversal starting from vertex 0:', end=' ') bfs(adjList, 0, visited) if __name__ == '__main__': main()>
C# using System; using System.Collections.Generic; // Class to represent a graph using adjacency list class Graph { int vertices; List [] adjList; public Graph(int vertices) { this.vertices = vertices; adjList = nový zoznam [ vrcholy ]; pre (int i = 0; i< vertices; ++i) adjList[i] = new List (); } // Funkcia na pridanie hrany do grafu public void AddEdge(int u, int v) { adjList[u].Add(v); } // Funkcia na vykonanie šírky prvého vyhľadávania na grafe // reprezentovaná pomocou zoznamu susedných vzťahov public void BFS(int startNode) { // Vytvorenie frontu pre BFS Queue front = nový front (); bool[] navštívené = nové bool[vrcholy]; // Označiť aktuálny uzol ako navštívený a zaradiť ho do frontu[startNode] = true; queue.Enqueue(startNode); // Iterácia cez front while (queue.Count != 0) { // Vyradí vrchol z frontu a vytlačí ho int currentNode = queue.Dequeue(); Console.Write(currentNode + ' '); // Získanie všetkých susedných vrcholov vyradeného // vrchola currentNode Ak sused // nebol navštívený, potom ho označte ako navštívený a // zaraďte ho do frontu (int sused v adjList[currentNode]) { if (!visited[neighbor] ) { navštívený[sused] = true; fronta.Enqueue(sused); } } } } } class MainClass { public static void Main(string[] args) { // Počet vrcholov v grafe int vertices = 5; // Vytvorenie grafu Graf grafu = new Graph(vertices); // Pridanie hrán do grafu grafu.AddEdge(0, 1); graph.AddEdge(0, 2); graph.AddEdge(1, 3); graph.AddEdge(1, 4); graph.AddEdge(2, 4); // Vykonanie prechodu BFS počnúc vrcholom 0 Console.Write( 'Breadth First Traversal od vrcholu 0: '); graf.BFS(0); } }>
Javascript // Class to represent a graph using adjacency list class Graph { constructor() { this.adjList = {}; } // Function to add an edge to the graph addEdge(u, v) { if (!this.adjList[u]) this.adjList[u] = []; this.adjList[u].push(v); } // Function to perform Breadth First Search on a graph represented using adjacency list bfs(startNode) { // Create a queue for BFS const queue = []; const visited = new Array(Object.keys(this.adjList).length).fill(false); // Mark the current node as visited and enqueue it visited[startNode] = true; queue.push(startNode); // Iterate over the queue while (queue.length !== 0) { // Dequeue a vertex from queue and print it const currentNode = queue.shift(); console.log(currentNode + ' '); // Get all adjacent vertices of the dequeued vertex currentNode // If an adjacent has not been visited, then mark it visited and enqueue it for (const neighbor of this.adjList[currentNode] || []) { if (!visited[neighbor]) { visited[neighbor] = true; queue.push(neighbor); } } } } } // Create a graph const graph = new Graph(); // Add edges to the graph graph.addEdge(0, 1); graph.addEdge(0, 2); graph.addEdge(1, 3); graph.addEdge(1, 4); graph.addEdge(2, 4); // Perform BFS traversal starting from vertex 0 console.log('Breadth First Traversal starting from vertex 0: '); graph.bfs(0);>
Výkon
Breadth First Traversal starting from vertex 0: 0 1 2 3 4>
Časová zložitosť: O(V+E), kde V je počet uzlov a E je počet hrán.
Pomocný priestor: O(V)
Analýza zložitosti algoritmu BFS (Breadth-First Search):
Časová zložitosť algoritmu BFS: O(V + E)
- BFS skúma všetky vrcholy a hrany v grafe. V horšom prípade navštívi každý vrchol a hranu raz. Časová zložitosť BFS je teda O(V + E), kde V a E je počet vrcholov a hrán v danom grafe.
Priestorová zložitosť algoritmu BFS: O(V)
- BFS používa front na sledovanie vrcholov, ktoré je potrebné navštíviť. V najhoršom prípade môže front obsahovať všetky vrcholy v grafe. Priestorová zložitosť BFS je teda O(V), kde V a E sú počty vrcholov a hrán v danom grafe.
Aplikácie BFS v grafoch:
BFS má rôzne aplikácie v teórii grafov a počítačovej vede, vrátane:
- Hľadanie najkratšej cesty: BFS možno použiť na nájdenie najkratšej cesty medzi dvoma uzlami v neváženom grafe. Sledovaním rodiča každého uzla počas prechodu je možné rekonštruovať najkratšiu cestu.
- Detekcia cyklu: BFS možno použiť na detekciu cyklov v grafe. Ak sa uzol navštívi dvakrát počas prechodu, indikuje to prítomnosť cyklu.
- Pripojené komponenty: BFS možno použiť na identifikáciu pripojených komponentov v grafe. Každý pripojený komponent je množina uzlov, ktoré sa dajú dosiahnuť jeden od druhého.
- Topologické triedenie: BFS možno použiť na vykonávanie topologického triedenia na orientovanom acyklickom grafe (DAG). Topologické triedenie usporiada uzly v lineárnom poradí tak, že pre akúkoľvek hranu (u, v) sa u objaví v poradí pred v.
- Prechod binárnych stromov podľa poradia úrovní: BFS možno použiť na vykonanie prechodu binárneho stromu podľa poradia úrovne. Toto prechádzanie navštívi všetky uzly na rovnakej úrovni pred prechodom na ďalšiu úroveň.
- Smerovanie siete: BFS možno použiť na nájdenie najkratšej cesty medzi dvoma uzlami v sieti, čo je užitočné na smerovanie dátových paketov v sieťových protokoloch.
Problémy pri prvom vyhľadávaní šírky alebo BFS pre graf:
Áno nie | Problémy | Prax |
---|---|---|
1. | Nájdite úroveň daného uzla v neorientovanom grafe | Odkaz |
2. | Minimalizujte maximálny susedný rozdiel v ceste z ľavého horného rohu do pravého dolného rohu | Odkaz |
10. | Skontrolujte, či je cieľ danej matice dosiahnuteľný s požadovanými hodnotami buniek | Odkaz |
Často kladené otázky o šírke prvého vyhľadávania (BFS) pre graf:
Otázka 1: Čo je BFS a ako funguje?
odpoveď: BFS je algoritmus prechodu grafu, ktorý systematicky skúma graf navštívením všetkých vrcholov na danej úrovni pred prechodom na ďalšiu úroveň. Začne od počiatočného vrcholu, zaradí ho do frontu a označí ho ako navštívený. Potom vyradí vrchol z frontu, navštívi ho a zaradí všetkých jeho nenavštívených susedov do frontu. Tento proces pokračuje, kým sa front nevyprázdni.
Otázka 2: Aké sú aplikácie BFS?
odpoveď: BFS má rôzne aplikácie, vrátane hľadania najkratšej cesty v neváženom grafe, detekcie cyklov v grafe, topologického triedenia orientovaného acyklického grafu (DAG), hľadania spojených komponentov v grafe a riešenia hádaniek, ako sú bludisko a sudoku.
Otázka 3: Aká je časová zložitosť BFS?
odpoveď: Časová zložitosť BFS je O(V + E), kde V je počet vrcholov a E je počet hrán v grafe.
Otázka 4: Aká je vesmírna zložitosť BFS?
odpoveď: Priestorová zložitosť BFS je O(V), pretože používa front na sledovanie vrcholov, ktoré je potrebné navštíviť.
Otázka 5: Aké sú výhody používania BFS?
odpoveď: BFS sa jednoducho implementuje a je efektívny na nájdenie najkratšej cesty v neváženom grafe. Tiež zaručuje, že sú navštívené všetky vrcholy v grafe.
Súvisiace články:
- Najnovšie články o BFS
- Prvý prechod do hĺbky
- Aplikácie Breadth First Traversal
- Aplikácie hĺbkového prvého vyhľadávania
- Časová a priestorová zložitosť prvého vyhľadávania šírky (BFS)