What is the meaning of “from distinct vertex chains” in this nearest neighbor algorithm?

后端 未结 3 592
不知归路
不知归路 2020-12-29 18:43

The following pseudo-code is from the first chapter of an online preview version of The Algorithm Design Manual (page 7 from this PDF).

The example is of a

相关标签:
3条回答
  • 2020-12-29 19:01

    This is how I see it, after explanation of Ernest Friedman-Hill (accepted answer):

    So the example from the same book (Figure 1.4). I've added names to the vertices to make it clear Figure 1.4

    So at first step all the vertices are single vertex chains, so we connect A-D, B-E and C-F pairs, b/c distance between them is the smallest.

    At the second step we have 3 chains and distance between A-D and B-E is the same as between B-E and C-F, so we connect let's say A-D with B-E and we left with two chains - A-D-E-B and C-F

    At the third step there is the only way to connect them is through B and C, b/c B-C is shorter then B-F, A-F and A-C (remember we consider only endpoints of chains). So we have one chain now A-D-E-B-C-F.

    At the last step we connect two endpoints (A and F) to get a cycle.

    0 讨论(0)
  • 2020-12-29 19:11

    1) The description states that every vertex always belongs either to a "single-vertex chain" (i.e., it's alone) or it belongs to one other chain; a vertex can only belong to one chain. The algorithm says at each step you select every possible pair of two vertices which are each an endpoint of the respective chain they belong to, and don't already belong to the same chain. Sometimes they'll be singletons; sometimes one or both will already belong to a non-trivial chain, so you'll join two chains.

    2) You repeat the loop n times, so that you eventually select every vertex; but yes, the actual iteration count isn't used for anything. All that matters is that you run the loop enough times.

    0 讨论(0)
  • 2020-12-29 19:18

    Though question is already answered, here's a python implementation for closest pair heuristic. It starts with every point as a chain, then successively extending chains to build one long chain containing all points. This algorithm does build a path yet it's not a sequence of robot arm movements for that arm starting point is unknown.

    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()
    
    0 讨论(0)
提交回复
热议问题