2个版本
0.1.1 | 2023年10月11日 |
---|---|
0.1.0 | 2023年10月11日 |
#1452 在 算法
14KB
276 行
bentobox
bentobox是一个赛车事件中快速、无分配的前N名领奖台蒙特卡洛模型。仅根据获胜概率推导出任意位置的概率。还推导出多个选手的联合概率,这些选手具有任意(精确和前N名)排名。
性能
使用tinyrand RNG在14名选手的前4名领奖台上进行大约20M次模拟/秒。大约80%的时间用于RNG例程。
示例
来源于examples/multi.rs
。
use bentobox::mc;
use bentobox::probs::SliceExt;
use bentobox::selection::Selection;
use tinyrand::StdRand;
use bentobox::capture::{CaptureMut, Capture};
// probs taken from a popular website
let mut probs = vec![
1.0 / 11.0,
1.0 / 41.0,
1.0 / 18.0,
1.0 / 12.0,
1.0 / 91.0,
1.0 / 101.0,
1.0 / 4.8,
1.0 / 14.0,
1.0 / 2.9,
1.0 / 91.0,
1.0 / 9.0,
1.0 / 91.0,
1.0 / 5.0,
1.0 / 21.0,
];
// force probs to sum to 1 and extract the approximate overround used (multiplicative method assumed)
let overround = probs.normalize();
println!("fair probs: {probs:?}");
println!("overround: {overround:.3}");
// create an MC engine for reuse
let mut engine = mc::MonteCarloEngine::default()
.with_iterations(10_000)
.with_probabilities(Capture::Borrowed(&probs))
.with_podium_places(4)
.with_rand(CaptureMut::Owned(StdRand::default()));
// simulate top-N rankings for all runners
// NOTE: rankings and runner numbers are zero-based
for runner in 0..probs.len() {
println!("runner: {runner}");
for rank in 0..4 {
let frac = engine.simulate(&vec![Selection::Top { runner, rank }]);
println!(
" rank: 0~{rank}, prob: {}, fair price: {:.3}, market odds: {:.3}",
frac.quotient(),
1.0 / frac.quotient(),
1.0 / frac.quotient() / overround
);
}
}
// simulate a same-race multi for a chosen selection vector
let selections = vec![
Selection::Top { runner: 0, rank: 0 },
Selection::Top { runner: 1, rank: 1 },
Selection::Top { runner: 2, rank: 2 },
];
let frac = engine.simulate(&selections);
println!(
"probability of {selections:?}: {}, fair price: {:.3}, market odds: {:.3}",
frac.quotient(),
1.0 / frac.quotient(),
1.0 / frac.quotient() / overround
);
依赖项
~66KB