问题描述
用于一般理解的全局任务:我需要绘制函数 f(x) 的结果。简单的任务,但有两个问题:
每次获得新的 f(x) 值时,我都想更新 f(x) 的图。我不想因此解决 f(x),我想增加细节水平,所以每次我看图时,我都会在我的所有 (x_min,x_max) 范围内看到它,在这个范围内慢慢更新范围。
因此问题是:我需要一个函数,它以正确的顺序提供 x 的列表。
受二分搜索的启发,我想出了以下算法:
list
a 个 x 值仅包含唯一值并且已排序。
def dissort(a)
step = len(a) - 1
picked = [False for x in a]
out = []
while False in picked and step > 0:
for k in range(0,len(a),step):
if not picked[k]:
out.append(a[k])
picked[k] = True
step = step // 2
return out
in = [1,2,3,4,5,6,7,8,9]
out = [1,9,8]
assert(dissort(in) == out)
我在这里看到了一些缺陷:picked
数组可能是不必要的,每次细节级别增加时都会不必要地检查所选值。目前我对性能感到满意,但将来我可以将它用于更大的列表。
有没有办法让它更高效?是否已经在某些 python 包中实现了?我找不到。
解决方法
如果您的输入大小是 2 的幂,您可以获得与您的算法相同的顺序,如下所示:
要知道将第 n 个值放置在输出数组中的何处,请将 n 的二进制表示反转位的顺序并将其用作输出数组中的索引:
示例
n | bin | rev | out-index
0 = 000 -> 000 = 0
1 = 001 -> 100 = 4
2 = 010 -> 010 = 2
3 = 011 -> 110 = 6
4 = 100 -> 001 = 1
5 = 101 -> 101 = 5
6 = 110 -> 011 = 3
7 = 111 -> 111 = 7
So IN: [A,B,C,D,E,F,G,H] -> OUT: [A,H]
花费O(n)时间
如何反转位的顺序见Reverse bits in number
优化方式:https://stackoverflow.com/a/746203/1921273
,x 值的随机顺序是否可以? 如果是这样:
import random
xvals = random.sample(range(10),10)
结果:
[9,5,1,7,6,2,3,4,8]
这些数字不会重复。当然,每次调用它的结果都会不同。您可以生成任意数量的 x 值:
random.sample(range(20),20)
[10,18,13,14,19,17,11,15,9,8,12,16]
我相信这也是 O(n)。
唯一的问题可能是:在每次增加 x 值数量的迭代中,您是否也不希望前一次迭代有任何重复?还是以上就够了?
,为什么要搞得这么复杂?
为什么不将 x 和 f(x) 值存储在 dict 中,并对 dict 键进行排序:
data = {}
# every time you get a new x and f(x) value,store it in the dict:
data[x] = f(x)
# then when you want to plot:
xvals = sorted(data.keys())
yvals = [data[x] for x in xvals]
# Now you have a x values and y values,sorted by x value,so just:
plot(xvals,yvals)
这样的事情对你有用吗?
另外,顺便说一句:作为一般规则,你想要一些高性能的东西是可以理解的,但相对于你的算法需要 10 分钟到一个小时来收敛 f(x) 的每个值,每当一个新值出现时在,即使使用 O(n*ln(n)) 排序,将所有现有结果与新结果重新排序,也将比等待非常新值排序的时间。 (Python sorted 可以在不到 2.5 毫秒的时间内对 10,000 个数字进行排序。重点是,与 10 分钟的算法相比,再减少 0.5 到 1.0 毫秒,这不会对您的整个过程产生任何影响。