예제 #1
0
        private static double CalculateNewRating(GlickoPlayer competitor, List<GlickoOpponent> opponents, double newRatingDeviation)
        {
            var sum = 0.0;

            foreach(var opponent in opponents)
            {
                sum += opponent.GPhi * (opponent.Result - Edeltaphi(competitor.GlickoRating, opponent));
            }

            return competitor.GlickoRating + ((Math.Pow(newRatingDeviation, 2)) * sum);
        }
예제 #2
0
        private static double RatingImprovement(GlickoPlayer competitor, List <GlickoOpponent> opponents, double variance)
        {
            double sum = 0;

            foreach (var opponent in opponents)
            {
                sum += opponent.GPhi * (opponent.Result - Edeltaphi(competitor.GlickoRating, opponent));
            }

            return(variance * sum);
        }
예제 #3
0
        private static double CalculateNewRating(GlickoPlayer competitor, List <GlickoOpponent> opponents, double newRatingDeviation)
        {
            var sum = 0.0;

            foreach (var opponent in opponents)
            {
                sum += opponent.GPhi * (opponent.Result - Edeltaphi(competitor.GlickoRating, opponent));
            }

            return(competitor.GlickoRating + ((Math.Pow(newRatingDeviation, 2)) * sum));
        }
예제 #4
0
        public void GlickoUpdateNoOpponents()
        {
            var expectedValue = 0.06;

            var player1Opponents = new List<GlickoOpponent>();

            player1 = GlickoCalculator.CalculateRanking(player1, player1Opponents);
            var actualValue = player1.Volatility;

            Assert.AreEqual(expectedValue, actualValue);
        }
예제 #5
0
        private static double CalculateNewVolatility(GlickoPlayer competitor, List<GlickoOpponent> opponents, double variance)
        {
            var rankingChange = RatingImprovement(competitor, opponents, variance);
            var rankDeviation = competitor.GlickoRatingDeviation;            
            
            var A = VolatilityTransform(competitor.Volatility);
            var a = VolatilityTransform(competitor.Volatility);

            var k = 1;
            double B = 0.0;

            if (Math.Pow(rankingChange, 2) > (Math.Pow(competitor.GlickoRatingDeviation, 2) + variance))
            {
                B = Math.Log(Math.Pow(rankingChange, 2) - Math.Pow(competitor.GlickoRatingDeviation, 2) - variance);
            }

            if (Math.Pow(rankingChange, 2) <= (Math.Pow(competitor.GlickoRatingDeviation, 2) + variance))
            {                
                var x = VolatilityTransform(competitor.Volatility) - (k * VolatilityChange); 

                while(VolatilityFunction(x, rankingChange, rankDeviation, variance, competitor.Volatility) < 0)
                {
                    k++;
                }                
            }

            B = VolatilityTransform(competitor.Volatility) - (k * VolatilityChange);

            var fA = VolatilityFunction(A, rankingChange, rankDeviation, variance, competitor.Volatility);
            var fB = VolatilityFunction(B, rankingChange, rankDeviation, variance, competitor.Volatility);

            while (Math.Abs(B - A) > ConvergenceTolerance)
            {
                var C = A + ((A - B) * fA / (fB - fA));
                var fC = VolatilityFunction(C, rankingChange, rankDeviation, variance, competitor.Volatility);

                if ((fC * fB) < 0)
                {
                    A = B;
                    fA = fB;
                }
                else
                {
                    fA = fA / 2;
                }

                B = C;
                fB = fC;
            }

            return Math.Exp(A / 2);
        }
예제 #6
0
        private static double ComputeVariance(GlickoPlayer competitor, List <GlickoOpponent> opponents)
        {
            double sum = 0;

            foreach (var opponent in opponents)
            {
                var eDeltaPhi = Edeltaphi(competitor.GlickoRating, opponent);

                sum += Math.Pow(opponent.GPhi, 2) * eDeltaPhi * (1 - eDeltaPhi);
            }

            return(Math.Pow(sum, -1));
        }
