【问题标题】:random selection from 1-D vector data从一维矢量数据中随机选择
【发布时间】:2016-11-08 18:35:40
【问题描述】:

请您分享您对以下问题的想法

假设你有一个像

这样的一维矢量数据
Data=[ a1 a2 a3 a4..... an];   0<ai<100

我们如何找到数据的子集,例如

Data_subset=[ a3 a7 a8]  or  Data_subset=[ a1 a17 a81 a92 a93 a100 a101 ]

最能满足这个条件:abs(sum(Data_subset)-700)&lt;10

有什么想法吗?

【问题讨论】:

  • 这似乎与knapsack problem 非常相似,众所周知,这很难完全解决
  • 我称之为subset sum problem
  • 当你说“哪个最能满足这个条件”时,你的意思是你想要任何保持abs(sum(Data_subset)-700) &lt; 10 为真的子集,还是你想要具有最小值abs(sum(Data_subset)-700) 的子集?
  • 事实上,它更像是子集和问题的软约束变体,就像@beaker 提到的那样。
  • 感谢您宝贵的cmets。看来我有一个严重的数学挑战。 @Noel Segura:是的。子集的长度并不重要,它们的总和非常接近我们的常数的子集。比如说,总和(子集)= S+/-s

标签: matlab random numbers


【解决方案1】:

您可以通过以下方式计算唯一子集的数量(忽略顺序)

唯一 = 总和 (((N-1)^2+N-1)/2) + N 从 N=1 到 N=99

因此,如果您只需要对长度为 100 的向量执行此操作,那么您将只有 166750 个唯一数据子集。在这种情况下,您应该通过测试每个子集来暴力破解问题,也就是说,如果您可以创建一种生成它们的方法。

您可以使用 matlab 函数 perms() 之类的东西,它会为您提供向量的每个排列,但您应该有类似 1e156 种不同排列的东西。

我能想到的唯一部分解决方案是使用 randperm() 然后创建一个循环来测试该随机排列的子集

    nPerms = 100
    subSetsSaved = cell()
    cellIndex=1; 
    for iRand=1:1:nPerms
         randOrder = randperm(length(data));
         dataPerm = permute(data,randOrder);
         for jSub=1:1:length(data)
               subSet = dataPerm(1:jSub);
               if (abs(sum(subSet)-700)<10)
                     subSetsSaved{cellIndex} = subSet;
                     cellIndex = cellIndex+1;
               end
          end
     end

您甚至可以使用这个随机排列循环来尝试随机生成所有 166750 个唯一子集。您所要做的就是随机生成、排序和测试唯一性。当然,这些解决方案在效率方面并不理想,因此如果这是一个您需要快速解决的问题,或者如果您的集合远大于 N=100,您将需要一种不同的方法。

【讨论】:

  • 我不确定我是否理解您对唯一子集数量的计算。从我可以看到它是二进制的:每个元素要么在子集中,要么不在子集中,所以唯一子集的数量是 2^n 其中n 是原始向量的长度。
猜你喜欢
  • 1970-01-01
  • 2018-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多