It works?!
This commit is contained in:
196
src/lib.rs
196
src/lib.rs
@@ -1,9 +1,11 @@
|
||||
mod matrix;
|
||||
mod factor_graph;
|
||||
mod gaussian;
|
||||
mod math;
|
||||
mod matrix;
|
||||
|
||||
use matrix::Matrix;
|
||||
use factor_graph::*;
|
||||
use gaussian::Gaussian;
|
||||
use matrix::Matrix;
|
||||
|
||||
/// Default initial mean of ratings.
|
||||
const MU: f32 = 25.0;
|
||||
@@ -24,9 +26,9 @@ const DRAW_PROBABILITY: f32 = 0.10;
|
||||
const DELTA: f32 = 0.0001;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Rating {
|
||||
mu: f32,
|
||||
sigma: f32,
|
||||
pub struct Rating {
|
||||
pub mu: f32,
|
||||
pub sigma: f32,
|
||||
}
|
||||
|
||||
impl Default for Rating {
|
||||
@@ -38,42 +40,155 @@ impl Default for Rating {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn _team_sizes(rating_groups: &[&[Rating]]) -> Vec<usize> {
|
||||
let mut team_sizes = Vec::new();
|
||||
|
||||
for group in rating_groups {
|
||||
let last = team_sizes.last().map(|v| *v).unwrap_or(0);
|
||||
|
||||
team_sizes.push(group.len() + last);
|
||||
}
|
||||
|
||||
team_sizes
|
||||
}
|
||||
|
||||
fn factor_graph_builders(rating_groups: &[&[Rating]]) {
|
||||
fn rate(rating_groups: &[&[Rating]]) {
|
||||
let flatten_ratings = rating_groups
|
||||
.iter()
|
||||
.flat_map(|group| group.iter())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let flatten_weights = vec![1.0; flatten_ratings.len()].into_boxed_slice();
|
||||
|
||||
let size = flatten_ratings.len();
|
||||
let group_size = rating_groups.len();
|
||||
|
||||
let rating_vars = (0..size).map(|_| Variable::new()).collect::<Vec<_>>();
|
||||
let perf_vars = (0..size).map(|_| Variable::new()).collect::<Vec<_>>();
|
||||
let team_perf_vars = (0..group_size).map(|_| Variable::new()).collect::<Vec<_>>();
|
||||
let team_diff_vars = (0..group_size - 1).map(|_| Variable::new()).collect::<Vec<_>>();
|
||||
let tau_sqr = TAU.powi(2);
|
||||
let beta_sqr = BETA.powi(2);
|
||||
|
||||
let team_sizes = _team_sizes(rating_groups);
|
||||
}
|
||||
let mut variable_arena = VariableArena::new();
|
||||
|
||||
fn rate(rating_groups: &[&[Rating]]) {
|
||||
let ranks = (0..rating_groups.len()).collect::<Vec<_>>();
|
||||
let weights = vec![1.0; rating_groups.len()];
|
||||
let min_delta = DELTA;
|
||||
let mut ss = Vec::new();
|
||||
let mut ps = Vec::new();
|
||||
let mut ts = Vec::new();
|
||||
let mut ds = Vec::new();
|
||||
|
||||
for _ in 0..size {
|
||||
ss.push(variable_arena.create());
|
||||
ps.push(variable_arena.create());
|
||||
ts.push(variable_arena.create());
|
||||
}
|
||||
|
||||
for _ in 0..size - 1 {
|
||||
ds.push(variable_arena.create());
|
||||
}
|
||||
|
||||
let mut factor_id = 0;
|
||||
|
||||
let mut skill = Vec::new();
|
||||
|
||||
for (i, rating) in flatten_ratings.iter().enumerate() {
|
||||
let variable = ss[i];
|
||||
let gaussian = Gaussian::with_mu_sigma(rating.mu, (rating.sigma.powi(2) + tau_sqr).sqrt());
|
||||
|
||||
skill.push(PriorFactor::new(
|
||||
&mut variable_arena,
|
||||
factor_id,
|
||||
variable,
|
||||
gaussian,
|
||||
));
|
||||
|
||||
factor_id += 1;
|
||||
}
|
||||
|
||||
let mut skill_to_perf = Vec::new();;
|
||||
|
||||
for i in 0..size {
|
||||
let mean = ss[i];
|
||||
let value = ps[i];
|
||||
|
||||
skill_to_perf.push(LikelihoodFactor::new(
|
||||
&mut variable_arena,
|
||||
factor_id,
|
||||
mean,
|
||||
value,
|
||||
beta_sqr,
|
||||
));
|
||||
|
||||
factor_id += 1;
|
||||
}
|
||||
|
||||
let mut perf_to_team = Vec::new();;
|
||||
|
||||
for i in 0..size {
|
||||
perf_to_team.push(SumFactor::new(
|
||||
&mut variable_arena,
|
||||
factor_id,
|
||||
ts[i],
|
||||
vec![ps[i]],
|
||||
vec![1.0],
|
||||
));
|
||||
|
||||
factor_id += 1;
|
||||
}
|
||||
|
||||
let mut team_diff = Vec::new();;
|
||||
|
||||
for i in 0..size - 1 {
|
||||
team_diff.push(SumFactor::new(
|
||||
&mut variable_arena,
|
||||
factor_id,
|
||||
ds[i],
|
||||
vec![ts[i], ts[i + 1]],
|
||||
vec![1.0, -1.0],
|
||||
));
|
||||
|
||||
factor_id += 1;
|
||||
}
|
||||
|
||||
let mut trunc = Vec::new();
|
||||
|
||||
for i in 0..size - 1 {
|
||||
trunc.push(TruncateFactor::new(
|
||||
&mut variable_arena,
|
||||
factor_id,
|
||||
ds[i],
|
||||
DELTA,
|
||||
false,
|
||||
));
|
||||
|
||||
factor_id += 1;
|
||||
}
|
||||
|
||||
for factor in &skill {
|
||||
factor.start(&mut variable_arena);
|
||||
}
|
||||
|
||||
for factor in &skill_to_perf {
|
||||
factor.update_value(&mut variable_arena);
|
||||
}
|
||||
|
||||
for factor in &perf_to_team {
|
||||
factor.update_sum(&mut variable_arena);
|
||||
}
|
||||
|
||||
for factor in &team_diff {
|
||||
factor.update_sum(&mut variable_arena);
|
||||
}
|
||||
|
||||
for factor in &trunc {
|
||||
factor.update(&mut variable_arena);
|
||||
}
|
||||
|
||||
for factor in &team_diff {
|
||||
factor.update_term(&mut variable_arena, 0);
|
||||
factor.update_term(&mut variable_arena, 1);
|
||||
}
|
||||
|
||||
for factor in &perf_to_team {
|
||||
factor.update_term(&mut variable_arena, 0);
|
||||
}
|
||||
|
||||
for factor in &skill_to_perf {
|
||||
factor.update_mean(&mut variable_arena);
|
||||
}
|
||||
|
||||
for i in 0..size {
|
||||
let value = variable_arena
|
||||
.get(ss[i])
|
||||
.map(|variable| variable.get_value())
|
||||
.unwrap();
|
||||
|
||||
let mu = value.mu();
|
||||
let sigma = value.sigma();
|
||||
|
||||
println!("player={}, mu={}, sigma={}", i, mu, sigma);
|
||||
}
|
||||
}
|
||||
|
||||
fn quality(rating_groups: &[&[Rating]]) -> f32 {
|
||||
@@ -151,4 +266,21 @@ mod tests {
|
||||
|
||||
assert_eq!(quality(&[&[alice], &[bob]]), 0.41614607);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rate_1vs1() {
|
||||
let alice = Rating {
|
||||
mu: 25.0,
|
||||
sigma: SIGMA,
|
||||
};
|
||||
|
||||
let bob = Rating {
|
||||
mu: 30.0,
|
||||
sigma: SIGMA,
|
||||
};
|
||||
|
||||
rate(&[&[alice], &[bob]]);
|
||||
|
||||
assert_eq!(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user