Algoritmo de configuración de etiquetas para resolver el problema de la ruta más corta con la ventana de tiempo (ESPPRC)

El siguiente artículo proviene del mago de datos, autor Deng Faheng, Zhou Hang

Prólogo

Hola a todos ~!

Presumiblemente, todos se sentirán un poco perdidos cuando empiecen a aprender el modelo de investigación de operaciones. Por ejemplo, muchos sustantivos mágicos, todo tipo de restricciones. . . De todos modos, al principio estaba en un estado de ignorancia.

Entonces, esta vez traemos un problema básico de ruta más corta con la ventana de tiempo (Problema de ruta más corta con ventanas de tiempo, denominado SPPTW) , utilizando un algoritmo básico preciso, es decir, el algoritmo de configuración de etiquetas, para resolverlo. Como las referencias son relativamente antiguas, este método se ha optimizado en gran medida. Por supuesto, solo comenzando con lo básico y escalando paso a paso podemos continuar resolviendo problemas más difíciles. (Francamente, es difícil para el editor ser picante)

Sin más preámbulos, ¡comience este artículo!

Para descargar el código relevante y los ejemplos en este artículo, preste atención al número público [sonido del programa], la respuesta de fondo [SPPTWCPP] no incluye []

Directorio

1. Introducción a SPPTW 2. Introducción al
algoritmo de configuración de etiquetas
3. Poda dominante: dominar
4. Orden de procesamiento de etiquetas: clasificación de diccionario
5. Flujo de algoritmos y ejemplos
6. Compartir código fuente C ++

Introducción a SPPTW

Primero, introduzcamos brevemente el problema a tratar.

Problema de ruta más corta (SPP) :

En un gráfico, cada arista tiene un número asociado, lo llamamos peso . Para la siguiente figura G = (N, A), cada borde tiene un solo peso para representar el costo (puede entenderse como la longitud del borde). Dado el punto de partida p, encuentre la ruta con el menor costo para que p alcance los puntos restantes .

Por ejemplo, la imagen de arriba. Cada lado tiene derecho a representar los costos. El problema tradicional de la ruta más corta requiere que encontremos la ruta de costo mínimo desde el punto de partida (como v_0) hasta los puntos restantes. Por ejemplo, la ruta más corta de v_0 a v_4 es v_0 → v_2 → v_3 → v_4, y el costo total es 19; y la ruta de v_0 → v_4, el costo total es 30, por lo que no es la ruta más corta de v_0 a v_4.

Tenga en cuenta que en el clásico problema del camino más corto, los pesos en los bordes son generalmente positivos .

En SPPTW:

Cada borde en la figura tiene dos pesos , uno de los cuales representa el tiempo empleado y el otro representa el costo de escuchar el borde . Cada nodo i tiene una ventana de tiempo [a_i, b_i], y la ruta debe cumplir con las restricciones de la ventana de tiempo al acceder al nodo, a saber:

Si el tiempo para llegar al punto i es anterior al tiempo a_i cuando se abre la ventana de tiempo, debe esperar hasta que se abra la ventana de tiempo antes de ingresar; si el tiempo de llegada excede el tiempo de tiempo cerrado b_i, no puede acceder al nodo.

(D_ij representa el tiempo, c_ij representa el costo, [xx, aa] representa la ventana de tiempo. Consulte la definición a continuación para obtener más detalles)

Sobre esta base, encontrar el camino con el menor costo total desde el punto de partida p (punto v_1) a los puntos restantes es el problema que tenemos que resolver.

En la figura podemos ver que el peso del costo de v_1 → v_4 es negativo. El algoritmo en este documento no solo puede resolver el caso donde el costo es positivo, sino también resolver el caso donde el costo es negativo . Solo asegúrese de que el consumo de tiempo sea positivo .

Sobre esta base, se establece el modelo del problema:

La ruta X_1 ^ 0 se puede representar mediante el siguiente diagrama:

El modelado tradicional de problemas de cortocircuito puede eliminar directamente algunas definiciones y no las repetirá. Veamos primero el método de etiquetado para tratar el problema tradicional de la ruta más corta.

Introducción al algoritmo de establecimiento de etiquetas

Los algoritmos de etiquetado (algoritmos de etiquetado) son un método importante para resolver el problema de la ruta más corta, pero también la parte central de la mayoría de los algoritmos de ruta más corta.

De acuerdo con diferentes estrategias de procesamiento para los nodos de etiquetas, los algoritmos de etiquetado se pueden dividir en dos sistemas: configuración de etiquetas (LS) y corrección de etiquetas (LC).

Dos algoritmos clásicos relacionados con el problema del camino más corto, el algoritmo de Dijkstra y el algoritmo de Bellman-Ford, pertenecen a LS y LC, respectivamente.

El algoritmo LS revisa gradualmente la etiqueta a través del proceso de iteración. Cada iteración selecciona la etiqueta más pequeña en el conjunto de nodos candidatos para salir del conjunto de nodos candidatos, y cambia la etiqueta del nodo de la etiqueta temporal a la etiqueta permanente durante mucho tiempo. Este es un algoritmo de ruta más corto basado en la estrategia codiciosa. Cada vez que la etiqueta convertida en una etiqueta permanente representa la ruta más corta al nodo actual, se considera el "mejor actual".

El algoritmo LC no cambia necesariamente ninguna etiqueta de nodo de una etiqueta temporal a una etiqueta permanente en cada iteración, sino que solo corrige la etiqueta temporal una vez, y todas las etiquetas de nodo siguen siendo etiquetas temporales; solo cuando todas las iteraciones terminan, todos los nodos La etiqueta también se convierte en una etiqueta permanente. El algoritmo LC considera el "óptimo final", y la ruta más corta necesita esperar varias iteraciones hasta que se complete el algoritmo completo antes de que pueda determinarse.

Principalmente presentamos el algoritmo LS. Aquí presentamos el algoritmo Dijkstra para resolver el problema de la ruta más corta sin restricciones de ventana de tiempo. En este algoritmo, para el nodo i, la etiqueta es (C [i], p [i]), donde C [i] representa la distancia más corta desde el punto de partida al nodo i, y p [i] se registra bajo la distancia d [i] , En la ruta del punto de partida al nodo i, el número de nodo antes del nodo i. s_0 representa el punto de partida. c_ij representa la distancia a través del borde (i, j). El proceso de ejecución es el siguiente:

Paso0: Inicializar Deje S estar vacío, S * = N, C [s_0] = 0, p [s_0] = -1; deje la etiqueta de distancia inicial C [j] = ∞ para el vértice i (i ≠ s_0) en N.

Paso 1: juicio de límites. Si S = N, C [j] es la longitud de ruta más corta, y la ruta más corta se puede obtener retrocediendo a través de la información registrada por p [j]. Fin De lo contrario, continúe con el paso 2.

Paso 2: Actualiza la marca. De S para encontrar el costo total mínimo de nodo i, S desde deleción, adición de S. Para todos los puntos siguientes j a partir de i, si C [j]> C [i] + c_ij, entonces deje que C [j] = C [i] + c_ij, p [j] = i Ve al paso 1.

El cálculo principal de este algoritmo es el ciclo step2. Incluye dos procesos: el proceso de encontrar un nodo (encontrar el nodo i con el menor costo de S *) y el proceso de actualizar el costo total (el costo de actualizar el nodo adyacente al nodo i).

Sin embargo, el algoritmo simple de Dijkstra no puede manejar la restricción de la ventana de tiempo, ni puede manejar bordes de peso negativos: en el proceso de bucles continuos, algunos bordes son ignorados por nosotros. Incluso si su valor de peso es negativo, podemos optimizar el costo. No me importará

A continuación, propondremos una versión mejorada del algoritmo LS, que puede manejar las restricciones de la ventana de tiempo y satisfacer los bordes de peso negativos.

Poda dominante: dominar

Después de comprender el algoritmo LS para resolver el problema del camino más corto, volvemos al problema más corto bajo la restricción de la ventana de tiempo. Debido al peso del tiempo, nuestro marcador ya no puede registrar solo un costo variable como en la sección anterior. Hacemos una etiqueta para cada estado de cada ruta a cada punto (T, C) y registramos el tiempo total y el costo total de la ruta cuando llega al punto .

Según la definición, podemos dar el método de procesamiento de la marca:

Por supuesto, puede usar el agotamiento para resolver directamente el problema con un método similar a Dijkstra. Pero esperamos encontrar un método de poda efectivo para evitar la alta complejidad de tiempo causada por el agotamiento. Afortunadamente, no todos los marcadores son válidos para encontrar el camino más corto desde el punto de partida hasta cada punto. Ilustramos con el ejemplo:

La  regla de dominar nos permite filtrar las etiquetas inválidas .

Podemos usar una función para expresar visualmente esta relación:

