Prohledávání do šířky (breadth-first search, BFS) je jedním ze základních grafových algoritmů, který slouží k průchodu daného grafu. Jeho principy jsou základem pro další algoritmy, jako je například Jarník-Primův algoritmus nebo Dijkstrův algoritmus.
Princip
Při prohledávání do šířky začneme procházet graf z libovolného uzlu. Tento uzel zpracujeme a při objevení jeho dosud nenalezených potomků tyto uložíme do fronty a postupně zpracováváme stejným způsobem. Takto postupujeme, dokud není fronta prázdná.
Díky ukládání do fronty dochází k procházení grafu po vlnách – uzly jsou zpracovávány v pořadí daném jejich vzdáleností od kořene.
Výstupem algoritmu je strom prohledávání do hloubky obsahující všechny uzly dosažitelné z výchozího uzlu - tzv. BF-strom. BF-strom je stromem nejkratších cest z daného uzlu ve smyslu počtu hran.
Složitost
Za předpokladu, že je složitost přístupu k potomkům daného uzlu konstantní, stejně jako složitost uložení a výběru z fronty, tak je asymptotická složitost celého algoritmu , protože každou hranu a každý uzel projde právě jednou.
Kód
001.
/**
002.
* Dosud neobjeveny uzel
003.
*/
004.
private
static
final
int
FRESH =
0
;
005.
/**
006.
* Otevreny uzel
007.
*/
008.
private
static
final
int
OPEN =
1
;
009.
/**
010.
* Uzavreny uzel
011.
*/
012.
private
static
final
int
CLOSED =
2
;
013.
014.
/**
015.
* Prohledavani do sirky
016.
*
017.
* @param graph graf k prohledani
018.
* @param rootNr cislo uzlu, ktery je korenem
019.
* @return pole predchudcu
020.
*/
021.
public
static
GraphNodeIface[] breadthFirstSearch(GraphIface graph,
int
rootNr) {
022.
GraphNodeIface[] predecessors =
new
GraphNodeIface[graph.getVertexCount()];
//pole predchudcu
023.
int
[] state =
new
int
[graph.getVertexCount()];
024.
for
(
int
i =
0
; i < state.length; i++) {
025.
state[i] = FRESH;
026.
}
027.
state[rootNr] = OPEN;
//koren je otevreny
028.
predecessors[rootNr] =
null
;
//koren nema predky
029.
030.
Queue<GraphNodeIface> l =
new
LinkedList<GraphNodeIface>();
//fronta - pokud zde frontu nahradime zasobnikem, tak ziskame prohledavani do hloubky
031.
l.add(graph.getNode(rootNr));
032.
033.
while
(!l.isEmpty()) {
034.
GraphNodeIface node = l.poll();
035.
List<GraphNodeIface> successors = node.getSuccessors();
036.
for
(GraphNodeIface succ : successors) {
//potomci zpracovavaneho uzlu
037.
if
(state[succ.getId()] == FRESH) {
//byl prave objeven
038.
l.add(succ);
//pridame ke zpracovani
039.
state[succ.getId()] = OPEN;
040.
predecessors[succ.getId()] = node;
041.
}
042.
}
043.
state[node.getId()] = CLOSED;
044.
}
045.
return
predecessors;
046.
}
047.
048.
/**
049.
* Operace, ktere by mel splnovat graf
050.
*
051.
* @author Pavel Micka
052.
*/
053.
public
interface
GraphIface<ENTITY> {
054.
055.
/**
056.
* Prida hranu do grafu
057.
*
058.
* @param from uzel, ze ktereho hrana vychazi
059.
* @param to uzel, do ktereho hrana vede
060.
*/
061.
public
void
addEdge(
int
from,
int
to);
062.
063.
/**
064.
* Vrati pocet hran grafu
065.
*
066.
* @return pocet hran grafu
067.
*/
068.
public
int
getEdgeCount();
069.
070.
/**
071.
* Vrati uzel s danym identifikatorem
072.
*
073.
* @param id
074.
* @return
075.
*/
076.
public
GraphNodeIface getNode(
int
id);
077.
078.
/**
079.
* Vrati pocet vrcholu grafu
080.
*
081.
* @return pocet vrcholu grafu
082.
*/
083.
public
int
getVertexCount();
084.
085.
/**
086.
* Odstrani hranu, v pripade vicenasobneho vyskytu odstrani prvni vyskyt
087.
*
088.
* @param from uzel, ze ktereho hrana vychazi
089.
* @param to uzel, do ktereho hrana vede
090.
*/
091.
public
void
removeEdge(
int
from,
int
to);
092.
093.
/**
094.
* Operace, ktere by mel splnovat uzel grafu
095.
*
096.
* @param <ENTITY>
097.
*/
098.
public
interface
GraphNodeIface<ENTITY> {
099.
100.
/**
101.
* @return the id
102.
*/
103.
public
int
getId();
104.
105.
/**
106.
* @return the successors
107.
*/
108.
public
List<GraphNodeIface> getSuccessors();
109.
110.
/**
111.
* @return the value
112.
*/
113.
public
ENTITY getValue();
114.
115.
/**
116.
* @param value the value to set
117.
*/
118.
public
void
setValue(ENTITY value);
119.
}
120.
}
Literatura
- KOLÁŘ, Josef. Teoretická informatika. 2. vyd. Praha : Česká informatická společnost, 2004. 205 s. ISBN 80-900853-8-5.