How to replace estimations and guesses with a Monte Carlo simulation
TL;DR:
- в игре по оценке разработке нельзя дать точный ответ, пока софт полностью не написан
- умножать и бесконечно планировать не вариант, потому что значимых результатов не даёт
- на оценку сроков нужно давать вероятностный ответ и подсвечивать риски
- для того, чтобы посчитать вероятности можно провести простую симуляцию с помощью метода Монте Карло
Some prefer to spend days analysing and planning their changes so that they can estimate more accurately — others choose to multiply by N whatever estimations they make. I wouldn’t recommend any of these approaches.
The problem with the first approach is that it considers software development to be a deterministic process when, in fact, it’s stochastic. In other words, you can’t accurately determine how long it will take to write a particular piece of code unless you have already written it.
The problem with multiplying estimations by N is that you’re simply exchanging cycle time for predictability. Instead of actually trying to be accurate, you’re merely adding a buffer to your estimations. That buffer wouldn’t be a problem if it weren’t for the fact that engineers determine it by licking the tip of their finger and putting it up in the air.
Unfortunately, the only way to win at the estimation game is not to play it.
Симуляция [[методом Монте Карло]] для команды из нескольких разработчиков и оценённых story points:
extern crate rand;
use rand::distributions::{Distribution, Uniform};
use rand::thread_rng;
use std::collections::HashMap;
const TOTAL_RUNS: i32 = 1_000_000;
const STORIES_TARGET: i32 = 50;
const TEN_DAY_THROUGHPUTS: [i32; 10] = [1, 2, 0, 1, 1, 2, 3, 1, 2, 1];
fn main() {
let mut rng = thread_rng();
let throughput = Uniform::from(0..TEN_DAY_THROUGHPUTS.len());
let mut outcomes: HashMap<i64, i32> = HashMap::new();
let one_day = Duration::days(1);
let start_date: DateTime<Local> = Local::now();
for _ in 0..TOTAL_RUNS {
let mut current_date = start_date;
let mut stories_completed = 0;
while stories_completed < STORIES_TARGET {
let random_index = throughput.sample(&mut rng);
stories_completed += TEN_DAY_THROUGHPUTS[random_index];
current_date = current_date + one_day;
}
let count = outcomes.entry(current_date.timestamp()).or_insert(0);
*count += 1;
}
println!("Total Simulations: {}", TOTAL_RUNS);
}
Результат симуляции:
Link:: https://lucasfcosta.com/2021/09/20/monte-carlo-forecasts.html