Ruby 查找哈希组合以匹配所需的值百分比分布

Ruby 查找哈希组合以匹配所需的值百分比分布,ruby,algorithm,random,language-agnostic,combinations,Ruby,Algorithm,Random,Language Agnostic,Combinations,给定一个散列数组,我正在寻找一种方法来选择这些散列的随机子集,以便子集的属性分布与所需的百分比匹配 例如,给定以下数组: [ { question_id: 1, grade: 1, marks: [ { topic: 'number', ao: 1 }, { topic: 'ratios', ao: 2 } ] }, { question_id: 2, grade: 3, marks: [ {

给定一个散列数组,我正在寻找一种方法来选择这些散列的随机子集,以便子集的属性分布与所需的百分比匹配

例如,给定以下数组:

[
  {
    question_id: 1,
    grade: 1,
    marks: [
      { topic: 'number', ao: 1 },
      { topic: 'ratios', ao: 2 }
    ]
  },
  {
    question_id: 2,
    grade: 3,
    marks: [
      { topic: 'number', ao: 2 },
      { topic: 'number', ao: 2 }
    ]
  },
  {
    question_id: 3,
    grade: 2,
    marks: [
      { topic: 'number', ao: 1 },
      { topic: 'geometry', ao: 1 },
      { topic: 'ratios', ao: 1 },
      { topic: 'number', ao: 2 },
      { topic: 'geometry', ao: 2 }
    ]
  },
  {
    question_id: 4,
    grade: 3,
    marks: [
      { topic: 'number', ao: 1 },
      { topic: 'ratios', ao: 2 },
      { topic: 'geometry', ao: 2 },
      { topic: 'geometry', ao: 2 }
    ]
  },
  {
    question_id: 5,
    grade: 1,
    marks: [
      { topic: 'ratios', ao: 1 },
      { topic: 'ratios', ao: 2 }
    ]
  },
  {
    question_id: 6,
    grade: 1,
    marks: [
      { topic: 'number', ao: 1 },
      { topic: 'number', ao: 2 },
      { topic: 'number', ao: 2 },
      { topic: 'ratios', ao: 2 }
    ]
  },
  {
    question_id: 7,
    grade: 3,
    marks: [
      { topic: 'number', ao: 2 }
    ]
  },
  {
    question_id: 8,
    grade: 3,
    marks: [
      { topic: 'geometry', ao: 1 }
    ]
  }
]
我希望找到满足以下条件的随机组合:

分数总数=10

50%的分数是主题编号
20%的分数是主题比率
30%的分数是主题几何

40%的分数为1级
50%的分数为2级
10%的分数为3级

50%的分数为ao 1
50%的分数为AO2

满足这些要求的示例结果是:

[
  {
    question_id: 3,
    grade: 2,
    marks: [
      { topic: 'number', ao: 1 },
      { topic: 'geometry', ao: 1 },
      { topic: 'ratios', ao: 1 },
      { topic: 'number', ao: 2 },
      { topic: 'geometry', ao: 2 }
    ]
  },
  {
    question_id: 6,
    grade: 1,
    marks: [
      { topic: 'number', ao: 1 },
      { topic: 'number', ao: 2 },
      { topic: 'number', ao: 2 },
      { topic: 'ratios', ao: 2 }
    ]
  },
  {
    question_id: 8,
    grade: 3,
    marks: [
      { topic: 'geometry', ao: 1 }
    ]
  }
]
理想情况下,如果不存在满足这些要求的组合(具有一定程度的公差),我将期望收到一个错误

我解决这个问题的最初方法是找到所有可能的问题组合,这些问题的总分数为10分,然后迭代这些组合,检查每个组合是否满足所有其他要求

我从这个算法开始,该算法从一个数组中找出所有可能的数字组合,求和为所需的总数:

def subset_sum(数字、目标、部分=[]、结果=[])
s=partial.0,:+
如果s==目标
结果=目标
(0..(number.length-1))。每个都有|
n=数字[i]
剩余=数字。删除(i+1)
子集和(剩余、目标、部分+[n],结果)
结束
结果
结束
结束

然而,在我的问题的实际应用中,我希望问题数组的长度超过1000,总分数等于40。对于这些数字,此解决方案的优化程度太低,运行时间很长。

我不确定,但可能与背包问题有关()。如果这是真的,那么您的程序可能会因大量输入而失败。你可以试试动态规划@Eric,我想你指的是状态空间的构造,从中可以进行随机选择。在我的骨子里,我相信这是NP完全的,因此不适合使用动态规划。要应用DP解决方案,必须确定将采用的状态空间和递归计算。Dennis,我认为你唯一的办法是枚举散列的组合,只保留那些通过所有测试的组合(你可以从中取样),这意味着计算时间将随着散列的数量呈指数增长(但不取决于你强加的需求数量)。如果你能在合理的时间内选择所有有效的组合,如果有超过15+个散列(远远少于1000个),我会感到惊讶。我不确定,但这可能与背包问题有关()。如果这是真的,那么您的程序可能会因大量输入而失败。你可以试试动态规划@Eric,我想你指的是状态空间的构造,从中可以进行随机选择。在我的骨子里,我相信这是NP完全的,因此不适合使用动态规划。要应用DP解决方案,必须确定将采用的状态空间和递归计算。Dennis,我认为你唯一的办法是枚举散列的组合,只保留那些通过所有测试的组合(你可以从中取样),这意味着计算时间将随着散列的数量呈指数增长(但不取决于你强加的需求数量)。如果您能够在合理的时间内选择所有有效的组合(如果有超过15个以上的散列(远远少于1000个),我会感到惊讶。