예제 #7
0
        private static double CalculateNewVolatility(GlickoPlayer competitor, List <GlickoOpponent> opponents, double variance)
        {
            var rankingChange = RatingImprovement(competitor, opponents, variance);
            var rankDeviation = competitor.GlickoRatingDeviation;

            var A = VolatilityTransform(competitor.Volatility);
            var a = VolatilityTransform(competitor.Volatility);

            double B;

            if (Math.Pow(rankingChange, 2) > (Math.Pow(competitor.GlickoRatingDeviation, 2) + variance))
            {
                B = Math.Log(Math.Pow(rankingChange, 2) - Math.Pow(competitor.GlickoRatingDeviation, 2) - variance);
            }
            else
            {
                var    k = 1;
                double x;

                do
                {
                    x = a - (k * VolatilityChange);
                    k++;
                } while (VolatilityFunction(x, rankingChange, rankDeviation, variance, competitor.Volatility) < 0);
                B = x;
            }

            var fA = VolatilityFunction(A, rankingChange, rankDeviation, variance, competitor.Volatility);
            var fB = VolatilityFunction(B, rankingChange, rankDeviation, variance, competitor.Volatility);

            while (Math.Abs(B - A) > ConvergenceTolerance)
            {
                var C  = A + ((A - B) * fA / (fB - fA));
                var fC = VolatilityFunction(C, rankingChange, rankDeviation, variance, competitor.Volatility);

                if ((fC * fB) < 0)
                {
                    A  = B;
                    fA = fB;
                }
                else
                {
                    fA = fA / 2;
                }

                B  = C;
                fB = fC;
            }

            return(Math.Exp(A / 2));
        }
예제 #8
0
        public void GlickoUpdateRatingDeviationCorrect()
        {
            var expectedValue = 151.52;

            var player1Opponents = new List<GlickoOpponent>
            {
                new GlickoOpponent(player2, 1),
                new GlickoOpponent(player3, 0),
                new GlickoOpponent(player4, 0)
            };

            player1 = GlickoCalculator.CalculateRanking(player1, player1Opponents);
            var actualValue = Math.Round(player1.RatingDeviation, 2);

            Assert.AreEqual(expectedValue, actualValue);
        }
예제 #9
0
        public void GlickoUpdateCorrect()
        {
            var expectedValue = 0.059995984286488495;

            var player1Opponents = new List<GlickoOpponent>
            {
                new GlickoOpponent(player2, 1),
                new GlickoOpponent(player3, 0),
                new GlickoOpponent(player4, 0)
            };

            player1 = GlickoCalculator.CalculateRanking(player1, player1Opponents);
            var actualValue = player1.Volatility;

            Assert.AreEqual(expectedValue, actualValue);
        }
예제 #10
0
        public void RankTournament(int tournamentId)
        {
            var tournament = _tournamentDbHelper.GetTournamentPlayersAndMatches(tournamentId);
            var newRankings = new List<PlayerGlickoHistory>();

            foreach (var attendee in tournament.TournamentAttendees)
            {
                var playerOpponents = new List<GlickoOpponent>();
                var playerRanking = attendee.Player.PlayerGlickoHistories.OrderByDescending(x => x.Tournament.Date).First();

                var glickoPlayer = new GlickoPlayer((double)playerRanking.Ranking, (double)playerRanking.Deviation,
                    (double)playerRanking.Volatility);

                var matches =
                    tournament.Matches.Where(x => x.Player1Id == attendee.PlayerId || x.Player2Id == attendee.PlayerId);

                foreach (var match in matches)
                {
                    var opponentPlayer = match.Player1Id != attendee.PlayerId ? match.Player1 : match.Player2;
                    var opponentRank = opponentPlayer.PlayerGlickoHistories.OrderByDescending(x => x.TournamentId == tournamentId).First();

                    var opponentGlicko = new GlickoPlayer((double)opponentRank.Ranking,
                        (double)opponentRank.Deviation, (double)opponentRank.Volatility);

                    var result = match.WinnerId == attendee.PlayerId ? 1 : 0;

                    var glickoOpponent = new GlickoOpponent(opponentGlicko, result);

                    playerOpponents.Add(glickoOpponent);
                }

                glickoPlayer = GlickoCalculator.CalculateRanking(glickoPlayer, playerOpponents);

                var newRank = new PlayerGlickoHistory()
                {
                    Deviation = Convert.ToDecimal(glickoPlayer.RatingDeviation),
                    Ranking = Convert.ToDecimal(glickoPlayer.Rating),
                    Volatility = Convert.ToDecimal(glickoPlayer.Volatility),
                    PlayerId = attendee.PlayerId,
                    TournamentId = tournamentId
                };

                newRankings.Add(newRank);
            }

            UpdateRankingsDb(newRankings);
        }
