$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的,按最大佔比的返回,否則算首個相乘求出期望值和實際值,還沒最佳化和嚴格驗證,就先跑了幾個測試,感覺是不是寫的麻煩了,演算法不好
需求如下:分類會有多種,每種分類都有對應的佔比,比如ABC三類對應為2:4:6,每種分類出現過的次數會有記錄,比如A,B,C各出現過2,4,6次那麼認為當前是平衡狀態,下一次預計出現的分類則為B類,因為平衡狀態下,B類佔比最大。當然一開始肯定不是平衡的,所以需要計算當前各類出現過的次數,根據佔比返回每次應該出現的分類
本作品採用《CC 協議》,轉載必須註明作者和本文連結