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,6 +1,6 @@
use std::collections::{HashMap, HashSet};
use crate::{Game, Gaussian, Player, N_INF};
use crate::{Game, Gaussian, Player, PlayerIndex, N_INF};
#[derive(Clone, Debug)]
pub struct Skill {
@@ -48,7 +48,7 @@ impl Agent {
#[derive(Clone, Debug)]
pub struct Item {
name: String,
index: PlayerIndex,
likelihood: Gaussian,
}
@@ -65,6 +65,7 @@ pub struct Event {
}
impl Event {
/*
pub fn names(&self) -> Vec<&str> {
self.teams
.iter()
@@ -72,6 +73,7 @@ impl Event {
.map(|item| item.name.as_str())
.collect::<Vec<_>>()
}
*/
pub fn result(&self) -> Vec<u16> {
self.teams
@@ -93,18 +95,28 @@ fn compute_elapsed(last_time: f64, actual_time: f64) -> f64 {
#[derive(Clone, Debug)]
pub struct Batch {
pub skills: HashMap<String, Skill>,
pub skills: HashMap<PlayerIndex, Skill>,
pub events: Vec<Event>,
pub time: f64,
p_draw: f64,
}
/*
fn test<S, I>(inp: S) where S: AsRef<[I]>, I: AsRef<[u8]> {
for a in inp.as_ref().iter() {
for b in a.as_ref().iter() {
println!("{}", b);
}
}
}
*/
impl Batch {
pub fn new<C: AsRef<str> + Clone>(
composition: Vec<Vec<Vec<C>>>,
pub fn new(
composition: Vec<Vec<Vec<PlayerIndex>>>,
results: Vec<Vec<u16>>,
time: f64,
agents: &mut HashMap<String, Agent>,
agents: &mut HashMap<PlayerIndex, Agent>,
p_draw: f64,
) -> Self {
let mut this = Self {
@@ -119,17 +131,16 @@ impl Batch {
this
}
pub fn add_events<C: AsRef<str> + Clone>(
pub fn add_events(
&mut self,
composition: Vec<Vec<Vec<C>>>,
composition: Vec<Vec<Vec<PlayerIndex>>>,
results: Vec<Vec<u16>>,
agents: &mut HashMap<String, Agent>,
agents: &mut HashMap<PlayerIndex, Agent>,
) {
let this_agent = composition
.iter()
.flatten()
.flatten()
.map(AsRef::as_ref)
.collect::<HashSet<_>>();
for a in this_agent {
@@ -140,7 +151,7 @@ impl Batch {
skill.elapsed = elapsed;
} else {
self.skills.insert(
a.to_string(),
*a,
Skill {
forward: agents[a].receive(elapsed),
elapsed,
@@ -157,7 +168,7 @@ impl Batch {
.map(|t| {
let items = (0..composition[e][t].len())
.map(|a| Item {
name: composition[e][t][a].as_ref().to_string(),
index: composition[e][t][a],
likelihood: N_INF,
})
.collect::<Vec<_>>();
@@ -180,22 +191,22 @@ impl Batch {
self.iteration(from, agents);
}
pub fn posterior(&self, agent: &str) -> Gaussian {
pub fn posterior(&self, agent: &PlayerIndex) -> Gaussian {
let skill = &self.skills[agent];
skill.likelihood * skill.backward * skill.forward
}
pub fn posteriors(&self) -> HashMap<String, Gaussian> {
pub fn posteriors(&self) -> HashMap<PlayerIndex, Gaussian> {
self.skills
.keys()
.map(|a| (a.clone(), self.posterior(a)))
.map(|a| (*a, self.posterior(a)))
.collect::<HashMap<_, _>>()
}
fn within_prior(&self, item: &Item, agents: &mut HashMap<String, Agent>) -> Player {
let r = &agents[&item.name].player;
let g = self.posterior(&item.name) / item.likelihood;
fn within_prior(&self, item: &Item, agents: &mut HashMap<PlayerIndex, Agent>) -> Player {
let r = &agents[&item.index].player;
let g = self.posterior(&item.index) / item.likelihood;
Player::new(g, r.beta, r.gamma, N_INF)
}
@@ -203,7 +214,7 @@ impl Batch {
pub fn within_priors(
&self,
event: usize,
agents: &mut HashMap<String, Agent>,
agents: &mut HashMap<PlayerIndex, Agent>,
) -> Vec<Vec<Player>> {
self.events[event]
.teams
@@ -217,7 +228,7 @@ impl Batch {
.collect::<Vec<_>>()
}
fn iteration(&mut self, from: usize, agents: &mut HashMap<String, Agent>) {
fn iteration(&mut self, from: usize, agents: &mut HashMap<PlayerIndex, Agent>) {
for e in from..self.events.len() {
let teams = self.within_priors(e, agents);
let result = self.events[e].result();
@@ -226,8 +237,8 @@ impl Batch {
for (t, team) in self.events[e].teams.iter_mut().enumerate() {
for (i, item) in team.items.iter_mut().enumerate() {
self.skills.get_mut(&item.name).unwrap().likelihood =
(self.skills[&item.name].likelihood / item.likelihood)
self.skills.get_mut(&item.index).unwrap().likelihood =
(self.skills[&item.index].likelihood / item.likelihood)
* g.likelihoods[t][i];
item.likelihood = g.likelihoods[t][i];
@@ -238,7 +249,7 @@ impl Batch {
}
}
pub fn convergence(&mut self, agents: &mut HashMap<String, Agent>) -> usize {
pub fn convergence(&mut self, agents: &mut HashMap<PlayerIndex, Agent>) -> usize {
let epsilon = 1e-6;
let iterations = 20;
@@ -267,20 +278,24 @@ impl Batch {
i
}
pub fn forward_prior_out(&self, agent: &str) -> Gaussian {
pub fn forward_prior_out(&self, agent: &PlayerIndex) -> Gaussian {
let skill = &self.skills[agent];
skill.forward * skill.likelihood
}
pub fn backward_prior_out(&self, agent: &str, agents: &mut HashMap<String, Agent>) -> Gaussian {
pub fn backward_prior_out(
&self,
agent: &PlayerIndex,
agents: &mut HashMap<PlayerIndex, Agent>,
) -> Gaussian {
let skill = &self.skills[agent];
let n = skill.likelihood * skill.backward;
n.forget(agents[agent].player.gamma, skill.elapsed)
}
pub fn new_backward_info(&mut self, agents: &mut HashMap<String, Agent>) {
pub fn new_backward_info(&mut self, agents: &mut HashMap<PlayerIndex, Agent>) {
for (agent, skill) in self.skills.iter_mut() {
skill.backward = agents[agent].message;
}
@@ -288,7 +303,7 @@ impl Batch {
self.iteration(0, agents);
}
pub fn new_forward_info(&mut self, agents: &mut HashMap<String, Agent>) {
pub fn new_forward_info(&mut self, agents: &mut HashMap<PlayerIndex, Agent>) {
for (agent, skill) in self.skills.iter_mut() {
skill.forward = agents[agent].receive(skill.elapsed);
}
@@ -307,7 +322,14 @@ mod tests {
fn test_one_event_each() {
let mut agents = HashMap::new();
for k in ["a", "b", "c", "d", "e", "f"] {
let a = PlayerIndex::new(0);
let b = PlayerIndex::new(1);
let c = PlayerIndex::new(2);
let d = PlayerIndex::new(3);
let e = PlayerIndex::new(4);
let f = PlayerIndex::new(5);
for k in [a, b, c, d, e, f] {
let agent = Agent::new(
Player::new(
Gaussian::new(25.0, 25.0 / 3.0),
@@ -319,14 +341,14 @@ mod tests {
f64::NEG_INFINITY,
);
agents.insert(k.to_string(), agent);
agents.insert(k, agent);
}
let mut b = Batch::new(
let mut batch = Batch::new(
vec![
vec![vec!["a"], vec!["b"]],
vec![vec!["c"], vec!["d"]],
vec![vec!["e"], vec!["f"]],
vec![vec![a], vec![b]],
vec![vec![c], vec![d]],
vec![vec![e], vec![f]],
],
vec![vec![1, 0], vec![0, 1], vec![1, 0]],
0.0,
@@ -334,25 +356,32 @@ mod tests {
0.0,
);
let post = b.posteriors();
let post = batch.posteriors();
assert_eq!(post["a"].mu(), 29.205220743876975);
assert_eq!(post["a"].sigma(), 7.194481422570443);
assert_eq!(post[&a].mu(), 29.205220743876975);
assert_eq!(post[&a].sigma(), 7.194481422570443);
assert_eq!(post["b"].mu(), 20.79477925612302);
assert_eq!(post["b"].sigma(), 7.194481422570443);
assert_eq!(post[&b].mu(), 20.79477925612302);
assert_eq!(post[&b].sigma(), 7.194481422570443);
assert_eq!(post["c"].mu(), 20.79477925612302);
assert_eq!(post["c"].sigma(), 7.194481422570443);
assert_eq!(post[&c].mu(), 20.79477925612302);
assert_eq!(post[&c].sigma(), 7.194481422570443);
assert_eq!(b.convergence(&mut agents), 1);
assert_eq!(batch.convergence(&mut agents), 1);
}
#[test]
fn test_same_strength() {
let mut agents = HashMap::new();
for k in ["a", "b", "c", "d", "e", "f"] {
let a = PlayerIndex::new(0);
let b = PlayerIndex::new(1);
let c = PlayerIndex::new(2);
let d = PlayerIndex::new(3);
let e = PlayerIndex::new(4);
let f = PlayerIndex::new(5);
for k in [a, b, c, d, e, f] {
let agent = Agent::new(
Player::new(
Gaussian::new(25.0, 25.0 / 3.0),
@@ -364,14 +393,14 @@ mod tests {
f64::NEG_INFINITY,
);
agents.insert(k.to_string(), agent);
agents.insert(k, agent);
}
let mut b = Batch::new(
let mut batch = Batch::new(
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]],
],
vec![vec![1, 0], vec![0, 1], vec![1, 0]],
2.0,
@@ -379,28 +408,105 @@ mod tests {
0.0,
);
let post = b.posteriors();
let post = batch.posteriors();
assert_eq!(post["a"].mu(), 24.96097857478182);
assert_eq!(post["a"].sigma(), 6.298544763358269);
assert_eq!(post[&a].mu(), 24.96097857478182);
assert_eq!(post[&a].sigma(), 6.298544763358269);
assert_eq!(post["b"].mu(), 27.095590669107086);
assert_eq!(post["b"].sigma(), 6.010330439043099);
assert_eq!(post[&b].mu(), 27.095590669107086);
assert_eq!(post[&b].sigma(), 6.010330439043099);
assert_eq!(post["c"].mu(), 24.88968178743119);
assert_eq!(post["c"].sigma(), 5.866311348102562);
assert_eq!(post[&c].mu(), 24.88968178743119);
assert_eq!(post[&c].sigma(), 5.866311348102562);
assert!(b.convergence(&mut agents) > 1);
assert!(batch.convergence(&mut agents) > 1);
let post = b.posteriors();
let post = batch.posteriors();
assert_ulps_eq!(post["a"].mu(), 25.000000, epsilon = 0.000001);
assert_ulps_eq!(post["a"].sigma(), 5.4192120, epsilon = 0.000001);
assert_ulps_eq!(post[&a].mu(), 25.000000, epsilon = 0.000001);
assert_ulps_eq!(post[&a].sigma(), 5.4192120, epsilon = 0.000001);
assert_ulps_eq!(post["b"].mu(), 25.000000, epsilon = 0.000001);
assert_ulps_eq!(post["b"].sigma(), 5.4192120, epsilon = 0.000001);
assert_ulps_eq!(post[&b].mu(), 25.000000, epsilon = 0.000001);
assert_ulps_eq!(post[&b].sigma(), 5.4192120, epsilon = 0.000001);
assert_ulps_eq!(post["c"].mu(), 25.000000, epsilon = 0.000001);
assert_ulps_eq!(post["c"].sigma(), 5.4192120, epsilon = 0.000001);
assert_ulps_eq!(post[&c].mu(), 25.000000, epsilon = 0.000001);
assert_ulps_eq!(post[&c].sigma(), 5.4192120, epsilon = 0.000001);
}
#[test]
fn test_add_events() {
let mut agents = HashMap::new();
let a = PlayerIndex::new(0);
let b = PlayerIndex::new(1);
let c = PlayerIndex::new(2);
let d = PlayerIndex::new(3);
let e = PlayerIndex::new(4);
let f = PlayerIndex::new(5);
for k in [a, b, c, d, e, f] {
let agent = Agent::new(
Player::new(
Gaussian::new(25.0, 25.0 / 3.0),
25.0 / 6.0,
25.0 / 300.0,
N_INF,
),
N_INF,
f64::NEG_INFINITY,
);
agents.insert(k, agent);
}
let mut batch = Batch::new(
vec![
vec![vec![a], vec![b]],
vec![vec![a], vec![c]],
vec![vec![b], vec![c]],
],
vec![vec![1, 0], vec![0, 1], vec![1, 0]],
0.0,
&mut agents,
0.0,
);
batch.convergence(&mut agents);
let p = batch.posteriors();
assert_ulps_eq!(p[&a].mu(), 25.000000, epsilon = 0.000001);
assert_ulps_eq!(p[&a].sigma(), 5.4192120, epsilon = 0.000001);
assert_ulps_eq!(p[&b].mu(), 25.000000, epsilon = 0.000001);
assert_ulps_eq!(p[&b].sigma(), 5.4192120, epsilon = 0.000001);
assert_ulps_eq!(p[&c].mu(), 25.000000, epsilon = 0.000001);
assert_ulps_eq!(p[&c].sigma(), 5.4192120, epsilon = 0.000001);
batch.add_events(
vec![
vec![vec![a], vec![b]],
vec![vec![a], vec![c]],
vec![vec![b], vec![c]],
],
vec![vec![1, 0], vec![0, 1], vec![1, 0]],
&mut agents,
);
assert_eq!(batch.events.len(), 6);
batch.convergence(&mut agents);
let p = batch.posteriors();
assert_ulps_eq!(p[&a].mu(), 25.00000315330858, epsilon = 0.000001);
assert_ulps_eq!(p[&a].sigma(), 3.880150268080797, epsilon = 0.000001);
assert_ulps_eq!(p[&b].mu(), 25.00000315330858, epsilon = 0.000001);
assert_ulps_eq!(p[&b].sigma(), 3.880150268080797, epsilon = 0.000001);
assert_ulps_eq!(p[&c].mu(), 25.00000315330858, epsilon = 0.000001);
assert_ulps_eq!(p[&c].sigma(), 3.880150268080797, epsilon = 0.000001);
}
}