精华内容
下载资源
问答
  • 系统方法——复杂问题的解决方案

    千次阅读 2013-10-05 02:43:02
    传统的解决问题的方法,是将一个复杂问题分解为多个...对于大部分复杂系统来说,系统具有整体性和层次性,必须要用系统的方法来解决问题。后面可以看到,系统方法是统一各学科的唯一方法,也是探索生命与智慧的基础。

    系统方法——复杂问题的解决方案

    前言:

           传统的解决问题的方法,是将一个复杂问题分解为多个简单问题,逐个分析并解决简单问题来达到解决复杂问题的目的。例如:生物分解为组织,组织分解为分子,分子分解为原子。传统方法学认为:任何复杂的事物都可以分解为多个简单的事物加以处理。这在一定程度上是正确的,它取决于两个条件。第一,各个部分之间的相互作用是不存在的,或者对于研究目的来说可以忽略不计。只有在这个条件下,部分才能从系统这个整体中被分出来,然后再被装配起来。第二个条件是,描述各个部分行为的关系是线性的,只有这样,累加性的条件才能成立,也就是,描述系统整体的行为方式与各部分行为方式具有同一种形式。部分可以叠加得到整体,等等。对于大部分复杂系统来说,系统具有整体性和层次性,必须要用系统的方法来解决问题。后面可以看到,系统方法是统一各学科的唯一方法,也是探索生命与智慧的基础。

     

    研究系统方法的目的

           系统方法来解决问题,一般而言,有三个目的:分析,设计和诊断。系统分析表示分析一个存在的未知系统的功能。既然存在,又为什么说未知呢?未知表示我们还不知道这个系统的功能,这个系统就像一个黑盒子,我们需要分析来了解它的功能,。系统设计表示我们已经知道了一个系统的主要功能或者全部功能,我们需要设计并实现它。诊断表示一个系统出现功能错误:没有功能或者功能并不是需求的。

     

     

    系统的特性

    1.      系统的组成,层次性

    系统是元素和元素之间的关系组成的一个整体。元素也可以是系统。这就表示,系统具有层次性的。元素之间的关系是构成系统的关键。没有关系,多个元素在一起不能构成系统。这可以看出,整体大于部分之和。例如一栋建筑和等量的建筑材料相比,从系统论的观点来看,这栋建筑比这些建筑材料多了“居住”的功能,这个多出来的功能,是因为构成建筑的各个元素(建筑材料)之间有了关系,不论是这个关系是物理还是化学关系还是其他关系。

    2.      系统的开放性与功能性

    这里讨论的系统都是开放性的,开放性是指,要研究的系统拥有功能性,因此可以与其他系统有交互关系。封闭的或者说没有功能的系统是没有意义的,功能性是系统可以构成元素的基础。因为构成系统的元素之间是有关系的,在系统中一个与其他元素没有任何关系的元素,完全可以从系统中移除,以减少系统的复杂度。所以系统具有开发性。例如城市系统中的一栋房子,具有“居住”的功能;一个导弹系统中的雷达具有搜索定位功能,导弹具有飞行与爆炸功能。等等。

    系统方法——统一各个学科之间的解决问题的方法

           很多年前,工程师Bode、社会学家Mosteller、数学家Tukey和生物学家Winsor等人发表了题为“科学通才教育”的论文。作者们强调:“需要一种比较简单的、比较统一的解决科学问题的方法。”他们写道:“我们经常听到这样的议论:一个人再也对付不了宽广的领域,专业太窄了……。我们需要一种比较简单的、比较统一的解决科学问题的方法。我们需要实行科学(不是一门特殊科学)的人,总而言之,我们需要科学通才。”然后,作者们说明了在物理化学、生物物理学这样一类领域里以及把物理学、化学和数学用于医学中需要通才的情况和原因。作者们指出:“任何一个研究团体都需要通才,无论它是一个大学里设立的研究小组还是一个基金会、或是一个工业团体的研究机构……。在一个工程技术团体里,通才能够很自然的关系系统问题,每当把部分纳入平衡的整体,就发生这样的问题。(Bode等人,1949)

           我国杰出科学家钱学森对系统理论与系统科学的创立有独特贡献。他最早提出,从马克思主义哲学到系统学的桥梁,可以称作“系统观”或“系统论”。

          基本上,任何一门学科深入研究下去,都会发现一个共同的东西,那就是系统。在软件领域,经常在论坛上看到有人讨论“我是精通一个方面好还是熟悉多个方面好?”这种问题。许多人可能都有这种疑问,因为要学的东西太多,在知识爆炸的年代,没有一个人可以把所有方面都精通。俗话说,授人以鱼不如授人以渔,系统方法就是渔。而现实却恰好相反。许多人学习了很多知识,却不知道怎么使用。就像一个程序员学习了一门编程语言,还是不会制作任何软件;或者一名医学员学完了医学的知识让他去诊断病人确不知道从何入手一样。原因就是没有将研究目标系统化。对于以系统方法解决问题的人来说,知识只是工具,系统方法才是的解决方案。找程序bug的过程和医生诊断疾病的过程及其相似:首先,根据程序表象推断错误原因,再找出错误位置加以修复。医生诊断疾病也同样,首先根据病人的表象,推断原因,定位病变位置,再对症下药。如何快速的推断出bug原因和位置,这就需要了解程序系统内部结构。医生诊断病情也是如此,需要了解人体系统结构和功能。只不过这两者解决的问题不同,所需要的知识域不同,但是解决问题的方法是相同的。

           知识可以帮助人更快速的找出问题的解决方案:例如一个人了解了很多建筑学的知识,那么他就很容易的使用它的知识来设计建筑(系统设计);一个了解医学的人,可以很容易的使用它的知识来诊断与治疗疾病(系统诊断)。一个了解计算机的人,可以很容易的使用它的知识来开发软件(系统分析,设计,诊断)。拥有很多知识可以让一个人更快速的找出与他的知识相关的问题的解决方案。没有与问题相关的知识或者知识不足,并不是说就不能解决问题了,只是时间的问题罢了。当一个问题所需的知识不能够满足的时候,基本上都需要查找资料。对于“我是精通一个方面好还是熟悉多个方面好?”这种问题的答案,现在已经很清楚了——如果你决定要往某个方面发展,并且你将要面对的问题是这个方面的,那么精通它。再配合系统方法,得以快速解决问题。

    看来没有必要再做说明了。物理学、生物学或社会科学的传统教育都是把他们作为独立里的领域来处理,普遍地趋向于愈来愈小的子领域成为独立的学科,这个过程一再重复,到了每门专业成为举足轻重的、支离破碎的子领域的程度。与此相反,从系统方法出发,到底要学习什么,是根据问题来的,知识只是解决问题的工具,而系统方法是解决方案。一个人的精力毕竟有限,能根据问题快速找到解决方案才是要点所在,你需要学会你要面对问题的所有知识域。知识可以帮助你快速的整理出系统内部关系,从而找到解决方案。

    系统与生命以及智慧

    我极力避免在谈论系统方法的时候将它与生命系统放在一起。这通常会导致极为混乱和矛盾的事情。因为人们到现在依然没能认清生命的奥秘。一个物体从无机物变为有机物之后,一切都不同了并且变得难以解释。

           无生命界与有生命界的一个明显不同是凯尔文勋爵的退化论与达尔文的进化论之间,物理学的耗散定律与生物学进化规律之间的尖锐对立。按照热力学第二定律,在物理性质的事件中普遍趋向最无序的状态而使差别拉平,宇宙随之达到所谓的最终的热寂状态。那时所有能量递降为低温下均匀分布的热,世界的进程就会停止。与此相反,生命世界显示出:在胚胎发育和生物进化中,它是向更高级的有序状态、不均匀状态和有组织状态过渡。这就是生命系统与非生命系统的区别——生命系统是自我进化到有序的,而非生命系统总是趋于混乱。

        如果说要让一个非生命系统有序,必须要人为的修改系统,使之毁坏重建以达到有序状态。在非生命系统的生命周期内,总是要不断的进行维护升级,以让系统保持活力。如果说在这段时间内它是有生命的,那么也是人赋予的。

        智慧特性是生命系统的又一大特征,也许这就是人类永远也做不到真正的人工智能的原因吧。因为它是非生命系统,如果产生了意识,那就成了生命系统。一个人能够创造出生命,天理不容。

        系统方法能够统一多个学科,但是很难统一生命系统。但是可以说,非生命系统是生命系统的一个子集,生命系统包含了非生命系统的一切特性,对于生命系统,仍然可以用系统的方法去研究它。

    系统方法的未来以及发展

           系统方法应该成为一种普遍的方法。生命系统对人们理解生命以及智慧的奥秘将有所帮助。

    参考:《一般系统论》《系统科学哲学》

     

    展开全文
  • 复杂系统与复杂网络

    千次阅读 2009-11-02 17:57:00
    复杂系统与复杂网络 20世纪90年代以来,以Internet为代表的信息技术的迅猛发展使人类社会大步迈入了网络时代。从Internet到WWW,从大型电力网络到全球交通网络,从大脑神经网络到各种新陈代谢网络,从科研合作网络到...

    复杂系统与复杂网络                          

      20世纪90年代以来,以Internet为代表的信息技术的迅猛发展使人类社会大步迈入了网络时代。从InternetWWW,从大型电力网络到全球交通网络,从大脑神经网络到各种新陈代谢网络,从科研合作网络到各种经济、政治、社会关系网络等,可以说,人们已经生活在一个充满着各种各样的复杂网络的世界中。人类社会的网络化是一把“双刃剑”:它既给人类社会生产与生活带来了极大便利,提高了人类生产效率和生活质量,但也给人类社会生活带来了一定的负面冲击,如传染病和计算机病毒的快速传播以及大规模的停电事故等。因此,人类社会的日益网络化需要人类对各种人工和自然的复杂网络的行为有更好的认识。长期以来,通信网络、电力网络、生物网络、和社会网络等分别是通信科学、电力科学、生命科学、和社会学等不同学科的研究对象,而复杂网络理论所要研究的则是各种看上去互不相同的复杂网络之间的共性和处理它们的普适方法。20世纪末开始,复杂网络研究正渗透到数理学科、生命学科和工程学科等众多不同的领域,对复杂网络的定量与定性特征的科学理解,已成为网络时代科学研究的一个极其重要的挑战性课题,甚至被称为“网络的新科学(new science of networks)”。

      以生命科学为例,20世纪的生命科学研究主流是建立在还原论基础上的分子生物学。还原论的基本前提是,在由不同层次组成的系统内,高层次的行为是由低层次的行为所决定的。具有还原论观点的生物学家通常认为,只要认识了构成生命的分子基础(如基因和蛋白质)就可以理解细胞或个体的活动规律,而组分之间的相互作用常常被忽略不计。尽管基于还原论的分子生物学极大地促进了人类对单个分子功能的认识,然而绝大多数生物特征都来自于细胞的大量不同组分,如蛋白质、DNARNA和小分子之间的交互作用。对这些极其复杂的交互作用网络的结构和动力学的理解已成为21世纪生命科学的关键性研究课题和挑战之一。

      对网络的科学研究最早起源于著名的欧拉七桥问题。之后的近两百年中,数学家们一直致力于对简单的规则网络和随机网络进行抽象的数学研究。随着近年来计算机存储能力和处理数据能力的增强,以及一些大规模系统的数据库的建立,人们重新获得了真实网络的特征数据,发现真实网络既不是规则的,也不是随机的,而是呈现一定规律的复杂网络。复杂网络之所以复杂,不仅在于网络规模的巨大,网络结构的复杂,而且网络在时间、空间上都具有动态的复杂性,网络行为也具有复杂性。

      许多真实系统都可以用网络的形式加以描述,一个典型的网络是由许多节点与链接节点之间的边组成的。节点代表系统中的个体,边则表示节点之间的作用关系。如WWW网络可以看成是网页之间通过超链接构成的网络;Internet网络可以看作不同的计算机通过光缆链接构成的网络;科学家合作网络可以看作不同的科学家合作关系构成的网络;基因调控网络可以看作是不同的基因通过调控与被调控关系构成的网络。

      这些真实网络的普遍存在,促使来自不同学科领域的科学家共同致力于复杂网络的研究。这些学科领域包括复杂性科学、数学、物理、生物、计算机等。复杂网络的研究可以使人们更好的了解现实世界的复杂系统,为设计具有良好性能的网络提供依据。同时复杂网络的理论成果将会广泛地应用到生物、计算机等各个学科领域。

      复杂网络的研究大致可以描述为三个密切相关但又依次深入的方面:大量的真实网络的实证研究,分析真实网络的统计特性;构建符合真实网络统计性质的网络演化模型,研究网络的形成机制和内在机理研究网络上的动力学行为,如网络的鲁棒性和同步能力,网络的拥塞及网络上的传播行为等。

      

    转自:http://www.sciencenet.cn/m/user_content.aspx?id=216824

      参考文献:

      [1] 汪小帆,李翔,陈关荣. 复杂网络理论及其应用. 北京: 清华大学出版社,2006.

      [2] 郭雷,许晓鸣. 复杂网络. 上海: 上海科技教育出版社,2006.

      [3] 曾宪钊. 网络科学.  北京:军事科学出版社, 2006.

      [4] 何大韧,刘宗华,汪秉宏. 复杂系统与复杂网络. 北京: 高等教育出版社,2008.

     

    展开全文
  • 尤其是“阿尔法狗”战胜人类,为复杂系统建模仿真研究提供了启示。社会管理、战争决策、经济治理、指挥控制、医疗健康等复杂系统领域,一直存在着对经验、直觉等认知建模的需求。“阿尔法狗”所采用的人工神经元网络...

    原文链接:https://mp.weixin.qq.com/s/BQ1lpYF5hu58n6YEs0HKGg

    近几年来,人工智能受到广泛关注。尤其是“阿尔法狗”战胜人类,为复杂系统建模仿真研究提供了启示。社会管理、战争决策、经济治理、指挥控制、医疗健康等复杂系统领域,一直存在着对经验、直觉等认知建模的需求。“阿尔法狗”所采用的人工神经元网络方法,能否为解决这个问题带来曙光,这值得研究和探讨。

       

     

    复杂系统性质与深度学习启示

     

    人类在对复杂系统的研究中,存在大量关于直觉、经验、认知等无法用形式化方法表示的特性,这意味着仅依赖传统基于相似性原理及形式化知识的建模仿真方法,难以真正表达复杂系统的深层次规律。如何获取和表达非形式化的知识,并将这些知识用于复杂系统的理解和建模,一直是各领域复杂系统研究中亟待解决的难题。“阿尔法狗”(AlphaGo)通过深度增强学习方法,成功解决了围棋这一复杂博弈系统的认知和决策问题,为用智能建模方法去深入理解复杂系统提供了新的思路。

       

    复杂系统及面临的建模难题

     

    根据系统论,世界可分为简单系统与复杂系统,简单系统主要是诸如“1+1=2”的那些系统,也就是整体等于各部分之和。所有的系统都像钟表一样,即使结构再复杂,也可以分解还原。系统的性质表现在其结构不会变化,因果关系确定,结果可重复、可预测,状态稳定等方面,如自行车就是这样的系统。复杂的事物,如航空母舰,只要是可以分解还原的,就都是简单系统。

       

    复杂系统就是那些“1+1≠2”的系统,即整体不等于各部分之和,研究每一个组成部分,并不能得到整体性质。如人体,死人和活人所有的物质都是一样的,但是一个有生命,一个没生命。从性质上看,它的系统结构是可变,因果不明确,结果不可预测、也不可重复,而且会产生出新的系统性质。社会系统、经济系统、战争系统、人体系统等,凡是与人有关的系统都是典型的复杂系统。“社会危机的不可预测性”“战争中的偶然性”“结果的不可重复性”等都在说明复杂系统的复杂性特点。复杂系统在各种信息关系网络的交互作用下,会不断地产生演化。因此,要想管控这些系统,就不可回避地需解决系统复杂性问题。

       

    系统复杂性表现为3种主要性质,其他性质可从这3种性质中衍生出来。

       

    1)适应性。Holland认为“适应性产生复杂性”,其最大特点是“环境会导致系统结构不断发生改变”。为适应环境,系统自身结构会不断调整,演化出新的系统结构,从而导致系统产生出新的性质和功能。这是由系统学“系统结构决定系统功能和性质”这一原理所决定的。

       

    2)不确定性。不确定性存在的直接结果就是“会导致因果不再一一对应,也不会是完全唯一”。从物理学角度来说,海森堡测不准原理就指出了“不确定性的客观存在性”,即状态的不确定性与人的认识多少无关。从社会学角度来说,由于自由意志的存在,导致人或者人的组织有了选择的自由,因而也会产生不确定性。

       

    3)涌现性。涌现性最直接的后果是“会得到新的整体性质,并且这种性质不可预测”。由于系统的自组织、自适应和不断演化,新的系统性质会分层次涌现,且涌现的结果具有非线性,所以它是不可预测的,既有不可预测的随机性,但是也有总体的规律性,而且不以人的意志为转移。往往是“意料之外,情理之中”的结果。看起来好像不可思议,但细想又是很有道理的。

       

    复杂系统的上述性质给建模带来了诸多困难。传统建模依据相似性原理,基本原则是结果可重复。对实际系统完成建模后,只要有相同的输入,就会得到相同的输出结果,所以能够用仿真系统的输出来代表实际系统的输出,这是仿真系统运行最基本的原理。但是,复杂系统结构动态可变,结果不重复,且涌现不可预测,这些复杂性特点严重动摇了传统建模的基础,导致采用传统思路对复杂系统建模从根本上就出现了问题,那么,对社会、经济、战争、城市、人体等复杂系统的建模就会变得非常困难。

       

    具体来说,复杂系统建模主要存在以下4个方面的困难。第一,复杂系统不可分解,其整体性质不具备局部可加性,因此必须进行整体性建模,而不能先局部建模、再通过局部模型的简单叠加来得到整体。第二,复杂系统具有适应性,结构动态可变,这就要求模型的结构也必须动态可变,也就是要求模型是“活”的,能“变”是对复杂系统建模的基本要求。第三,复杂系统的因果关系不明确,结果具有不确定性,这就要求模型必须能反映出多种可能的结果,而不是只有一种固定的结果。第四,复杂系统演化具有非线性和涌现性,这要求模型能反映出这种非线性的演化和涌现过程。

       

    要解决上述这些问题,仅靠传统的建模方法是不可能实现的。中国科协主办的第58期、第82期“新观点新学说”学术沙龙中曾对这一问题进行过深入研讨,研讨得出的基本结论是:基于相似性原理的建模仿真方法从根本上并不适合复杂系统建模。

       

    哪些方法比较适合复杂系统建模呢?目前,通过学术界的多方尝试,在复杂系统建模方面已取得了一些进展,提出了一些新的建模方法,主要有以下4种,这些方法虽然解决了复杂系统某一方面的建模难题,但也或多或少存在着一些瓶颈或不足。

       

    1)多智能体建模。这种建模方法依赖多智能体之间的相互作用,虽然可以反映出复杂系统内部要素的适应性行为及相互影响,但目前的“智能体”实际上并不智能,大多数都过于简单,还反映不了实际情况,因而建立的系统模型也就比较简单。

       

    2)复杂网络建模。它用复杂网络来反映系统的整体性质,是一种比较合适的理论和方法。但现在复杂网络的研究与应用大多数都是单向的,也就是对已有的复杂系统数据进行分析,来确定它是否属于复杂系统,或者具有什么结构或性质等,因而利用复杂网络方法对复杂系统进进行实证研究的多,但反向过来做实际建模工作的还比较少。

       

    3)大数据建模。大数据建模是用数据模型来代替数学模型,利用大数据的相关性,来回避复杂系统因果性难找的难题。这种方法可以解决许多复杂系统问题,但复杂系统具有不可预测性,因而这种方法最大的难点是用“过去”很难代替“未来”。建模的重要价值就是得到有预测功能的模型,也就是建立能够预测未来的模型,这对于大数据建模来说可以做,但仍然存在很多困难。

       

    4)平行系统建模。平行系统是指由某一个自然的现实系统和对应的一个或多个虚拟或理想的人工系统所组成的共同系统。平行系统建模方法是解决复杂系统管理的一种比较实用的理论和方法。这种方法采用虚、实平行的建模方式来解决复杂性问题,并将人引入模型运行过程之中。但是,采用这种方法仍然需要在“虚”系统里对复杂系统进行建模,因而以上的建模难题也同样存在。

       

    究其原因,不管采用上述哪种方法,均与缺乏对非形式化知识的建模方法有关。类似于经验、直觉、记忆之类的知识,其本质都是建立在各类知识相互纠缠基础上的,所以很难用简单的因果形式,比如某个数学公式或者“IF-THEN-ELSE”等形式表现出来,这就需要找到一种非形式化知识的建模方法,才能解决复杂系统的建模难题。

       

    “阿尔法狗”带来的曙光

     

    “阿尔法狗”(AlphaGo)采用深度增强学习的方法,不仅在围棋上战胜了人类,而且揭示了一种复杂系统建模的可能。尤其是“阿尔法狗”采用的深度学习方法,被认为是人工智能领域的重大突破。然而,对深度学习既不能有过高的估计,认为它是万能的,能解决一切人工智能问题;也不能过低估计,认为它只是一种普通的技术进展,而忽视它在智能认知方法上取得的突破,以及蕴含在这一突破中的颠覆性意义。

       

    1)“阿尔法狗”在4 个方面的突破值得关注。第一,通过深度学习方法掌握了对弈知识,所有的围棋规则和方法都不是编在程序里,而是它通过大量棋谱和自我对弈学习出来的。第二,发现了人类没有的围棋着法,意味着可能突破了人类已有的知识极限,具备了超出人类的可能。第三,在一定程度上捕捉棋感直觉,得到了一种对经验知识的获取方法。棋感,是人类通过训练得到的一种经验直觉,某种意义上说“只可意会,不可言传”。所以,经验直觉并没有形式化的表现形式,也不能用传统的方法来进行处理,因而这种能力过去被认为是人类独有、计算机难以做到的。第四,这种方法具有一定通用性,因而极具参考价值。

       

    2)“阿尔法狗”的深度强化学习启示了一种对智能的建模方法。它主要依赖4种方法完成走子。一是策略网络。主要功能是通过学习前人棋谱来获取走子经验,预测下一步棋的走子策略,并且可以通过自我对弈不断进化出更高级的策略网络版本。二是估值网络。主要功能是通过大量的自我博弈,来完成对整个棋局胜负的判定预测。三是快速走子。主要功能是加快走棋速度,采用局部特征匹配与线性回归相结合的方法,通过剪枝来提高快速走子速度。上述3种方法虽然都能下棋,但是它们的融合和协同运行才是最高水平,所产生的能力才能打败人类。四是蒙特卡洛树搜索,主要功能是搜索计算后续步的获胜概率,它相当于1个总控和调度,来控制对前3个算法的选择,完成对策略空间的搜索,确定出最终的落子方案。

       

    “阿尔法狗”采用的核心方法是深度学习方法,通过建立人工神经元网络,来理解概念和捕捉经验。学习方法主要是有监督训练、无监督训练等,实质就是分类和聚类。学习条件是通过大批量的训练样本,也就是数据,从而总结出特征。学习结果就是形成对应的人工神经元网络。从输入的各种数据出发,通过整合,建立起网络内部的各个连接,最后得到正确的下棋结果。这些连接的逐步整合,就意味着对问题的逐渐理解。

       

    “阿尔法狗”的设计者也不知道策略网络和价值网络内部是如何连接的,因为这是它自己学习训练不断优化得到的。所以,这个网络对我们来说就是一个“黑箱”。人工智能开山鼻祖之一的Minsky曾指出:“智能的诀窍就是没有诀窍。”其实是说,智能实际上是自然的,不知道要怎么建立这些网络,但却把它建立起来了,这才最符合智能的本质。这启示了智能的建模过程其实就是“涌现”,只有涌现出现了,也才能做从简单到复杂的事情。

       

    深度学习下的认知是什么?

     

    深度学习下的认知是一种非常接近人类的认知方式。知识主要以公式、规则、文本等形式化方式表达,基本上都是通过抽象化方式、以理性方式学习到的。如从小学、中学、大学直到研究生,无论是学习牛顿定律、运动方程等各个学科知识,还是阅读的各类书籍,这些知识都能够被表示成形式化的方式。但是,除此而外,我们学到的更多知识,是从眼睛、耳朵、皮肤等各个感官中间获得的。如,人的眼睛相当于每200毫秒拍一幅图像,到3岁时就已经看过几亿张图片了。这个过程也是学习的过程,只不过是以直觉感性的方式进行的。再如,球扔过来,伸手就能抓得住,不必知道任何抛物线定律、引力定律,也不用计算空气阻力,凭的是感觉经验。这说明可以通过试错的方法学习知识,而且学习到的知识远超过在学校里学到的形式化知识。

       

    对环境的感知是最常见的学习,这种经验学习是是不能言传的,必须亲身体会。结果可能有对有错,理解也可能会有偏差。很多复杂系统根本找不到对应的因果关系和形式化表达方式,依据的主要就是感觉和经验。事实上,在处理复杂系统问题时,所谓“高手”和“低手”的差别,除了基本能力以外,主要就是在经验与直觉上的差别。以围棋对弈为例,棋手都会按照规则去计算和走子,但关键的差距在于经验和棋感不同样。

       

    既然AlphaGo能模拟人的经验和直觉,那训练得到的人工神经元网络是否可以作为一种知识的表达形式呢?人类大脑的神经元大致是由细胞体、树突、轴突和突触等构成,把它们都转化为数字的形式就变成了人工神经元网络。通过人工神经元网络,可以识别猫,也可以下围棋,还可以作为飞行员去开飞机。目前,这些都已经先后取得了成功,并且可以表现为不同的形式,其基础都是人工神经元网络模型。因此,知识可以转变成以神经元网络为基础的特定表达形式。也就是说,知识并非一定要用符号、公式或者文字等方式去表达,人工神经元网络本身也可以是一种特殊的知识表达形式。

       

    人工神经元对知识的表达能够完善人类知识的数字化表达形式。形式化知识表达方法主要有规则、公式、文本等,人类长久以来积累下来的知识基本上都属于这一类。用人工神经元网络表达可以表达出非形式化知识,即经验、直觉等,如我们看到、听到、感知到并理解的东西,人类的很多知识要依靠这种方式积累。因此,我们既可以用形式化表达的知识,创造出“深蓝”“沃森”这一类智能系统,也可以用非形式化的经验类知识,创造出“阿尔法狗”和“AI飞行员”等为代表的另外一类智能系统。

       

    这就相当于对认知进行了建模。那么,什么叫认知建模呢?国防大学认知智能学习小组对此给出一个简单的定义:通过捕获人类经验、直觉和记忆等非形式化知识,与形式化知识一起,构建能够反映复杂系统特征的认知模型,实现对复杂系统的深度理解和仿真,从而实现对复杂系统的演化预测和管控。这里的“认知”,实际上包括了理解、预测和决策3大环节。如何对复杂系统进行认知建模与仿真,就是需要讨论的主要问题。

       

     

    认知仿真带来的问题与思考

     

    智能技术的不断发展,在增强人类获得认知、积累知识能力的同时,不仅会改变我们对复杂系统的认知能力,同时也为我们提供了用认知仿真方法去深入理解复杂系统的新思路。认知仿真的核心是模拟人类的认知方法,深入分析和探讨认知仿真的相关问题,将进一步拓展和丰富复杂系统建模仿真理论与技术方法。

       

    经验直觉认知复杂系统建模的特殊模式吗?

     

    1)经验直觉认知:是意识还是物质?经验直觉认知是对事物运行规律的深刻理解,是对各种因素的综合权衡,难以用形式化的方式表达。

       

    主要有以下3个方面的困难:第一,它是主观的,从属于个人。每个人的认知必定是主观的,是对事物的一种理解;第二,经验认知并没有统一的形式化表示方式,难以记录和传递。第三,经验认知难以用直接方式传授,接受者要有“悟”的过程,能否接受、接受多少,很大程度上取决于个人的理解能力,高手与低手的差别往往在于认知水平的差距。很多传统领域对复杂系统的理解和管控,往往依赖于人们认知经验的积累。如“宰相必起于州部”“猛将必发于卒伍”说明了在社会治理和战争指挥中经验积累的必要性和重要性。经验积累是对客观事物规律的认知,虽然复杂系统的规律是一种客观存在,而人们认识规律却是一种主观的行为。传统复杂系统建模是将其规律模型化,而直接对规律的认知进行建模可能是另一种复杂系统建模的有效途径。一旦经验和直觉能够通过某种物质模型(如神经网络)表示出来,经验直觉的意识属性也就会物质化,将直接带来意识与物质的统一。

       

    目前来看,以深度神经元网络作为经验直觉物质载体和表现形式的认知模型似乎越来越成功。“阿尔法狗”的突破在于找到了一种生成人工神经元网络的方法,可以将对围棋的经验直觉这种非形式化的知识捕捉下来,进入走子网络和估值网络之中,并用多层网络描述了经验的综合性。这种方法目前已经可以适应视频游戏、德州扑克、星际争霸等多种游戏形式,从看别人玩游戏中进行总结,或在不完全信息博弈中进行估算,几乎战无不胜。最近用神经网络构建的认知模型又开始挑战自动编程、写诗写书。这种方法之所以能达到了顶级玩家的水平,其实还是那句话:规则谁都懂,差的就是经验和直觉,差就差在神经元网络的训练效果和所用数据质量上。

       

    2)复杂系统建模:是对认知的捕捉吗?

     

    复杂系统具有多面性,需要从多个方面对其进行认识:第一方面,来源于认识世界的3大方法:理论推导、科学实验和仿真建模,这是我们认识复杂系统最基础的方法。第二方面,来源于后来出现的复杂网络和大数据方法,复杂网络被用来描述复杂系统的结构,大数据被用来挖掘复杂系统的特性,目的都是为了找到复杂系统的运行规律。第三方面,与深度学习方法的出现有关,从复杂系统的角度来看,它并不只是简单的智能技术,还可以看作是一种复杂系统的建模方法,也就是通过捕捉经验直觉建立神经元网络模型,来描述和表达出复杂系统的运行规律。不管从哪个角度认知事物规律,反映出来的都是认知的某个侧面,只有将它们都结合起来,才有可能更逼近于最后的真相。

       

    对复杂系统认知表现出来的这些特殊性,虽然在很大程度上制约了采用传统形式对其建模的可能性,但同时也带来了复杂系统建模的新机遇。这可以看作是认知物质化带来的直接后果,也就是意识与物质在人工神经元网络上的统一,使得对经验直觉等认知的捕捉,成为新的建模可能形式。值得思考的是,当年处于导体与绝缘体之间的半导体带来了信息革命,处于理论推导和科学实验之间的仿真计算(虚拟实践)带来了第三条认识世界的道路。今天,处于意识和物质之间的认知捕捉,也可能会给我们带来对复杂系统建模的新突破。

       

    3)经验直觉捕捉:是新出现的特殊建模形式吗?

     

    关于经验直觉捕捉是否是一种复杂系统建模的特殊模式,现在主要有两种观点。

       

    第一种观点认为,是一种复杂系统建模的特殊模式,因为经验直觉能够捕捉下来,并更好地反映出复杂系统性质。比如“阿尔法狗”,它学习的不是下围棋的逻辑,而是建立在几千万盘棋上的试错经验。捕捉获取的是只可意会的非形式化知识,形成的结果是人工神经元网络。这种方法相较于其他建模方法更具有整体性、适应性、不确定性等复杂性特点。

       

    这个观点的核心是要把所谓的经验直觉等非形式化的知识捕捉下来。从“阿尔法狗”的成功来看,深度学习、增强学习等一系列经验直觉捕捉技术手段,已显现出了初步曙光,卷积神经网络(convolutional neural network,CNN)、长短时记忆(longshort-term memory,LSTM)、深度玻尔兹曼机(deep boltzmann machine,DBM)等方法也都在不断完善进步,“阿尔法狗”的创始人Demis Hassabis认为,人工智能就是深度学习加上增强学习。现出现了一些更新型的模型,如DeepMind公司提出的想象力模型。该模型认为,单纯的试错学习其计算量太大,仅靠给定规则又可能丢失创新性的结果,因此,将两者结合就出现了想象力模型,模拟的是人类思考问题的经验方式:给定一个问题后,先想象这么做会产生的结果,然后才开始行动。这对复杂系统意义重大,因为复杂系统的规则往往不会像围棋博弈那么明确,信息经常是不完全、不可预知,就需要先设想可能会发生什么情况再采取行动。如在“推箱子”游戏中,智能Agent在不了解规则的情况下,就需要先通过想象来看看这样做的后果,然后再根据结果行动。“宇宙飞船导航”游戏也是一样,要先想象一下各个星球对飞船的吸引力结果,再决定如何规划航行的轨迹。类似这种模拟人类思考模式的新模型,可能在今后会见到更多。

       

    第二种观点认为,经验直觉的捕捉并不是一种复杂系统建模的特殊形式。认为“阿尔法狗”获取的其实不是真正的经验直觉,而是一种大数据分析和抽取经验的方法。本质上还是一种剪枝和搜索方法,而非人的模糊直觉。“阿尔法狗”虽然扫荡了围棋的定式,改写了棋形,但并没有动摇围棋的棋理。一个没有感情的机器,是没有办法完全获得完整的人类经验和直觉的。依赖经验的模型是否可信本身也存疑。很多经验和直觉有时并不可靠。正因如此,构建的认知模型是否可信值得怀疑,尤其是在战争决策、社会管理这样的高敏感度场合。同时,有研究证明,现在很多学习算法模型其实很容易被误导。比如,一个通过深度学习算法产生出来的识别“猫”的神经元网络,只要稍微修改其中的数据,就会把“猫”识别为“烤面包机”,这意味着所产生的认知极易被误导。

       

    神经元网络是否为复杂系统模型的表达形式?

     

    1)复杂系统与人工神经元网络的相似性。

       

    复杂系统模型主要用于描述复杂系统的运行规律,且取决于其内部的结构和演化。由于复杂性的存在,模型的内部结构应该反映多层网络、节点之间相互纠缠影响,并且可以涌现出整体运行规律。无论是对人体、社会、战争,还是互联网、作战体系等复杂系统进行建模,都应该反映出这些特征。从相似性角度来说,如果用人工神经元网络作为复杂系统的模型表达形式,至少在形式上是比较接近的。

       

    人工神经元网络又完全不同于传统的模型,它是一种所谓的“认知表达”形式,是由人自己认识并通过人工神经元网络表示出来的,可以被看成是一种应用类似大脑神经突触联接结构进行的信息处理数学模型,通过调整内部大量节点之间相互连接的关系,实现对事物的理解。因此人工神经元网络表示的是对复杂系统规律的某种认知,并将这种认知以模型的形式展现出来。但人工神经元网络是否能反映出复杂系统规律的核心原理呢?众所周知,飞机的发明是人类掌握了鸟类飞翔的空气动力学原理,人工神经网络是不是也是复杂认知智能的原理,目前尚未有定论。从性质上来看,人工神经元网络与复杂系统高度相似,这为复杂系统建模奠定了基础。

       

    人工神经元网络建模不同于传统模型,主要表现在以下4个方面。第一,整体性建模,是对整体特征的抽象;第二,结构是动态的,对数据的特征进行动态适应性调整;第三,结果是不确定的,训练过程本身也存在随机性;第四,可以描述出概念涌现,低层次特征的抽象组合会涌现出对高层概念的理解,就象从众多的动物特征中识别出具体的“猫”。

       

    神经元网络可以被看成是复杂系统的模型表达形式主要有两方面。第一,符合相似性原理。用人工神经元网络的黑箱模型来模拟复杂系统的黑箱,两者之间具有天然的相似性,当然这是在高层次上的整体相似;第二,不同认知可以有不同结构的差异性。发展不同的人工神经元网络和它的组合,就可以表示出不同类型的复杂系统,就像可以利用不同模型的差异性进行组合,表示不同类型的飞机一样,如小飞机、大飞机、民用飞机、战斗机等。有人把人工神经元网络的结构进行了划分,不同的结构组合之后,就会形成各种各样的结构形式,组合出很多不同类型的复杂系统认知模型。

       

    但是认知模型的建模,最后到底是建一个还是建多个?对于认知智能来说,不会只有一个方面,比如只会下棋,它还必须会其他东西,因为这些知识对一个人的认知来说,是完全纠缠在一起的。因此,对复杂系统的理解,也不能只关注一个或几个方面。但是,这样就引出另外一个必须回答的问题:复杂系统的模型到底应该是一个极为复杂的统一整体模型,还是由若干个不同类型模型构成的组合?群体认知是不是多种模型的综合?这些问题都直接挑战了复杂系统模型本身的结构性问题。

       

    2)人工神经元网络的黑箱特性。

       

    人工神经元网络的黑箱特性,增加了人类理解模型的难度。为了看清楚神经元网络内部发生了什么变化,DeepMind 开发了tensorflow 牧场,但还是很难看清内部发生了什么。有报道说,“阿尔法狗”自我对弈的棋谱人类已经无法理解了。那么,是不是打开了这个黑箱,就可以帮助我们更接近围棋之神呢?换言之,打开了这个黑箱,我们是不是也能从中得到复杂系统更深层次的规律或者是知识呢?目前还难以回答这一问题。为了破解黑箱特性带来的理解难题,现在又出现了一个新的研究热点,就是对深度学习产生的人工神经元网络黑箱进行探测。有人建议对这些计算机里面的人工神经元网络进行“脑外科手术”,目的当然是要想弄清楚里面到底是什么。Voosen指出,应该发展出一门新的学科,叫“人工智能神经科学”,可能也是出于同样的考虑。

       

    人工神经元网络黑箱之所以是个难题就与它与复杂系统性质密切相关。一是人工神经元网络的所有连接极为复杂,而且整体纠缠,牵一发而动全身。有人形容这些信息是“全息”的,也就是“人人有我,我有人人”,每一部分都关系到整体,整体又都影响每个局部;二是人工神经元网络的连接还是动态的,因为认知总是在不断变化,模型也会跟着不断变化,基本上是“此一时,彼一时”,不会总是固定不变。比如,有很多网民在和微软“小冰”对话时,就不断教它说脏话,结果小冰真的就学会了说脏话。但是,要把它改回来并不容易,不是调哪个软件参数就改得回来的,需要用大量数据重新再去对它进行训练。这是因为在训练好的人工神经元网络中,每一个连接都相互关联,动一处必然会引发一大片都要随动。

       

    可进化是否是智能认知模型的固有属性?

     

    1)复杂系统的进化与反身性。

       

    根据复杂系统理论,适应性是进化的动力。但是,如果从建模角度考虑,还要回答一个问题,到底是谁进化了,是复杂系统,还是人类的认知?

     

    客观上,复杂系统在适应环境中是不断进化的,因而反映复杂系统原理的模型也需要不断进化。但主观上,对复杂系统的认知也在不断进化,因为理解在不断加深,所以认知模型也需要进化。这两个侧面,一个客观,一个主观,无论是复杂系统本身,还是我们对复杂系统的认知,其实都在进化。因而,认知也应该成为建模必须要考虑的核心问题之一。

       

    要理解这个问题,首先需要了解复杂系统的另一个重要性质——“反身性”。这是复杂系统的一个非常关键核心的性质,但被很多研究者所忽视。“反身性”是人也是系统的组成部分之一,人的任何行为(包括认知),都会对系统造成反作用,都会导致系统的状态发生改变,任何与人有关的复杂系统都具有这个特性。

       

    对于自然界中的系统,人对其影响不大,因此可以假设人不在系统之中。如,无论人们预测明天是否会下雨,都不会影响明天气象的自然规律。但是,如果证监会主席或某些重要的知情者评论股市,甚至是某人造出的谣言,就可能会影响股市的波动,因为人本身就属于股市所在的系统。这就是反身性。同样,战场上指挥员对战场态势的认知,也会构成对战场系统的影响。因此,复杂系统与认知是分不开的。对自然界中的简单系统,我们可以不考虑反身性的问题,但是只要是与人相关的复杂系统研究,就必须要体现认知的反身性影响。因此,模型的进化很自然就与系统本身和认知都有关系。

       

    “阿尔法狗”的成功依赖于其策略网络、价值网络、增强学习的不断发展。策略网络通过学习人类16万盘棋中蕴藏的有限容量经验知识而不断进化;价值网络通过自我对弈的3000万棋面中蕴藏的经验知识而不断进化,而且还脱离了人的限制;增强学习则是“左右互博,见多识广”,人类已经很难理解其对弈的招数,进化出来的新版本,已经远远超出了它自己的初始版本。

       

    因此,可得出一个结论:进化是智能认知模型的固有属性。不会进化的模型,显然满足不了仿真的需要。同时,也可以得到一个推论:认知模型应该是动态的,也就是结构应该是不固定的。从结论和推论来看,人工神经元网络是比较符合这一特点的。

       

    2)模型进化的极限与方向。如果模型要进化,还应解决“极限”和“方向”两个问题。“极限”探讨的是进化是否有尽头。如,“阿尔法狗”的能力会不会一直增长?它一直在“左右互搏”,新版本跟老版本对抗,不断学习,提高自己,会不会有能力提升的极限呢?如果到了这个极限,会不会还继续进化?如果再进化,它还是不是认知模型呢?比如,据说“阿尔法狗”现在相当于22段,那它会不会达到50段、100段?这都是需要探讨的问题。人类现在已经进化成了直立行走的动物,但我们现在也不知道人类的行走方式是不是已经停止了进化,也不知道这是不是就是人类行走进化的极限。

       

    “方向”探讨的是进化方向是否是唯一确定的,也就是说,进化会不会有几种不同的结果?是不是都能从低手进化成高手?提出这个问题,是因为复杂系统有一个固有问题,即混沌从复杂系统来看,系统的演化可能会进化涌现出更有序的系统结构,也可能掉入混沌状态中去,进化的方向就会有很大的不确定性。

       

    认知模型的进化是否会突破人类容忍的极限?

     

    1)智能模型的容忍极限与超越可能。作为深入理解和管控复杂系统的一种新思路,将智能技术用于复杂系统建模仿真研究会出现哪些可能性,有以下2种观点。

       

    第一,智能建模完全有可能超越人类的容忍极限。现在的技术已经显现出了端倪,“阿尔法狗”对围棋这一复杂博弈系统的认知和控制已经超出了人类。深度学习技术与算法还在不断改进完善,在图像理解、语音识别、围棋博弈、德州扑克、飞机驾驶、星际争霸等等诸多领域,攻克了一个个人类的智能堡垒,现在自主编程又出现了,将来只会越来越多。

       

    第二,智能建模只能不断逼近人类认知,根本无法超越。“阿尔法狗”也只能在单一智能上超过人类,在综合智能、创造性等方面差距还很大,目前也还没有见到任何算法可以“真正”理解它所处理的内容。如果仅仅是单独训练不同的人工神经元网络,而不是把它放到认知整体上来看,它永远不会成为真正的智能。只有当很多神经元网络模型能够做到像复杂网络一样交错纠缠在一起之后,才能在更高层次上涌现出真正的智能。更重要的一点是,没有自主的直觉和意识,就根本谈不上“超越”人类,但是自主的直觉和意识,就目前的进展而言,还根本一点也看不出有这种可能性。

       

    2)认知智能研究的矛盾与悖论。认知智能研究会带来一系列值得思考的问题。对认知智能模型的研究,或许可以解决复杂系统理解和管理问题,但也可能带来更多的新问题。例如,我们建立的认知模型,会不会比我们更了解复杂系统?与之相关的另外一个很值得讨论的问题是,被认知后的复杂系统会带来什么变化?

     

    一般说来,我们对一个系统的认识和理解加深了,掌控它的程度也会更进一步。比如,我们认识了一台机器的原理和结构,就很容易对它进行拆解、组装或维修。但是,对于复杂系统而言,这个问题可能就不是那么简单,甚至还可能出现一个悖论:我们为了掌控复杂系统,就必须对它充分认识;但对它认识越多,却发现不是离真相越近,反而可能是越远了。这个悖论之所以产生,就是因为反身性原理,我们认知的本身会导致系统发生演化,而这种演化又具有非线性、不确定性等特点,而蝴蝶效应又会使结果具有很强的不可预测性。因此,当我们利用认知智能去解决社会、经济、战争等复杂系统问题时,是否会激发系统产生更复杂的演化,导致新的安全、社会等问题,就非常值得我们深入思考。

       

    因此,人工智能的发展面临着新的“囚徒困境”:谁来决定该不该发展它?发展它可能面临很大的风险,但你不发展别人发展也许更加危险!这背后的核心问题其实是理性发展与非理性发展两种观点的博弈。所以,马斯克不断呼吁限制人工智能,但他也是最积极的投资者之一,恐怕就是这个道理。

       

     

    结 论

     

    复杂系统的认知仿真是否可以成为解决社会、经济、战争等复杂系统的终极手段,其结论不得而知。但是,不断深入的研究包括建模仿真,会使人们逐步认识和理解复杂系统的运行规律,在掌握和控制复杂系统的道路上不断进步;同时这些认知也可能会激发出更复杂的演化,导致复杂系统产生出更多的新问题,使得对复杂系统的认识和管理更加困难。比如,在智能化程度上先进与后进国家间的差距如果过大,就很可能带来不可预知的巨大危险性。

       

    因此,深入地研究认知建模与仿真问题可能是解决复杂系统问题的一条可行途径,但同时也必须从复杂系统观点出发,从理论上有所突破,才有可能取得较大的进展。复杂性与智能认知,是不是殊途同归,还是一个值得思考的问题。

       

    基金项目:军民共用重大研究计划联合基金项目(U1435218);国家自然科学基金项目(61174156,61273189,61174035,61374179,61403400,61403401)

     

    参考文献(略)  

     

     

     

    本文作者:胡晓峰,贺筱媛,陶九阳

     

    作者简介:胡晓峰,国防大学联合作战学院,教授,研究方向为战争模拟、军事运筹、军事信息系统工程。

     

    本文发表于《科技导报》2018 年第12 期,敬请关注。

     

    (责任编辑  卫夏雯)

    展开全文
  • 降低软件复杂性的一般原则和方法

    千次阅读 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.

    作者介绍

    政华,顺谱,陶鑫,美团打车调度系统工程团队工程师。

    招聘信息

    美团打车调度系统工程团队诚招高级工程师/技术专家,我们的目标,是与算法、数据团队密切协作,建设高性能、高可用、可配置的打车调度引擎, 为用户提供更好的出行体验。欢迎有兴趣的同学加入呦~~

    展开全文
  • 复杂网络中重要节点挖掘方法综述

    万次阅读 2016-11-08 09:58:05
    复杂网络的一些相关概念可以参考我上一篇博客:复杂网络入门复杂网络中的节点各种的重要性是不一样的,如在微博这一社交平台中,一些微博红人和一些明星大咖的影响力和一个微博新手的重要性是不一样的;在大学校园里...
  • ERP系统实施一般方法与步骤

    万次阅读 2018-03-15 13:50:29
    企业ERP系统实施是一项复杂且细节的系统工程,一般以项目形式完成。项目领导小组一般由企业高层领导和服务方组成,通过定期和不定期会议指导项目的运作和排除项目组难以解决的困难。项目组的构成包括服务方的咨询...
  • 软件开发复杂性的解决方法(二)

    千次阅读 2013-06-19 10:50:28
     利用面向对象(object-oricnted,OO)技术可以充分体现分解、抽象、模块化、信息隐蔽等思想,可以很有效地提高软件生产率、缩短软件开发时间、提高软件质量,是控制软件复杂性的有效途径。   6.面向对象的...
  • 软件开发复杂性的解决方法(一)

    千次阅读 2013-05-21 07:56:01
    要在规定的时间、规定的开发费用内开发满足用户需求的高质量的软件系统。这里指的高质量不仅是指错误率低,还包括好用、易用,可移植,易维护等要求。 软件开发的复杂性: 1.主要是现在的计算机体
  • 既然业务逻辑复杂,那意味着项目前期的业务建模、需求分析、分析设计极为重要,直接抛开这几个阶段进入技术实施开发阶段,不管套用什么设计模式、架构模式,系统的扩展性肯定难以保证。 项目的扩展性虽然最终体现为...
  • 系统软件项目成本构成及估算方法

    万次阅读 2014-12-12 17:25:32
    由于系统软件通常是一些规模大、复杂程度高的人一机系统,因此,系统软件的开发、使用、维护、管理的过程,是一个非常复杂系统工程,需要有巨大的人力、物力、财力资源,需要各种计算机软、硬件的支持。...
  •  结构化分析与设计方法是一种面向数据流的需求分析和设计方法,它适用于分析和设计大型数据处理系统,是一种简单、实用的方法,曾获得广泛的应用。 1 结构化分析   结构化分析方法的基本思想是自顶向下逐层...
  • 在我的Ubuntu系统可以正常使用中文输入法之前我做了很多努力,查阅了相关的资料,终于解决了这个并不复杂但是足够让人心烦的问题。  首先,个人认为没有必要更换系统默认的ibus输入法为fcitx。原因有二:一是卸载...
  • 复杂网络】自学笔记整理

    千次阅读 多人点赞 2020-06-29 17:15:45
    复杂网络是研究复杂系统的一种角度和方法,它主要关注系统中个体相互关联的作用。(一种拓扑结构) 2.当今应用        通过分析社交网络之间的关系,确定人们在社会中的社会关系...
  • 系统参数配置的存储管理与应用的通用方法

    万次阅读 多人点赞 2011-08-19 12:06:19
    系统参数配置的存储管理与应用的通用方法 作者:成晓旭   1 【背景】  在应用软件的设计、开发过程中,尤其是一些大型的复杂的业务系统,为了符合起码的系统通用性设计,系统运行参数需要在系统现场进行设置...
  • 复杂性思维第二版 一、复杂性科学

    万次阅读 2017-10-27 21:44:26
    一、复杂性科学 原文:Chapter 1 Complexity Science 译者:飞龙 ...2002年,Wolfram 发表了 “新科学”一文,在这里介绍了他和其他人在细胞自动机上的工作,并描述了一种用于计算系统研究的科
  • 复杂网络综述

    万次阅读 多人点赞 2016-11-05 09:44:55
    本人毕业设计是关于复杂网络的,之前完全没听说过的概念,于是就在网上找了一些论文来看,顺便做下笔记,这篇文章主要讲了复杂网络的一些基础概述。 这里的网络不是(不仅仅是)计算机网络这门课中的网络,它表示的...
  • 复杂网络分析总结

    万次阅读 多人点赞 2018-04-08 15:31:40
    参考文献 在我们的现实生活中,许多复杂系统都可以建模成一种复杂网络进行分析,比如常见的电力网络、航空网络、交通网络、计算机网络以及社交网络等等。复杂网络不仅是一种数据的表现形式,它同样也是一种科学...
  • 复杂网络介绍(一)

    万次阅读 多人点赞 2018-10-11 15:21:05
    复杂网络 1.定义: 复杂网络即呈现高度复杂性的网络...1)节点:由于复杂网络是复杂系统的抽象,因此复杂网络中的节点对应为复杂系统中的一个个实体。 2)边:边是复杂网络中节点与节点之间的关系,即对应复...
  • 软件固有的复杂

    千次阅读 2012-08-22 16:34:37
    软件固有的复杂性 一颗垂死的恒星正处在塌缩的边缘,一名儿童在学习如何阅读,白细胞向病毒发起进攻——这是真实事件的几个例子,它们包含着真正可怕的复杂性。软件也可能包含巨大复杂性的元素,但是这里的复杂性...
  • 复杂网络研究及其前沿概述

    千次阅读 2019-02-22 21:25:26
    复杂网络研究及其前沿概述1 引言2 复杂网络研究史2.1 七桥问题2.2 随机图理论2.3 小世界网络、无标度网络3 复杂网络的研究特点3.1 网络规模大3.2 网络结构具有复杂性和多元性3.3 网络具有时空复杂性3.4 复杂网络存在...
  • Android复杂界面布局解决方案

    万次阅读 2018-01-12 20:38:56
         我们知道,很多App的界面是非常复杂的,如果按照常规的方法去写layout.xml文件的话,app在控件少的时候没有问题,但是如果控件一旦变多,或者控件之间的嵌套非常复杂的时候,后期维护成本是非常巨大的,第...
  • 分布式系统调用链监控

    万次阅读 热门讨论 2016-12-23 22:51:51
    分布式系统调用链监控 应用架构由集中式向分布式演进后,整个调用关系变得复杂。...复杂的调用导致系统出问题后难以定位问题。 无法准确知道整体系统性能及运行情况。 全链路性能监控一个请求完整的调用链可能如下图
  • 工业PID控制方法的C语言实现详解

    万次阅读 多人点赞 2015-05-14 11:57:42
    无论多么复杂系统,总是可以由简单的子系统构成,分析典型环节的特点,其目的是为了通过典型环节的特点分析更为复杂系统,实际工程应用中,真正完全通过理论的方式建立模型是非常困难的,实际的模型建立过程是...
  • 一文读懂复杂网络(应用、模型和研究历史)

    万次阅读 多人点赞 2018-05-02 09:40:05
    摘要:随着近几年关于复杂网络(Complex network)理论及其应用研究的不断深入,已有大量关于复杂网络的文章发表在Science,Nature,RL,NAS等国际一流的刊物上,侧面反映了复杂网络已经成为物理界的一个新兴的研究...
  • 复杂网络研究的意义

    千次阅读 2005-11-17 00:32:00
    复杂网络研究的意义 clarensis复杂网络的研究,为我们提供了一种复杂性研究的新视角、新方法,并且提供了一种比较的视野。可以在复杂网络研究的旗帜下,对各种复杂网络进行比较、研究和综合概括。首先,网络的现象...
  • 关于钱学森定义复杂网络一事的探究

    千次阅读 多人点赞 2018-11-11 21:27:41
    由于本人从事与复杂网络有关的研究,多次在网上看到有关“钱学森给出复杂网络的定义”这样内容的文章,甚至百度百科也是这么介绍的。 百度百科-复杂网络 钱学森给出了复杂网络的一个较严格的定义:具有自组织、...
  • 现在的架构很多,各种各样的,如高并发架构、异地多活架构、容器化架构、微服务架构、高可用架构、弹性化架构等,还有和这些架构相关的管理型的技术方法,如 DevOps、应用监控、自动化运维、SOA 服务治理、去 IOE ...
  • 总结——复杂网络动力学

    万次阅读 2012-08-17 09:42:49
    “用复杂网络的动力学理论来分析软件系统方法调用网络的动态演化过程” 1、动力学是什么,在复杂网络中是如何体现的?  看了这么久的复杂网络动力学,却突然发现头脑里面竟然没有一个清晰的概念,只知道埋头看书...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,372,020
精华内容 548,808
关键字:

复杂系统方法