使用C语言中的蒙特卡洛方法近似计算π

CCBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,我们将学习如何使用C编程语言中的蒙特卡洛方法来近似计算π的值。我们将首先在单位正方形内生成随机点,然后计算落在四分之一圆内的点的数量,以计算π的近似值。最后,我们将打印计算出的近似值。

本实验涵盖了使用蒙特卡洛方法估计π的关键步骤,包括生成随机点、计算四分之一圆内的点的数量,以及使用圆内点的数量与总点数的比例来计算近似值。本实验提供了微积分和解析几何概念在C编程语言中的实际应用。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL c(("C")) -.-> c/BasicsGroup(["Basics"]) c(("C")) -.-> c/ControlFlowGroup(["Control Flow"]) c(("C")) -.-> c/FunctionsGroup(["Functions"]) c(("C")) -.-> c/UserInteractionGroup(["User Interaction"]) c/BasicsGroup -.-> c/variables("Variables") c/ControlFlowGroup -.-> c/for_loop("For Loop") c/FunctionsGroup -.-> c/math_functions("Math Functions") c/UserInteractionGroup -.-> c/output("Output") subgraph Lab Skills c/variables -.-> lab-435134{{"使用C语言中的蒙特卡洛方法近似计算π"}} c/for_loop -.-> lab-435134{{"使用C语言中的蒙特卡洛方法近似计算π"}} c/math_functions -.-> lab-435134{{"使用C语言中的蒙特卡洛方法近似计算π"}} c/output -.-> lab-435134{{"使用C语言中的蒙特卡洛方法近似计算π"}} end

在单位正方形中生成随机点

在这一步中,我们将学习如何使用C编程语言在单位正方形内生成随机点,这是使用蒙特卡洛方法近似计算π的关键部分。

首先,让我们在 ~/project 目录中创建一个新的C文件来实现随机点生成:

cd ~/project
nano random_points.c

现在,让我们编写生成随机点的代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NUM_POINTS 10000

int main() {
    // 为随机数生成器设定种子
    srand(time(NULL));

    // 在单位正方形中生成随机点
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        printf("Point %d: (%.4f, %.4f)\n", i + 1, x, y);
    }

    return 0;
}

让我们来分析一下这段代码:

  • srand(time(NULL)) 使用当前时间为随机数生成器设定种子
  • (double)rand() / RAND_MAX 生成一个介于0和1之间的随机数
  • 我们在单位正方形 (0,0) 到 (1,1) 中生成10,000个随机点

编译并运行程序:

gcc random_points.c -o random_points
./random_points

示例输出:

Point 1: (0.7234, 0.5678)
Point 2: (0.2345, 0.9876)
...
Point 10000: (0.1122, 0.3344)

计算四分之一圆内的点数并近似计算π

在这一步中,我们将修改之前的程序,以计算落在四分之一圆内的点数,并利用这些信息来近似计算π的值。

让我们更新 random_points.c 文件:

cd ~/project
nano random_points.c

用以下实现替换之前的代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define NUM_POINTS 100000

int main() {
    // 为随机数生成器设定种子
    srand(time(NULL));

    int points_inside_circle = 0;

    // 生成随机点并计算落在四分之一圆内的点的数量
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        // 检查点是否在四分之一圆内
        if (x*x + y*y <= 1.0) {
            points_inside_circle++;
        }
    }

    // 近似计算π
    double pi_approximation = 4.0 * points_inside_circle / NUM_POINTS;

    printf("总点数: %d\n", NUM_POINTS);
    printf("四分之一圆内的点数: %d\n", points_inside_circle);
    printf("π的近似值: %.6f\n", pi_approximation);
    printf("π的实际值:    %.6f\n", M_PI);
    printf("差值:        %.6f\n", fabs(pi_approximation - M_PI));

    return 0;
}

使用数学库编译程序:

gcc random_points.c -o random_points -lm
./random_points

示例输出:

总点数: 100000
四分之一圆内的点数: 78540
π的近似值: 3.141600
π的实际值:    3.141593
差值:        0.000007

让我们来分析一下关键的变化:

  • 增加点数以提高精度
  • 添加计算四分之一圆内点数的逻辑
  • 使用公式:π ≈ 4 *(圆内点数)/(总点数)
  • 包含与π的实际值的比较

打印近似值

在这最后一步中,我们将通过创建一个函数来打印结果并改进输出格式,从而增强我们的π近似值程序。

让我们修改 random_points.c 文件:

cd ~/project
nano random_points.c

用一个新的打印函数和改进后的输出来更新代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define NUM_POINTS 1000000

// 函数:打印近似值结果
void print_pi_approximation(int total_points, int points_inside_circle) {
    double pi_approximation = 4.0 * points_inside_circle / total_points;

    printf("π近似值结果\n");
    printf("=====================\n");
    printf("生成的总点数:        %d\n", total_points);
    printf("四分之一圆内的点数:  %d\n", points_inside_circle);
    printf("近似的π值:          %.8f\n", pi_approximation);
    printf("π的实际值:          %.8f\n", M_PI);
    printf("绝对差值:            %.8f\n", fabs(pi_approximation - M_PI));
    printf("近似精度:            %.4f%%\n",
           (1 - fabs(pi_approximation - M_PI) / M_PI) * 100);
}

int main() {
    // 为随机数生成器设定种子
    srand(time(NULL));

    int points_inside_circle = 0;

    // 生成随机点并计算落在四分之一圆内的点的数量
    for (int i = 0; i < NUM_POINTS; i++) {
        double x = (double)rand() / RAND_MAX;
        double y = (double)rand() / RAND_MAX;

        // 检查点是否在四分之一圆内
        if (x*x + y*y <= 1.0) {
            points_inside_circle++;
        }
    }

    // 打印近似值结果
    print_pi_approximation(NUM_POINTS, points_inside_circle);

    return 0;
}

编译并运行程序:

gcc random_points.c -o random_points -lm
./random_points

示例输出:

π近似值结果
=====================
生成的总点数:        1000000
四分之一圆内的点数:  785398
近似的π值:          3.14159200
π的实际值:          3.14159265
绝对差值:            0.00000065
近似精度:            99.9998%

关键改进:

  • 创建了一个专用函数 print_pi_approximation()
  • 将点数增加到1,000,000以提高精度
  • 添加了更详细的输出格式
  • 包含了近似精度百分比

总结

在本实验中,我们首先学习了如何使用C编程语言在单位正方形内生成随机点,这是使用蒙特卡洛方法近似计算π的关键部分。我们使用当前时间为随机数生成器设定种子,然后使用 rand() 函数在单位正方形 (0,0) 到 (1,1) 内生成10,000个随机点。

接下来,我们修改了程序以计算落在四分之一圆内的点的数量,并利用这些信息来近似计算π的值。我们生成了100,000个随机点,并检查哪些点落在四分之一圆内。通过计算圆内点的数量与总点数的比例,我们能够估算出π的值。