查找最接近的值算法

时间:2014-08-26 16:04:48

标签: python algorithm search

def find_closest(data, target, key = lambda x:f(x))

这是我的函数定义,其中数据是值的集合,我想找到尽可能少量评估中评估最接近目标的值,即abs(target-f(x))是最小的。 f(x)是单调的。

我听说二进制搜索可以在O(log(n))时间执行此操作,python中是否有库实现?是否有更有效的搜索算法?

编辑:我希望在评估f(x)方面尽量减少复杂性,因为这是昂贵的部分。我想找到数据中的x,当用f(x)计算时,它最接近目标。 data位于f的域中,target的范围为f。是的,数据可以快速排序。

3 个答案:

答案 0 :(得分:0)

您可以使用bisect模块中的实用程序。您必须在x上评估data,即list(f(x) for x in data),以获得单调/排序列表以进行二等分。

我不知道标准库中的二进制搜索直接在fdata上运行。

答案 1 :(得分:0)

如果显示的数据已经排序且功能严格单调, 对数据应用函数f,然后使用bisect.bisect

执行二进制搜索
import bisect
def find_closest(data, target, key = f):

    data = map(f, data)
    if f(0) > f(1):
        data = [-e for e in data]
    try:
        return data[bisect.bisect_left(data, target)]
    except IndexError:
        return data[-1]

答案 2 :(得分:0)

使用bisect_left()方法查找下限。 Bisect_left接受随机访问元素列表,以避免计算所有元素,您可以使用已定义__len____getitem__方法的计算函数值的延迟集合。 仔细检查边界条件的返回值。 您的繁重计算将被称为O(log(N) + 1) = O(log(N))次。

from bisect import bisect_left
from collections import defaultdict

class Cache(defaultdict):
    def __init__(self, method):
        self.method = method
    def __missing__(self, key):
        return self.method(key)

class MappedList(object):
    def __init__(self, method, input):
        self.method = method
        self.input = input
        self.cache = Cache(method)
    def __len__(self):
        return len(self.input)
    def __getitem__(self, i):
        return self.cache[input[i]]

def find_closest(data, target, key = lambda x:x):
    s = sorted(data)
    evaluated = MappedList(key, s)
    index = bisect_left(evaluated, target)
    if index == 0:
        return data[0]
    if index == len(data):
        return data[index-1]
    if target - evaluated[index-1] <= evaluated[index] - target:
        return data[index-1]
    else:
        return data[index]