Cupboard

Экспериментальная проверка теоремы Байеса на примере задачи со шкафами

by evgkch

JavaScript

/**
	* Экспериментальная проверка теоремы Байеса
	* на примере задачи со шкафами.
	* -------------------------------------------
	* Задача
	* В шкафу n - полок. Книга лежит в шкафу с вероятностью p.
  * Открыли одну полку и книги там не оказалось.
  * С какой вероятностью книга в шкафу?
	*/

class Cupboard {

  static create(shelvesNumber, p) {
  	const i = Math.random() < p
    	? Math.floor(Math.random() * shelvesNumber)
      : null;
    const shelves = Array.from({ length: shelvesNumber }, (c, j) => j == i ? 1 : 0);
    return new Cupboard(shelves);
  }
  
  static getPByBaies(n, p) {
  	return p === 0 ? 0 : (n * p - p) / (n - p);
  }

	constructor(shelves) {
    this.shelves = shelves;
  }
  
  get hasBookInCupboard() {
  	return this.shelves.includes(1);
  }
  
  openRandomShelf() {
  	const hasBookInShelf = this.shelves[
    	Math.floor(Math.random() * this.shelves.length)
    ];
    return { hasBookInShelf };
  }
}

function test(count) {
	return (n, p) => {
  	const PAIfNotPB = [];
    for (let i = 0; i < count; i++){
    	// Создаем шкаф
      const myCupboard = Cupboard.create(n, p);
      // Открываем случайную полку
      const { hasBookInShelf } = myCupboard.openRandomShelf();
      // Записываем случаи, указанные в условии
      if (!hasBookInShelf)
        PAIfNotPB.push(myCupboard.hasBookInCupboard);
    };
    // Результат
    const empyric = PAIfNotPB.reduce((a, b) => a + b) / PAIfNotPB.length;
    // Аналитически
    const theoretically = Cupboard.getPByBaies(n, p);
    const delta = `${p === 0 ? 0 : Math.round(Math.abs(theoretically - empyric) * 10000 / theoretically) / 100}%`;
    console.log({ n, p, count, empyric, theoretically, delta })
  }
}

test(1000000)(3, 0.5)
test(1000000)(3, 1)
test(1000000)(3, 0)
test(1000000)(10, 0.75)