예제 #11
0
        public static GlickoPlayer CalculateRanking(GlickoPlayer competitor, List<GlickoOpponent> opponents)
        {
            var variance = ComputeVariance(competitor, opponents);

            var updatedVolatility = CalculateNewVolatility(competitor, opponents, variance);
            
            var preratingDeviation = CalculatePreRatingDeviation(competitor.GlickoRatingDeviation, updatedVolatility);

            var newRatingDeviation = CalculateNewRatingDeviation(preratingDeviation, variance);
            var newRating = CalculateNewRating(competitor, opponents, newRatingDeviation);

            competitor.RatingDeviation = ConvertRatingDeviationToOriginal(newRatingDeviation);

            if (opponents.Count == 0) return competitor;

            competitor.Rating = ConvertRatingToOriginal(newRating);
            competitor.Volatility = updatedVolatility;

            return competitor;
        }
예제 #12
0
        public static GlickoPlayer CalculateRanking(GlickoPlayer competitor, List <GlickoOpponent> opponents)
        {
            var variance = ComputeVariance(competitor, opponents);

            var updatedVolatility = CalculateNewVolatility(competitor, opponents, variance);

            var preratingDeviation = CalculatePreRatingDeviation(competitor.GlickoRatingDeviation, updatedVolatility);

            var newRatingDeviation = CalculateNewRatingDeviation(preratingDeviation, variance);
            var newRating          = CalculateNewRating(competitor, opponents, newRatingDeviation);

            competitor.RatingDeviation = ConvertRatingDeviationToOriginal(newRatingDeviation);

            if (opponents.Count == 0)
            {
                return(competitor);
            }

            competitor.Rating     = ConvertRatingToOriginal(newRating);
            competitor.Volatility = updatedVolatility;

            return(competitor);
        }
예제 #13
0
파일: Program.cs 프로젝트: ikhanage/Glicko2
        static void Main(string[] args)
        {
            var player1 = new GlickoPlayer(ratingDeviation: 200);
            var player2 = new GlickoPlayer(1400, 30);
            var player3 = new GlickoPlayer(1550, 100);
            var player4 = new GlickoPlayer(1700, 300);

            var player1Opponents = new List<GlickoOpponent>
            {
                new GlickoOpponent(player2, 1),
                new GlickoOpponent(player3, 0),
                new GlickoOpponent(player4, 0)
            };

            Console.WriteLine(String.Format("Player ranking: {0}", player1.Rating));
            Console.WriteLine(String.Format("Player ranking deviation: {0}", player1.RatingDeviation));

            player1 = GlickoCalculator.CalculateRanking(player1, player1Opponents);

            Console.WriteLine(String.Format("Player ranking: {0}", player1.Rating));
            Console.WriteLine(String.Format("Player ranking deviation: {0}", player1.RatingDeviation));

            Console.ReadKey();
        }
예제 #14
0
        private static double RatingImprovement(GlickoPlayer competitor, List<GlickoOpponent> opponents, double variance)
        {
            double sum = 0;

            foreach (var opponent in opponents)
            {
                sum += opponent.GPhi * (opponent.Result - Edeltaphi(competitor.GlickoRating, opponent));
            }

            return variance * sum;
        }
예제 #15
0
 private static double Edeltaphi(double playerRating, GlickoPlayer opponent)
 {
     return(1 / (1 + (Math.Exp(-opponent.GPhi * (playerRating - opponent.GlickoRating)))));
 }
예제 #16
0
        private static double ComputeVariance(GlickoPlayer competitor, List<GlickoOpponent> opponents)
        {
            double sum = 0;
            foreach (var opponent in opponents)
            {
                var eDeltaPhi = Edeltaphi(competitor.GlickoRating, opponent);

                sum += Math.Pow(opponent.GPhi, 2) * eDeltaPhi * (1 - eDeltaPhi);
            }

            return Math.Pow(sum, -1);
        }
예제 #17
0
 private static double Edeltaphi(double playerRating, GlickoPlayer opponent)
 {
     return 1 / (1 + (Math.Exp(-opponent.GPhi * (playerRating - opponent.GlickoRating))));
 }
예제 #18
0
        public void GlickoUpdateRatingDeviationNoOpponents()
        {
            var expectedValue = 200.27;

            var player1Opponents = new List<GlickoOpponent>();

            player1 = GlickoCalculator.CalculateRanking(player1, player1Opponents);
            var actualValue = Math.Round(player1.RatingDeviation, 2);

            Assert.AreEqual(expectedValue, actualValue);
        }