¿Cuál es el significado de "de distintas cadenas de vértices" en este algoritmo de vecino más cercano?

El siguiente pseudocódigo es del primer capítulo de una versión preliminar en línea de El manual de diseño de algoritmos (página 7 de este PDF).

El ejemplo es de un algoritmo defectuoso, pero todavía quiero entenderlo:

[...] Una idea diferente podría ser conectar repetidamente el par de puntos finales más cercano cuya conexión no creará un problema, como la terminación prematura del ciclo. Cada vértice comienza como su propia cadena de vértices. Después de fusionar todo, terminaremos con una sola cadena que contiene todos los puntos. Conectar los dos extremos finales nos da un ciclo. En cualquier paso durante la ejecución de esta heurística de par más cercano, tendremos un conjunto de vértices únicos y cadenas de vértices disjuntos disponibles para fusionar. En pseudocódigo:

ClosestPair(P)
    Let n be the number of points in set P.
    For i = 1  to n − 1 do
        d = ∞
        For each pair of endpoints (s, t) from distinct vertex chains
            if dist(s, t) ≤ d then sm = s, tm = t, and d = dist(s, t)
        Connect (sm, tm) by an edge
    Connect the two endpoints by an edge

este producto está hecho por encargo con un tiempo de producción de XNUMX a XNUMX semanas sm y tm debiera ser sm y tm.

En primer lugar, no entiendo qué significaría "de distintas cadenas de vértices". Segundo, i se utiliza como contador en el bucle exterior, pero i ¡en sí mismo nunca se usa en ningún lugar! ¿Podría alguien más inteligente que yo explicar lo que realmente está pasando aquí?

preguntado el 27 de agosto de 11 a las 19:08

Interesante, ¡estaba a punto de plantearme las mismas preguntas! -

¡Exactamente las mismas preguntas! Palabra por palabra. De hecho, estaba deprimido porque no soy lo suficientemente inteligente para el libro, bueno, al menos solo :-P ¡gracias por publicar! -

3 Respuestas

Así es como lo veo, después de la explicación de Ernest Friedman-Hill (respuesta aceptada):

Entonces, el ejemplo del mismo libro (Figura 1.4). He añadido nombres a los vértices para que quede claro. Figura 1.4

Entonces, en el primer paso, todos los vértices son cadenas de un solo vértice, por lo que conectamos pares AD, BE y CF, b / c la distancia entre ellos es la más pequeña.

En el segundo paso tenemos 3 cadenas y la distancia entre AD y BE es la misma que entre BE y CF, entonces conectamos digamos AD con BE y salimos con dos cadenas - ADEB y CF

En el tercer paso, la única forma de conectarlos es a través de B y C, b / c BC es más corto que BF, AF y AC (recuerde que consideramos solo los puntos finales de las cadenas). Entonces tenemos una cadena ahora ADEBCF.

En el último paso, conectamos dos puntos finales (A y F) para obtener un ciclo.

Respondido el 16 de diciembre de 12 a las 07:12

No entendía que BE previene AB y EF porque solo se eligen vértices en diferentes cadenas. Esto completó mi comprensión - ricab

Una imagen vale más que mil palabras, ¡gracias! Pero esta parte no la entendí: "b / c la distancia entre ellos es la más pequeña". Para saber eso, me parece que tendrías que recorrer todos los demás puntos para averiguar cuál de las distancias respectivas es la más pequeña. - sofocar

@stifin AD tiene distancia 1-e y DE tiene 1 + e y afaiu ya se sabe - Eugene Platonov

Está indicado en el texto del libro, pero el libro no explica cómo eso se sabe. - sofocar

1) La descripción establece que cada vértice siempre pertenece a una "cadena de un solo vértice" (es decir, está solo) o pertenece a otra cadena; un vértice solo puede pertenecer a una cadena. El algoritmo dice que en cada paso usted selecciona todos los pares posibles de dos vértices que son cada uno un punto final de la cadena respectiva a la que pertenecen, y que no pertenecen ya a la misma cadena. A veces serán singletons; a veces uno o ambos ya pertenecerán a una cadena no trivial, por lo que unirá dos cadenas.

2) Repites el bucle n veces, de modo que eventualmente seleccione cada vértice; pero sí, el recuento de iteraciones real no se usa para nada. Todo lo que importa es que ejecute el ciclo suficientes veces.

