Search code examples
python-3.xfunctioncoordinatesknnclosest-points

incorrect result showing in K nearest neighbour approach


I am reforming the 2D coordinate number in a aligned way which was not aligned (coordinate numbers were suffled) before.

I have below input coordinates,

X = [2, 2, 3, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 5, 4, 3, 5, 5, 5] 
Y = [2, 3, 3, 3, 4, 5, 6, 6, 6, 5, 4, 3, 2, 2, 2, 2, 3, 4, 5]

I have to make it aligned. Therefore, I first applied Sorted function on this coordinates. I got below output after it.

merged_list1 = sorted(zip(X, Y))

output

X1_coordinate_reformed = [2, 2, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6]
Y1_coordinate_reformed = [2, 3, 2, 3, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6]

Still it iot aligned properly. I want two consecutive nodes place next to each other. Therefore I am applying the approach to find the nearest coordinate from origin to find the very first node. Then from the first node, I found another nearest coordinate and so on...For that, I have applied below code,

First I wrote a function which calculates the distance and gives index of the nearest coordinate from the list.

def solve(pts, pt):
    x, y = pt
    idx = -1
    smallest = float("inf")
    for p in pts:
        if p[0] == x or p[1] == y:
            dist = abs(x - p[0]) + abs(y - p[1])
            if dist < smallest:
                idx = pts.index(p)
                smallest = dist
            elif dist == smallest:
                if pts.index(p) < idx:
                    idx = pts.index(p)
                    smallest = dist
    return idx

coor2 = list(zip(X1_coordinate_reformed, Y1_coordinate_reformed))  # make a list which contains tuples of X and Y coordinates
pts2 = coor2.copy()
origin1 = (0, 0)

new_coor1 = []

for i in range(len(pts2)):
    pt = origin1
    
    index_num1 = solve(pts2, pt)
    print('index is', index_num1)
    
    origin1 = pts2[index_num1]
    new_coor1.append(pts2[index_num1])
    del pts2[index_num1]

After running the code, I got below output,

[(6, 6), (5, 6), (4, 6), (4, 5), (4, 4), (4, 3), (3, 3), (2, 3), (2, 2), (3, 2), (4, 2), (5, 2), (5, 3), (5, 4), (5, 5), (6, 5), (6, 4), (6, 3), (6, 2)]

Which is not correct because it can be clearly understand that,

coor2 = [(2, 2), (2, 3), (3, 2), (3, 3), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6)]

origin = (0, 0)

if we find the distance between Origin which was (0, 0) in very first and from every coordinate from above coor2 list, we will get (2,2) is nearest coordinate. Then How come my code gives (6,6) is the nearest coordinate??

The interesting thing is, if I apply the same procedure (sorting followed by finding nearest coordinate) on below coordinates,

X2_coordinate = [2, 4, 4, 2, 3, 2, 4, 3, 1, 3, 4, 3, 1, 2, 0, 3, 4, 2, 0]
Y2_coordinate = [3, 4, 2, 1, 3, 2, 1, 0, 0, 2, 3, 4, 1, 4, 0, 1, 0, 0, 1]

After applying sorted function

X2_coordinate_reformed = [0, 0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]
Y2_coordinate_reformed = [0, 1, 0, 1, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]

After applying method of searching nearest coordinates mentioned above, the result I got

[(0, 0), (0, 1), (1, 1), (1, 0), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 4), (3, 3), (3, 2), (3, 1), (3, 0), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)]

Kindly suggest me where I am doing wrong and what should I change??


Solution

  • It is better to use scipy for finding closest coordinate.

    The code given below works.

    from scipy import spatial
    
    pts = merged_list1.copy()
    
    origin = (0, 0)
    origin = np.array(origin)
    
    new_coordi = []
    for i in range(len(pts)):
        x = origin
        distance,index = spatial.KDTree(pts).query(x)
        new_coordi.append(pts[index])
        origin = np.array(pts[index])
        del pts[index]