Bredth-first search ( BFS ) är en av graftraversalmetoderna . Låt grafen ges och det initiala hörnet . Den bredd-första sökalgoritmen korsar systematiskt alla kanter för att "upptäcka" alla hörn som kan nås från , samtidigt som den beräknar avståndet (minsta antal kanter) från till varje nåbar vertex. Algoritmen fungerar för både riktade och oriktade grafer. [ett]
Bredth-first search har detta namn eftersom vi i traverseringsprocessen går i bredd, det vill säga innan vi börjar söka efter hörn på avstånd , korsas hörnen på avstånd .
Bredth first search är en av de oinformerade sökalgoritmerna [2] .
Breadth-First Search fungerar genom att gå igenom de individuella nivåerna i grafen , med början vid källnoden .
Betrakta alla kanter som utgår från noden . Om nästa nod är målnoden, avslutas sökningen; annars läggs noden till i kön . Efter att alla kanter som lämnar noden har kontrollerats, tas nästa nod från kön och processen upprepas.
Notera: uppdelningen av hörn i ovikta och ovikta är nödvändig för en godtycklig graf (eftersom den kan ha cykler). För ett träd är denna operation inte nödvändig, eftersom varje vertex endast kommer att väljas en gång.
Nedan finns pseudokoden för algoritmen för det fall då det bara är nödvändigt att hitta målnoden. Beroende på den specifika tillämpningen av algoritmen kan ytterligare kod krävas för att lagra den nödvändiga informationen (avstånd från startnoden, överordnad nod, etc.)
Rekursiv formulering:
BFS( start_node , goal_node ) { return BFS'({ start_node }, ∅, goal_node ); } BFS'( fringe , visited , goal_node ) { if ( fringe == ∅) { // Målnoden hittades inte returnera falskt; } if ( goal_node ∈ fringe ) { return true; } return BFS'({ child | x ∈ frans , child ∈ expand( x )} \ visited , visited ∪ fringe , goal_node ); }Iterativ formulering:
BFS( start_node , goal_node ) { för (alla noder i) besökte [ i ] = falskt; // initialt är listan över besökta noder tom kö .push( start_node ); // från den besökta källnoden [ start_node ] = sant; while (! kö .empty() ) { // tills kön är tom nod = kö .pop(); // hämta det första elementet i kön if ( nod == goal_node ) { return true; // kontrollera om den aktuella noden är målet } foreach ( barn i expand( node )) { // alla efterföljare av den aktuella noden, ... if (besökt[ barn ] == false) { // ... som ännu inte har besökts ... queue .push ( barn ); // ... lägg till i slutet av kön... besökte [ barn ] = sant; // ... och markera som besökt } } } returnera falskt; // Målnoden går inte att nå }Pascal implementering :
function BFS ( v : Node ) : Boolean ; börja kö ( v ) ; medan kön inte är tom , börja curr := dequeue () ; om is_goal ( curr ) sedan börja BFS := sant ; avsluta ; slut ; mark ( curr ) ; för nästa i efterföljare ( curr ) gör om det inte är markerat ( nästa ) , börja sedan kö ( nästa ) ; slut ; slut ; BFS := falskt ; slut ;Ange antalet hörn och kanter i grafen som respektive .
Eftersom alla expanderade noder är lagrade i minnet är rymdkomplexiteten för algoritmen [2] .
Den iterativa fördjupningssökningsalgoritmen liknar bredden-första-sökningen genom att varje iteration undersöker hela nivån av nya noder innan den går vidare till nästa nivå, men kräver betydligt mindre minne.
Eftersom algoritmen i värsta fall besöker alla noder i grafen, när grafen lagras i form av närliggande listor , är algoritmens tidskomplexitet [2] [3] .
Om varje nod har ett ändligt antal efterföljare är algoritmen komplett: om det finns en lösning hittar algoritmen för bredd-först den, oavsett om grafen är ändlig eller inte. Men om det inte finns någon lösning slutar sökningen inte på den oändliga grafen.
Om grafens kantlängder är lika, är bredd-först-sökning optimal, det vill säga den hittar alltid den kortaste vägen. I fallet med en viktad graf hittar sökningen med bredd först en bana som innehåller det minsta antalet kanter, men inte nödvändigtvis den kortaste.
Kostnad -först-sökning är en generalisering av bredd-först-sökning och är optimal på en viktad graf med icke-negativa kantvikter. Algoritmen besöker grafens noder i ordning efter ökande kostnad för vägen från startnoden och använder vanligtvis en prioritetskö .
Bredd-första sökning föreslogs formellt av E. F. Moore i samband med att hitta en väg i en labyrint [4] . Lee upptäckte självständigt samma algoritm i samband med PCB-ledningar [5] [6] [7] .
Bredth-First Search kan tillämpas på problem relaterade till grafteori :
Algoritmer för grafsökning | ||
---|---|---|
Oinformerade metoder | ||
Informerade metoder | ||
Genvägar | ||
Minsta spännträd | ||
Övrig |