Вычисление числа Пи на языке D методом «краника»

Вычисление числа Пи на языке D методом «краника»

Вычисление числа Пи — одна из вечных задач в математике и вычислительной технике. Существует множество методов для этого, от классических геометрических до сложных алгоритмов на основе численных методов. Сегодня мы рассмотрим один из таких методов, известный как метод «краника» (или «шланга»), и как его реализовать на языке программирования D.

Что такое метод «краника»?

Метод «краника» основан на концепции моделирования бросков точек в круг, вписанный в квадрат. Если случайным образом бросать точки в квадрат, вероятность того, что точка попадет внутрь круга, равна отношению площади круга к площади квадрата. Используя это соотношение, можно вычислить значение числа Пи.

Формулировка метода

Пусть у нас есть квадрат со стороной 2, вписанный круг имеет радиус 1. Площадь квадрата равна 4, а площадь круга — Пи. Если случайным образом бросать точки в квадрат, доля точек, попавших в круг, будет примерно равна отношению площади круга к площади квадрата:

число точек в кругеобщее число точекπ4\frac{\text{число точек в круге}}{\text{общее число точек}} \approx \frac{\pi}{4}

Отсюда получаем:

π4×число точек в кругеобщее число точек\pi \approx 4 \times \frac{\text{число точек в круге}}{\text{общее число точек}}

Реализация на языке D

Теперь, когда мы поняли теорию, перейдем к практике. Давайте напишем программу на языке D, которая вычисляет число Пи методом «краника».

Написание кода

import std.stdio;
import std.random;
import std.math;

void main()
{
    // Общее количество бросков
    int totalPoints = 1_000_000;
    int pointsInCircle = 0;

    // Генерация случайных точек
    foreach (i; 0 .. totalPoints)
    {
        double x = uniform(-1.0, 1.0);
        double y = uniform(-1.0, 1.0);

        // Проверка, попала ли точка в круг
        if (x * x + y * y <= 1.0)
        {
            pointsInCircle++;
        }
    }

    // Вычисление Пи
    double piEstimate = 4.0 * pointsInCircle / totalPoints;

    // Вывод результата
    writeln("Оценка Пи: ", piEstimate);
}

Подробное описание кода

  1. Импортируем модули:
  • std.stdio для работы с вводом/выводом.
  • std.random для генерации случайных чисел.
  • std.math для математических операций.
  1. Основная функция main:
  • totalPoints — общее количество случайных точек.
  • pointsInCircle — количество точек, попавших в круг.
  1. Генерация случайных точек:
  • В цикле foreach генерируем координаты точек x и y с использованием функции uniform для равномерного распределения в диапазоне от -1 до 1.
  • Проверяем, попала ли точка в круг, используя условие if (x * x + y * y <= 1.0).
  1. Вычисление и вывод результата:
  • Используем формулу для вычисления Пи: piEstimate = 4.0 * pointsInCircle / totalPoints.
  • Выводим результат на экран с помощью writeln.

Оптимизация и улучшение точности

Метод «краника» прост в реализации, но его точность зависит от количества точек. Чем больше точек, тем точнее оценка числа Пи. Рассмотрим несколько способов улучшения точности и производительности.

  1. Увеличение количества точек:
    Увеличивая totalPoints, мы получаем более точную оценку, но это требует больше времени на вычисления.
  2. Параллельные вычисления:
    Язык D поддерживает параллельные вычисления с помощью модуля std.parallelism. Это позволяет значительно ускорить процесс при использовании многоядерных процессоров.

Пример кода с параллельными вычислениями

import std.stdio;
import std.random;
import std.math;
import std.parallelism;

void main()
{
    // Общее количество бросков
    int totalPoints = 10_000_000;

    // Параллельное выполнение
    int pointsInCircle = taskPool.parallel(totalPoints, &estimatePi).sum;

    // Вычисление Пи
    double piEstimate = 4.0 * pointsInCircle / totalPoints;

    // Вывод результата
    writeln("Оценка Пи: ", piEstimate);
}

int estimatePi(size_t start, size_t end)
{
    int count = 0;
    foreach (i; start .. end)
    {
        double x = uniform(-1.0, 1.0);
        double y = uniform(-1.0, 1.0);

        if (x * x + y * y <= 1.0)
        {
            count++;
        }
    }
    return count;
}

Объяснение кода

  1. Импортируем необходимые модули:
  • std.parallelism для параллельных вычислений.
  1. Основная функция main:
  • totalPoints — общее количество случайных точек.
  • Используем taskPool.parallel для параллельного выполнения функции estimatePi и суммируем результаты с помощью .sum.
  1. Функция estimatePi:
  • Принимает диапазон значений и вычисляет количество точек, попавших в круг в этом диапазоне.
  • Возвращает количество точек в круге.

Метод «краника» — простой и наглядный способ вычисления числа Пи, который легко реализуется на языке D. Несмотря на свою простоту, этот метод демонстрирует мощь и гибкость языка D, особенно при использовании параллельных вычислений. Попробуйте увеличить количество точек или использовать другие методы оптимизации для улучшения точности и производительности вашего кода.


Карпов Ярослав

Автор статьи:

Обновлено:

23.05.2024


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *