栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

数据库随机抽题解决(类似背包问题算法)

数据库随机抽题解决(类似背包问题算法)

数据库随机抽题解决(类似背包问题算法)

题目:
题库中有N道题,每道题都有一个分数,我们传入一个指定分数和指定题目数量,程序返回指定数量总分为指定分数的数组
例子:传入总分100,题目数量10,题库中返回10道题,其总分相加为100

解题思路
1.获得分数的一维数组,然后获得总分,通过函数sel_set计算出所有可能出现的组合,将组合数目和指定题数相同的返回
2.判断返回是否为空,为空则无相应题目,不为空则查出所有分数在返回的分数数组中数据
3.首先循环查出来的所有数据random_data ,然后循环分数数组score_array ,如果查出来的所有数据中有分数和分数数组中分数相同则保存在return中,然后销毁这个分数数组中的分数,然后将data的key保存在del中,下一次循环时先判断这个key是否存储过,没有存储过才继续保存到return中
4.如果存储的数组个数和分数数组中的数组个数相同则返回数据

    public function test_sum(){
        // 取出分数
        $data=DB::table('table')->whereNotNull('score')->get()->toArray();
        $data = array_column($data,'score');

        // 取出考试设置
        $exam_set = DB::table('table')->first();
        $total_grade =$exam_set->total_grade;
        $exam_number = $exam_set->exam_number;
        // 排列组合
        $score_array  = $this->sel_set($total_grade,$data,$exam_number);
        if (empty($score_array)){
            print_r('当前题库无匹配!');
            return "当前题库无匹配";
        }
        // 方法1  15道题         算法耗时:100 ms 内存:memory usage: 21.56 M
        $random_data  = table::whereIn('score',$score_array)->inRandomOrder()->get()->toArray();
        $return = [];
        $del = [];
        $r_data_count = count($score_array);
        foreach ($random_data as $key=>$val){
            foreach ($score_array as $k => $v){
                if ($val['score'] == $v && !in_array($key,$del)){
                    $return[] = $val;
                    unset($score_array[$k]);
                    $del[] = $key;
                }
            }
            if (count($return) == $r_data_count){
                break;
            }
        }
    }



    public function sel_set($need, $arr,$exam_number) {
        //子集数2的数组元素数次方
        $arr_count =count($arr);
        // 修改
        $return_list = [];
        $set_count = pow(2, $arr_count);
        //set_arr用来存放符合需求的子集
        $set_arr = array();
        //set_count个子集,所以循环set_count次
        for( $i = 1; $i < $set_count; $i++ ) {
            //tmp用来存放每次子集
            $tmp = array();
            //将子集对应编号转化二进制
            $dec = decbin($i);
            //数组集合有arr_count个元素,所以将二进制左补0为对应位,以便取数组元素
            $dec = str_pad($dec, $arr_count, 0, STR_PAD_LEFT);
            //对该二进制数循环 判断是否为1
            for( $j = 0; $j < $arr_count; $j++ ) {
                //如果当前位为1, 则将数组对应元素放入子集数组
                if( 1 == $dec[$j] ) {
                    array_push($tmp, $arr[$j]);
                }
            }
            //判断当前子集之和是否等于设定的定值,符合则存入set_arr
            if( $need == array_sum($tmp) ) {
                if (count($tmp) ==  $exam_number){
                    return $tmp;
                }
            }
        }
        //返回符合要求的集合或空集合
        return $set_arr;
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/281472.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号