基于藏品规模与序列号稀有度的PHP物品评分公式设计
PHP 藏品序列号稀有度评分实现方案
核心设计逻辑
- 拆分两个独立可配置的评分模块,无硬绑定的强制计算规则,适配灵活调整需求
- 组级维度:按单组总持有量设置对应基准分,严格遵循「组总持有量越少,整体稀有度越高」的原则,保证同序列号的藏品在低库存组别中的得分高于高库存组别
- 组内维度:在组基准分的基础上,根据藏品实际序列号做均匀线性扣减,保证组内#1为得分最高档,随序列号增大梯度递减,杜绝同组所有物品得分一致的情况
- 特殊适配:1件装的孤品单独走手动赋值流程,不纳入通用计算公式,支持设置远高于低库存组#1的分值
预设组基准分映射表
针对现有固定档位的藏品组,直接通过映射表配置组内#1的基准分,比复杂数学函数更易调整:
| 单组总持有量 | 组内#1对应基准分 |
|---|---|
| 10件 | 1000 |
| 20件 | 600 |
| 150件 | 200 |
| 350件 | 120 |
| 1000件 | 50 |
| 5000件 | 15 |
| 10000件 | 8 |
| 50000件 | 2 |
注:映射表的具体数值可根据业务需求随时调整,仅需保持「组持有量越小,基准分越高」的排序逻辑即可,无固定绝对得分值的强制要求。
组内线性得分计算规则
为保证梯度连续无断点,统一采用线性扣减逻辑:
- 组内得分区间设置为从最高基准分(#1的得分)平滑过渡到组内最低分
- 可配置参数:组内最低分默认设置为组基准分的10%,避免组内末端藏品得分过低失去参考价值
- 均匀扣减步长计算公式:
step = (group_base_score - min_group_score) / (group_total - 1) - 单藏品最终得分计算公式:
final_score = group_base_score - (serial_no - 1) * step
举个计算实例:10件组的基准分是1000,按10%的最低分比例计算,组内末端最低分为100,扣减步长为(1000-100)/(10-1) = 100。最终#1得1000分,#2得900分,#3得800分……直至#10得100分,全程线性无同分。
PHP 可复用实现代码
/** * 计算藏品稀有度得分 * @param int $groupTotal 单组总持有量,取值1代表孤品 * @param int $serialNo 藏品序列号,从1开始编号 * @param int $soloScore 孤品手动配置得分,默认值5000 * @param float $minScoreRatio 组内最低得分占组基准分的比例,默认值0.1(即10%) * @return float|int 藏品最终得分 */ function calculateItemScore(int $groupTotal, int $serialNo, int $soloScore = 5000, float $minScoreRatio = 0.1): float|int { // 孤品单独处理,不套用通用公式 if ($groupTotal === 1) { return $soloScore; } // 预设的各组基准分映射,可根据业务随时调整 $groupBaseMap = [ 10 => 1000, 20 => 600, 150 => 200, 350 => 120, 1000 => 50, 5000 => 15, 10000 => 8, 50000 => 2, ]; // 对未在预设档位的组,按就近持有量比例折算基准分,保证稀有度逻辑一致 if (!isset($groupBaseMap[$groupTotal])) { $nearestKey = array_reduce(array_keys($groupBaseMap), function ($carry, $key) use ($groupTotal) { return abs($key - $groupTotal) < abs($carry - $groupTotal) ? $key : $carry; }, array_key_first($groupBaseMap)); $baseScore = $groupBaseMap[$nearestKey] * ($nearestKey / $groupTotal); } else { $baseScore = $groupBaseMap[$groupTotal]; } // 计算组内扣减步长 $minScore = $baseScore * $minScoreRatio; $step = ($baseScore - $minScore) / ($groupTotal - 1); // 计算最终得分并保留两位小数 $finalScore = $baseScore - ($serialNo - 1) * $step; return round($finalScore, 2); }
实际调用效果
- 10件组#1藏品:调用
calculateItemScore(10, 1),返回得分1000 - 10件组#10藏品:调用
calculateItemScore(10, 10),返回得分100 - 1000件组#1藏品:调用
calculateItemScore(1000, 1),返回得分50,远低于同序列号在10件组的得分,符合跨组稀有度逻辑 - 1件孤品:调用
calculateItemScore(1, 1, 5000),返回得分5000,满足高于低库存组#1得分的手动配置需求 - 50000件组#25000藏品:调用
calculateItemScore(50000, 25000),返回得分1.1,符合组内线性梯度要求
规则匹配校验
- 跨组稀有度逻辑:组基准分严格随组总持有量升高而递减,同序列号在低库存组的得分必然更高,匹配第一条规则
- 组内梯度逻辑:固定步长线性扣减,#1为组内最高分,随序列号增大得分均匀下降,无同组同分情况,匹配第二条规则
- 孤品处理逻辑:独立分支适配,不纳入通用计算流程,支持手动设置高值,匹配第三条规则
- 灵活调整逻辑:所有参数均可手动修改,无强制的固定绝对得分标准,匹配第四条规则
内容的提问来源于stack exchange,提问作者3s2ng
相关产品推荐
相关产品推荐

