计算给出数组中最小标准差的子集
Posted
技术标签:
【中文标题】计算给出数组中最小标准差的子集【英文标题】:Computing the subset giving the minimum standard deviation in an array 【发布时间】:2013-12-07 06:33:27 【问题描述】:让我们有一个大小为N
的向量。例如:
x = rand(N,1)
我想计算向量中长度为K
的子集的最小标准差。
当N
和K
很小时,很容易找到最佳子集,因为我可以使用nchoosek(N,K)
枚举所有可能的子集。但是当N
和K
的值大于假设N=50
和K=25
时,nchoosek
无法计算组合,因为可能的子集的大小很大。
我想知道是否有更好的算法来计算子集,从而有效地给出数组中的最小标准偏差。例如通过动态编程。有什么想法吗?
更新:
我在答案之后循环实现了它,并与组合解决方案进行了比较。结果总是一样的,但速度却是前所未有的。
n = 20;
k = 10;
x = rand(n,1);
C = nchoosek(x, k);
tic
mins = realmax;
for i = 1:size(C,1)
s = std(C(i,:));
if s < mins
mins = s;
bestC = C(i,:);
end
end
toc
tic
[x2, j] = sort(x);
mins2 = realmax;
for i = 1:(n-k+1)
s = std(x2(i:(i+k-1)));
if s < mins2
mins2 = s;
idx = j((i:(i+k-1)));
end
end
toc
if mins == mins2
'Equal'
end
给予
Elapsed time is 7.786579 seconds.
Elapsed time is 0.002068 seconds.
ans =
Equal
【问题讨论】:
【参考方案1】:对数组进行排序,然后使用长度为K
的滚动窗口一次性计算。
我相信这会给你正确的答案,如果我能证明它会思考。
手摇论据,在“扩展这个”部分可能存在逻辑差距:
考虑您列表中的元素x
。让我们尝试找出包含该元素的一组大小为 2 的最小标准差。我们将通过选择x
和最接近x
的元素来获得它。将此扩展到k
元素,我们将得到一个集合,它是包含x
的排序列表的连续部分。因此,要选择k
元素的最小子集(即任何x
),我们只需如前所述遍历排序列表。
【讨论】:
我认为您是正确的,并且我认为我发布的解决方案使用conv
而不是 matlab 循环(可能更快也可能不会更快)找到它。但我也无法证明。
@Dan 发布了一个理由,但我认为它不完整。
这种归纳方法证明了添加最接近的元素会导致波动性的最小增加。但是,它并没有说它会给你一组大小为 n+1 且波动性最小的集合。显然,情况并非如此,因为从异常值开始绝对不必将您引导至最小波动率集。这可以通过从每一点开始来反驳,但这里还没有证明这是否足够。--直觉上感觉这个答案是正确的,所以我会给你我的投票,希望它是正确的。
@DennisJaheruddin 你是对的,它不是水密的。我认为这可能是一种更好的证明方法。第 1 步:证明对于任何非连续子集,我们可以通过用其中一个“洞”中的元素替换适当的(例如最小或最大)元素来减少方差。第 2 步:重复应用第 1 步,我们看到任何最小方差子集都必须是排序列表的连续部分。当然,繁琐的部分是证明第 1 步。但是这种方法可以避免您指出的问题。以上是关于计算给出数组中最小标准差的子集的主要内容,如果未能解决你的问题,请参考以下文章