-
2018-06-18 06:04:48更多相关内容
-
复杂性科学及其演变 (2004年)
2021-04-28 21:01:09复杂性科学是研究复杂系统行为与性质的科学,具有统一的方法论——整体论或非还原论。复杂性科学诞生的标志是一般系统论的创立。依据研究对象的变化,我们可把复杂性科学的发展历史大致划分为3个阶段,它们分别是:... -
复杂性科学研究现状与展望 (2005年)
2021-04-28 23:23:42研究和总结了复杂性、复杂系统与复杂性科学的基本... 总结了复杂性科学的研究对象、基本原理和基本研究方法; 综述了国内外研究现状。指出了存在的问题和今后需要重点研究的问题; 提出了我国发展复杂性科学的建议。 -
科学成果评价的复杂性 (2006年)
2021-05-15 10:58:28科学成果评价的目的是承认杰出研究。...从传统认识论的局限与向复杂性范式的转换、复杂系统及其复杂性、科学成果评价的复杂性、从复杂性看成果评价的方法论原则等4个方面探讨了科学成果评价活动的复杂性问题。 -
复杂性,科学,方法论?
2020-03-07 17:56:09石头兄弟希望我们可以从复杂性的视角看一下微服务,但迟迟未能动笔。因为本着“澄清概念,判定标准,构建系统”的一般原则,虽然微服务已经有了很多的文字描述,那么复杂性到底是什么呢?只是编程中所...石头兄弟希望我们可以从复杂性的视角看一下微服务,但迟迟未能动笔。因为本着“澄清概念,判定标准,构建系统”的一般原则,虽然微服务已经有了很多的文字描述,那么复杂性到底是什么呢?只是编程中所涉及到的时间复杂度和空间复杂度么?
只能求助于文献,于是断断续续读完了第三本关于复杂性的书。
什么是复杂性
在《说文解字》中,对“复杂”二字的解释如下:
复,行故道也。 杂,五彩相会,从衣,集声。
复杂的英文complex 最早的意思就是编辫子、缠绕、编织,后转化为把许多东西结合在一起。
把“复杂”上升到哲学的高度,本体论方面,指事物的组成多且杂;认识论方面,指难于理解和解释,不容易处理。于是,复杂性成为了认识的避难所。
复杂性是一种自组织临界性? 复杂性是辩证法的统一? 复杂性是系统的一种涌现? ...
人们总是希望定义复杂性,例如计算复杂性包括了时间和空间,描述复杂性也称为算法复杂性,越随机的东西越复杂。
复杂性可能产生于一些由经过适当选择的规则所定义的系统。德国学者克拉莫(F Cramer)利用系统定义了复杂性:
复杂性可以定义为系统表明自身方式数目的对数,或是系统可能状态数目的对数:K= Log N,N是不同的可能状态数。
对系统的全面而细致的分类是探索复杂性的前提。复杂系统的特征是:不稳定性、多连通性,非集中控制性,不可分解性、涌现性、进化过程的多样性及进化能力。
如果说混沌涉及时间上的不规则性,那么复杂性则可能意味着空间上的不规则性,甚至混沌本身也是复杂性的一部分。
美学始终属于哲学而不是科学,那么复杂性呢?
什么是复杂性科学
很多人认为,“复杂性研究”是可能的,“复杂性科学”是不可能的。所有学科领域复杂性研究的总和才是所谓的“复杂性科学”。实际上,不能把复杂性全部归结为认识过程的不充分性,必须承认存在客观的复杂性,真正的复杂性应当具备自身特有的规定性。
复杂性科学可能是系统科学发展的新阶段。复杂性科学注意研究对象的完整性,注意构成对象系统的要素之间的联系性,更注意由部分组成整体之后的涌现性。
复杂性科学的特点如下:
只能通过研究方法论来界定,其度量标尺和框架就是非还原的研究方法论。
不是一门具体的学科,是学科互涉的交叉学科。
寻找各学科之间的互相联系、互相合作的统一机制。
抛弃还原论适用于所有科学的梦想。
创立新的理论框架体系或者范式。
复杂性科学的核心理论包括涌现生成理论,复杂适应系统理论,遗传进化理论、自组织临界性理论、人工生命理论、复杂网络理论。
研究复杂性系统的基本方法应当是在唯物辩证法指导下的系统科学方法,定性与定量结合,微观与宏观结合,还原论与整体论结合,科学推理与哲学思辩结合。
复杂性科学简史
大道至简,简单是分析科学家的终极追求,世界的简单性信念是近代科学研究的重要传统和发展动力之一。生命是简单性范式的有力挑战,由于近代科学不能很好地解释生命世界中的秩序、目的性和精神等问题,一直存在活力论和还原论之争。生物有机体的整体属性并不等于各组成部分的属性之和,是一个开放系统,可以动态调整平衡。
相信宇宙是受自然法则支配的。
复杂性科学的兴起源于对机械论的反思,伴随系统运动的深入和延伸,是后现代思潮在科学层面上的反映(后现代主义追求的是非中心化、反逻辑性和无结构的东西)。复杂性科学建立在事实实验的基础上,例如蝴蝶效应、自组织临界性,元胞自动机、人工生命实验等。计算机是复杂性科学重要的技术基础和研究手段。
在复杂性科学的发展中——
系统是贝塔朗菲们的美好设想,一般系统论、信息论、控制论、运筹学、系统工程等是其代表。
演化是普利高津们的艰难探索,耗散结构理论是解决自组织出现的条件环境问题,协同学是解决自组织的动力学问题,突变论从数学抽象角度研究自组织的途径问题,超循环论解决了自组织的结合形式问题,分形与混沌从时空角度研究了自组织的复杂性和图景问题。
涌现是复杂性范式的初步形成,由过去的构成论变成了生成论。
那么,复杂性科学可以作为一种科学范式么?一种科学范式需要包括世界观、价值观、方法论、符号通式以及范例等内容。一种科学范式有内外标志,外在标志是存在机构,刊物等共同体,内在标志是通用语言、共同信念、共有价值和范例。
对比一下传统世界观与复杂性世界观——
经典科学的思维方式建立在“有序”“分割”和“理性”三大支柱上,集中表现为普遍性原则,可还原原则和可分离原则这三个原则。统一性和简单性是共同的理想。传统科学的缺陷:它们都是研究被动消极的对象,并把对象和环境完全隔离。
复杂性范式的思维方式认为世界的本质是复杂的,简单性不过是复杂性海洋中的孤独。把时间当作内在的一个参数,因此系统是演化的,是单向不可逆的,具有生成演化的过程。在有机自然观的前提下,以非线性特性为核心,由此推出复杂系统的整体性、自主性、关联性、涌现性和多样性等特征。
面对复杂系统,一般通过隐喻类比,符号通式是非线性模型和算法模型,算法模型是最常用的表达方式。
关于复杂性科学的方法论
科学的方法论最早是朴素的整体方法论,后分析还原方法论,而后是综合整体方法论。
关于还原论
所谓简单性问题,指一切可以用还原论方法解决的问题,已经得到系统、全面、透彻的研究,形成完全成熟的普适方法论和具体方法的体系。
还原论分为狭义和广义,进而分为本体论、方法论和理论还原论。
本体还原论:无演化性,可分解性,线性因果和叠加原理。
理论还原论指的是两个理论之间的关系,而所谓理论必须包括基本理论规律和特有的理论词项和观察词项,并已做了明确的表述和界定,具备可连通条件和可导出条件。
方法论还原论是一种旨在将复杂性分解为简单的组成部分以研究其本质与规律的认识复杂性的方法。通过认识部分到达认识整体,一种由里及表、由本质到现象的认识方法。
我们承认在本体论上的物理世界是可还原的,但未必允许认识论和方法论上的还原论。
复杂性科学要超越还原论,超越、扬弃不是绝对的否定和抛弃,而是经过它和超越它。
关于整体论
整体论是关于整体的理论或学说,是一种知识论,形式包括:机体论,能体论,系统整体论,生态整体论,全息整体论,纠结整体论,关系整体论,辩证整体论。
整体方法不对整体进行还原分解,不能从部分中推到。一般整体论从生物、生理、心理、历史等领域的范例入手,控制论把控制和通讯建立在整体论的基础上,耗散结构区分系统和环境的开放性,协同学强调子系统的相互作用。
什么是系统?系统就是由许多部分所组成的整体,
系统的概念就是要强调整体,强调整体是由相互关联、相互制约的各个部分组成的。——钱学森复杂性科学是对还原论的超越,不仅仅是对传统整体论的继承、发展,复兴,同样要超越整体论。
新的方法论——融贯论(syncretism)
整体也可能小于部分之和,在一个简化理性的世界很难设计出什么整体性。
综合集成方法的实质是把专家体系、数据与信息体系以及计算机体系有机结合起来,构成一个高度智能化的人、机结合系统。理论基础是思维科学,方法基础是系统科学与数学,技术基础是以计算机为主的现代信息技术,哲学基础是马克思主义的实践论和认识论。
综合微观分析的理论框架包含两种对系统行为的解释:宏观解释和微观解释。这相当于系统自组织理论中的中观方法。建立融贯思维,在纯粹分析思维和整体思维之间架起一座桥梁。
复杂性科学的方法论原则——
还原方法与整体方法相结合
微观分析与宏观综合相结合
定性判断与定量描述相结合
认识理解与实际行动相结合
科学推理与哲学思辨相结合
复杂性科学的研究方法
中国文化是基于隐喻的文化,而欧美文化是基于规则的文化。
隐喻
形而上学排除在科学之外, 一切语言都可能是隐喻性的。
隐喻是以一个观念迂回地表达另一个观念的方法,是产生诗人、圣人和神秘主义的方法。丰富的隐喻和类比,是创造性科学和诗歌的核心。隐喻是所有事物极度抽象的集合,是定义复杂性的重要途径。隐喻,类比和模型,引导揭开世界上许多复杂的谜团。
模型
模型是一个实验性的理想化的结构,被用来作为测试的设备。
模型像想象和运动一样普遍,是现代科学方法的核心。几个重要复杂性模型:
复杂适应系统的回声模型:适应性造就复杂性。
涌现理论中的生成模型:引入神经网络,建立具有可变结构的受限生成过程模型。
自组织临界性理论的沙堆模型:开放的、有多个自由度的、远离平衡态的动力学系统在临界态上运作,以阵发的、混沌的、类似雪崩的形式演化,并能够演化到一个稳定的自组织临界态。
人工生命研究中的人工生命模型:Tierra 模型
数值方法
计算机是数值方法的革命性工具,非线性是复杂性产生的根源之一。
“一生二,二生三,三生万物”——老子
关于混沌,周期三就蕴含着混沌, 出现三个周期,任何周期都可能出现。菲根鲍姆常数有两个,γ=4.669201609... ,α=2.502907875...,反映了混沌分岔的速度比例,规矩按照一定的规律走向混沌。
数值方法是混沌研究的重要方法之一,分形理论是理解非线性动力学的关键结构。
计算方法
什么是计算?
就是一组符号串的变换,从一个已知的符号开始,按照一定规则,经过有限步骤,最后得到一个满足预先规定的符号串,这种变换过程就是计算。
计算复杂性把数学问题分为可解、难解和不可解三类。
思维的本质可能是计算,一切思维可以看作符号形式操作的过程,世界是由算法控制的么?
虚拟方法
模拟的本质是把要模拟的过程的各部分与称作为例程的计算过程的各部分联系起来的一种映射。尤其是VR等技术的兴起,为使用虚拟方法来研究复杂性提供了另一个有力的手段。
至此,复杂性科学的研究方法一般包括以上的隐喻、模型、数值方法、计算方法和虚拟方法等。
读一本哲学博士的书不是一件轻松的事,有所得就不是光阴的浪费,在读了几本关于复杂性的书之后,似乎可以开始从复杂性的视角来审视一下微服务了。
关联阅读
-
复杂性思维第二版 一、复杂性科学
2017-10-27 21:44:26一、复杂性科学 原文:Chapter 1 Complexity Science 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 这本书的论点是,复杂性科学是一种“新型科学”,我借鉴自 Stephen Wolfram。2002年,Wolfram ...一、复杂性科学
原文:Chapter 1 Complexity Science
译者:飞龙
自豪地采用谷歌翻译
这本书的论点是,复杂性科学是一种“新型科学”,我借鉴自 Stephen Wolfram。
2002年,Wolfram 发表了 “新科学”一文,在这里介绍了他和其他人在细胞自动机上的工作,并描述了一种用于计算系统研究的科学方法。在之后的章节中,我们会回顾 Wolfram,但是现在我打算将他的标题用于更广泛的东西。
我认为复杂性是新的,不是因为它将科学工具应用到一个新的主题,而是因为它使用不同的工具,允许不同种类的工作,并最终改变了我们认为是“科学”的东西。
为了证明差异,我将从经典科学的一个例子开始:假设有人问你为什么行星轨道是椭圆形的。你可以引用万有引力的牛顿定律,并用它来写出描述行星运动的微分方程。然后,你可以求解微分方程,并展示出解是椭圆。证明完毕!
大多数人发现这种解释令人满意。它包括一个数学推导 - 所以它有一些严格的证明 - 它解释了具体的观察,椭圆轨道,通过诉诸一般的原则,引力。
让我用另一种解释来对比一下。假设你搬到像底特律这样种族隔离的城市,你想知道为什么这样。如果你做一些研究,你可能会发现 Thomas Schelling 的一篇文章,称为“分离动态模型”,它提出了一个简单的种族隔离模型:
这里是我对这个模型的描述:
城市的谢林模型是一个单元格数组,每个单元格代表一个房子。这些房子被两种“智能体”占据,标有红色和蓝色,数量大致相等。大约10%的房子是空的。
在任何时间点,智能体可能会高兴或不高兴,这取决于附近的其他智能体。在模型的一个版本中,如果智能体至少有两个邻居像自己一样,则智能体很高兴,如果邻居是一个或者零个,则智能体不高兴。
这个模拟通过随机选择一个智能体来运行,并检查它是否快乐。如果是的话,没有任何反应 如果不是,智能体随机选择一个未占用的单元格并移动。
如果你从一个完全未分离的模拟城市开始,并在短时间内运行该模型,类似的智能体会聚集到一起。随着时间的流逝,这些社区会增长和合并,直到存在少量的大型社区,大多数智能体都生活在均匀的社区中。
模型中的分离程度令人惊讶,这是真实城市的分离的解释。也许底特律是分离的,因为人们不喜欢人数太多,并且如果他们的社区的组成使他们不开心,将会搬走。
这个解释与行星运动的解释是一样的吗?许多人会说不是,但为什么?
最明显的是,谢林模型是非常抽象的,也就是说不现实的。我们很容易假设,人比行星更复杂,但是当你想想看,行星就像人一样复杂(特别是拥有人的行星)。
这两个系统都很复杂,而且这两个模型都是基于简化的;例如,在行星运动的模型中,我们包含了地球与太阳之间的力,并忽略行星之间的相互作用。
重要的区别是,对于行星运动,我们可以展示,我们忽略的力小于我们包含的力,来捍卫我们的模型。并且我们可以扩展模型,来包含其他相互作用,并显示这种效果很小。对于谢林模型,它难以合理简化。
更糟糕的是,谢林模型不符合任何物理规律,它只使用简单的计算,而不是数学推导。谢林模型不像经典科学,许多人发现它们不那么引人注目,至少一开始是这样。但是,我将尝试演示,这些模型做了大量的实用工作,包括预测,解释和设计。本书的目标之一是解释如何这样做。
1.1 范式转变
当我向人们介绍这本书时,别人经常问我,这种新型科学是不是一种范式转变。我不这么认为,并且这里是解释。
Thomas Kuhn 在 1962 年的“科学革命结构 ”中介绍了“范式转变”一词。它是指科学史上的一个过程,其中一个领域的基本假设改变,或者一个理论被另一个理论取代。他列举了哥白尼革命,燃烧的氧气模型取代了燃素说,以及相对论的出现。
复杂性科学的发展不是取代旧的模型,而是(在我看来)标准模型的逐渐转变,它们是各种种类的可接受的模型。
例如,经典模型倾向于以定律为基础,以方程式的形式表示,并通过数学推导求解。复杂性不足的模型通常是基于规则的,表示为计算,而不是由分析来模拟。
不是每个人都认为这些模型令人满意。例如,在 Sync 中,Steven Strogatz 写道了他的萤火虫自发同步模型。他展示了一个演示该现象的仿真,但是写道:
对于其它随机的初始条件和其他数量的振荡器,我重复模拟了几十次。每次都会同步 […] 现在的挑战是证明它。只有可靠的证明才能演示,同步是不可避免的,这种方式计算机都做不到;最好的证明就是澄清为什么它是不可避免的。
Strogatz 是一位数学家,所以他对证明的热情是可以理解的,但他的证明并不能解决这个现象中最有趣的部分。为了证明“同步是不可避免的”,Strogatz 做了几个简化的假设,特别是每个萤火虫可以看到所有其他的萤火虫。
在我看来,解释整个萤火虫族群为何可以同步,尽管事实上他们不能看到彼此,是更有趣的事情。这种全局行为,如何从局部交互中产生,是第(?)章的主题。这些现象的解释通常使用基于智能体的模型,它探索(以难以或不可能使用数学分析或的方式)允许或阻止同步的条件。
我是一名计算机科学家,所以我对计算模型的热情可能并不奇怪。我不是说 Strogatz 是错误的,而是人们对于提出什么问题,和用什么工具来回答他们,有不同的看法。这些意见基于价值判断,所以没有理由能够达成一致。
然而,科学家们对于哪些模型是好的科学,其他哪些是边缘科学,伪科学,或者是非科学,已经有了很大的共识。
我声称,这是本书的核心论点,即这种共识是基于时间变化的标准,复杂性科学的出现反映了这些标准的逐渐转变。
1.2 科学模型的轴线
我将经典模型描述为基于物理定律,以方程式表示,并通过数学分析求解的模型;相反,复杂系统的模型通常基于简单的规则并以计算实现。
我们可以将这一趋势看作是沿着两个轴线的转变:
基于方程式 → 基于 模拟
分析 → 计算
这种新的科学方式在其他几个方面是不同的。我在这里介绍他们,所以你知道即将会发生什么,但是在你看到本书后面的例子之前,有一些可能没有任何意义。
连续 → 离散
经典模型倾向于基于连续数学,如微积分;复杂系统的模型通常基于离散数学,包括图和细胞自动机。
线性 → 非线性
经典模型通常是线性的,或者使用非线性系统的线性近似; 复杂性科学对非线性模型更为友好。一个例子是混沌理论。
混沌理论在这本书中没有涉及,但是你可以在 http://en.wikipedia.org/wiki/Chaos 上阅读它。
确定性 → 随机
经典模型通常是确定性的,这可能反映了底层哲学的确定性,它在第(?)章中讨论。复杂模型往往具有随机性。
抽象 → 具体
在经典模型中,行星是质点,飞机是无摩擦的,牛是球形的(见 http://en.wikipedia.org/wiki/Spherical_cow)。像这样的简化通常对于分析是必要的,但是计算模型可能更加现实。
译者注:真空中的球形鸡
一,二 → 很多
在天体力学中,两体问题可以通过分析求解;而三体问题不能。经典模型通常限于少量相互作用的元素,复杂性科学作用于较大的复合体(这是名称的来源)。
单一 → 复合
在经典模型中,元素往往是可互换的;复杂模型更经常包含异质性。
这些是概括性的,所以我们不应该过于认真地对待它们。而我并不意味着弃用经典科学。更复杂的模型不一定更好;实际上通常更糟。
此外,我并不是说这些变化是突然的或完全的。相反,它们向着被认为是可接受的,值得尊重的工作的前沿逐渐迁移。过去被怀疑的工具现在很普遍,一些被广泛接受的模型现在受到审查。
例如,当 Appel 和 Haken 在 1976 年证明了四色定理时,他们使用电脑列举了 1,936 个特殊情况,在某种意义上说,这些特例是其证明的前提。当时很多数学家没有把这个定理当成真正的证明。现在计算机辅助证明是常见的,一般(但并非普遍)是可接受的。
相反,大量的经济分析基于人类行为的模型,称为“经济人”,或者一个有逼格的词:“Homo economicus”。基于这种模型的研究数十年间受到高度重视,特别是如果涉及到数学技巧的话。最近,这种模型受到怀疑,而包含不完整信息和有限理性的模型是热门话题。
1.3 一种新的的模型
复杂模型通常适用于不同的目的和解释:
预测 → 解释
谢林的分离模型可能揭示了一个复杂的社会现象,但对预测没有用。另一方面,一个简单的天体力学模型可以预测日食,在未来几年内可以精确到秒。
现实主义 → 工具主义
经典模型依赖于现实主义的解释;例如,大多数人接受电子是存在的真实事物。工具主义一种观点,即使他们假设的实体不存在,模型也可以有用。乔治·皮特写道:“所有模型都是错误的,但有些是有用的。”它可能是工具主义的座右铭。
简化论 → 整体论
简化论是一种观点,通过理解其组件来解释系统的行为。例如,元素的周期表是简化论的胜利,因为它用原子中的简单电子模型来解释元素的化学行为。整体论认为,系统层面出现的一些现象不存在于组件层面,不能在组件层面上解释。
我们在第(?)章会回到解释模型,第(?)章会回到工具主义,第(?)章会回到整体论。
1.4 一种新的工程
我一直在科学背景下谈论复杂系统,但复杂性也是工程中的变化和社会系统的组织的一个原因和影响:
中心化(集权) → 去中心化(放权)
中心化系统在概念上简单并易于分析,但去中心化系统可能更加强大。例如,万维网中的客户端向中心化服务器发送请求;如果服务器关闭,则这个服务不可用。在对等网络中,每个节点都是客户端和服务器。要取消服务,你必须删除每个 节点。
隔离 → 互动
在经典工程中,大型系统的复杂性通过隔离组件和最小化相互作用进行管理。这仍然是一个重要的工程原理;然而,廉价计算能力的普及,使得组件之间复杂交互的系统的设计变得越来越可行。
一对多 → 多对多
在许多通信系统中,广播服务正在由一些服务扩展,有时是替换。这些服务允许用户彼此通信,并创建,共享和修改内容。
自上而下 → 自下而上
在社会,政治和经济系统方面,许多通常是集中组织的活动现在都是草根运动。即使是分层结构的典范,军队,指挥和控制的也开始下放。
分析 → 计算
在经典工程中,可行的设计空间受到我们分析能力的限制。例如,设计艾菲尔铁塔成为了可能,因为 Gustave Eiffel 开发了新颖的分析技术,特别是用于处理风压负载。现在,用于计算机辅助设计和分析的工具,可以构建几乎可以想象的任何东西。弗兰克·盖里(Frank Gehry)的毕尔包古根汉美术馆(Guggenheim Museum Bilbao)是我最喜欢的例子。
设计 → 搜索
工程有时被描述为,在可行的设计空间中寻找解决方案。越来越多的搜索过程可以自动化。例如,遗传算法在大型设计空间中探索,并发现人类工程师不会想像(或喜欢)的解决方案。最终的遗传算法,演变,不可避免地生成违反人类工程规则的设计。
1.5 一种新的思维
我们现在正在深入一个领域,但是我所假设的,科学建模中的标准转变,有关 20 世纪中逻辑和认识论的发展。
亚里士多德逻辑 → 多值逻辑
在传统逻辑中,任何命题都是真或假。这个系统适用于类似数学的证明,但对于许多现实世界的应用而言是失败的(以一种戏剧化的方式)。替代方案包括多值逻辑,模糊逻辑和其他旨在处理不确定性(indeterminacy),模糊性和不确定性(uncertainty)的系统。Bart Kosko 在《模糊思维》(Fuzzy Thinking)中讨论了一些这种系统。
频率论的概率 → 贝叶斯主义
贝叶斯概率已经存在了几个世纪,但直到最近才被广泛使用,这是由于廉价计算能力变得可用,以及概率性声明中勉强接受了主观性。莎朗·贝尔奇·麦格雷恩(Sharon Bertsch McGrayne)在《不会死亡的理论》(The Theory That Would Not Die)中介绍了这一历史。
客观 → 主观
启蒙运动和现代主义哲学,建立在对客观真理的信仰上。也就是说,独立于持有他们的人的真理。20 世纪的发展,包括量子力学,哥德尔不完备定理和库恩的科学史研究,都引起了人们对“看似不可避免的主观性”的关注,甚至在“自然科学”和数学中。丽贝卡·戈德斯坦(Rebecca Goldstein)介绍了Gödel对不完备性的证明的历史背景。
物理定律 → 理论 → 模型
有些人区分了定律,理论和模型,但我认为这是一回事。使用“定律”的人很有可能认为,它在客观上是真实的,不可改变的;使用“理论”的人承认它可以修改;而“模型”承认它是基于简化和近似的。
一些被称为“物理定律”的概念是真正的定义;实际上,其他的只是模型的断言,它很好预测或解释了系统的行为。我们在第(?)章中会回到屋里定律的本质。
确定性 → 不确定性
确定性是一个观点,所有事件都是由之前事件导致,不可避免。不确定性的形式包括随机性,概率因果和基本不确定性。我们在第(?)章再回到这个主题。
这些趋势并不普遍或完整,但核心观点正沿着这些轴线转变。作为证据,考虑对托马斯·库恩(Thomas Kuhn)的《科学革命的结构》(The Structure of Scientific Revolutions)的反应 ,公布后受到谴责,现在被认为几乎毫无争议。
这些趋势是复杂性科学的因和果。例如,高度抽象的模型现在更容易接受,因为人们预期,每个系统都应该有一个独特的,正确的模型。相反,复杂系统的发展挑战了确定性,和物理定律的相关概念。
本章概述了本书中出现的主题,但在看到示例之前,并不是全部都是有意义的。当你读到本书的最后,你可能会发现,再次阅读本章会有帮助。
-
复杂系统研究方法的讨论 (2009年)
2021-05-18 01:20:25复杂系统是复杂性科学的研究对象,因 此对研究复杂系统的方法进行总结和归纳是充满挑战且极具意义的。通过讨论,归纳出了自下而上的“涌现”方法和 自上而下的“控制”方法这两条研究路线,其中包含了隐喻、模型、数值... -
降低软件复杂性的一般原则和方法
2019-09-24 10:37:31一、前言 斯坦福教授、Tcl语言发明者John Ousterhout 的著作《A Philosophy of Software Design》[1],自出版以来,好评...而冠名为“哲学",则是一些通用的原则和方法论,这些原则方法论串起来,能够形成一个体系。...一、前言
斯坦福教授、Tcl语言发明者John Ousterhout 的著作《A Philosophy of Software Design》[1],自出版以来,好评如潮。按照IT图书出版的惯例,如果冠名为“实践”,书中内容关注的是某项技术的细节和技巧;冠名为“艺术”,内容可能是记录一件优秀作品的设计过程和经验;而冠名为“哲学",则是一些通用的原则和方法论,这些原则方法论串起来,能够形成一个体系。正如”知行合一”、“世界是由原子构成的”、“我思故我在”,这些耳熟能详的句子能够一定程度上代表背后的人物和思想。用一句话概括《A Philosophy of Software Design》,软件设计的核心在于降低复杂性。
本篇文章是围绕着“降低复杂性”这个主题展开的,很多重要的结论来源于John Ousterhout,笔者觉得很有共鸣,就做了一些相关话题的延伸、补充了一些实例。虽说是"一般原则“,也不意味着是绝对的真理,整理出来,只是为了引发大家对软件设计的思考。
二、如何定义复杂性
关于复杂性,尚无统一的定义,从不同的角度可以给出不同的答案。可以用数量来度量,比如芯片集成的电子器件越多越复杂(不一定对);按层次性[2]度量,复杂度在于层次的递归性和不可分解性。在信息论中,使用熵来度量信息的不确定性。
John Ousterhout选择从认知的负担和开发工作量的角度来定义软件的复杂性,并且给出了一个复杂度量公式:
子模块的复杂度cp乘以该模块对应的开发时间权重值tp,累加后得到系统的整体复杂度C。系统整体的复杂度并不简单等于所有子模块复杂度的累加,还要考虑该模块的开发维护所花费的时间在整体中的占比(对应权重值tp)。也就是说,即使某个模块非常复杂,如果很少使用或修改,也不会对系统的整体复杂度造成大的影响。
子模块的复杂度cp是一个经验值,它关注几个现象:
- 修改扩散,修改时有连锁反应。
- 认知负担,开发人员需要多长时间来理解功能模块。
- 不可知(Unknown Unknowns),开发人员在接到任务时,不知道从哪里入手。
造成复杂的原因一般是代码依赖和晦涩(Obscurity)。其中,依赖是指某部分代码不能被独立地修改和理解,必定会牵涉到其他代码。代码晦涩,是指从代码中难以找到重要信息。
三、解决复杂性的一般原则
首先,互联网行业的软件系统,很难一开始就做出完美的设计,通过一个个功能模块衍生迭代,系统才会逐步成型;对于现存的系统,也很难通过一个大动作,一劳永逸地解决所有问题。系统设计是需要持续投入的工作,通过细节的积累,最终得到一个完善的系统。因此,好的设计是日拱一卒的结果,在日常工作中要重视设计和细节的改进。
其次,专业化分工和代码复用促成了软件生产率的提升。比如硬件工程师、软件工程师(底层、应用、不同编程语言)可以在无需了解对方技术背景的情况下进行合作开发;同一领域服务可以支撑不同的上层应用逻辑等等。其背后的思想,无非是通过将系统分成若干个水平层、明确每一层的角色和分工,来降低单个层次的复杂性。同时,每个层次只要给相邻层提供一致的接口,可以用不同的方法实现,这就为软件重用提供了支持。分层是解决复杂性问题的重要原则。
第三,与分层类似,分模块是从垂直方向来分解系统。分模块最常见的应用场景,是如今广泛流行的微服务。分模块降低了单模块的复杂性,但是也会引入新的复杂性,例如模块与模块的交互,后面的章节会讨论这个问题。这里,我们将第三个原则确定为分模块。
最后,代码能够描述程序的工作流程和结果,却很难描述开发人员的思路,而注释和文档可以。此外,通过注释和文档,开发人员在不阅读实现代码的情况下,就可以理解程序的功能,注释间接促成了代码抽象。好的注释能够帮助解决软件复杂性问题,尤其是认知负担和不可知问题(Unknown Unknowns)。
四、解决复杂性之日拱一卒
4.1 拒绝战术编程
战术编程致力于完成任务,新增加特性或者修改Bug时,能解决问题就好。这种工作方式,会逐渐增加系统的复杂性。如果系统复杂到难以维护时,再去重构会花费大量的时间,很可能会影响新功能的迭代。
战略编程,是指重视设计并愿意投入时间,短时间内可能会降低工作效率,但是长期看,会增加系统的可维护性和迭代效率。
设计系统时,很难在开始阶段就面面俱到。好的设计应该体现在一个个小的模块上,修改bug时,也应该抱着设计新系统的心态,完工后让人感觉不到“修补”的痕迹。经过累积,最终形成一个完善的系统。从长期看,对于中大型的系统,将日常开发时间的10-15%用于设计是值得的。有一种观点认为,创业公司需要追求业务迭代速度和节省成本,可以容忍糟糕的设计,这是用错误的方法去追求正确的目标。降低开发成本最有效的方式是雇佣优秀的工程师,而不是在设计上做妥协。
4.2 设计两次
为一个类、模块或者系统的设计提供两套或更多方案,有利于我们找到最佳设计。以我们日常的技术方案设计为例,技术方案本质上需要回答两个问题,其一,为什么该方案可行? 其二,在已有资源限制下,为什么该方案是最优的?为了回答第一个问题,我们需要在技术方案里补充架构图、接口设计和时间人力估算。而要回答第二个问题,需要我们在关键点或争议处提供二到三种方案,并给出建议方案,这样才有说服力。通常情况下,我们会花费很多的时间准备第一个问题,而忽略第二个问题。其实,回答好第二个问题很重要,大型软件的设计已经复杂到没人能够一次就想到最佳方案,一个仅仅“可行”的方案,可能会给系统增加额外的复杂性。对聪明人来说,接受这点更困难,因为他们习惯于“一次搞定问题”。但是聪明人迟早也会碰到自己的瓶颈,在低水平问题上徘徊,不如花费更多时间思考,去解决真正有挑战性的问题。
五、解决复杂性之分层
5.1 层次和抽象
软件系统由不同的层次组成,层次之间通过接口来交互。在严格分层的系统里,内部的层只对相邻的层次可见,这样就可以将一个复杂问题分解成增量步骤序列。由于每一层最多影响两层,也给维护带来了很大的便利。分层系统最有名的实例是TCP/IP网络模型。
在分层系统里,每一层应该具有不同的抽象。TCP/IP模型中,应用层的抽象是用户接口和交互;传输层的抽象是端口和应用之间的数据传输;网络层的抽象是基于IP的寻址和数据传输;链路层的抽象是适配和虚拟硬件设备。如果不同的层具有相同的抽象,可能存在层次边界不清晰的问题。
5.2 复杂性下沉
不应该让用户直面系统的复杂性,即便有额外的工作量,开发人员也应当尽量让用户使用更简单。如果一定要在某个层次处理复杂性,这个层次越低越好。举个例子,Thrift接口调用时,数据传输失败需要引入自动重试机制,重试的策略显然在Thrift内部封装更合适,开放给用户(下游开发人员)会增加额外的使用负担。与之类似的是系统里随处可见的配置参数(通常写在XML文件里),在编程中应当尽量避免这种情况,用户(下游开发人员)一般很难决定哪个参数是最优的,如果一定要开放参数配置,最好给定一个默认值。
复杂性下沉,并不是说把所有功能下移到一个层次,过犹不及。如果复杂性跟下层的功能相关,或者下移后,能大大下降其他层次或整体的复杂性,则下移。
5.3 异常处理
异常和错误处理是造成软件复杂的罪魁祸首之一。有些开发人员错误的认为处理和上报的错误越多越好,这会导致过度防御性的编程。如果开发人员捕获了异常并不知道如何处理,直接往上层扔,这就违背了封装原则。
降低复杂度的一个原则就是尽可能减少需要处理异常的可能性。而最佳实践就是确保错误终结,例如删除一个并不存在的文件,与其上报文件不存在的异常,不如什么都不做。确保文件不存在就好了,上层逻辑不但不会被影响,还会因为不需要处理额外的异常而变得简单。
六、解决复杂性之分模块
分模块是解决复杂性的重要方法。理想情况下,模块之间应该是相互隔离的,开发人员面对具体的任务,只需要接触和了解整个系统的一小部分,而无需了解或改动其他模块。
6.1 深模块和浅模块
深模块(Deep Module)指的是拥有强大功能和简单接口的模块。深模块是抽象的最佳实践,通过排除模块内部不重要的信息,让用户更容易理解和使用。
Unix操作系统文件I/O是典型的深模块,以Open函数为例,接口接受文件名为参数,返回文件描述符。但是这个接口的背后,是几百行的实现代码,用来处理文件存储、权限控制、并发控制、存储介质等等,这些对用户是不可见的。
int open(const char* path, int flags, mode_t permissions);
与深模块相对的是浅模块(Shallow Module),功能简单,接口复杂。通常情况下,浅模块无助于解决复杂性。因为他们提供的收益(功能)被学习和使用成本抵消了。以Java I/O为例,从I/O中读取对象时,需要同时创建三个对象FileInputStream、BufferedInputStream、ObjectInputStream,其中前两个创建后不会被直接使用,这就给开发人员造成了额外的负担。默认情况下,开发人员无需感知到BufferedInputStream,缓冲功能有助于改善文件I/O性能,是个很有用的特性,可以合并到文件I/O对象里。假如我们想放弃缓冲功能,文件I/O也可以设计成提供对应的定制选项。
FileInputStream fileStream = new FileInputStream(fileName); BufferedInputStream bufferedStream = new BufferedInputStream(fileStream); ObjectInputStream objectStream = new ObjectInputStream(bufferedStream);
关于浅模块有一些争议,大多数情况是因为浅模块是不得不接受的既定事实,而不见得是因为合理性。当然也有例外,比如领域驱动设计里的防腐层,系统在与外部系统对接时,会单独建立一个服务或模块去适配,用来保证原有系统技术栈的统一和稳定性。
6.2 通用和专用
设计新模块时,应该设计成通用模块还是专用模块?一种观点认为通用模块满足多种场景,在未来遇到预期外的需求时,可以节省时间。另外一种观点则认为,未来的需求很难预测,没必要引入用不到的特性,专用模块可以快速满足当前的需求,等有后续需求时再重构成通用的模块也不迟。
以上两种思路都有道理,实际操作的时候可以采用两种方式各自的优点,即在功能实现上满足当前的需求,便于快速实现;接口设计通用化,为未来留下余量。举个例子。
void backspace(Cursor cursor); void delete(Cursor cursor); void deleteSelection(Selection selection); //以上三个函数可以合并为一个更通用的函数 void delete(Position start, Position end);
设计通用性接口需要权衡,既要满足当前的需求,同时在通用性方面不要过度设计。一些可供参考的标准:
- 满足当前需求最简单的接口是什么?在不减少功能的前提下,减少方法的数量,意味着接口的通用性提升了。
- 接口使用的场景有多少?如果接口只有一个特定的场景,可以将多个这样的接口合并成通用接口。
- 满足当前需求情况下,接口的易用性?如果接口很难使用,意味着我们可能过度设计了,需要拆分。
6.3 信息隐藏
信息隐藏是指,程序的设计思路以及内部逻辑应当包含在模块内部,对其他模块不可见。如果一个模块隐藏了很多信息,说明这个模块在提供很多功能的同时又简化了接口,符合前面提到的深模块理念。软件设计领域有个技巧,定义一个"大"类有助于实现信息隐藏。这里的“大”类指的是,如果要实现某功能,将该功能相关的信息都封装进一个类里面。
信息隐藏在降低复杂性方面主要有两个作用:一是简化模块接口,将模块功能以更简单、更抽象的方式表现出来,降低开发人员的认知负担;二是减少模块间的依赖,使得系统迭代更轻量。举个例子,如何从B+树中存取信息是一些数据库索引的核心功能,但是数据库开发人员将这些信息隐藏了起来,同时提供简单的对外交互接口,也就是SQL脚本,使得产品和运营同学也能很快地上手。并且,因为有足够的抽象,数据库可以在保持外部兼容的情况下,将索引切换到散列或其他数据结构。
与信息隐藏相对的是信息暴露,表现为:设计决策体现在多个模块,造成不同模块间的依赖。举个例子,两个类能处理同类型的文件。这种情况下,可以合并这两个类,或者提炼出一个新类(参考《重构》[3]一书)。工程师应当尽量减少外部模块需要的信息量。
6.4 拆分和合并
两个功能,应该放在一起还是分开?“不管黑猫白猫”,能降低复杂性就好。这里有一些可以借鉴的设计思路:
- 共享信息的模块应当合并,比如两个模块都依赖某个配置项。
- 可以简化接口时合并,这样可以避免客户同时调用多个模块来完成某个功能。
- 可以消除重复时合并,比如抽离重复的代码到一个单独的方法中。
- 通用代码和专用代码分离,如果模块的部分功能可以通用,建议和专用部分分离。举个例子,在实际的系统设计中,我们会将专用模块放在上层,通用模块放在下层以供复用。
七、解决复杂性之注释
注释可以记录开发人员的设计思路和程序功能,降低开发人员的认知负担和解决不可知(Unkown Unkowns)问题,让代码更容易维护。通常情况下,在程序的整个生命周期里,编码只占了少部分,大量时间花在了后续的维护上。有经验的工程师懂得这个道理,通常也会产出更高质量的注释和文档。
注释也可以作为系统设计的工具,如果只需要简单的注释就可以描述模块的设计思路和功能,说明这个模块的设计是良好的。另一方面,如果模块很难注释,说明模块没有好的抽象。
7.1 注释的误区
关于注释,很多开发者存在一些认识上的误区,也是造成大家不愿意写注释的原因。比如“好代码是自注释的"、"没有时间“、“现有的注释都没有用,为什么还要浪费时间”等等。这些观点是站不住脚的。“好代码是自注释的”只在某些场景下是合理的,比如为变量和方法选择合适的名称,可以不用单独注释。但是更多的情况,代码很难体现开发人员的设计思路。此外,如果用户只能通过读代码来理解模块的使用,说明代码里没有抽象。好的注释可以极大地提升系统的可维护性,获取长期的效率,不存在“没有时间”一说。注释也是一种可以习得的技能,一旦习得,就可以在后续的工作中应用,这就解决了“注释没有用”的问题。
7.2 使用注释提升系统可维护性
注释应当能提供代码之外额外的信息,重视What和Why,而不是代码是如何实现的(How),最好不要简单地使用代码中出现过的单词。
根据抽象程度,注释可以分为低层注释和高层注释,低层次的注释用来增加精确度,补充完善程序的信息,比如变量的单位、控制条件的边界、值是否允许为空、是否需要释放资源等。高层次注释抛弃细节,只从整体上帮助读者理解代码的功能和结构。这种类型的注释更好维护,如果代码修改不影响整体的功能,注释就无需更新。在实际工作中,需要兼顾细节和抽象。低层注释拆散与对应的实现代码放在一起,高层注释一般用于描述接口。
注释先行,注释应该作为设计过程的一部分,写注释最好的时机是在开发的开始环节,这不仅会产生更好的文档,也会帮助产生好的设计,同时减少写文档带来的痛苦。开发人员推迟写注释的理由通常是:代码还在修改中,提前写注释到时候还得再改一遍。这样的话就会衍生两个问题:
- 首先,推迟注释通常意味着根本就没有注释。一旦决定推迟,很容易引发连锁反应,等到代码稳定后,也不会有注释这回事。这时候再想添加注释,就得专门抽出时间,客观条件可能不会允许这么做。
- 其次,就算我们足够自律抽出专门时间去写注释,注释的质量也不会很好。我们潜意识中觉得代码已经写完了,急于开展下一个项目,只是象征性地添加一些注释,无法准确复现当时的设计思路。
避免重复的注释。如果有重复注释,开发人员很难找到所有的注释去更新。解决方法是,可以找到醒目的地方存放注释文档,然后在代码处注明去查阅对应文档的地址。如果程序已经在外部文档中注释过了,不要在程序内部再注释了,添加注释的引用就可以了。
注释属于代码,而不是提交记录。一种错误的做法是将功能注释放在提交记录里,而不是放在对应代码文件里。因为开发人员通常不会去代码提交记录里去查看程序的功能描述,很不方便。
7.3 使用注释改善系统设计
良好的设计基础是提供好的抽象,在开始编码前编写注释,可以帮助我们提炼模块的核心要素:模块或对象中最重要的功能和属性。这个过程促进我们去思考,而不是简单地堆砌代码。另一方面,注释也能够帮助我们检查自己的模块设计是否合理,正如前文中提到,深模块提供简单的接口和强大的功能,如果接口注释冗长复杂,通常意味着接口也很复杂;注释简单,意味着接口也很简单。在设计的早期注意和解决这些问题,会为我们带来长期的收益。
八、后记
John Ousterhout累计写过25万行代码,是3个操作系统的重要贡献者,这些原则可以视为作者编程经验的总结。有经验的工程师看到这些观点会有共鸣,一些著作如《代码大全》、《领域驱动设计》也会有类似的观点。本文中提到的原则和方法具有一定实操和指导价值,对于很难有定论的问题,也可以在实践中去探索。
关于原则和方法论,既不必刻意拔高,也不要嗤之以鼻。指导实践的不是更多的实践,而是实践后的总结和思考。应用原则和方法论实质是借鉴已有的经验,可以减少我们自行摸索的时间。探索新的方法可以帮助我们适应新的场景,但是新方法本身需要经过时间检验。
九、参考文档
-
John Ousterhout. A Philosophy of Software Design. Yaknyam Press, 2018.
-
梅拉尼·米歇尔. 复杂. 湖南科学技术出版社, 2016.
-
Martin Fowler. Refactoring: Improving the Design of Existing Code (2nd Edition) . Addison-Wesley Signature Series, 2018.
作者介绍
政华,顺谱,陶鑫,美团打车调度系统工程团队工程师。
招聘信息
美团打车调度系统工程团队诚招高级工程师/技术专家,我们的目标,是与算法、数据团队密切协作,建设高性能、高可用、可配置的打车调度引擎, 为用户提供更好的出行体验。欢迎有兴趣的同学加入呦~~
-
复杂性研究面临的难题
2018-01-02 00:00:00一、什么是复杂性目前无法表述清楚 在汉语中“复杂”一词的意思为“事物的种类、头绪等多而杂”。在《朗文当代英语词典》中,形容词complex被解释为:(1)难于理解、解释或处理,不清楚或不简单; (2)由许多密切... -
计算复杂性综述
2019-05-15 15:50:10计算复杂性 目录 文章目录计算复杂性前言正文一、计算复杂性理论基本问题(一)时间复杂度(二)Cook-Karp论题(三)Church论题二、判定问题类(一)P问题(Polynomial Problem)(二)NP问题(Non-deterministic ... -
计算复杂性理论
2019-06-09 00:24:03计算复杂性理论(Computational complexity theory)被认为是理论计算机科学和数学的一个分支。 对于计算机而言,任何一个问题的求解都需要资源(即使是最简单的1+1的问题)。计算复杂性理论通过引入数学计算模型来... -
常见复杂网络分析方法
2019-09-18 15:38:07常见的复杂网络分析方法基本分析方法关联分析方法 注:本文部分内容来自《复杂网络分析与应用》与《中国航空复杂网络的结构特征与应用分析》 1.赵正旭,郭阳,等.复杂网络分析与应用[M]北京:科学出版社,2018. 2.陈... -
战争科学论——认识和理解战争的科学基础和思维方法
2018-03-16 00:00:00全书共7章,分别介绍什么是战争研究的科学基础,复杂系统与复杂性科学思想,复杂性研究在复杂网络、大数据及深度学习方面的新进展,信息化战争的科学思维方法,复杂性科学思想与战争研究,从科学思维到科学方法,... -
可计算性理论与复杂性介绍
2019-01-26 20:15:37前言 原文:An Introduction to ...计算科学可以追溯到在这些现代计算机设备还没有被想象出来之前很长一段时间。在一个更经常被问到的问题中,围绕着编程语言、框架和库的问题,我们常常想当然地认为,计算机的基本... -
常用数据科学方法总结梳理笔记
2019-05-10 16:27:06常用数据科学方法 【未经允许,不得转载】 ... -
解决问题的科学方法
2018-06-10 23:11:05解决问题的科学方法本人思考和总结的一些解决问题的方法和流程。欢迎补充和批评,以及添加一些材料。 一,明确定义,问题是什么出现了问题,往往忽略了这一步,没有仔细思考问题到底是什么,问题本质是什么。这有助... -
【复杂网络】网络科学导论学习笔记
2020-09-03 21:12:321.当今社会越来越多的现象会涉及复杂网络相关应用 举例:社交网络、搜索引擎 2.Internet的拓扑结构 原因:为预测和提高Internet的性能,特此引入Internet的拓扑结构 具体形式:(1)IP层次 (2)路由器层次 (3)... -
软件开发复杂性的解决方法(二)
2013-06-19 10:50:28利用面向对象(object-oricnted,OO)技术可以充分体现分解、抽象、模块化、信息隐蔽等思想,可以很有效地提高软件生产率、缩短软件开发时间、提高软件质量,是控制软件复杂性的有效途径。 6.面向对象的... -
复杂性思维中文第二版 十一、进化
2018-04-14 12:17:02生物学乃至整个科学最重要的思想,是通过自然选择的进化论,它声称由于自然选择而创造出新的物种并改变现有的物种。自然选择是个体间遗传差异导致生存和繁殖差异的过程。 在了解生物学的人中,进化论被广泛认为是一... -
AI+科学计算-昇思MindSpore都给我们带来哪些惊喜?
2022-03-31 17:56:46AI框架之力初显:它山之石,可以攻玉 传统科学计算方法通过数值迭代的方式解决问题,面临着维度灾难引起的计算量指数上升的问题,导致在复杂问题或者场景中“算不起”,甚至是“算不动”。而科学计算的诸多领域仍然... -
Kolmogorov复杂性 简介
2014-03-25 11:02:57信息距离是基于Kolmogorov复杂性定义的,是衡量事物本质联系的一种通用性度量。与其它度量方法相比,信息距离具有普适性、领域无关性和参数无关性等性质,因此它可以用来处理结构化、非结构化、甚至难以理解的对象和... -
复杂性思维中文第二版 六、生命游戏
2018-04-09 20:59:22六、生命游戏 原文:Chapter 6 Game of Life 译者:飞龙 协议:CC BY-NC-SA 4.0... 像上一章中的一些 CA 一样,GoL 遵循简单的规则并产生令人惊讶的复杂行为。 就像沃尔夫勒姆的规则 110 一样,事实证明 Go... -
科学研究设计六:有效性威胁
2017-11-18 08:46:51内部有效性和外部有效性 -
复杂性思维中文第二版 五、细胞自动机
2018-04-07 23:38:17几乎所有不明显的简单过程,都可以看作是具有复杂性相同的计算。 更具体来说,计算等价性原理表明,在自然界中发现的系统可以执行达到最高(“通用”)级别的计算能力的计算,并且大多数系统实际上实现了这种最高... -
复杂网络节点重要性算法之局部中心性
2019-07-05 10:11:24为了权衡算法的效率和效果, Chen 等人提出了一种基于半局部信息的节点重要性排序方法,简称半局部中心性(semi-local centrality). 首先定义N(w)为节点Vw的两层邻居度,其值等于从 Vw出发 2步内可到达的邻居的数目, ... -
数据科学研究的现状与趋势全解
2019-11-27 17:29:10大数据时代的到来催生了一门新的学科——数据科学。首先,本文探讨了数据科学的内涵、发展简史、学科地位及知识体系等基本问题,并提出了专业数据科学与专业中的数据科学之间的区别与联系;其次,分析现阶段数据科学... -
数据科学猫:数据分析的主要类型、描述性分析、预测性分析与规范性分析
2021-04-21 13:19:52也欢迎大家搜索微信公众号“进击的橘子猫”,我也会定期分享数据科学、Python、大数据、项目管理与PPT的相关知识。 让我们进击起来吧! 简介 本篇介绍三大数据分析的方法,以及机器学习在这三种方法中的定位... -
复杂性思维中文第二版 九、基于智能体的模型
2018-04-12 11:36:57自 20 世纪 70 年代以来,基于智能体的模型已成为经济学和其他社会科学,以及一些自然科学中的重要工具。 基于智能体的模型对非均衡系统的动态建模(尽管它们也用于研究均衡系统)非常有用。 它们对于理解个人... -