Exemplo n.º 1
0
        private static Rating CalculateNewRating(GameInfo gameInfo, Rating selfRating, Rating opponentRating,
                                                 PairwiseComparison comparison)
        {
            double drawMargin = DrawMargin.GetDrawMarginFromDrawProbability(gameInfo.DrawProbability, gameInfo.Beta);

            double c =
                Math.Sqrt(
                    Square(selfRating.StandardDeviation)
                    +
                    Square(opponentRating.StandardDeviation)
                    +
                    2 * Square(gameInfo.Beta));

            double winningMean = selfRating.Mean;
            double losingMean  = opponentRating.Mean;

            switch (comparison)
            {
            case PairwiseComparison.Win:
            case PairwiseComparison.Draw:
                // NOP
                break;

            case PairwiseComparison.Lose:
                winningMean = opponentRating.Mean;
                losingMean  = selfRating.Mean;
                break;
            }

            double meanDelta = winningMean - losingMean;

            double v;
            double w;
            double rankMultiplier;

            if (comparison != PairwiseComparison.Draw)
            {
                // non-draw case
                v = TruncatedGaussianCorrectionFunctions.VExceedsMargin(meanDelta, drawMargin, c);
                w = TruncatedGaussianCorrectionFunctions.WExceedsMargin(meanDelta, drawMargin, c);
                rankMultiplier = (int)comparison;
            }
            else
            {
                v = TruncatedGaussianCorrectionFunctions.VWithinMargin(meanDelta, drawMargin, c);
                w = TruncatedGaussianCorrectionFunctions.WWithinMargin(meanDelta, drawMargin, c);
                rankMultiplier = 1;
            }

            double meanMultiplier = (Square(selfRating.StandardDeviation) + Square(gameInfo.DynamicsFactor)) / c;

            double varianceWithDynamics = Square(selfRating.StandardDeviation) + Square(gameInfo.DynamicsFactor);
            double stdDevMultiplier     = varianceWithDynamics / Square(c);

            double newMean   = selfRating.Mean + (rankMultiplier * meanMultiplier * v);
            double newStdDev = Math.Sqrt(varianceWithDynamics * (1 - w * stdDevMultiplier));

            return(new Rating(newMean, newStdDev));
        }
        private static void UpdatePlayerRatings <TPlayer>(GameInfo gameInfo,
                                                          IDictionary <TPlayer, Rating> newPlayerRatings,
                                                          IDictionary <TPlayer, Rating> selfTeam,
                                                          IDictionary <TPlayer, Rating> otherTeam,
                                                          PairwiseComparison selfToOtherTeamComparison)
        {
            double drawMargin  = DrawMargin.GetDrawMarginFromDrawProbability(gameInfo.DrawProbability, gameInfo.Beta);
            double betaSquared = Square(gameInfo.Beta);
            double tauSquared  = Square(gameInfo.DynamicsFactor);

            int totalPlayers = selfTeam.Count() + otherTeam.Count();

            double selfMeanSum      = selfTeam.Values.Sum(r => r.Mean);
            double otherTeamMeanSum = otherTeam.Values.Sum(r => r.Mean);

            double c = Math.Sqrt(selfTeam.Values.Sum(r => Square(r.StandardDeviation))
                                 +
                                 otherTeam.Values.Sum(r => Square(r.StandardDeviation))
                                 +
                                 totalPlayers * betaSquared);

            double winningMean = selfMeanSum;
            double losingMean  = otherTeamMeanSum;

            switch (selfToOtherTeamComparison)
            {
            case PairwiseComparison.Win:
            case PairwiseComparison.Draw:
                // NOP
                break;

            case PairwiseComparison.Lose:
                winningMean = otherTeamMeanSum;
                losingMean  = selfMeanSum;
                break;
            }

            double meanDelta = winningMean - losingMean;

            double v;
            double w;
            double rankMultiplier;

            if (selfToOtherTeamComparison != PairwiseComparison.Draw)
            {
                // non-draw case
                v = TruncatedGaussianCorrectionFunctions.VExceedsMargin(meanDelta, drawMargin, c);
                w = TruncatedGaussianCorrectionFunctions.WExceedsMargin(meanDelta, drawMargin, c);
                rankMultiplier = (int)selfToOtherTeamComparison;
            }
            else
            {
                // assume draw
                v = TruncatedGaussianCorrectionFunctions.VWithinMargin(meanDelta, drawMargin, c);
                w = TruncatedGaussianCorrectionFunctions.WWithinMargin(meanDelta, drawMargin, c);
                rankMultiplier = 1;
            }

            foreach (var teamPlayerRatingPair in selfTeam)
            {
                Rating previousPlayerRating = teamPlayerRatingPair.Value;

                double meanMultiplier   = (Square(previousPlayerRating.StandardDeviation) + tauSquared) / c;
                double stdDevMultiplier = (Square(previousPlayerRating.StandardDeviation) + tauSquared) / Square(c);

                double playerMeanDelta = (rankMultiplier * meanMultiplier * v);
                double newMean         = previousPlayerRating.Mean + playerMeanDelta;

                double newStdDev =
                    Math.Sqrt((Square(previousPlayerRating.StandardDeviation) + tauSquared) * (1 - w * stdDevMultiplier));

                newPlayerRatings[teamPlayerRatingPair.Key] = new Rating(newMean, newStdDev);
            }
        }