Complejidad temporal del algoritmo Held-Karp para TSP

9

Cuando revisé " Un enfoque de programación dinámica para problemas de secuencia " de Michael Held y Richard M. Karp, se me ocurrió la siguiente pregunta: ¿por qué la complejidad de su algoritmo para TSP es (k=2n1k(k1)(n1k))+(n1) (p. 199), quiero decir, ¿de dónde sacan el factor k ? Si entendí correctamente, k1 significa el número de adiciones para cada subconjunto de ciudades. Entonces, ¿por cada operación de suma se acopla con desconocidos para mí k operaciones? Supongo que está conectado de alguna manera a tomar el mínimo, pero el mínimo de computación no parece requerir tantas operaciones.

El algoritmo de programación dinámica de Held y Karp e independientemente Bellman se ejecuta de la siguiente manera: para cada par (S,ci) , es decir, una ruta que pasa por c1 , todos los elementos de S y que terminan en ci computan

OPT[S,ci]=min{OPT[S{ci},cj]+d(cj,ci):cjS{ci}},

donde d(cj,ci) significa la distancia entre las ciudades cj y ci . Luego, en la fórmula del papel k significa el tamaño de S .

Oleksandr Bondarenko
fuente

Respuestas:

5

Adición a continuación, aclarando los términos k(k1) :

Entonces, si examina los términos en la expresión, puede imaginar (como analogía) el término es una enumeración de todas las cadenas binarias que contienen 1 que tienen un 1 en la primera posición. En otras palabras, dejamos que cada posición en la cadena binaria represente la elección de si una de las ciudades del problema está en el subconjunto exacto que estamos considerando en ese momento. Entonces, para 5 ciudades, 10101 corresponde al subconjunto {1,3,5}.(n1k)kn

Por lo tanto, para calcular en todos los subconjuntos de {1, ..., }, simplemente contamos a través de cada subconjunto binario (es decir, contamos a través de cadenas binarias) de tamaño = 2 (es decir, cadenas binarias de tamaño que contienen dos 1), luego tamaño = 3, luego tamaño = 4, ... luego tamaño = n. (Tenga en cuenta que el subconjunto size = 1 debe contener solo la primera ciudad y, por lo tanto, es irrelevante calcular su distancia parcial, ya que la distancia desde 1 -> todas las demás ciudades del subconjunto -> 1 es exactamente 0).nn

En cada subconjunto con ciudades, tenemos que considerar hasta candidatos, rutas parciales óptimas. Específicamente, la ruta total óptima podría atravesar el subconjunto dado y terminar en cualquiera de las ciudades , excluyendo la primera ciudad. Luego, para cada subruta candidata, calculamos el recorrido óptimo hasta ese punto como el mínimo de cualquiera de las subrutas anteriores, size = más la distancia desde la ciudad terminal para esa subruta hasta el ciudad terminal para la actual ruta secundaria candidata. Esto le da a las comparaciones que debemos hacer. La discrepancia entre mi término y elkk1k1k1(k1)(k2)(k1)(k2)k(k1)El término en el análisis vinculado es una diferencia de notación (sumaría en un rango diferente, dada mi definición de de lo que hicieron). Por lo menos, sin embargo, debería ilustrar la complejidad de orden cuadrático de ese término.k


Qué interesante: acabo de terminar de codificar este algoritmo exacto en C ++ hace unos minutos. (Así que perdona la tangente de la teoría pura a una pequeña discusión práctica. :))

Cuesta tiempo y espacio, al menos en mi implementación. Sin embargo, en términos prácticos, cuando sus requisitos de espacio crecen tan rápido, se vuelven mucho más dolorosos que los requisitos de tiempo. Por ejemplo, en mi PC (con 4 GB de RAM), puedo resolver instancias con hasta 24 ciudades, algo más que eso, y me quedo sin memoria.O(2nn2)O(2nn)

Por supuesto, podría ser un mal programador, y podrías hacerlo mejor que yo en la práctica. :)

