Задать вопрос
@Battle-Of-Two-K

Как запрограммировать задачу Бюффона о бросании иглы на Python?

У меня уже есть наработки по этому вопросу. Я написал код. Но сколько бы иголок я не "кидал" в каждой итерации, число pi = 3.1415... никогда не достигается. Самое близкое значение, которое я получил это 3.0985, но затем значение отдаляется и в среднем, получается около 2.7, хотя с повышением количества "брошенных" иголок значение должно быть всё ближе к pi. Рекомендую ознакомится с данной статьёй: https://habr.com/ru/post/172827/

Код, который написал я, смотрите ниже:

from tkinter import Tk, Canvas
from random import randint
from math import sin, cos, pi

# https://habr.com/ru/post/172827/ - сайт, на котором брал инфу

amount_needles = 10

# Параметры полотна
CANVAS_OPTIONS = {
    'width': 1220,
    'height': 720,
    'bg': 'black'
}

# Параметры иголок:
NEEDLES_OPTIONS = {
    'fill': '#87939A',
    'width': 2,
    'length': 20
}

needles_ids = []
lines_ids = []
list_overlapping = []


def draw_lines(distance_bet_lines=NEEDLES_OPTIONS['length']):
    global lines_ids
    for coord_x in range(distance_bet_lines, CANVAS_OPTIONS['width'], distance_bet_lines):
        lines_ids.append(canvas.create_line(coord_x, 0, coord_x, CANVAS_OPTIONS['height'], fill='#1E1E1E',
                                            width=2))


def draw_needles():
    global needles_ids
    for amount_iterations in range(amount_needles):
        coord_x = randint(0, CANVAS_OPTIONS['width'])
        coord_y = randint(0, CANVAS_OPTIONS['height'])
        random_angle = randint(0, 360)
        needles_ids.append(canvas.create_line(coord_x, coord_y,
                                              coord_x - cos(random_angle * pi / 180) * NEEDLES_OPTIONS['length'],
                                              coord_y - sin(random_angle * pi / 180) * NEEDLES_OPTIONS['length'],
                                              fill=NEEDLES_OPTIONS['fill'], width=NEEDLES_OPTIONS['width']))


def paint_needles():
    for line in lines_ids:
        line_coordinates = canvas.coords(line)
        overlaps = canvas.find_overlapping(*line_coordinates)

        for overlap_needle in overlaps:
            if overlap_needle in needles_ids:
                canvas.itemconfig(overlap_needle, fill='yellow')
                list_overlapping.append(overlap_needle)


def process():
    global amount_needles
    global list_overlapping
    global needles_ids

    root.after(100, process)
    draw_needles()
    paint_needles()
    print(f'Общее кол-во иголок: {len(needles_ids)}')
    print(f'Кол-во иголок, которые пересекли нить: {len(list_overlapping)}')
    print(f'Вероятность пересечения: {2 / (len(list_overlapping) / len(needles_ids))}')
    print('-' * 50)
    list_overlapping = []


def draw_chart():
    pass


root = Tk()

canvas = Canvas(root, **CANVAS_OPTIONS)
canvas.pack()

draw_lines()

# TODO: за кол-во бросаемых иголок отвечает amount_needles, которая находится в 7 строке!!!!!

# TODO: Если нужно разом "бросить" все иголки:
# draw_needles()
# paint_needles()
# print(f'Общее кол-во иголок: {len(needles_ids)}')
# print(f'Кол-во иголок, которые пересекли нить: {len(list_overlapping)}')
# print(f'Вероятность пересечения: {2 / (len(list_overlapping) / len(needles_ids))}')


# TODO: Если нужно постепенно бросать иголки:
process()

root.mainloop()
  • Вопрос задан
  • 759 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 3
@U235U235
У Бюффона игла бесконечно тонкая, нити тоже бесконечно тонкие, а у вас нет. Если уменьшите длину иглы, то станет еще хуже, если сделаете длинее - то точность увеличится.
Ответ написан
@NicolayChe
Длина иголки должна совпадать с длиной расстояния между нитей
Иголка - диаметр окружности, точек пересечения или касания 2
Если иголка меньшего расстояния точек пересечения линий и окружности иголки может быть 0, 1, 2
Если иголка длиннее, то точек пересечения 4

Условия эксперимента читай внимательней L-длина иголки, L-расстояние между нитями
Ответ написан
@Battle-Of-Two-K Автор вопроса
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы