¿Cómo podemos encontrar eficientemente la segunda caminata más corta entre dos vértices de un gráfico?

El algoritmo de Dijkstra en sí mismo puede verse como una aplicación del paradigma de programación dinámica. Recuerdas la mejor solución para algunos vértices y luego reutilizas esa información para resolver otros vértices de manera eficiente.

El algoritmo de Dijkstra solo está garantizado para trabajar con gráficos con longitudes de borde positivas. Para estos gráficos, cada caminata más corta también es un camino más corto, porque no tiene sentido dejar un vértice y luego regresar al mismo vértice. El algoritmo de Dijkstra usa esto implícitamente: para cada vértice encontramos el camino más corto que lo alcanza (tenga en cuenta que el algoritmo nunca verifica los vértices repetidos) y al final informamos que el camino más corto encontrado es el camino más corto que queríamos.

Podemos usar el mismo enfoque para encontrar las primeras k caminatas más cortas de A a B, para una k pequeña. En lugar de calcular la mejor manera de llegar a cada vértice desde A, simplemente calcularemos y almacenaremos las k mejores formas. (Más detalles: la cola de prioridad durante el algoritmo contiene eventos de la forma “Puedo alcanzar el vértice X usando una caminata de longitud D”. Para cada vértice, procesamos los k mejores eventos).

  • Caso I (Segundo camino más corto entre todos los pares de vértices):
    Mi sugerencia es ejecutar Floyd-Warshall una vez, enumerando [math] d_ {min} (u, v), \ forall u, v \ in V [/ math], para algunos [math] G = (V, E) [/mates]. Una vez hecho esto, configure [math] d_ {2} (u, v) [/ math], donando el segundo camino más corto entre dos vértices para que sea infinito. Ahora tomaremos el conjunto de aristas E e iteraremos sobre todos [math] (u, v) \ en VXV [/ math]. Configuraremos y actualizaremos [math] d_ {2} (u, v) [/ math] de la siguiente manera:
    si [matemáticas] d_ {min} (u, v) [/mates]
  • Esto se ejecuta en [matemáticas] O (| V | ^ {2} | E |) [/ matemáticas]
  • Caso II (Segunda ruta más corta entre una tupla de vértice dada):
    Este es un problema mucho más fácil de resolver, y una simple modificación dinámica a Djikstra lo resolverá. Para encontrar la ruta k-más corta en general, esta es una buena referencia: http://www.ics.uci.edu/~eppstein

    Para hacer esto aún más claro: Primero ejecute Djikstra y enumere [math] d_ {min} (u, s), \ forall s \ in V – \ {u \} [/ math] (Esto incluye el vértice terminal que le interesa ) Dado un [matemático] (u, v) [/ matemático] fijo para el cual necesitamos [matemático] d_ {2} (u, v) [/ matemático], se puede aplicar el mismo algoritmo que el anterior, excepto que esta vez, solo iteramos sobre todos los vértices [matemática] v ^ {‘} \ en V – \ {u, v \} [/ matemática], que es una iteración externa sobre el conjunto de todos los Bordes. Aquí está la condición:
    [matemáticas] \ forall (x, y) \ en E, \ ni, x, y \ neq u \ vee v [/ matemáticas]:
    si [matemáticas] d_ {min} (u, v) Como no necesitábamos enumerar todos los pares de vértices, nos ahorramos [math] O (| V | ^ {2}) [/ math] complejidad.

  • La complejidad de esto es la misma que la de Djikstra. No creo que pueda existir una solución más eficiente.

me pidieron que respondiera, así que intentemos:

un enfoque fácil sería comenzar a calcular el camino más corto. deje que E ‘sea el conjunto de bordes que pertenecen a ese camino y G (V, E) sea el gráfico. luego:
para cada borde e en E ‘calcule la ruta más corta para G (V, E \ {e}) (el gráfico donde eliminó el borde e). tome la mejor solución de todos estos resultados.

la eficiencia es O (V * E * log (E)).

Mira el algoritmo de Yen que puede ayudar

O
simplemente puede escanear el gráfico y luego tomar una copia y luego aplicar floydwarshall a su copia y luego aplicar esta función

  int scndpath = inf;
 bucle (i, 0, n) bucle (j, 0, n)
 if ((cpdgarph [inicio] [i] + gráfico [i] [j] + cpdgraph [j] [destino]) 
 > cpdgraph [inicio] [destino]) 
 scndpath = 
 min (scndpath, (cpdgarph [inicio] [i] + gráfico [i] [j] + cpdgraph [j] [destino])) 

Pensé que este enlace wiki podría ser útil.
K ruta de acceso más corta

More Interesting

¿Hay alguna prueba de que los algoritmos de clasificación no pueden tener una complejidad mejor que O (Nlog (N))?

¿Cómo atravesar una matriz desde una posición dada vertical u horizontal o diagonalmente para encontrar un elemento en C ++? ¿Podría proporcionar un código de muestra?

¿Qué tipo de algoritmo de localización utilizan generalmente los misiles de crucero?

¿Aproximadamente cuántas personas en el mundo pueden resolver un cubo rubix sin algoritmos?

¿Cómo se imprime el reverso de una pila de objetos iterables?

Cómo resolver el problema M_SEQ en SPOJ

¿Debo usar kits de herramientas como scikit-learn para comenzar con el aprendizaje automático?

¿Por qué se garantiza que la liebre y la tortuga se encontrarán en el algoritmo de detección de ciclos de Floyd?

¿Cómo aprenden los algoritmos de aprendizaje de refuerzo del juego de ajedrez a jugar bien, dado que cada movimiento no está etiquetado como bueno o malo, a diferencia del aprendizaje supervisado donde cada dato está etiquetado como bueno o malo?

¿Cuál es el método racional (algoritmo) a seguir al votar?

Cómo usar el 'mapa combinatorio' de una triangulación de un polígono 2D para probar si un borde dado de la triangulación es un borde límite

¿Para qué sirven las estructuras de datos?

Cómo crear un sistema de clasificación que dependa de tres variables (nivel, resultado y tiempo) cuanto más altas sean las dos primeras, mejor, mientras que por un tiempo, un valor menor es mejor

¿Cuáles son los beneficios del ordenamiento dinámico y sus desventajas en comparación con otros algoritmos de ordenamiento?

¿Por qué la búsqueda de Breadth-first (y otros algoritmos relacionados) se consideran parte del campo de IA?