给定n个元素(a1,a2,...,an)的有序集合,我可以使用什么算法来挑选这些元素中的M个(M 例如,如果起始集是从1到9的数字(即n = 9),并且我想对其进行均匀采样,那么我最终只得到其中的5个(即M = 9),我&# 39; d选择1,3,5,7,9。要获得原始9中的3个,我将使用1,5,9等等。但是,对于任何n和M,选择元素的伪代码会是什么样的? 该问题的数学公式如下:给定M < n,找到集q(1),q(2),...,q(M)使得1 <= q(k)<1。对于任何k,q(k + 1)&lt; = M:[1,M-1],并且对于k:[1,M-1],q(k + 1)-q(k)的和是最大值可能的。
答案 0 :(得分:0)
根据Nico建议最大化最小差异(目标函数的形式相当灵活),有一个简单的 O(n ^ 2 M)-time 动态程序,就像这样。
def prune(a, M):
n = len(a)
# The [i][j] entry is the max min gap
# for a[0], ..., a[i] choose j + 1 (a[0] is always chosen).
table = [[float('inf')] * M for i in range(n)]
for i in range(1, n):
for j in range(M):
table[i][j] = max(min(table[k][j], a[i] - a[k])
for k in range(i))
# Trace back the sequence of argmaxes to recover the chosen indexes.
使用总单调性可以将其改善为 O(n M)时间。我们的想法是,随着i
的增加,k
的正确值也会增加,当我们增加k
时目标减少,我们就可以继续下一个i
。
上述两种算法都能处理相当普遍的目标。如果max为OK,那么有一个 O(n log n)-time 算法,它使用二进制搜索来猜测最小间隙,然后检查它是否可行。我等你来更新这个问题。