考虑到散列数组,我正在寻找一种选择这些散列的随机子集的方法,以使子集的属性分布与所需百分比匹配。
例如,给定以下数组:
[
{
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%的分数是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。对于这些数字,此解决方案还没有经过优化,运行时间也很长。