Supongamos que tengo un gráfico dirigido con pesos de borde extraídos del rango donde es constante. Si estoy tratando de encontrar la ruta más corta utilizando el algoritmo de Dijkstra , ¿cómo puedo modificar la estructura del algoritmo / datos y mejorar la complejidad del tiempo a ?
algorithms
data-structures
shortest-path
weighted-graphs
usuario1675999
fuente
fuente
Respuestas:
Si los pesos de borde son enteros en , puede implementar Dijkstra's para que se ejecute en tiempo O ( K | V | + | E | ) , siguiendo la sugerencia de @ rrenaud. Aquí hay una explicación más explícita.{ 0 , 1 , ... , K} O ( KEl | VEl | + | miEl | )
En cualquier momento, las teclas (finitas) en la cola de prioridad están en algún rango , donde D es el valor de la última clave eliminada de la cola de prioridad. (Cada clave es al menos D , porque la secuencia de claves eliminadas por el algoritmo de Dijkstra no es decreciente, y cada clave es como máximo D + K , porque cada clave tiene un valor d [ u ] + w t ( u , w ) para un poco de borde ( u ,{ D , D + 1 , ... , D + K} re re D + K re[u]+wt(u,w) donde d [ u ] es la distancia desde la fuente a algún vértice u que ya se ha eliminado, entonces d [ u ] ≤ D. )(u,w) d[u] u d[u]≤D
Debido a esto, puede implementar la cola de prioridad con una matriz circular de tamaño K + 1 , con cada celda que contiene un depósito. Almacene cada vértice con la clave k en el depósito en la celda A [ h ( k ) ] donde h ( k ) = k mod ( K + 1 ) . Realizar un seguimiento de D . Realice las operaciones de la siguiente manera:A[0..K] K+1 k A[h(k)] h(k)=kmod(K+1) D
delete-min : Mientras está vacía, el incremento D . Luego borre y devuelva un vértice de A [ h ( D ) ] .A[h(D)] D A[h(D)]
inserte con la tecla : Agregue el vértice al cubo de A [ h ( k ) ] .k A[h(k)]
tecla de disminución a k ' : mueve el vértice de A [ h ( k ) ] a A [ h ( k ' ) ] .k k′ A[h(k)] A[h(k′)]
Insertar y disminuir clave son operaciones de tiempo constante, por lo que el tiempo total dedicado a esas operaciones será . El tiempo total de permanencia en delete-min será O ( | V | ) más el valor final de D . El valor final de D es la distancia máxima (finita) desde la fuente a cualquier vértice (porque un delete-min que toma i iteraciones aumenta D en i ). La distancia máxima es como máximo K ( | V | - 1O(|V|+|E|) O(|V|) D D i D i porque cada ruta tiene como máximo | V | - 1 aristas. Por lo tanto, el tiempo total empleado por el algoritmo es O ( K | V | + | E | ) .K(|VEl | -1) El | VEl | -1 O ( KEl | VEl | + | miEl | )
fuente
Asumo aquí que es un número entero y los pesos de borde son integrales. De lo contrario, realmente no le compra nada, siempre puede volver a escalar los pesos para que el borde mínimo haya costado 1 y el máximo haya costado K , por lo que el problema es idéntico al problema estándar de la ruta más corta.K 1 K
Algoritmo / bosquejo de prueba: Implemente la cola de prioridad en este tipo de locura como una matriz de listas codificadas por costo y de otro modo usar el algoritmo estándar de Dijkstra. Mantenga un contador que rastree el costo del artículo mínimo en el montón. Resuelva la llamada en cola después de que los elementos se eliminen mediante escaneo lineal . Sí, este tipo de sonido parece una locura, pero constante KK× | VEl | K le permite engañar y engañar a su intuición algorítmica contra escaneos lineales. Solo necesita escanear desde el último marcador min porque el algoritmo de Disjkstra es bueno para su implementación de cola. En el momento en que solicita una cola, los elementos insertados en la cola son siempre mayores o iguales al mínimo anterior. El camino más largo más corto posible tiene longitud , entonces su costo de escaneo amortizado es K × | V | = O ( | V | ) si K es constante.K× | VEl | K× | VEl | =O( | VEl | )
fuente
puede usar la clasificación topológica para encontrar la solución, dejar que la fuente tenga un grado 0 y luego ir desde cada borde de la fuente, si otro vértice tiene 0 grados, luego ponerlo en la cola y seguir haciendo eso. en este caso (sin ciclo dentro del gráfico) puede alcanzar V + E ya que atravesaría cada vértice y bordes una y solo una vez.
fuente