一、要求

比方说一个试卷,总共 60 题,每道题都由难度、章节、类型 3 个属性
按照难度 简单 20 题 一般 30 题 困难 10 题
按照章节 章节一 10 题 章节二 15 题 章节 3 20 题,章节四 15 题
按照类型 文字题 20 题 图片题 20 题 视频题 20 题
每种维度题目数量是可以自行设置的,保证总题量等于 60 就行
不是每个最细分类(我这里称 sku 把)都有题目或者说有足量的题目,这种情况要考虑到
然后随机从数据库中取出这些题,有没有比较好的算法?

二、实现办法

1、方法一

    $tmp = [];
    for ($i=1;$i<=60;$i++){
        if($i <= 20) $item = ['简单'];
        if($i <= 50 && $i>20) $item = ['一般'];
        if($i <= 60 && $i>50) $item = ['困难'];
        $tmp[] = $item;
    }
    shuffle($tmp);
    foreach ($tmp as $key => &$value){
        if($key < 10) array_push($value,'章节一');
        if($key < 25 && $key>=10) array_push($value,'章节二');
        if($key < 45 && $key>=25) array_push($value,'章节三');
        if($key < 60 && $key>=45) array_push($value,'章节四');
    }
    shuffle($tmp);
    foreach ($tmp as $key => &$value){
        if($key < 20) array_push($value,'文字题');
        if($key < 40 && $key>=20) array_push($value,'图片题');
        if($key < 60 && $key>=40) array_push($value,'视频题');
    }
    $qa = [];
    foreach ($tmp as $v){
        $index = implode('-',$v);
        $qa[$index] = isset($qa[$index]) ? $qa[$index] + 1 : 1;
    }
    dd($qa);

效果
aaa.png

2、方式二


$origin = [
    'level' => [
        ['text' => '简单', 'total' => 20],
        ['text' => '一般', 'total' => 30],
        ['text' => '困难', 'total' => 10]
    ]
];
$data = [];
for ($index = 0; $index < 60; $index++) {
    $item = [];
    foreach ($origin as $type => $values) {
        $total = array_sum(array_column($values, 'total'));
        $random = rand(1, $total);
        foreach ($values as $key => $value) {
            if ($random <= $value['total']) {
                $item[$type] = $value['text'];
                $origin[$type][$key]['total']--;
                break;
            } else {
                $random -= $value['total'];
            }
        }
    }
    $data[] = $item;
}