《算法之美》 第二章:美丽的数学


前言

我们如果想让计算机认识这个世界,那么我们首先应当将这个世界数字化,才能被计算机所认知,而将世界数字化的基础是建立在数学和计算机编程之上的。

本章,将带领大家走进数学的世界,见识一下数学的魅力。


一、全章总览

本文将带大家体验书中的例子,诸如蒙特卡洛法求解圆周率,求解最大公约数和最小公倍数,闰年问题等等,同时对课后实验题做出解答。事不宜迟,我们这就开始吧!

二、案例分析

1.蒙特卡洛法求解圆周率

圆周率,是第一个被发现的无限不循环小数,历史上曾有许多杰出的数学家执着于对他的求解,在这些数学家其中,有一处名为蒙特卡洛的城市,在那里,出现了一个很有趣的解法。

我们知道,赌博是一项充满了随机性的活动,但是只要实验的次数偶多,根据概率与统计的知识,我们便可以巧妙地计算圆周率的值。

我们首先做一个正方形,及其内切圆,同时不断在这个正方形中随机选取一个点,当我们选取很多很多点后,在圆内的点的数量与选取的点的总数之比,就等于π/4,。

因此,我们通过计算机模拟这个过程,就可以近似计算出π的值。

代码如下:

# Alkaid#3529
import random

print("This is monte carlo")


def monte_carlo(n):
    m = 0
    for i in range(1, n + 1):
        x = random.randint(1, 10000)
        y = random.randint(1, 10000)
        if x ** 2 + y ** 2 < 10000 * 10000:
            m += 1

    return 4 * m / n


print(monte_carlo(1000000))

在大量实验后,我们可以得到较为精确的 π 值:

在这里插入图片描述

2.最大公约数和最小公倍数

首先我们思考最大公约数,两个数的最大公约数,如果存在,则一定落在[1, min(a, b)]之间,因此我们只需循环判断此区间内的每一个数,找到最大的可以同时被a, b整除的那个数并返回即可。

代码如下:

# Alkaid#3529

print("This is greatest common divisor")


def divisor(a, b):
    """
    求解两数的最大公约数
    :param a: 参数一
    :param b: 参数二
    :return: 返回求解结果
    """
    temp = min(a, b)
    while temp > 0:
        if a % temp == 0 and b % temp == 0:
            return temp
        else:
            temp -= 1
    
    return temp


divisor(10, 5)

接下来我们判断最小公倍数,我们容易发现,两个数的最小公倍数一定会落在[max(a, b), a * b]之间,因此我们只需对此区间内的每个数循环判断,找到并返回最小的那个即可。

代码如下:

# Alkaid#3529

print("This is lcm")


def lcm(a, b):
    temp = max(a, b)
    while temp < a * b + 1:
        if temp % a == 0 and temp % b == 0:
            return temp
        else:
            temp += 1

    return temp

print(lcm(10, 43))

3.闰年问题

闰年问题是入门期常见的问题之一,我们只需明白闰年的判断规则,即可很快地实现对闰年的判断:能被 4 整除且不能被 100 整除,或者能被 400 整除的年份,就是闰年。

明确思路后,我们可以轻易写出代码。

代码如下:

# Alkaid#3529

print("This is leap year")


def leap(year):
    if year % 4 == 0:
        if year % 100 == 0:
            if year % 400 == 0:
                return True
            else:
                return False
        else:
            return True
    else:
        return False


print(leap(1900))

4.空间三角形面积

在三维空间坐标系中,已知三点的坐标,求这三点围成的三角形的面积。方法有很多,书中给出的三斜求积术是一种简单粗暴的办法,笔者在此处也选择使用海伦公式求解,但是我们换一种思路实现,利用类和对象来简化代码。

# Alkaid#3529

from math import sqrt

print("This is Space triangle area")


class Point(object):
    def __init__(self, x=0, y=0, z=0):
        self.x = x
        self.y = y
        self.z = z


def Calculate_area(a: Point, b: Point, c: Point):
    s1 = sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2 + (a.z - b.z) ** 2)
    s2 = sqrt((c.x - b.x) ** 2 + (c.y - b.y) ** 2 + (c.z - b.z) ** 2)
    s3 = sqrt((a.x - c.x) ** 2 + (a.y - c.y) ** 2 + (a.z - c.z) ** 2)

    s = (s1 + s2 + s3) / 2

    area = sqrt(s * (s - s1) * (s - s2) * (s - s3))

    return area


a = Point(1, 1, 1)
b = Point(3, 3, 2)
c = Point(4, 2, 2)

print(Calculate_area(a, b, c))

我们可以快速得到答案:

在这里插入图片描述


总结

本章带大家运用计算机解决了一些常见的数学问题,相信大家也能感受到计算机在我们解决大量简单问题中发挥了出色的作用,下一章开始,我们将正式进入数据结构的学习,了解多种常见的数学结构,大家做好准备,我们很快出发。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alkaid3529

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值