以下Python代码旨在以某种特殊顺序遍历一个由(c, g)组成的二维网格,这些数据存储在”jobs”和”job_queue”中。但是在尝试理解代码后,我不确定这是哪种顺序。有人能告诉我这种顺序是什么,并解释每个函数的目的吗?谢谢和问候!
import Queuec_begin, c_end, c_step = -5, 15, 2 g_begin, g_end, g_step = 3, -15, -2 def range_f(begin,end,step): # like range, but works on non-integer too seq = [] while True: if step > 0 and begin > end: break if step < 0 and begin < end: break seq.append(begin) begin = begin + step return seq def permute_sequence(seq): n = len(seq) if n <= 1: return seq mid = int(n/2) left = permute_sequence(seq[:mid]) right = permute_sequence(seq[mid+1:]) ret = [seq[mid]] while left or right: if left: ret.append(left.pop(0)) if right: ret.append(right.pop(0)) return ret def calculate_jobs(): c_seq = permute_sequence(range_f(c_begin,c_end,c_step)) g_seq = permute_sequence(range_f(g_begin,g_end,g_step)) nr_c = float(len(c_seq)) nr_g = float(len(g_seq)) i = 0 j = 0 jobs = [] while i < nr_c or j < nr_g: if i/nr_c < j/nr_g: # increase C resolution line = [] for k in range(0,j): line.append((c_seq[i],g_seq[k])) i = i + 1 jobs.append(line) else: # increase g resolution line = [] for k in range(0,i): line.append((c_seq[k],g_seq[j])) j = j + 1 jobs.append(line) return jobs def main(): jobs = calculate_jobs() job_queue = Queue.Queue(0) for line in jobs: for (c,g) in line: job_queue.put((c,g)) main()
编辑:
每个(c,g)都有一个值。实际上,这段代码是在(c,g)的二维网格中搜索,以找到值最小的网格点。我猜测代码使用了某种启发式搜索算法?原始代码在这里 http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/gridsvr/gridregression.py,这是一个用于搜索SVM算法中两个参数c和g的最佳值,以最小化验证误差的脚本。
回答:
permute_sequence
重新排列一个值列表,使中间值首先出现,然后是每半部分的中间点,然后是剩余四分之一部分的中间点,依此类推。因此,permute_sequence(range(1000))
的开始部分如下所示:
[500, 250, 750, 125, 625, 375, ...]
calculate_jobs
交替填充行和列,使用permute_sequence
提供的一维坐标序列。
如果你最终还是要搜索整个二维空间,这并不能帮助你更快完成。你不妨按顺序扫描所有点。但我认为这个想法是尽早在搜索中找到一个不错的近似最小值。我怀疑通过随机打乱列表也能达到类似的效果。
xkcd的读者会注意到,小便池协议只会给出略有不同(可能更好)的结果:
[0, 1000, 500, 250, 750, 125, 625, 375, ...]