He investigado un poco y parece que me falta una pequeña parte de este algoritmo. Entiendo cómo funciona Breadth-First Search, pero no entiendo cómo exactamente me llevará a un camino específico, en lugar de solo decirme a dónde puede ir cada nodo individual. Creo que la forma más fácil de explicar mi confusión es proporcionar un ejemplo:
Entonces, por ejemplo, digamos que tengo un gráfico como este:
Y mi objetivo es llegar de A a E (todos los bordes no están ponderados).
Comienzo en A, porque ese es mi origen. Pongo en cola A, seguido inmediatamente de la retirada de A y de explorarlo. Esto produce B y D, porque A está conectado a B y D. Por lo tanto, hago cola tanto B como D.
Detengo B y lo exploro, y descubro que conduce a A (ya explorado) y C, entonces hago cola C. Luego elimino D, y descubro que conduce a E, mi objetivo. Luego elimino C, y descubro que también conduce a E, mi objetivo.
Sé lógicamente que la ruta más rápida es A-> D-> E, pero no estoy seguro de cómo ayuda exactamente la búsqueda de amplitud, cómo debo registrar las rutas para que cuando termine, pueda analizar los resultados y ver Que el camino más corto es A-> D-> E?
Además, tenga en cuenta que en realidad no estoy usando un árbol, por lo que no hay nodos "primarios", solo hijos.
Respuestas:
Técnicamente, Breadth-first search (BFS) por sí solo no le permite encontrar la ruta más corta, simplemente porque BFS no está buscando una ruta más corta: BFS describe una estrategia para buscar un gráfico, pero no dice que debe buscar nada en particular.
El algoritmo de Dijkstra adapta BFS para permitirle encontrar las rutas más cortas de una sola fuente.
Para recuperar la ruta más corta desde el origen a un nodo, debe mantener dos elementos para cada nodo en el gráfico: su distancia más corta actual y el nodo anterior en la ruta más corta. Inicialmente, todas las distancias se establecen en infinito, y todos los predecesores se configuran en vacío. En su ejemplo, establece la distancia de A en cero y luego continúa con el BFS. En cada paso, verifica si puede mejorar la distancia de un descendiente, es decir, la distancia desde el origen hasta el predecesor más la longitud del borde que está explorando es menor que la mejor distancia actual para el nodo en cuestión. Si puede mejorar la distancia, establezca la nueva ruta más corta y recuerde el predecesor a través del cual se ha adquirido esa ruta. Cuando la cola BFS está vacía, elija un nodo (en su ejemplo, es E) y recorra sus predecesores de regreso al origen.
Si esto suena un poco confuso, wikipedia tiene una buena sección de pseudocódigo sobre el tema.
fuente
Como se señaló anteriormente, BFS solo se puede usar para encontrar la ruta más corta en un gráfico si:
No hay bucles
Todos los bordes tienen el mismo peso o no tienen peso.
Para encontrar el camino más corto, todo lo que tiene que hacer es comenzar desde la fuente y realizar una búsqueda amplia primero y detenerse cuando encuentre su nodo de destino. Lo único que necesita hacer es tener una matriz anterior [n] que almacenará el nodo anterior para cada nodo visitado. El anterior de fuente puede ser nulo.
Para imprimir la ruta, realice un ciclo simple a través de la matriz anterior [] desde el origen hasta llegar al destino e imprima los nodos. DFS también se puede utilizar para encontrar la ruta más corta en un gráfico en condiciones similares.
Sin embargo, si el gráfico es más complejo y contiene aristas y bucles ponderados, entonces necesitamos una versión más sofisticada de BFS, es decir, el algoritmo de Dijkstra.
fuente
To print the path, simple loop through the previous[] array from source till you reach destination.
Pero anterior de fuente es nulo. Creo que es lo que quería decir,backtrace from destination using the previous array until you reach the source
.De tutorial aquí
fuente
He perdido 3 días y
finalmente resolví una pregunta gráfica
utilizada para
encontrar la distancia más corta
usando BFS
Quiere compartir la experiencia.
He perdido 3 días probando todas las alternativas anteriores, verificando y volviendo a verificar una y otra vez por encima de
que no son el problema.
(Intente pasar tiempo buscando otros problemas, si no encuentra problemas con los anteriores 5).
Más explicación del comentario a continuación:
Suponga que arriba el gráfico de su gráfico
va hacia abajo
Para A, los adyacentes son B y C
Para B, los adyacentes son D y E
Para C, los adyacentes son F y G
digamos, el nodo de inicio es A
cuando llega a A, a, B y C, la distancia más corta a B y C desde A es 1
cuando alcanza D o E, a través de B, la distancia más corta a A y D es 2 (A-> B-> D)
de manera similar, A-> E es 2 (A-> B-> E)
también, A-> F y A-> G es 2
Entonces, ahora en lugar de 1 distancia entre nodos, si es 6, entonces simplemente multiplique la respuesta por 6
ejemplos,
si la distancia entre cada uno es 1, entonces A-> E es 2 (A-> B-> E = 1 + 1 )
si la distancia entre cada uno es 6, entonces A-> E es 12 (A-> B-> E = 6 + 6)
sí, bfs puede tomar cualquier ruta
pero estamos calculando para todas las rutas
si tiene que ir de A a Z, entonces recorremos todos los caminos desde A hasta un I intermedio, y dado que habrá muchos caminos, descartamos todos menos el camino más corto hasta I, luego continuamos con el camino más corto hasta el siguiente nodo J
nuevamente si hay múltiples rutas de I a J, solo tomamos un
ejemplo más corto ,
supongamos,
A -> I tenemos distancia 5
(PASO) supongamos, I -> J tenemos múltiples rutas, de distancias 7 y 8, ya que 7 es más corto
tomamos A -> J como 5 (A-> I más corto) + 8 (más corto ahora) = 13,
entonces A-> J es ahora 13
, repetimos ahora arriba (PASO) para J -> K y así sucesivamente, hasta obtener a Z
Lea esta parte, 2 o 3 veces, y dibuje en papel, seguramente obtendrá lo que estoy diciendo, la mejor de las suertes
fuente
Según la respuesta de acheron55, publiqué una posible implementación aquí .
Aquí hay un breve resumen:
Todo lo que tiene que hacer es hacer un seguimiento de la ruta a través de la cual se ha alcanzado el objetivo. Una forma simple de hacerlo es empujar en
Queue
toda la ruta utilizada para llegar a un nodo, en lugar del nodo en sí.El beneficio de hacerlo es que cuando se alcanza el objetivo, la cola retiene el camino utilizado para alcanzarlo.
Esto también es aplicable a los gráficos cíclicos, donde un nodo puede tener más de un padre.
fuente
Visitando este hilo después de un período de inactividad, pero dado que no veo una respuesta completa, aquí están mis dos centavos.
La búsqueda de amplitud siempre encontrará la ruta más corta en un gráfico no ponderado. El gráfico puede ser cíclico o acíclico.
Vea a continuación el pseudocódigo. Este pseudocódigo asume que está utilizando una cola para implementar BFS. También supone que puede marcar vértices como visitados, y que cada vértice almacena un parámetro de distancia, que se inicializa al infinito.
Tenga en cuenta que este enfoque no funciona para gráficos ponderados; para eso, consulte el algoritmo de Dijkstra.
fuente
La siguiente solución funciona para todos los casos de prueba.
fuente