Obviamente, en la figura, si la pendiente k> = 0 entre los dos puntos, el punto final está dominado. (Como X_i ^ 1 dominateX_i ^ 5) Debido a que los dos caminos representados por los dos marcadores alcanzarán el mismo punto, y el camino al final de la pendiente tiene un mayor tiempo y costo, por supuesto, peor. Cuando k = 0, dibujamos varias líneas rectas en la figura . Cada línea se dibuja por un punto (que representa una marca), y el siguiente punto termina. Esto significa que en el tiempo correspondiente a esta línea, el costo de la marca es el costo mínimo. En otros casos, no es posible determinar qué ruta es mejor.

Filtramos a través de una función EFF (). En la introducción de la primera parte de LS, mencionamos el concepto de marcadores permanentes , lo que significa que hemos asegurado la validez de los marcadores permanentes, y sus valores de marcador no cambiarán durante el proceso de expansión posterior. Damos un método para expandir la marca permanente correspondiente al nodo j.

Definición:

Q_j es el conjunto de etiquetas permanentes para el nodo j. (El costo mínimo de todos los marcadores en Q_j es la ruta más corta de p a j)

Expanda Q_j de las siguientes maneras:

La extensión aquí en realidad implica que todas las etiquetas que pueden dominar la nueva etiqueta deben existir en Q_j. ¿Cómo garantizar esto? Damos una solución en la siguiente sección.

Marcar orden de procesamiento: clasificación de diccionario

En el proceso de etiquetas de procesamiento LS, expandimos las etiquetas en el orden de los nodos, por lo que para múltiples etiquetas de un nodo, necesitamos procesarlas en una secuencia. Esta secuencia es la mejor para encontrar todos los puntos no válidos en el proceso de expansión, es decir, la búsqueda EFF mientras se expande.

En la imagen de la función, usamos la pendiente k para representar la relación dominante, es fácil pensar en juzgar k de izquierda a derecha y encontrar todos los segmentos de línea donde k> = 0. Después de la conversión, se ordena en el orden de comparar T y luego C. Por lo tanto, también consideramos almacenar en el orden de juzgar T antes de juzgar C al almacenar la marca, y el procesamiento se procesa de pequeño a grande. Esto se llama clasificación de diccionario . Obviamente, esta es una clasificación total , que satisface nuestras necesidades.

Tenemos las siguientes tres proposiciones:

El orden lexicográfico nace para cooperar con el juicio dominante. Estas son operaciones de poda para evitar el agotamiento. Después de agregar estas dos operaciones, encontrará muchas rutas inviables durante el proceso de enumeración. Una vez que no sea factible, la expansión de la ruta se detendrá de inmediato .

Dividimos todas las etiquetas en tres partes:

Q es una colección marcada permanentemente

P es una colección de etiquetas procesadas.

T es el conjunto de etiquetas sin procesar.

Clasificamos todas las etiquetas en orden lexicográfico para asegurarnos de que todas las etiquetas en T no puedan dominar las etiquetas en P. Debido a que el tiempo d_ij de cada borde es positivo, la nueva marca que se ha expandido debe organizarse después de la marca original, y la marca original ya no se puede dominar. La relación de dominación es transitiva . Según el método de inducción , la marca en T no puede ser dominada por ninguna marca P.

También podemos usar la definición de P, Q, T para dar una relación:

Podemos usar esta fórmula para calcular T en el algoritmo.

Algoritmo de flujo y ejemplos

Un ejemplo simple:

Código compartido

El código C ++ se proporciona a continuación. Las castañas usan las castañas simples anteriores, nombradas de acuerdo con la definición anterior. Después de comprender el flujo del algoritmo, el código en sí no es difícil. El objetivo del código aquí es cooperar con la explicación, como referencia, por lo que no elegí estructuras de datos complejas y habilidades gramaticales. Los amigos que lo necesitan pueden probarlo por sí mismos como ejercicio.

Para descargar el código relevante y los ejemplos en este artículo, preste atención al número público [sonido del programa], la respuesta de fondo [SPPTWCPP] no incluye []

Este artículo está casi por aquí ~

Este tweet ha sido revisado muchas veces. Gracias al Director Senior Deng Faheng y al Maestro Qin Hu por su apoyo, ¡he proporcionado muchas enmiendas! Muchas gracias

¡El editor trabajará duro para escribir más tweets emocionantes para todos!

Hasta la próxima ( _ ) / ~~

Supongo que te gusta

Origin www.cnblogs.com/dengfaheng/p/12672757.html
Recomendado
Clasificación