Use PlayerIndex instead of String

This commit is contained in:
2022-06-14 22:51:11 +02:00
parent 3fbac02de3
commit 9b025fb53a
6 changed files with 352 additions and 254 deletions

View File

@@ -1,11 +1,11 @@
use std::collections::{HashMap, HashSet};
use crate::{utils, Agent, Batch, Gaussian, Player, N_INF};
use crate::{utils, Agent, Batch, Gaussian, Player, PlayerIndex, N_INF};
pub struct History {
size: usize,
pub batches: Vec<Batch>,
pub agents: HashMap<String, Agent>,
batches: Vec<Batch>,
agents: HashMap<PlayerIndex, Agent>,
mu: f64,
sigma: f64,
gamma: f64,
@@ -17,11 +17,11 @@ pub struct History {
}
impl History {
pub fn new<C: AsRef<str> + Clone>(
composition: Vec<Vec<Vec<C>>>,
pub fn new(
composition: Vec<Vec<Vec<PlayerIndex>>>,
results: Vec<Vec<u16>>,
times: Vec<f64>,
priors: HashMap<String, Player>,
priors: HashMap<PlayerIndex, Player>,
mu: f64,
sigma: f64,
beta: f64,
@@ -32,7 +32,6 @@ impl History {
.iter()
.flatten()
.flatten()
.map(AsRef::as_ref)
.collect::<HashSet<_>>();
let agents = this_agent
@@ -44,7 +43,7 @@ impl History {
.unwrap_or_else(|| Player::new(Gaussian::new(mu, sigma), beta, gamma, N_INF));
(
a.to_string(),
*a,
Agent {
player,
message: N_INF,
@@ -73,9 +72,9 @@ impl History {
this
}
fn trueskill<C: AsRef<str> + Clone>(
fn trueskill(
&mut self,
composition: Vec<Vec<Vec<C>>>,
composition: Vec<Vec<Vec<PlayerIndex>>>,
results: Vec<Vec<u16>>,
times: Vec<f64>,
) {
@@ -207,8 +206,8 @@ impl History {
(step, i)
}
pub fn learning_curves(&self) -> HashMap<String, Vec<(f64, Gaussian)>> {
let mut data: HashMap<String, Vec<(f64, Gaussian)>> = HashMap::new();
pub fn learning_curves(&self) -> HashMap<PlayerIndex, Vec<(f64, Gaussian)>> {
let mut data: HashMap<PlayerIndex, Vec<(f64, Gaussian)>> = HashMap::new();
for b in &self.batches {
for agent in b.skills.keys() {
@@ -217,7 +216,7 @@ impl History {
if let Some(entry) = data.get_mut(agent) {
entry.push(point);
} else {
data.insert(agent.to_string(), vec![point]);
data.insert(*agent, vec![point]);
}
}
}
@@ -261,16 +260,20 @@ mod tests {
#[test]
fn test_init() {
let a = PlayerIndex::new(0);
let b = PlayerIndex::new(1);
let c = PlayerIndex::new(2);
let composition = vec![
vec![vec!["a"], vec!["b"]],
vec![vec!["a"], vec!["c"]],
vec![vec!["b"], vec!["c"]],
vec![vec![a], vec![b]],
vec![vec![a], vec![c]],
vec![vec![b], vec![c]],
];
let results = vec![vec![1, 0], vec![0, 1], vec![1, 0]];
let mut priors = HashMap::new();
for k in ["a", "b", "c"] {
for k in [a, b, c] {
let player = Player::new(
Gaussian::new(25.0, 25.0 / 3.0),
25.0 / 6.0,
@@ -278,7 +281,7 @@ mod tests {
N_INF,
);
priors.insert(k.to_string(), player);
priors.insert(k, player);
}
let mut h = History::new(
@@ -295,16 +298,16 @@ mod tests {
let p0 = h.batches[0].posteriors();
assert_ulps_eq!(p0["a"].mu(), 29.205220743876975, epsilon = 0.000001);
assert_ulps_eq!(p0["a"].sigma(), 7.194481422570443, epsilon = 0.000001);
assert_ulps_eq!(p0[&a].mu(), 29.205220743876975, epsilon = 0.000001);
assert_ulps_eq!(p0[&a].sigma(), 7.194481422570443, epsilon = 0.000001);
let observed = h.batches[1].skills["a"].forward.sigma();
let observed = h.batches[1].skills[&a].forward.sigma();
let gamma: f64 = 0.15 * 25.0 / 3.0;
let expected = (gamma.powi(2) + h.batches[0].posterior("a").sigma().powi(2)).sqrt();
let expected = (gamma.powi(2) + h.batches[0].posterior(&a).sigma().powi(2)).sqrt();
assert_ulps_eq!(observed, expected, epsilon = 0.000001);
let observed = h.batches[1].posterior("a");
let observed = h.batches[1].posterior(&a);
let p = Game::new(
h.batches[1].within_priors(0, &mut h.agents),
vec![0, 1],
@@ -319,17 +322,21 @@ mod tests {
#[test]
fn test_one_batch() {
let a = PlayerIndex::new(0);
let b = PlayerIndex::new(1);
let c = PlayerIndex::new(2);
let composition = vec![
vec![vec!["aj"], vec!["bj"]],
vec![vec!["bj"], vec!["cj"]],
vec![vec!["cj"], vec!["aj"]],
vec![vec![a], vec![b]],
vec![vec![b], vec![c]],
vec![vec![c], vec![a]],
];
let results = vec![vec![1, 0], vec![1, 0], vec![1, 0]];
let times = vec![1.0, 1.0, 1.0];
let mut priors = HashMap::new();
for k in ["aj", "bj", "cj"] {
for k in [a, b, c] {
let player = Player::new(
Gaussian::new(25.0, 25.0 / 3.0),
25.0 / 6.0,
@@ -337,7 +344,7 @@ mod tests {
N_INF,
);
priors.insert(k.to_string(), player);
priors.insert(k, player);
}
let mut h1 = History::new(
@@ -353,22 +360,22 @@ mod tests {
);
assert_ulps_eq!(
h1.batches[0].posterior("aj").mu(),
h1.batches[0].posterior(&a).mu(),
22.904409330892914,
epsilon = 0.000001
);
assert_ulps_eq!(
h1.batches[0].posterior("aj").sigma(),
h1.batches[0].posterior(&a).sigma(),
6.0103304390431,
epsilon = 0.000001
);
assert_ulps_eq!(
h1.batches[0].posterior("cj").mu(),
h1.batches[0].posterior(&c).mu(),
25.110318212568806,
epsilon = 0.000001
);
assert_ulps_eq!(
h1.batches[0].posterior("cj").sigma(),
h1.batches[0].posterior(&c).sigma(),
5.866311348102563,
epsilon = 0.000001
);
@@ -376,37 +383,37 @@ mod tests {
let (_step, _i) = h1.convergence();
assert_ulps_eq!(
h1.batches[0].posterior("aj").mu(),
h1.batches[0].posterior(&a).mu(),
25.00000000,
epsilon = 0.000001
);
assert_ulps_eq!(
h1.batches[0].posterior("aj").sigma(),
h1.batches[0].posterior(&a).sigma(),
5.41921200,
epsilon = 0.000001
);
assert_ulps_eq!(
h1.batches[0].posterior("cj").mu(),
h1.batches[0].posterior(&c).mu(),
25.00000000,
epsilon = 0.000001
);
assert_ulps_eq!(
h1.batches[0].posterior("cj").sigma(),
h1.batches[0].posterior(&c).sigma(),
5.41921200,
epsilon = 0.000001
);
let composition = vec![
vec![vec!["aj"], vec!["bj"]],
vec![vec!["bj"], vec!["cj"]],
vec![vec!["cj"], vec!["aj"]],
vec![vec![a], vec![b]],
vec![vec![b], vec![c]],
vec![vec![c], vec![a]],
];
let results = vec![vec![1, 0], vec![1, 0], vec![1, 0]];
let times = vec![1.0, 2.0, 3.0];
let mut priors = HashMap::new();
for k in ["aj", "bj", "cj"] {
for k in [a, b, c] {
let player = Player::new(
Gaussian::new(25.0, 25.0 / 3.0),
25.0 / 6.0,
@@ -414,7 +421,7 @@ mod tests {
N_INF,
);
priors.insert(k.to_string(), player);
priors.insert(k, player);
}
let mut h2 = History::new(
@@ -430,22 +437,22 @@ mod tests {
);
assert_ulps_eq!(
h2.batches[2].posterior("aj").mu(),
h2.batches[2].posterior(&a).mu(),
22.90352227792141,
epsilon = 0.000001
);
assert_ulps_eq!(
h2.batches[2].posterior("aj").sigma(),
h2.batches[2].posterior(&a).sigma(),
6.011017301320632,
epsilon = 0.000001
);
assert_ulps_eq!(
h2.batches[2].posterior("cj").mu(),
h2.batches[2].posterior(&c).mu(),
25.110702468366718,
epsilon = 0.000001
);
assert_ulps_eq!(
h2.batches[2].posterior("cj").sigma(),
h2.batches[2].posterior(&c).sigma(),
5.866811597660157,
epsilon = 0.000001
);
@@ -453,22 +460,22 @@ mod tests {
let (_step, _i) = h2.convergence();
assert_ulps_eq!(
h2.batches[2].posterior("aj").mu(),
h2.batches[2].posterior(&a).mu(),
24.99866831022851,
epsilon = 0.000001
);
assert_ulps_eq!(
h2.batches[2].posterior("aj").sigma(),
h2.batches[2].posterior(&a).sigma(),
5.420053708148435,
epsilon = 0.000001
);
assert_ulps_eq!(
h2.batches[2].posterior("cj").mu(),
h2.batches[2].posterior(&c).mu(),
25.000532179593538,
epsilon = 0.000001
);
assert_ulps_eq!(
h2.batches[2].posterior("cj").sigma(),
h2.batches[2].posterior(&c).sigma(),
5.419827012784138,
epsilon = 0.000001
);
@@ -476,17 +483,21 @@ mod tests {
#[test]
fn test_learning_curves() {
let a = PlayerIndex::new(0);
let b = PlayerIndex::new(1);
let c = PlayerIndex::new(2);
let composition = vec![
vec![vec!["aj"], vec!["bj"]],
vec![vec!["bj"], vec!["cj"]],
vec![vec!["cj"], vec!["aj"]],
vec![vec![a], vec![b]],
vec![vec![b], vec![c]],
vec![vec![c], vec![a]],
];
let results = vec![vec![1, 0], vec![1, 0], vec![1, 0]];
let times = vec![5.0, 6.0, 7.0];
let mut priors = HashMap::new();
for k in ["aj", "bj", "cj"] {
for k in [a, b, c] {
let player = Player::new(
Gaussian::new(25.0, 25.0 / 3.0),
25.0 / 6.0,
@@ -494,7 +505,7 @@ mod tests {
N_INF,
);
priors.insert(k.to_string(), player);
priors.insert(k, player);
}
let mut h = History::new(
@@ -513,29 +524,29 @@ mod tests {
let lc = h.learning_curves();
let aj_e = lc["aj"].len();
let cj_e = lc["cj"].len();
let aj_e = lc[&a].len();
let cj_e = lc[&c].len();
assert_eq!(lc["aj"][0].0, 5.0);
assert_eq!(lc["aj"][aj_e - 1].0, 7.0);
assert_eq!(lc[&a][0].0, 5.0);
assert_eq!(lc[&a][aj_e - 1].0, 7.0);
assert_ulps_eq!(
lc["aj"][aj_e - 1].1.mu(),
lc[&a][aj_e - 1].1.mu(),
24.99866831022851,
epsilon = 0.000001
);
assert_ulps_eq!(
lc["aj"][aj_e - 1].1.sigma(),
lc[&a][aj_e - 1].1.sigma(),
5.420053708148435,
epsilon = 0.000001
);
assert_ulps_eq!(
lc["cj"][cj_e - 1].1.mu(),
lc[&c][cj_e - 1].1.mu(),
25.000532179593538,
epsilon = 0.000001
);
assert_ulps_eq!(
lc["cj"][cj_e - 1].1.sigma(),
lc[&c][cj_e - 1].1.sigma(),
5.419827012784138,
epsilon = 0.000001
);
@@ -543,10 +554,14 @@ mod tests {
#[test]
fn test_env_ttt() {
let a = PlayerIndex::new(0);
let b = PlayerIndex::new(1);
let c = PlayerIndex::new(2);
let composition = vec![
vec![vec!["a"], vec!["b"]],
vec![vec!["a"], vec!["c"]],
vec![vec!["b"], vec!["c"]],
vec![vec![a], vec![b]],
vec![vec![a], vec![c]],
vec![vec![b], vec![c]],
];
let results = vec![vec![1, 0], vec![0, 1], vec![1, 0]];
@@ -564,36 +579,36 @@ mod tests {
let (_step, _i) = h.convergence();
assert_eq!(h.batches[2].skills["b"].elapsed, 1.0);
assert_eq!(h.batches[2].skills["c"].elapsed, 1.0);
assert_eq!(h.batches[2].skills[&b].elapsed, 1.0);
assert_eq!(h.batches[2].skills[&c].elapsed, 1.0);
assert_ulps_eq!(
h.batches[0].posterior("a").mu(),
h.batches[0].posterior(&a).mu(),
25.0002673,
epsilon = 0.000001
);
assert_ulps_eq!(
h.batches[0].posterior("a").sigma(),
h.batches[0].posterior(&a).sigma(),
5.41938162,
epsilon = 0.000001
);
assert_ulps_eq!(
h.batches[0].posterior("b").mu(),
h.batches[0].posterior(&b).mu(),
24.999465,
epsilon = 0.000001
);
assert_ulps_eq!(
h.batches[0].posterior("b").sigma(),
h.batches[0].posterior(&b).sigma(),
5.419425831,
epsilon = 0.000001
);
assert_ulps_eq!(
h.batches[2].posterior("b").mu(),
h.batches[2].posterior(&b).mu(),
25.00053219,
epsilon = 0.000001
);
assert_ulps_eq!(
h.batches[2].posterior("b").sigma(),
h.batches[2].posterior(&b).sigma(),
5.419696790,
epsilon = 0.000001
);