Editar: Un poco más de detalles sobre un detalle de su pregunta: el término proviene del hecho de que, en el peor de los casos, debe calcular la distancia parcial y óptima de los subconjuntos anteriores (hay como máximo de ellos; tenga en cuenta que se suma sobre en el análisis que vinculó) al actual. Esto requiere, nuevamente en el peor de los casos, comparaciones de con subconjuntos de tamaño para un total de .k(k1)nknO(k)k1O(k2)

Además, si mi explicación no fue lo suficientemente clara, aquí hay algunas notas agradables de Vazirani ( PDF ). Desplácese hacia abajo hasta P. 188 para una discusión sobre TSP, incluido un análisis de Held-Karp.

Daniel Apon
fuente
¡Oh por supuesto! Me siento tonto pensando en eso ahora; Actualizaré mi respuesta. De hecho, había escuchado ese comentario exacto antes, y lo transmití sin pensarlo. Y sí, escribir en un archivo / leer desde un archivo te permitirá ir de manera efectiva y arbitrariamente alta en el número de ciudades. ... también es un dolor por el que no vale la pena preocuparse a menos que esté tratando de resolver instancias de TSP con un propósito real. El mío definitivamente no era para un propósito práctico. ;)
Daniel Apon
2
Es hora de implementar el algoritmo Bjorklund :)
Suresh Venkat
@Suresh: ¡Buena idea!
Daniel Apon
@Daniel Apon ¿Podría, por favor, precisar por qué necesitamos comparaciones al calcular "la distancia parcial y óptima"?
Oleksandr Bondarenko
@Oleksandr: Claro, lo agregaré al principio de mi respuesta.
Daniel Apon
0

Nota principal

Es importante tener en cuenta que calcular y almacenar no
"distancia de la ruta óptima para combination of k cities"
pero
"a distancia de la ruta óptima para combination of k cities Y para end-point city from this combination".
Comprenderlo ayudará con el significado de los dos primeros multiplicadores en la siguiente fórmula.

Primera fase

El número de operaciones en la primera fase es:

k>=2(n1k1)choose city combinationof size = k1(k1)choose city to be the lastfrom k1 citiesin chosen combination((n1)(k1))choose citythat is not in chosen combinationto add to path

Falta superíndice en suma significa for all k>=2 that is valid for binomial coefficient. Entonces, el último término de suma no nulo válido será para Esto significa que nuestra suma no captura las últimas opciones de ciudad para conectar a la primera ciudad. Hay ciudades para conectarse a la primera ciudad. Así que finalmente agregaremos este término a la suma.k=n1

(n1n2)(n2)1
n1

Deje transformar la fórmula en el formulario que proporcione y que también se encuentre en la página de Held-Karp Wikipedia .

k>=2(n1k1)(k1)((n1)(k1))=k>=2(n1)!(k1)!(nk)!(k1)(nk)=k>=2(n1)!k!(n1k)!k(k1)=k>=2(n1k)k(k1)
manipulación de coeficientes binomiales conduce a: Entonces, el número de operaciones en la primera la fase es
k>=2(n1k)k(k1)=k>=2(n1)!k!(n1k)!k(k1)=k>=2(n3)!(k2)!(n3(k2))!(n1)(n2)=(n1)(n2)k>=2(n3k2)=(n1)(n2)2n3
(n1)(n2)2n3+(n1)

Segunda fase

La segunda fase está restaurando el camino óptimo mediante las marcas que hemos realizado en la primera fase simultáneamente con las distancias de cálculo.

Para cada ruta óptima "para combination of k cities Y para end-point city from this combination" hemos guardado la penúltima ciudad.

Para dar marcha atrás a la ruta óptima, necesitamos pedir alguna estructura de datos para devolver la penúltima ciudad "para combination of k cities Y para end-point city from this combination". Entonces esta estructura de datos debe ser algo así
Map<combination of k cities, Map<last city, second-to-last city>>. Como índice de combination of k citiespodemos usar, por ejemplo binary_string[city id]=1 if city id is in combination,. Por lo tanto, debemos analizar todos los elementos combination of k citiespara identificar la combinación e indexar nuestra estructura de datos. Esto nos da el número de operaciones para la segunda fase:

k>=2n1k=(n)(n1)21

dimathe47
fuente