PHP伪平均评分生成器优化:用最少合理票数调整目标评分
PHP伪平均评分生成脚本优化
需求说明
现有业务场景:某素材初始评分为2.7,对应票数7票。需要将评分调整至指定目标值(例如从2.7调整至4.6),要求通过最少的合理票数达成目标,避免原脚本中调至6.0时票数激增超500的不合理情况。
原脚本代码
<?php class RatingFaker { private $totalRating = 10; // Maximum rating threshold (5 or 10) private $maxRatingGenerate = 10; // We generate maximum rating values during the passage private $minRatingGenerarate = 5; // Minimally generates a rating value during a pass private $minRatingCheck = 3.5; // The minimum acceptable threshold from which we start to act public function __construct($minRatingCheck) { $this->minRatingCheck = $minRatingCheck; } private function calcAverageRating($ratings = []) { $totalWeight = 0; $totalReviews = 0; foreach ($ratings as $weight => $numberofReviews) { $WeightMultipliedByNumber = $weight * $numberofReviews; $totalWeight += $WeightMultipliedByNumber; $totalReviews += $numberofReviews; } //divide the total weight by total number of reviews $averageRating = $totalWeight / $totalReviews; return [ 'rating' => $averageRating, 'vote_num' => $totalReviews ]; } private function getRandVoters() { $randRating = rand($this->minRatingGenerarate, $this->maxRatingGenerate); $randVoters = rand(1, 99); return [ $randRating => $randVoters ]; } private function ratingLoop($valueList) { $valueList = array_merge($valueList, $this->getRandVoters()); $newRating = $this->calcAverageRating($valueList); if($newRating['rating'] < $this->minRatingCheck) { $valueList = array_merge($valueList, $this->getRandVoters()); return $this->ratingLoop($valueList); } if($newRating['rating'] > 10) { $newRating['rating'] = 10; } return [ 'rating' => round($newRating['rating'], 1), 'sum' => round($newRating['vote_num'] * round($newRating['rating'], 1)), 'voters' => $newRating['vote_num'] ]; } public function check($currentRate, $currentVoteNum) { if($currentRate < $this->minRatingCheck) { $rating = $this->ratingLoop([ $currentRate => $currentVoteNum, ]); } return $rating ?? []; } } $currentRate = 2.4; $voteNum = 88; $oldRating = [ 'rating' => $currentRate, 'sum' => round($voteNum * $currentRate), 'voters' => $voteNum ]; $rating = []; $ratingFaker = new RatingFaker(6.0); $rating = $ratingFaker->check($currentRate, $voteNum); echo '<pre>'; echo 'Was:'; print_r($oldRating); echo "<br>"; echo "<br>"; echo "<br>"; echo 'Now:'; print_r($rating); echo '</pre>';
优化后的脚本代码
<?php class RatingOptimizer { private $maxRating = 10; // 评分上限(支持5或10) /** * 计算达到目标评分所需的最少新增票数 * @param float $currentRate 当前评分 * @param int $currentVoteNum 当前票数 * @param float $targetRate 目标评分 * @return array 包含最终评分、总票数、总分的结果 */ public function adjustToTarget($currentRate, $currentVoteNum, $targetRate) { // 目标评分不能超过上限或低于0 if ($targetRate > $this->maxRating || $targetRate < 0) { throw new InvalidArgumentException("目标评分必须在0到{$this->maxRating}之间"); } // 当前评分已高于目标,无需调整 if ($currentRate >= $targetRate) { return [ 'rating' => round($currentRate, 1), 'voters' => $currentVoteNum, 'sum' => round($currentRate * $currentVoteNum) ]; } $currentTotal = $currentRate * $currentVoteNum; $addVoteNum = 0; // 计算最少需要的新增最高评分票数,确保平均评分达到目标 do { $addVoteNum++; $newTotal = $currentTotal + $this->maxRating * $addVoteNum; $newTotalVotes = $currentVoteNum + $addVoteNum; $newAverage = $newTotal / $newTotalVotes; } while (round($newAverage, 1) < $targetRate); // 处理极端情况,避免评分超出上限 if ($newAverage > $this->maxRating) { $newAverage = $this->maxRating; } return [ 'rating' => round($newAverage, 1), 'voters' => $newTotalVotes, 'sum' => round($newAverage * $newTotalVotes) ]; } } // 示例使用 $currentRate = 2.7; $currentVoteNum = 7; $targetRate = 4.6; $optimizer = new RatingOptimizer(); $result = $optimizer->adjustToTarget($currentRate, $currentVoteNum, $targetRate); echo '<pre>'; echo '初始状态:' . PHP_EOL; print_r([ 'rating' => $currentRate, 'voters' => $currentVoteNum, 'sum' => round($currentRate * $currentVoteNum) ]); echo PHP_EOL . '调整后状态:' . PHP_EOL; print_r($result); echo '</pre>';
优化说明
- 目标导向调整:新增
targetRate参数,直接指定需要达到的评分值,替代原脚本的阈值判断逻辑 - 最少票数计算:通过数学推导,优先添加最高评分的投票,用最少的新增票数快速提升平均评分,避免原脚本随机大量投票导致的票数激增问题
- 边界处理:增加参数合法性校验,处理目标评分超出上限、当前评分已高于目标等边界场景
- 精度控制:通过循环计算确保最终评分四舍五入后符合目标值,结果更精准
内容的提问来源于stack exchange,提问作者qubit3003
相关产品推荐
相关产品推荐

