More things, more tests
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
use crate::{gaussian::Gaussian, player::Player, N_INF};
|
use crate::{gaussian::Gaussian, player::Player, N_INF};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub(crate) struct Agent {
|
pub(crate) struct Agent {
|
||||||
pub(crate) player: Player,
|
pub(crate) player: Player,
|
||||||
pub(crate) message: Gaussian,
|
pub(crate) message: Gaussian,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use crate::{
|
|||||||
agent::Agent, game::Game, gaussian::Gaussian, player::Player, tuple_gt, tuple_max, N_INF,
|
agent::Agent, game::Game, gaussian::Gaussian, player::Player, tuple_gt, tuple_max, N_INF,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub(crate) struct Skill {
|
pub(crate) struct Skill {
|
||||||
pub(crate) forward: Gaussian,
|
pub(crate) forward: Gaussian,
|
||||||
backward: Gaussian,
|
backward: Gaussian,
|
||||||
@@ -52,7 +53,8 @@ impl Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct Batch {
|
#[derive(Debug)]
|
||||||
|
pub struct Batch {
|
||||||
pub(crate) events: Vec<Event>,
|
pub(crate) events: Vec<Event>,
|
||||||
pub(crate) skills: HashMap<String, Skill>,
|
pub(crate) skills: HashMap<String, Skill>,
|
||||||
pub(crate) time: u64,
|
pub(crate) time: u64,
|
||||||
@@ -220,7 +222,7 @@ impl Batch {
|
|||||||
self.iteration(from, agents);
|
self.iteration(from, agents);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn posterior(&self, agent: &str) -> Gaussian {
|
pub fn posterior(&self, agent: &str) -> Gaussian {
|
||||||
let skill = &self.skills[agent];
|
let skill = &self.skills[agent];
|
||||||
|
|
||||||
skill.likelihood * skill.backward * skill.forward
|
skill.likelihood * skill.backward * skill.forward
|
||||||
|
|||||||
95
src/game.rs
95
src/game.rs
@@ -227,6 +227,8 @@ impl Game {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use ::approx::assert_ulps_eq;
|
||||||
|
|
||||||
use crate::{Gaussian, Player, GAMMA};
|
use crate::{Gaussian, Player, GAMMA};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -406,4 +408,97 @@ mod tests {
|
|||||||
assert_eq!(c.mu, 28.555920328820527);
|
assert_eq!(c.mu, 28.555920328820527);
|
||||||
assert_eq!(c.sigma, 1.8856891308577184);
|
assert_eq!(c.sigma, 1.8856891308577184);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_1vs1_weighted() {
|
||||||
|
let w_a = vec![1.0];
|
||||||
|
let w_b = vec![2.0];
|
||||||
|
|
||||||
|
let t_a = vec![Player::new(
|
||||||
|
Gaussian::new(25.0, 25.0 / 3.0),
|
||||||
|
25.0 / 6.0,
|
||||||
|
0.0,
|
||||||
|
)];
|
||||||
|
let t_b = vec![Player::new(
|
||||||
|
Gaussian::new(25.0, 25.0 / 3.0),
|
||||||
|
25.0 / 6.0,
|
||||||
|
0.0,
|
||||||
|
)];
|
||||||
|
|
||||||
|
let g = Game::new(vec![t_a.clone(), t_b.clone()], vec![], vec![w_a, w_b], 0.0);
|
||||||
|
let p = g.posteriors();
|
||||||
|
|
||||||
|
assert_ulps_eq!(
|
||||||
|
p[0][0],
|
||||||
|
Gaussian::new(30.625173, 7.765472),
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
assert_ulps_eq!(
|
||||||
|
p[1][0],
|
||||||
|
Gaussian::new(13.749653, 5.733840),
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
|
||||||
|
let w_a = vec![1.0];
|
||||||
|
let w_b = vec![0.7];
|
||||||
|
|
||||||
|
let g = Game::new(vec![t_a.clone(), t_b.clone()], vec![], vec![w_a, w_b], 0.0);
|
||||||
|
let p = g.posteriors();
|
||||||
|
|
||||||
|
assert_ulps_eq!(
|
||||||
|
p[0][0],
|
||||||
|
Gaussian::new(27.630080, 7.206676),
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
assert_ulps_eq!(
|
||||||
|
p[1][0],
|
||||||
|
Gaussian::new(23.158943, 7.801628),
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
|
||||||
|
let w_a = vec![1.6];
|
||||||
|
let w_b = vec![0.7];
|
||||||
|
|
||||||
|
let g = Game::new(vec![t_a, t_b], vec![], vec![w_a, w_b], 0.0);
|
||||||
|
let p = g.posteriors();
|
||||||
|
|
||||||
|
assert_ulps_eq!(
|
||||||
|
p[0][0],
|
||||||
|
Gaussian::new(26.142438, 7.573088),
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
assert_ulps_eq!(
|
||||||
|
p[1][0],
|
||||||
|
Gaussian::new(24.500183, 8.193278),
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
|
||||||
|
let w_a = vec![1.0];
|
||||||
|
let w_b = vec![0.0];
|
||||||
|
|
||||||
|
let t_a = vec![Player::new(Gaussian::new(2.0, 6.0), 1.0, 0.0)];
|
||||||
|
let t_b = vec![Player::new(Gaussian::new(2.0, 6.0), 1.0, 0.0)];
|
||||||
|
|
||||||
|
let g = Game::new(vec![t_a, t_b], vec![], vec![w_a, w_b], 0.0);
|
||||||
|
let p = g.posteriors();
|
||||||
|
|
||||||
|
assert_ulps_eq!(
|
||||||
|
p[0][0],
|
||||||
|
Gaussian::new(5.557176746, 4.0527906913),
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
assert_ulps_eq!(p[1][0], Gaussian::new(2.0, 6.0), epsilon = 0.000001);
|
||||||
|
// NOTA: trueskill original tiene probelmas en la aproximación: post[2][1].mu = 1.999644
|
||||||
|
|
||||||
|
let w_a = vec![1.0];
|
||||||
|
let w_b = vec![-1.0];
|
||||||
|
|
||||||
|
let t_a = vec![Player::new(Gaussian::new(2.0, 6.0), 1.0, 0.0)];
|
||||||
|
let t_b = vec![Player::new(Gaussian::new(2.0, 6.0), 1.0, 0.0)];
|
||||||
|
|
||||||
|
let g = Game::new(vec![t_a, t_b], vec![], vec![w_a, w_b], 0.0);
|
||||||
|
let p = g.posteriors();
|
||||||
|
|
||||||
|
assert_ulps_eq!(p[0][0], p[0][0], epsilon = 0.000001);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
|
|
||||||
pub struct History {
|
pub struct History {
|
||||||
size: usize,
|
size: usize,
|
||||||
batches: Vec<Batch>,
|
pub batches: Vec<Batch>,
|
||||||
agents: HashMap<String, Agent>,
|
agents: HashMap<String, Agent>,
|
||||||
time: bool,
|
time: bool,
|
||||||
mu: f64,
|
mu: f64,
|
||||||
@@ -445,7 +445,7 @@ impl History {
|
|||||||
while self.time && self.batches.len() > k {
|
while self.time && self.batches.len() > k {
|
||||||
let b = &mut self.batches[k];
|
let b = &mut self.batches[k];
|
||||||
|
|
||||||
b.new_backward_info(&mut self.agents);
|
b.new_forward_info(&mut self.agents);
|
||||||
|
|
||||||
let intersect = this_agent
|
let intersect = this_agent
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1029,5 +1029,98 @@ mod tests {
|
|||||||
h.batches[0].posterior("b"),
|
h.batches[0].posterior("b"),
|
||||||
epsilon = 0.000001
|
epsilon = 0.000001
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ---------------------------------------
|
||||||
|
|
||||||
|
let composition = vec![
|
||||||
|
vec![vec!["a"], vec!["b"]],
|
||||||
|
vec![vec!["c"], vec!["a"]],
|
||||||
|
vec![vec!["b"], vec!["c"]],
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut h = History::new(
|
||||||
|
composition.clone(),
|
||||||
|
vec![],
|
||||||
|
vec![0, 10, 20],
|
||||||
|
vec![],
|
||||||
|
HashMap::new(),
|
||||||
|
0.0,
|
||||||
|
2.0,
|
||||||
|
1.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
h.convergence(ITERATIONS, EPSILON, false);
|
||||||
|
|
||||||
|
h.add_events(composition, vec![], vec![15, 10, 0], vec![], HashMap::new());
|
||||||
|
|
||||||
|
assert_eq!(h.batches.len(), 4);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
h.batches
|
||||||
|
.iter()
|
||||||
|
.map(|batch| batch.events.len())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec![2, 2, 1, 1]
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
h.batches
|
||||||
|
.iter()
|
||||||
|
.map(|b| b.get_composition())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec![
|
||||||
|
vec![vec![vec!["a"], vec!["b"]], vec![vec!["b"], vec!["c"]]],
|
||||||
|
vec![vec![vec!["c"], vec!["a"]], vec![vec!["c"], vec!["a"]]],
|
||||||
|
vec![vec![vec!["a"], vec!["b"]]],
|
||||||
|
vec![vec![vec!["b"], vec!["c"]]]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
h.batches
|
||||||
|
.iter()
|
||||||
|
.map(|b| b.get_results())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec![
|
||||||
|
vec![vec![1.0, 0.0], vec![1.0, 0.0]],
|
||||||
|
vec![vec![1.0, 0.0], vec![1.0, 0.0]],
|
||||||
|
vec![vec![1.0, 0.0]],
|
||||||
|
vec![vec![1.0, 0.0]]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
let end = h.batches.len() - 1;
|
||||||
|
|
||||||
|
assert_eq!(h.batches[0].skills["c"].elapsed, 0);
|
||||||
|
assert_eq!(h.batches[end].skills["c"].elapsed, 10);
|
||||||
|
|
||||||
|
assert_eq!(h.batches[0].skills["a"].elapsed, 0);
|
||||||
|
assert_eq!(h.batches[2].skills["a"].elapsed, 5);
|
||||||
|
|
||||||
|
assert_eq!(h.batches[0].skills["b"].elapsed, 0);
|
||||||
|
assert_eq!(h.batches[end].skills["b"].elapsed, 5);
|
||||||
|
|
||||||
|
h.convergence(ITERATIONS, EPSILON, false);
|
||||||
|
|
||||||
|
assert_ulps_eq!(
|
||||||
|
h.batches[0].posterior("b"),
|
||||||
|
h.batches[end].posterior("b"),
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_ulps_eq!(
|
||||||
|
h.batches[0].posterior("c"),
|
||||||
|
h.batches[end].posterior("c"),
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_ulps_eq!(
|
||||||
|
h.batches[0].posterior("c"),
|
||||||
|
h.batches[0].posterior("b"),
|
||||||
|
epsilon = 0.000001
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user