假设如果给出(x,y)值中的一堆点,并且需要通过在x轴中的2个最近值之间线性插值来生成点,那么最快的实现是什么?
我四处寻找,但我找不到满意的答案,我觉得这是因为我没有找到合适的词语。
例如,如果我被给予(0,0)(0.5,1)(1,0.5),那么我想得到一个0.7的值;它将是(0.7-0.5)/(1-0.5)*(0.5-1)+ 1;但是什么数据结构可以让我找到两个最接近的键值来插入?如果我能够做到最好的关键值,那么这是一个简单的线性搜索/二进制搜索吗?
答案 0 :(得分:2)
我通常实现O(1)插值的方式是通过一个额外的数据结构,我称之为IntervalSelector
,在时间O(1)将给出必须的序列的两个周围值内插。
IntervalSelector
是一个类,当给出sequence
n
个横坐标时,会记住一个table
,它会映射x
的任何给定值到索引i
,使sequence[i] <= x < sequence[i+1]
在时间O(1)。
注意:以下内容数组基于1。
构建表的算法如下:
delta
视为横坐标输入sequence
中两个连续元素之间的最小距离。count := (b-a)/delta + 1
,其中a
和b
分别是(升序)sequence
的第一个和最后一个,/
代表整数商分裂。table
定义为Array
个count
元素。i
与1
之间的n
设置table[(sequence[j]-a)/delta + 1] := j.
table
的每个条目重复到其后的未访问位置。 在输出时,如果table
j
将i
映射到(j-1)*d <= sequence[i] - a < j*d.
以下是一个例子:
由于元素3 rd 和4 th 是最接近的元素,我们将该区间划分为该最小长度的子区间。现在,我们在table
中记住每个deta-
区间左端的位置。稍后,当给出输入x
时,我们将此delta-
的{{1}}间隔计算为x
,并使用该表推导序列中的相应间隔。如果(x-a)/delta + 1
落在x
序列元素的左侧,我们会选择i
。
更确切地说:
如果(i-1)
和x
之间的任何输入a
计算b
,j := (x-a)/delta + 1
如果i := table[j].
放x < sequence[i]
。然后,索引i := i - 1
满足i
;否则这两个连续元素之间的距离将小于sequence[i] <= x < sequence[i+1]
,而不是。{/ p>
备注:请注意,如果delta
中连续元素之间的最小距离delta
太小,则表格将包含太多条目。我在这里介绍的简单描述忽略了这些需要额外工作的病理情况。
答案 1 :(得分:1)
是的,一个简单的二进制搜索应该做得很好,通常就足够了。
如果你需要变得更好,你可以尝试interpolation search(与你的值插值无关)。
如果您的点以固定间隔分布(如示例中的0 0.5 1
),您还可以简单地将值存储在数组中,并通过索引以恒定时间访问它们。