Guest User

Untitled

a guest
Oct 8th, 2025
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.24 KB | None | 0 0
  1. import numpy as np
  2.  
  3. HIDDEN_ELO_MEAN = 1500.0
  4. HIDDEN_ELO_SD = 350.0
  5. RANDOM_PROB = 0.5
  6.  
  7. ELO_MEAN = 1500.0
  8.  
  9. POPULATION = 1000
  10.  
  11. class Contestant:
  12. def __init__(self):
  13. self.hidden_elo = float(np.random.normal(HIDDEN_ELO_MEAN, HIDDEN_ELO_SD))
  14. self.elo = ELO_MEAN
  15.  
  16. def elo_rule(elo_a: float, elo_b: float) -> float:
  17. return 1 / (1 + 10 ** ((elo_b - elo_a) / 400))
  18.  
  19. # Should access hidden stats
  20. def actual_win_prob(a: Contestant, b: Contestant) -> float:
  21. return RANDOM_PROB * 0.5 + (1 - RANDOM_PROB) * elo_rule(a.hidden_elo, b.hidden_elo)
  22.  
  23. # Should only access public stats
  24. def predicted_win_prob(a: Contestant, b: Contestant) -> float:
  25. # Option 0: No model
  26. # return 0.5
  27. # Option 1: Elo model
  28. return elo_rule(a.elo, b.elo)
  29. # Option 2: Correct model
  30. # return RANDOM_PROB * 0.5 + (1 - RANDOM_PROB) * elo_rule(a.elo, b.elo)
  31.  
  32. K = 5
  33.  
  34. def update_elo(a: Contestant, b: Contestant, result: float):
  35. expected_a = predicted_win_prob(a, b)
  36. expected_b = 1 - expected_a
  37.  
  38. a.elo += K * (result - expected_a)
  39. b.elo += K * ((1 - result) - expected_b)
  40.  
  41. ema_alpha = 1 / 10000
  42. ema_loss = 0
  43. num_games = 0
  44.  
  45. def record_prediction(prediction: float, actual: float):
  46. global ema_loss
  47. global num_games
  48.  
  49. num_games += 1
  50.  
  51. loss = - (actual * np.log(prediction) + (1 - actual) * np.log(1 - prediction))
  52. ema_loss = ema_alpha * loss + (1 - ema_alpha) * ema_loss
  53.  
  54. if num_games % 1000 == 0:
  55. print(f"EMA Loss: {ema_loss:.4f}")
  56.  
  57. def simulate_match(a: Contestant, b: Contestant):
  58. predicted_prob = predicted_win_prob(a, b)
  59.  
  60. prob = actual_win_prob(a, b)
  61. if np.random.rand() < prob:
  62. res = 1
  63. else:
  64. res = 0
  65.  
  66. # Use this to see theoretic minimum
  67. # record_prediction(prob, res)
  68. # Use this to see actual performance
  69. record_prediction(predicted_prob, res)
  70.  
  71. update_elo(a, b, res)
  72.  
  73. def simulate_matches():
  74. contestants = [Contestant() for _ in range(POPULATION)]
  75.  
  76. while True:
  77. i = np.random.randint(0, POPULATION)
  78. j = np.random.randint(0, POPULATION)
  79. if i == j:
  80. continue
  81. simulate_match(contestants[i], contestants[j])
  82.  
  83. if __name__ == "__main__":
  84. simulate_matches()
  85.  
Advertisement
Add Comment
Please, Sign In to add comment