Get the two closest points from a list of points

跟風遠走 提交于 2020-01-11 14:30:10

问题


I am given a list of integers/floats and I need to find the two numbers closest together. How would I do that using only nested for loops?


回答1:


For each element, you have to compare the distance of it to each of the other elements with your previous "closest" value - any time this comparison yields smaller values, you remember that pair as the "two closest" ones.

So, it is straightforward:

def find_two_closest(numbers):
    # most distant points:
    delta = max(numbers), min(numbers)
    for i, element in enumerate(numbers):
        for j, sec_element in enumerate(numbers):
            if i == j:
                continue
            if abs(sec_element - element) < abs(delta[0] - delta[1]):
                delta = sec_element, element
    return delta



回答2:


If the points are one dimensional (as in your input is just a list of numbers like [1, 4, 6, 2]), then you can easily do it in O(n log n) time by sorting them and finding the ones with the smallest difference:

def smallest_difference(points):
    sorted_points = sorted(points)
    return min(abs(prev - cur) for cur, prev in zip(sorted_points, sorted_points[1:]))

If you want to get the closest points instead of the distance between the closest points, use the key= parameter of the min function:

import operator

def smallest_difference(points):
    sorted_points = sorted(points)
    return min(zip(sorted_points, sorted_points[1:]), key=lambda x: abs(x[1] - x[0]))

If the points are two dimensional (as in your input is a list of 2 element tuples like [(1, 2), (3, 4), (5, 2)]) then the Wikipedia article for this problem https://en.wikipedia.org/wiki/Closest_pair_of_points_problem describes how to extend this to two dimensions.




回答3:


Checking each two points is not necessary and it's slow O(n^2).

I suggest to:
1) Sort the input.
2) Compare each two following values and choose smallest.
Timing will be much better O(n*log n) assuming that you use efficient sorting algorithm.

Code example:

input = [0, 65, 10, 100, 1231] #whatever you put here; it might be tuple, list, set, range, etc.

def find_closest(input):
    sorted_input = sorted(input)
    best = (sorted_input[-2], sorted_input[-1], sorted_input[-1] - sorted_input[-2])
    for i, val in enumerate(sorted_input[:-1]):
        d = sorted_input[i+1]-val
        if d < best[2]:
            best = (val, sorted_input[i+1], d) 
return best

Function returns both values and distance between them.




回答4:


Here is a quick fix only with nested for loops and if conditions; and nothing else.

Needless to say that this is the most inefficient way of doing this, but I assume there is reason for it (learning something?). If that's the case, you should spend some time trying to learn the process.

my_list = [1, 3, 9, 14, 12, 20, 22]
c = list()

for value_1 in my_list:
    for value_2 in my_list:
        if value_1 != value_2 and value_2-value_1>0:
            c.append({
                    'val_1': value_1, 
                    'val_2': value_2, 
                    'delta':value_2 - value_1
                })

minimum = c[0]['delta']
for item in c:
    num = item['delta']
    if minimum > num:
       minimum = num

print(str.join('\n', [str(item) for item in c if item['delta'] == minimum]))

which returns:

{'val_1': 1, 'val_2': 3, 'subtraction': 2}
{'val_1': 12, 'val_2': 14, 'subtraction': 2}
{'val_1': 20, 'val_2': 22, 'subtraction': 2}


来源:https://stackoverflow.com/questions/36845202/get-the-two-closest-points-from-a-list-of-points

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!