兄弟們寫了個取當前出現未達到佔比且相差最大的型別的演算法,但感覺不是很好

伽藍幻夢發表於2024-02-02
        $category_ids = [1,2,3];
        $categories_ratio = [3, 6, 1];
        $categories_count = [4, 12, 3];
        $all_zero = true;
        $is_surpass = false;
        $categories_zero_count = array();

        // 檢查出現次數是否有0
        foreach ($categories_count as $key => $value) {
            if($value == 0){
                $categories_zero_count[$key] = $categories_ratio[$key];
            }
        }

        if(!empty($categories_zero_count)){
            $max_ratio = max($categories_zero_count);
            $max_ratio_key = array_keys($categories_zero_count, $max_ratio)[0];
            return $category_ids[$max_ratio_key];
        }

        // 計算每個元素的期望值
        $ratio_expected = array();
        foreach ($categories_ratio as $key => $value) {
            $ratio_expected[$key] = $value * $categories_count[0];
        }
        $count_expected = array();
        foreach ($categories_count as $key => $value) {
            $count_expected[$key] = $value * $categories_ratio[0];
        }
        // 計算每個元素的誤差
        $ratio_error = array();
        $low_ratio = array();
        foreach ($ratio_expected as $key=> $value)
        {
            $ratio_error[$key] = $value - $count_expected[$key];
            if($ratio_error[$key] != 0){
                $all_zero = false;
            }
            $low_ratio[$key] = floor($ratio_error[$key]*100/$value);
            if($low_ratio[$key] > 0){
                // 存在超出
                $is_surpass = true;
            }
        }
        // 相差全為0,取佔比最大的
        if($all_zero){
            $max_ratio = max($categories_ratio);
            $max_ratio_key = array_keys($categories_ratio, $max_ratio)[0];
            return $category_ids[$max_ratio_key];
        }
        // 比較,獲取應該不足的
        if(!empty($low_ratio)){
            // 存在超出
            if($is_surpass){
                $max_error = max($low_ratio);
                $max_error_key = array_keys($low_ratio, $max_error)[0];
                return $category_ids[$max_error_key];
            }else{
                // 不存在超出取首個 如0,-12,-123
                return $category_ids[0];
            }
        }

        return array_rand( $category_ids );

$category_ids是分類id
$categories_ratio是對應分類的佔比
$categories_count是對應分類出現的次數
理論上就是需要計算出當前出現的次數是否符合佔比,選出沒有達到佔比的分類id,比如都沒出現時,id 1出現了1次(正常應該是id2,它佔比高),那麼id1出現次數就為1: 0:0了,根據比例3, 6, 1,先去判斷如果有出現次數為0的,按最大佔比的返回,否則算首個相乘求出期望值和實際值,還沒最佳化和嚴格驗證,就先跑了幾個測試,感覺是不是寫的麻煩了,演算法不好:sob:

需求如下:分類會有多種,每種分類都有對應的佔比,比如ABC三類對應為2:4:6,每種分類出現過的次數會有記錄,比如A,B,C各出現過2,4,6次那麼認為當前是平衡狀態,下一次預計出現的分類則為B類,因為平衡狀態下,B類佔比最大。當然一開始肯定不是平衡的,所以需要計算當前各類出現過的次數,根據佔比返回每次應該出現的分類

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章