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

Finding a combination of hashes to match a desired percentage distribution of values

提问人:Denis sellu 提问时间:7/10/2019 更新时间:7/10/2019 访问量:74

问:

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

例如,给定以下数组:

[
  {
    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% 的分数是 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: 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(numbers, target, partial=[], result=[])
    s = partial.inject 0, :+

    if s == target
      result << partial
    end

    return if s >= target

    (0..(numbers.length - 1)).each do |i|
      n = numbers[i]
      remaining = numbers.drop(i+1)
      subset_sum(remaining, target, partial + [n], result)
    end

    result
  end
end

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

Ruby 算法 随机 语言无关 组合

评论

0赞 Eric Duminil 7/10/2019
我不确定,但它可能与背包问题(en.wikipedia.org/wiki/Knapsack_problem)有关。如果这是真的,则预计程序会在输入量大时失败。您可以尝试动态编程 en.wikipedia.org/wiki/Knapsack_problem#Solving
0赞 Cary Swoveland 7/11/2019
@Eric,我假设你指的是从中随机选择的状态空间的构造。在我的骨子里,我相信这是NP完备的,因此不适合使用动态规划。要应用 DP 解决方案,必须确定将采用的状态空间和递归计算。我看不出合适。
2赞 Cary Swoveland 7/11/2019
Dennis,我相信你唯一的办法是枚举哈希值的组合,并只保留那些通过所有测试的哈希值(你会从中采样),这意味着计算时间会随着哈希值的增加而呈指数级增长(但不取决于你施加的要求数量)。如果有超过 15+- 个哈希值(远低于 1,000 个),您可以在合理的时间内选择所有有效组合,我会感到惊讶。

答: 暂无答案