La búsqueda primero en anchura ( BFS ) es uno de los métodos transversales de grafos . Sea dada la gráfica y el vértice inicial . El algoritmo de búsqueda primero en amplitud atraviesa sistemáticamente todos los bordes para "descubrir" todos los vértices alcanzables desde , mientras calcula la distancia (número mínimo de bordes) desde cada vértice alcanzable . El algoritmo funciona tanto para gráficos dirigidos como no dirigidos. [una]
La búsqueda en anchura tiene este nombre porque en el proceso de recorrido vamos en anchura, es decir, antes de empezar a buscar vértices a distancia , se recorren los vértices a distancia .
La búsqueda primero en amplitud es uno de los algoritmos de búsqueda no informados [2] .
La búsqueda primero en amplitud funciona recorriendo los niveles individuales del gráfico , comenzando en el nodo de origen .
Considere todos los bordes salientes del nodo . Si el siguiente nodo es el nodo de destino, la búsqueda finaliza; de lo contrario, el nodo se agrega a la cola . Después de verificar todos los bordes que salen del nodo, se toma el siguiente nodo de la cola y se repite el proceso.
Nota: la división de vértices en desplegados y no desplegados es necesaria para un grafo arbitrario (ya que puede tener ciclos). Para un árbol , esta operación no es necesaria, ya que cada vértice se seleccionará una sola vez.
A continuación se muestra el pseudocódigo del algoritmo para el caso en que solo es necesario encontrar el nodo de destino. Según la aplicación específica del algoritmo, es posible que se requiera código adicional para almacenar la información necesaria (distancia desde el nodo inicial, nodo principal, etc.)
Formulación recursiva:
BFS( nodo_inicio , nodo_objetivo ) { return BFS'({ nodo_inicio }, ∅, nodo_objetivo ); } BFS'( margen , visitado , nodo_objetivo ) { if ( margen == ∅) { // Nodo de destino no encontrado devolver falso; } if ( nodo_objetivo ∈ franja ) { return true; } return BFS'({ hijo | x ∈ franja , hijo ∈ expandir( x )} \ visitado , visitado ∪ franja , nodo_objetivo ); }Formulación iterativa:
BFS( start_node , goal_node ) { para (todos los nodos i) visitados [ i ] = false; // inicialmente la lista de nodos visitados está vacía cola .push( start_node ); // comenzando desde el nodo de origen visitado [ start_node ] = true; while (! queue .empty() ) { // hasta que la cola esté vacía node = queue .pop(); // recupera el primer elemento de la cola if ( nodo == nodo_objetivo ) { return true; // comprobar si el nodo actual es el objetivo } foreach ( child in expand( node )) { // todos los sucesores del nodo actual, ... if (visited[ child ] == false) { // ... que aún no han sido visitados ... cola .push ( niño ); // ... añadir al final de la cola... visitado [ niño ] = verdadero; // ... y marcar como visitado } } } devolver falso; // El nodo de destino es inalcanzable }Implementación de Pascal :
función BFS ( v : Nodo ) : Booleano ; comenzar a poner en cola ( v ) ; mientras que la cola no está vacía , comience curr := dequeue () ; si es_objetivo ( actual ) , entonces comience BFS : = verdadero ; salida ; fin ; marca ( curr ) ; para siguiente en sucesores ( actual ) haga si no está marcado ( próximo ) luego comience a poner en cola ( próximo ) ; fin ; fin ; BFS := falso ; fin ;Denote el número de vértices y aristas en el gráfico como y respectivamente.
Dado que todos los nodos expandidos se almacenan en la memoria, la complejidad espacial del algoritmo es [2] .
El algoritmo de búsqueda de profundización iterativa es similar a la búsqueda en amplitud en el sentido de que cada iteración examina el nivel completo de nuevos nodos antes de pasar al siguiente nivel, pero requiere una memoria significativamente menor.
Dado que en el peor de los casos el algoritmo visita todos los nodos del grafo, al almacenar el grafo en forma de listas de adyacencia , la complejidad temporal del algoritmo es [2] [3] .
Si cada nodo tiene un número finito de sucesores, el algoritmo está completo: si existe una solución, el algoritmo de búsqueda en amplitud la encuentra, sea o no finito el gráfico. Sin embargo, si no hay solución, la búsqueda no termina en el gráfico infinito.
Si las longitudes de los bordes del gráfico son iguales, la búsqueda primero en anchura es óptima, es decir, siempre encuentra la ruta más corta. En el caso de un gráfico ponderado , la búsqueda primero en anchura encuentra una ruta que contiene el número mínimo de aristas, pero no necesariamente la más corta.
La búsqueda primero en costo es una generalización de la búsqueda primero en amplitud y es óptima en un gráfico ponderado con ponderaciones de borde no negativas. El algoritmo visita los nodos del grafo en orden creciente del costo de la ruta desde el nodo de inicio y, por lo general, utiliza una cola de prioridad .
La búsqueda primero en amplitud fue formalmente propuesta por E. F. Moore en el contexto de encontrar un camino en un laberinto [4] . Lee descubrió de forma independiente el mismo algoritmo en el contexto del cableado de PCB [5] [6] [7] .
La búsqueda primero en amplitud se puede aplicar a problemas relacionados con la teoría de grafos :