Respondido 27 ago 11, 23:08

un poco de aclaración para 1): enumeran solo los puntos finales de las cadenas. No es una especie de algoritmo de Kruskal, es una heurística de TSP, las cadenas crecen solo en los puntos finales. - unkulunkulu

Entiendo la idea general, lo que me falta es la primera iteración. En la primera iteración no hay puntos finales, entonces, ¿cómo se enumeran los vértices individuales? ej .: -5, -1, 0, 2. - ChrisOdney

Un Singleton es una cadena con un punto final. Al principio, cada punto es un Singleton. - Ernest Friedman-Hill

Gracias, no tienes idea de lo útiles que resultan tus comentarios dada la frustración. Lo que quería preguntar es si existe un orden específico en el que se procesan estos puntos. Aquí está mi entendimiento: ChrisOdney

@dhblah quizás mi respuesta aquí ayudaría - ricab

Aunque la pregunta ya está respondida, aquí hay una implementación de Python para la heurística del par más cercano. Comienza con cada punto como una cadena, luego se extiende sucesivamente para construir una cadena larga que contiene todos los puntos. Este algoritmo construye una ruta, pero no es una secuencia de movimientos del brazo del robot para ese punto de inicio del brazo que se desconoce.

import matplotlib.pyplot as plot
import math
import random


def draw_arrow(axis, p1, p2, rad):
    """draw an arrow connecting point 1 to point 2"""
    axis.annotate("",
              xy=p2,
              xytext=p1,
              arrowprops=dict(arrowstyle="-", linewidth=0.8, connectionstyle="arc3,rad=" + str(rad)),)


def closest_pair(points):
    distance = lambda c1p, c2p:  math.hypot(c1p[0] - c2p[0], c1p[1] - c2p[1])
    chains = [[points[i]] for i in range(len(points))]
    edges = []
    for i in range(len(points)-1):
        dmin = float("inf")  # infinitely big distance
        # test each chain against each other chain
        for chain1 in chains:
            for chain2 in [item for item in chains if item is not chain1]:
                # test each chain1 endpoint against each of chain2 endpoints
                for c1ind in [0, len(chain1) - 1]:
                    for c2ind in [0, len(chain2) - 1]:
                        dist = distance(chain1[c1ind], chain2[c2ind])
                        if dist < dmin:
                            dmin = dist
                            # remember endpoints as closest pair
                            chain2link1, chain2link2 = chain1, chain2
                            point1, point2 = chain1[c1ind], chain2[c2ind]
        # connect two closest points
        edges.append((point1, point2))
        chains.remove(chain2link1)
        chains.remove(chain2link2)
        if len(chain2link1) > 1:
            chain2link1.remove(point1)
        if len(chain2link2) > 1:
            chain2link2.remove(point2)
        linkedchain = chain2link1
        linkedchain.extend(chain2link2)
        chains.append(linkedchain)
    # connect first endpoint to the last one
    edges.append((chains[0][0], chains[0][len(chains[0])-1]))
    return edges


data = [(0.3, 0.2), (0.3, 0.4), (0.501, 0.4), (0.501, 0.2), (0.702, 0.4), (0.702, 0.2)]
# random.seed()
# data = [(random.uniform(0.01, 0.99), 0.2) for i in range(60)]
edges = closest_pair(data)
# draw path
figure = plot.figure()
axis = figure.add_subplot(111)
plot.scatter([i[0] for i in data], [i[1] for i in data])
nedges = len(edges)
for i in range(nedges - 1):
    draw_arrow(axis, edges[i][0], edges[i][1], 0)
# draw last - curved - edge
draw_arrow(axis, edges[nedges-1][0], edges[nedges-1][1], 0.3)
plot.show()

Respondido 20 Abr '15, 23:04

Gracias por esto. ¿Puedo preguntar por qué la línea más larga es curva en lugar de recta? La curva alarga la línea. - DBedrenko

@DBedrenko Porque si lo dibujas en línea recta, cruzará las líneas previamente dibujadas. Creo que la curva hace que se vea un poco mejor. En la línea penúltimo, cambie el último parámetro de draw_arrow a 0 si desea que sea recto. - 047

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.