均匀修剪有序集

时间:2015-08-27 14:58:50

标签: algorithm

给定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)的和是最大值可能的。

1 个答案:

答案 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 算法,它使用二进制搜索来猜测最小间隙,然后检查它是否可行。我等你来更新这个问题。