public function __construct(TrueSkillFactorGraph $parentGraph, array $teamRanks) { parent::__construct($parentGraph); $this->_teamRanks = $teamRanks; $gameInfo = $this->getParentFactorGraph()->getGameInfo(); $this->_epsilon = DrawMargin::getDrawMarginFromDrawProbability($gameInfo->getDrawProbability(), $gameInfo->getBeta()); }
private static function calculateNewRating(GameInfo $gameInfo, Rating $selfRating, Rating $opponentRating, $comparison) { $drawMargin = DrawMargin::getDrawMarginFromDrawProbability($gameInfo->getDrawProbability(), $gameInfo->getBeta()); $c = sqrt(square($selfRating->getStandardDeviation()) + square($opponentRating->getStandardDeviation()) + 2 * square($gameInfo->getBeta())); $winningMean = $selfRating->getMean(); $losingMean = $opponentRating->getMean(); switch ($comparison) { case PairwiseComparison::WIN: case PairwiseComparison::DRAW: // NOP break; case PairwiseComparison::LOSE: $winningMean = $opponentRating->getMean(); $losingMean = $selfRating->getMean(); break; } $meanDelta = $winningMean - $losingMean; if ($comparison != PairwiseComparison::DRAW) { // non-draw case $v = TruncatedGaussianCorrectionFunctions::vExceedsMarginScaled($meanDelta, $drawMargin, $c); $w = TruncatedGaussianCorrectionFunctions::wExceedsMarginScaled($meanDelta, $drawMargin, $c); $rankMultiplier = (int) $comparison; } else { $v = TruncatedGaussianCorrectionFunctions::vWithinMarginScaled($meanDelta, $drawMargin, $c); $w = TruncatedGaussianCorrectionFunctions::wWithinMarginScaled($meanDelta, $drawMargin, $c); $rankMultiplier = 1; } $meanMultiplier = (square($selfRating->getStandardDeviation()) + square($gameInfo->getDynamicsFactor())) / $c; $varianceWithDynamics = square($selfRating->getStandardDeviation()) + square($gameInfo->getDynamicsFactor()); $stdDevMultiplier = $varianceWithDynamics / square($c); $newMean = $selfRating->getMean() + $rankMultiplier * $meanMultiplier * $v; $newStdDev = sqrt($varianceWithDynamics * (1 - $w * $stdDevMultiplier)); return new Rating($newMean, $newStdDev); }
private static function updatePlayerRatings(GameInfo $gameInfo, RatingContainer &$newPlayerRatings, Team $selfTeam, Team $otherTeam, $selfToOtherTeamComparison) { $drawMargin = DrawMargin::getDrawMarginFromDrawProbability($gameInfo->getDrawProbability(), $gameInfo->getBeta()); $betaSquared = square($gameInfo->getBeta()); $tauSquared = square($gameInfo->getDynamicsFactor()); $totalPlayers = $selfTeam->count() + $otherTeam->count(); $meanGetter = function ($currentRating) { return $currentRating->getMean(); }; $selfMeanSum = sum($selfTeam->getAllRatings(), $meanGetter); $otherTeamMeanSum = sum($otherTeam->getAllRatings(), $meanGetter); $varianceGetter = function ($currentRating) { return square($currentRating->getStandardDeviation()); }; $c = sqrt(sum($selfTeam->getAllRatings(), $varianceGetter) + sum($otherTeam->getAllRatings(), $varianceGetter) + $totalPlayers * $betaSquared); $winningMean = $selfMeanSum; $losingMean = $otherTeamMeanSum; switch ($selfToOtherTeamComparison) { case PairwiseComparison::WIN: case PairwiseComparison::DRAW: // NOP break; case PairwiseComparison::LOSE: $winningMean = $otherTeamMeanSum; $losingMean = $selfMeanSum; break; } $meanDelta = $winningMean - $losingMean; if ($selfToOtherTeamComparison != PairwiseComparison::DRAW) { // non-draw case $v = TruncatedGaussianCorrectionFunctions::vExceedsMarginScaled($meanDelta, $drawMargin, $c); $w = TruncatedGaussianCorrectionFunctions::wExceedsMarginScaled($meanDelta, $drawMargin, $c); $rankMultiplier = (int) $selfToOtherTeamComparison; } else { // assume draw $v = TruncatedGaussianCorrectionFunctions::vWithinMarginScaled($meanDelta, $drawMargin, $c); $w = TruncatedGaussianCorrectionFunctions::wWithinMarginScaled($meanDelta, $drawMargin, $c); $rankMultiplier = 1; } $selfTeamAllPlayers =& $selfTeam->getAllPlayers(); foreach ($selfTeamAllPlayers as &$selfTeamCurrentPlayer) { $localSelfTeamCurrentPlayer =& $selfTeamCurrentPlayer; $previousPlayerRating = $selfTeam->getRating($localSelfTeamCurrentPlayer); $meanMultiplier = (square($previousPlayerRating->getStandardDeviation()) + $tauSquared) / $c; $stdDevMultiplier = (square($previousPlayerRating->getStandardDeviation()) + $tauSquared) / square($c); $playerMeanDelta = $rankMultiplier * $meanMultiplier * $v; $newMean = $previousPlayerRating->getMean() + $playerMeanDelta; $newStdDev = sqrt((square($previousPlayerRating->getStandardDeviation()) + $tauSquared) * (1 - $w * $stdDevMultiplier)); $newPlayerRatings->setRating($localSelfTeamCurrentPlayer, new Rating($newMean, $newStdDev)); } }
private function assertDrawMargin($drawProbability, $beta, $expected) { $actual = DrawMargin::getDrawMarginFromDrawProbability($drawProbability, $beta); $this->assertEquals($expected, $actual, '', DrawMarginTest::ERROR_TOLERANCE); }