伊恩·斯图尔特《改变世界的17个方程》微积分

它告诉我们什么?

要求出一个随时间变化的量的瞬时变化率,可以计算这个量在一个短的时间间隔内如何变化,再除以间隔长度。然后让这个间隔变得任意小。

为什么重要?

它为微积分提供了严谨的基础,而微积分是科学家们为自然界建模的主要方式。

它带来了什么?

切线和面积的计算。立体体积和曲线长度公式。牛顿运动定律、微分方程。能量和动量守恒定律。数学物理的大部分内容。

牛顿建立微积分的方法

莱布尼茨所用的符号与牛顿的不同,但本质思想多少是一回事。然而,它们背后的直觉是不同的。莱布尼茨的方法是形式化的,靠的是摆弄代数符号。牛顿的脑海中有一个物理模型,他考虑的函数是随时间变化的物理量。这就是他诡异的“流数”(fluxion)一词的由来——随着时间流逝而流动的东西。

批注:yysy,实际上在理解链式法则、隐函数求导的时候,我觉得就是在摆弄数学符号(捂脸)

牛顿的方法可以用一个例子来说明:数量y是另一个数量x的平方x^2。(这是伽利略从滚球中发现的规律:它的位置与经过的时间的平方成正比。因此y就是位置,x是时间。时间通常用符号t表示,但是平面中的标准坐标系使用xy。)首先引入一个新的数量o,表示x的微小变化。y的相应变化就是(x+o)^2-x^2,这可简化为2xo+o^2。因此变化率(在x增加至[x+o时,在微小长度间隔o上取平均)是\frac{2xo+o^2}{o}=2x+o,这取决于o,也只能是这样,因为我们取的是一个非零间隔内的平均变化率。然而,如果o越来越小,“流向”零,则变化率2x+o越来越接近2x。这就不依赖于o,而是给出了x处的瞬时变化率

莱布尼茨基本上做了相同的计算,用dx(“x的小变化”)来代替o,并定义了dy来表示y中相应的微小变化。当变量y取决于另一个变量x时,y相对于x的变化率被称为y的导数。牛顿表示y的导数的方法是在它上面加了一个点\dot{y}。莱布尼茨的写法是\frac{dy}{dx}。对于更高阶的导数,牛顿使用了更多的点,而莱布尼茨的写法则是类似于\frac{d^2y}{dx^2}。今天我们说yx的函数,写作y=f(x),但这个概念在当时还只是原始的形式。我们要么使用莱布尼茨的记法,要么使用牛顿的记法的一种变体,其中用撇来代替点(这比较容易印刷):y'y''。我们还会写f'(x)f''(x)来强调导数本身也是函数。计算导数的运算称为微分。

人们发现积分(求面积)是微分(求斜率)的逆运算。为了解释原因,想象一下下图的阴影区域的一端加上一个窄条。这个窄条非常接近宽为h、高为y的细长矩形。因此,它的面积非常接近hy。面积相对于x的变化率是y因此面积的导数就是原函数。牛顿和莱布尼茨都了解计算面积的方法,也就是所谓“积分”的运算,在这个意义上是微分的反转。莱布尼茨先是使用符号omn.(拉丁语中“和”omnia的缩写),后来换成\int,一个老式的长s,也代表“和”。牛顿没有系统化的积分符号。

然而,牛顿确实取得了一个重要进展。瓦利斯计算了所有幂函数x^{\alpha}的导数:\alpha x^{\alpha-1}。牛顿将结果推广到任何多项式——有限幂函数的组合,例如3x^7-25x^4+x^2-3。诀窍是分别考虑每个幂函数,求出相应的导数,并以相同的方式组合起来。牛顿注意到,同样的方法适用于无穷级数,也就是包含变量的无限多个幂函数的表达式。这让他可以在许多其他比多项式更复杂的表达式上做微积分运算。

鉴于两种版本的微积分之间存在密切的对应关系,主要区别在于记法不同(这并不重要),很容易想见这个谁先谁后的争议是怎么产生的。然而,其基础思想是对基本问题相当直接的表述,因此尽管有相似之处,牛顿和莱布尼茨独立地得出自己的版本也是很容易理解的。不管怎么说,费马和沃利斯得出的很多结果比他们都早。这个争议毫无意义。

更有成效的争论是针对微积分的逻辑结构,或者更确切地说,是微积分不合逻辑的结构。一位主要的批评者是英裔爱尔兰哲学家乔治·贝克莱(George Berkeley),他是克洛因镇的主教。贝克莱有一个宗教目的;他觉得从牛顿的工作中发展出来的唯物主义世界观,代表着上帝是一个超然的创造者,一旦创造出来的东西开始运转,他就撒手不管了,这可不像是基督教信仰中那个亲力亲为、无所不在的上帝。于是他攻击了微积分基础中的逻辑不一致,可能是希望让由此产生的科学名誉扫地。他的攻击对数学物理的进展没有明显的影响,原因很简单:使用微积分得到的结果对自然有如此深刻的洞察力,并且与实验结果如此一致,以至于逻辑基础似乎都不重要了。直至今日,物理学家仍然持这种观点:如果它管用,谁会关心逻辑上的吹毛求疵呢?贝克莱认为,如果你在大部分运算中认为一个小量是非零的,再把它设成零——然而先前已经让分子、分母同时除以这个量——那这在逻辑上说不通。除以0的运算在算术中是不可接受的,因为它没有明确的含义。贝克莱在1734年的一本小册子《分析学家;致一位不信神数学家的论文》中发表了他的批判。贝克莱认为这个想法是“消失量之鬼”

还有一个人不屈不挠地批判莱布尼茨:几何学家伯纳德·尼欧文蒂(Bernard Nieuwentijt)。他在1694年和1695年公开发表了他的批评。莱布尼茨没有试图用“无穷小”来解释他的方法——这个术语容易被误解。然而,他确实解释了,他所说的这个术语的意思不是一个可以任意小的固定的非零数量(这在逻辑上说不通),而是一个可变的非零数量,它可以变得任意小。牛顿和莱布尼茨的辩词基本是一样的。对于他们的反对方来说,这听起来肯定都是文字花招。

幸运的是,当时的物理学家和数学家并没有等到把微积分的逻辑基础搞清楚,再去应用到科学前沿上。他们有另一种方法可以确保做出明智的决定:与观察和实验进行比较。牛顿本人发明微积分恰恰就是为了这个目的。他推导出了物体被施力时如何运动的定律,并将它们与针对引力的定律相结合,解开了关于太阳系行星和其他天体的许多谜团。他的万有引力定律在物理学和天文学中是如此关键,它应该,也确实得到了自己的专门一章(下一章)。他的运动定律——严格来说是由三个定律组成的体系,其中一个定律包含了大部分数学内容——相当直接地引出了微积分。

讽刺的是,当牛顿在他的《自然哲学的数学原理》一书中发表这些定律及其科学应用时,他抹去了所有微积分的痕迹,代之以经典的几何论证。他可能认为几何对于他的目标读者来说更容易接受——如果他真是这么想的,那他几乎肯定是对的。然而,他的许多几何证明要么是受微积分启发,要么是依赖微积分技巧来找到正确答案,再靠这些答案来完成几何证明。在现代人看来,这在《自然哲学的数学原理》第二卷中对所谓的“生成数量”的处理中再明显不过了。这些数量通过“连续运动或流量(也就是他未发表的书中的‘流数’)”增加或减少。今天我们称它们为连续(实际上是可微)函数。牛顿没有显式地使用微积分运算,而是代之以“初始和最终比”的几何方法。他的开篇引理(给被反复使用,但本身并不值得关注的辅助数学结果起的名字)露了馅儿,因为它这样定义了这些流动量的相等:数量和数量之比,若在任何有限的时间内连续向相等收敛,并且在该时间结束时彼此接近的程度小于任意给定的差异,则最终是相等的。

所以说,微积分在《自然哲学的数学原理》中扮演着重要的幕后角色,却没有出现在台前。然而,微积分一旦走出幕后,牛顿思想的继承者们就很快逆向推演出了他的思维过程。他们用微积分语言重新描述了牛顿的主要观点——因为这提供了一个更自然、更强大的框架,然后出发去征服科学世界。

牛顿运动定律

在牛顿运动定律中已经可以看到这条线索。促使牛顿得出这些定律的是一个哲学问题:导致物体运动或改变其运动状态的原因是什么?经典的答案是亚里士多德给出的:物体运动是因为对其施加了力,而这会影响它的速度。亚里士多德还指出,为了让物体保持运动,必须持续向其施加力量。你可以在桌子上放一本书或类似的物体来检验亚里士多德的说法。如果你推这本书,它就会开始运动;如果你继续以相同的力推动它,它会以大致恒定的速度继续在桌子上滑动。如果你不推了,书就会停止运动。所以亚里士多德的观点似乎与实验一致。然而,这种一致是肤浅的,因为推力并不是影响书的唯一力量。桌子表面还有摩擦力。当书在稳定的力的推动下稳定地滑过桌面时,摩擦阻力与施加的推力相抵消,作用在物体上的力的总和实际上是零。

遵循着伽利略和笛卡儿的早期想法,牛顿意识到了这一点。由此产生的运动理论与亚里士多德的理论截然不同。牛顿的三个定律如下。

第一运动定律。任何物体都会继续其静止或匀速直线运动状态,除非施加于其上的力迫使它改变这种状态。

第二运动定律。运动的变化与施加的力成正比,且运动变化的方向就是施力的方向。(比例常数是物体质量的倒数,即1除以该质量。)

第三运动定律。任何作用力都对应着一个反向且相等的反作用力。

第一运动定律明确地反驳了亚里士多德。第三运动定律说,如果你推一件东西,它会反推回来。第二运动定律正是微积分的来源。所谓“运动的变化”,牛顿指的是物体速度变化的速率:加速度。这是速度对时间的导数、位置对时间的二阶导数。所以牛顿的第二运动定律以微分方程的形式指出了物体位置和作用于它的力之间的关系:

为了求出位置本身,我们必须解这个方程,从二阶导数推导出位置。

牛顿的运动定律不仅仅提供了一种计算物体运动方式的方法。它们引出了深刻的一般性物理原理。其中最重要的是“守恒定律”:它告诉我们,当一个物体系统运动时,无论它多么复杂,该系统的某些特征不会改变。无论运动多么纷杂混乱,总有几个量岿然不动。三个这样的守恒量是能量、动量和角动量

能量守恒

能量可以定义做功的能力。当一个物体抵抗(恒定的)重力,被提升到一定的高度时,将它举到这个高度所做的功,与物体的质量、重力和高度成正比。相反,如果我们松开物体,它可以做同样多的功,再落回到原始高度。这种能量称为势能。单看势能并不算非常有意思,但从牛顿第二运动定律可以得出一个美妙的数学结果,引出第二种能量:动能。当物体运动时,它的势能和动能都会发生变化。但是,一种能量的变化刚好弥补了另一种能量的变化:随着物体在重力作用下下降,它会加速。牛顿运动定律让我们能够计算其速度如何随高度变化。结果发现,势能的减少量恰好等于质量乘以速度平方的一半。如果我们给这个数量起个名字——动能,则总能量(即势能加动能)是守恒的。牛顿定律的这个数学结果证明了永动机是不可能实现的:如果没有外部能量输入,那么没有机械装置可以永远运行下去并做功。在物理上,势能和动能似乎是两个不同的东西;但在数学上,两者可以互换,就好像运动以某种方式将势能转化为动能一样。“能量”这个术语同时适用于两者,是一种好用的抽象。它的定义经过精心设计以保证守恒。作为类比,一个旅行者可以把英镑兑换成美元。货币兑换处有汇率表,比如说1英镑与1.4693美元价值相等。兑换处还扣下了一笔钱留给自己——算上银行手续费等技术细节后,交易中涉及的总货币价值应该是平衡的:扣除各种费用后,旅行者获得的金额恰好等于与其原始英镑金额相当的美元。然而,纸币中并没有这样一个实体的东西,从英镑钞票中变出来,再变进美元钞票和硬币中。交换的是这些特定物体中人为约定的货币价值。

能量是另一种类型的“物理”量。从牛顿的观点来看,位置、时间、速度、加速度和质量等量都有直接的物理解释。你可以用尺子来测量位置,用时钟计算时间,同时使用这两种工具来测量速度和加速度,使用天平测量质量。但是你并不能使用能量表来测量能量。确实,某些特定类型的能量可以测量。势能与高度成正比,因此如果你知道重量,有一把尺子就足够了。动能是质量乘以速度平方的一半,因此可以使用天平和速度计来测量。但是,能量作为一个概念,与其说是一个实际的东西,不如说是一个方便的虚构,可以帮我们轧平力学的账目

动量守恒

第二个守恒量——动量是一个简单的概念:质量乘以速度。当有多个物体时,它就有用武之地了。一个重要的例子是火箭:在这里,一个物体是火箭,另一个物体是它的燃料。当燃料被发动机喷出时,动量守恒意味着火箭必须向相反的方向运动。火箭在真空中就是这样工作的。

角动量也与此类似,但它讨论的是旋转而不是速度。它是火箭的核心,实际上也是整个力学的核心,无论是地面力学还是天体力学。关于月球的最大谜团之一就是其巨大的角动量。目前的理论是,大约45亿年前,有一颗火星大小的行星撞击地球,月球是飞溅出去的。这就解释了角动量,这个观点直到最近都得到了普遍接受,但现在看来,月球岩石中的水似乎太多了。这样的冲击应该会把大量的水烧干。无论最终的结果是什么,角动量在这里都是至关重要的。

对微积分的完善

微积分确实有效。它解决了物理和几何中的问题,得到了正确的答案。它甚至可以带来新的、基本的物理概念,如能量和动量。但这并没有回答贝克莱主教的异议。微积分必须在数学上成立,而不仅仅是符合物理。牛顿和莱布尼茨都明白,o或dx不能既是零又不是零。牛顿厌倦了使用流数的物理图像来逃避逻辑陷阱。莱布尼茨谈到了无穷小量。二人都提到接近零却永远不会达到零的量——但这东西到底是什么?具有讽刺意味的是,贝克莱对于“消失量之鬼”的奚落让他差点就解决了这个问题,但他没有考虑到——这些量是如何消失的——而这正是牛顿和莱布尼茨所强调的。如果能让它们以正确的方式消失,就可以得到一个形式完美的“鬼魂”。如果当初牛顿或莱布尼茨把他们的直觉用严谨的数学语言表达了出来,那么贝克莱可能已经领会了他们的意思。

当数学家回到微积分的逻辑时,他们意识到,当我们说o接近零时,我们的意思是,给定任何非零正数,都可以选择一个小于该数的o。(这很显然,比如让o为该数字的一半。)类似地,当我们说2x+o接近2x时,我们的意思是,这个差值在前面所说的这个意义上接近零。由于在这个例子里,这个差值恰好是o本身,那就更明显了:无论“接近零”是什么意思,显然当o接近零时,o接近零。比平方更复杂的函数则需要更复杂的分析。

这个关键问题的答案,是用正式的数学语言来陈述这个过程,而完全避免“流动”的想法。这一突破是通过波希米亚数学家和神学家伯纳德·博尔扎诺(Bernard Bolzano)以及德国数学家卡尔·魏尔施特拉斯(Karl Weierstrass)的工作实现的。博尔扎诺的工作可以追溯到1816年,但直到1870年左右,当魏尔施特拉斯将这一表述拓展到复变函数时才得到认可。他们对贝克莱的回答就是极限的概念。我将用文字说明定义,把符号版本留给附注。

除了0本身,诶嘿。 

  • 20
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以先分别遍历两个链表,得到它们的长度n和m。然后让较长的链表先走n-m步,这样两个链表就剩下相同长度了。接着同时从头开始遍历两个链表,直到找到第一个相同的结点为止,即为它们的第一个共同结点。 具体实现如下: ``` ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { int lenA = 0, lenB = 0; ListNode *curA = headA, *curB = headB; //分别遍历两个链表,得到它们的长度n和m while (curA) { lenA++; curA = curA->next; } while (curB) { lenB++; curB = curB->next; } //让较长的链表先走n-m步 curA = headA; curB = headB; if (lenA > lenB) { for (int i = 0; i < lenA - lenB; i++) curA = curA->next; } else { for (int i = 0; i < lenB - lenA; i++) curB = curB->next; } //同时从头开始遍历两个链表,直到找到第一个相同的结点为止 while (curA && curB) { if (curA == curB) return curA; curA = curA->next; curB = curB->next; } return nullptr; } ``` ### 回答2: 首先,我们可以先遍历链表a,将链表a的所有节点插入一个哈希表中。然后再遍历链表b,查找每个节点是否在哈希表中出现过。如果找到第一个在哈希表中出现的节点,则该节点就是链表a和链表b的第一个共同结点。 该算法的时间复杂度为O(n+m),其中n是链表a的长度,m是链表b的长度。遍历链表a需要O(n)的时间,将链表a的所有节点插入哈希表需要O(n)的时间。遍历链表b需要O(m)的时间,查找链表b的每个节点在哈希表中是否出现过需要O(m)的时间。 以下是该算法的示例代码: ```python # 定义链表节点 class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def getIntersectionNode(headA: ListNode, headB: ListNode) -> ListNode: hashset = set() # 创建哈希表 # 遍历链表a,将所有节点插入哈希表 while headA: hashset.add(headA) headA = headA.next # 遍历链表b,查找节点是否在哈希表中出现过 while headB: if headB in hashset: return headB headB = headB.next return None # 若没有共同结点,则返回None ``` 该算法利用哈希表的查找时间复杂度为O(1),因此总的时间复杂度为O(n+m)。 ### 回答3: 一个简单的思路是,先遍历链表a,将a中的每个结点存储在一个集合中。然后遍历链表b,对于b中的每个结点,判断该结点是否在集合中,如果在,则该结点即为两个链表的第一个共同结点。 这种算法的时间复杂度是O(n+m),其中n是链表a的长度,m是链表b的长度。 具体实现如下: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def find_first_common_node(headA, headB): node_set = set() current = headA while current: node_set.add(current) current = current.next current = headB while current: if current in node_set: return current current = current.next return None # 构造测试链表 a = ListNode(1) a.next = ListNode(2) a.next.next = ListNode(3) a.next.next.next = ListNode(6) a.next.next.next.next = ListNode(7) b = ListNode(4) b.next = ListNode(5) b.next.next = ListNode(6) b.next.next.next = ListNode(7) # 测试 result = find_first_common_node(a, b) if result: print("Found first common node:", result.val) else: print("No common node found.") ``` 上述代码在两个链表中都遍历了一次,时间复杂度为O(n+m)。并且通过使用集合,可以实现O(1)时间复杂度的判断当前结点是否在集合中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值