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
。是的,数据可以快速排序。
答案 0 :(得分:0)
您可以使用bisect
模块中的实用程序。您必须在x
上评估data
,即list(f(x) for x in data)
,以获得单调/排序列表以进行二等分。
我不知道标准库中的二进制搜索直接在f
和data
上运行。
答案 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]