• (zt)过程生成


    Infinity核心技术“过程生成”专题帖(更新2楼) - 新闻消息 - 无限星辰:失落的地球 - Powered by Discuz!

    递归之美:数学,电脑科学与分形
    ——转自http://mmdays.wordpress.com/2007/05/24/recursive/

    想像一下,我刚才说了一句话,那句话是:“想像一下,我刚才说了一句话,那句话是:“想像一下,我刚才说了一句话,那句话是:……….””,如此下去,就好像站在两面平行摆设的镜子中间,镜子中的影像不断的重复。再举个例子,写完一封信想要匿名保密,就署名“知名不具”。回信的人写:“知知名不具具”。之后再回信的时候就变成:知知知名不具具具,加上括号可能比较清楚:(知(知(知名不具)具)具)。

    递归就是类似这样子,不断的重复同样的东西,只不过每次重复的是比较小的东西了。大家应该对数学归纳法不陌生,在使用数学归纳法时,我们首先确定n=1的时候某件事情是成立,然后在证明n到n+1的过程是正确的,就可以从n=1的例子,一路推论出第n项是什么东西。就像是推骨牌一样,把第一张牌推倒了之后,剩下的骨牌自然就被前面的骨牌给推倒。


    递归的概念则是相反的方向:我们想要解决一个大小为n的问题,我首先做的事情是把问题化简成大小为n-1的问题,但是解决的方法还是一样,只不过大小是n-1。如此继续化简,最后变成大小为n=1的基本问题,接着只要n=1的基本问题解决了,原来大小为n的问题也跟着解决了。

    这又好像层层分工。假设每个人都会加法,然后今天我想求出1+2+…+n等于多少?其中一个办法就是递归,我先假设1+2+…+(n-1)已经有人算好,那么我只要再加上n,就可以得到答案了。然而1+2+…+(n-1)要怎么得到呢?我就请另外一位朋友帮我算。另外一位朋友接到这个问题以后,也用同样的方法,他把1+2+…+(n-2)的结果交给另外一位朋友算,然后把这个结果加上(n-1),就变成我想要的1+2+… +(n-1)了。朋友的朋友也继续用类似的方法,直到最后一位朋友只需要回答1,接着倒数第二位朋友就把1加上2,传给倒数第三位朋友,倒数第三位朋友加上3,一直到我收到1+2+…+(n- 1)的结果,再加上n,就大功告成了。

    不过可能会觉得,如此简单的问题,为何还需要递归呢?其实递归也是比较适合一些问题来解,也就是那些“解决方式一样,但是可以化成大小比较小”的问题,除此之外还可以轻松解决基本问题(n=1的时候)。举例来说,有个古老的问题叫做河内塔(Hanoi Tower),问题的定义引述如下(引用网站)


    1883年,一位法国的数学家Edouard Lucas教授在欧洲的一份杂志上介绍了一个相当吸引人的难题──迷人的智力游戏。这个游戏名为河内塔(Tower of Hanoi),它源自古印度神庙中的一段故事(也有一说是Lucas教授为增加此游戏之神秘色彩而捏造的)。传说在古老的印度,有一座神庙,据说它是宇宙的中心。在庙宇中放置了一块上面插有三根长木钉的木板,在其中的一根木钉上,从上至下被放置了64片直径由小至大的圆环形金属片。古印度教的天神指示祂的僧侣们将64片的金属片移至三根木钉中的其中一根上。规定在每次的移动中,只能搬移一片金属片,并且在过程中必须保持金属片由上至下是直径由小至大的次序,也就是说不论在那一根木钉上,圆环形的金属片都是直径较小的被放在上层。直到有一天,僧侣们能将64片的金属片依规则从指定的木钉上全部移动至另一根木钉上,那么,世界末日即随之来到,世间的一切终将被毁灭,万物都将至极乐世界。

    倘若这个故事的叙述为真,那么,我们只需加速移动金属片,是不是就能愈早到达极乐世界呢?果真要移动这64片金属片,那么,至少要花几次的搬动才能完成呢?有没有规律可循呢?


    这个问题,就很符合刚才的特性:我们可以把大问题化成小问题,而且解决的方法相同,只不过问题的大小变小了。另外基本问题(n=1),就是移动一根金属片所需要的次数,这个我们也可以轻易解决,所以这个问题就可以用递归来解。

    首先,我们假设有A、B、C三根柱子,这64片金属片一开始在柱子A上面,我们想要搬到柱子C。因为问题中规定某个金属片上面是空的时候才能移动,我们就假设有个人可以帮我们把63片比较小的金属片先从柱子A搬到柱子B上面,然后我们把最大的那一片从柱子A搬到柱子C,再请那位朋友把刚才的63片从柱子B搬到柱子C,整个问题就解决了。然后我们只要知道刚才那位朋友搬了几次,然后加上我们自己般动的1次,就是整个问题要求的搬动次数了。

    递归不仅仅在数学上有其重要性,在电脑科学之中扮演的角色更是至关重要。程式设计者对于递归绝对不会陌生,上面所举的河内塔问题,实际上也是电脑科学的经典例子之一,是初学程序设计的人一定会学到的东西。递归的思维,常常可以让程式设计者打造出简洁的程式,让繁冗的问题透过简单的程式码来解决(例如parser的设计)。演算法上所讲的dynamic programming,就是递归思维在演算法的具体呈现。

    递归同时也是分形(fractal)这门大学问的基石,分形是一种相当美妙的几何图案,就如同上面那一张蒙娜丽莎的图一样,图中有图,形中有形,且小的部分都是大的部分的缩影,我们就称之为分形。分形本身的数学定义,实际上就包含了递归定义在里面,我们甚至于可以说,分形是递归在几何学的一种具体呈现。但是分形不仅仅是一种数学概念而已,在自然界中,有许许多多的地方都出现自然的分形,让人赞叹递归原来就出现在我们的生活周围。图中的这棵花椰菜,就蕴含了递归的碎形图案与于其中。分形同时也在各个研究领域有着广泛的应用,光是在电脑科学领域,就有人把分形应用在影像和影片压缩之上(这不难想像,由于分形这种以小见大的特性,我们可以用小的来表现大的,因此可以有压缩的概念出现),在电脑图学上(computer graphics),也有人把碎形应用在设计电脑游戏之中的一些景物,打造出有效率和简洁的系统。现在电脑游戏之中的景物,很多都是玩家边玩、游戏系统边产生出即时的景物,这叫做procedural generation(过程生成),这种即时产生景物的技术,可以避免游戏软件预先储存一堆要展现的景物,帮整个软件瘦身。“过程生成”就使用了大量的分形产生与合成技术于其中,而这些都根植于递归这一个深刻却简单的思维。
    fractal:

    由B.B.Mandelbrot于1975年提出来的分形(fracta1)理论,是20世纪70年代同混沌理论一起发展起来的,是非线性科学的重要组成部分.不同于传统的欧氏几何以零维、一维、二维、三维、四维对应的点、线、面、体和时空来描述物体的形状,分形理论用“分维”(fractal dimension)来描述大自然.事实上任何物体的微观平面都是凹凸不平的,因而欧氏几何所描述的对象,严格来讲,在现实生活中是不存在的。

    分形是用来描述大自然的一门几何学,它所描述的图形可以是分数维.分形的特征是整体和局部有严格的或统计意义下的自相似性.描述分形的定量参数为分维,而维数的定义种类很多,如相似维数、Hausdorff维数、盒维数(box dimansion)、拓扑维数(topological dimension)等,需要随研究对象的改变来选择.研究表明,分形在自然界中随处可见,例如,曲折而不规则的闪电路径,弯曲复杂的海岸线形状、密如蛛网的人体血管系统、变换不定的宇宙星云分布以及材料的组织生长、准晶态的晶体结构、材料的损伤等等.从地理学、生物学到物理学、化学甚至社会科学都普遍存在分形现象.分形理论在高分子科学中的应用研究也有很多文献报道,例如分形理论与各种现代分析手段相结合,已用于研究高分子的链结构、结晶过程、凝胶化过程、高分子的相形态结构等等方面.

    "Fractal"原是一个几何概念, 意为多维、超维或分维, 它打破了原来3 维空间的概念, 不仅可以超过3 维, 而且还可以有小数维(小数点以后 1 位、2 位或更多位数)空间。“Fractal”引用在纤维纱和织物(称为纤维集合体)中, 就是立体多层次、有不同尺度的纤维粗细、长短配合,以及存在着凹凸状点接触的纱、线织物结构。

    美国和日本都开始注意纤维的分形(Fractal)结构的研究,它们触及了纤维表面凹凸构造的自相似性与大自然的色、光的对应关系。分形理论和混沌论都是20世纪物理学的第三次革命,它研究自然界非线性过程内在随机性所具有的特殊规律性, 从字面上看是指一类极其零碎而复杂但有其自相似性的体系, 是在自然界中普遍存在的。它是用自相似、无标度方法全面描述宏观、中观、微观大自然的科学概念, 混沌是物理概念, 其几何形态则是分形的概念。

    天然纤维内在的分形维自然扭曲是其特有的一种分形结构, 它与合成纤维有本质的不同, 合成纤维的机械或化学卷曲, 包括三维卷曲都与天然纤维的从微纤的扭曲开始、自相似放大、最后导致的纤维扭曲截然不同。合成纤维中的超细旦、竹节丝、异截面丝、异收缩丝等都是1 维、2维甚至3维的整数维变化, 而天然纤维则是符合分形理论的分形维变化。
    关于更多分形的图片可以查看这里:http://browse.deviantart.com/cus ... r/fractals/?order=5

    至于把分形应用在游戏之中,现在已经做到有多可怕的地步了呢?请大家看看以下的几张张图片,不妨猜猜拥有这种精致画面的游戏软件,其整个游戏的大小是多少呢?

    正确答案是97KB!没错,我没有打错字,你的眼睛也没有看错,这款游戏的大小只有97KB!传统的一片3.5吋磁片可以装下十几个这款游戏!这一款第一人称的射击游戏叫做.kkrieger,是由德国的demogroup .theprodukkt 所开发,截至目前为止还在beta测试版的阶段,这款游戏之所以可以压缩到这么小的境界,就是因为游戏之中的场景和音乐几乎全部都是由动态产生,游戏之中预先存放的资料只有一些简单的几何形状和MIDI音乐档,所以自然档案大小非常小。如果这款游戏没有用“过程生成”(Procedural Generation)的技巧进来的话,估计档案大小会爆增成200~300MB,这样的技术,真是令人叹为观止。而背后最大的功臣,就是这篇文章谈到的递归和碎形。各位也不妨下载来玩玩看吧 (下载点)。 不过需要注意到一件事情,这款游戏的载入时间非常长,因为他要靠着一点点的程式码即时来运算制造出场景,所以要耗去很多计算时间,这可说是一种time和space的tradeoff。


    看完这篇文章,各位有没有对看似枯燥的数学有了一点点不同的看法呢?没想到递归可以这样应用在游戏开发之中吧。下次学习数学感觉到枯燥时,不妨从应用的角度切入试试看吧!
  • 相关阅读:
    HashMap深度解析(二)(转)
    HashMap深度解析(一)(转)
    GeoHash核心原理解析(转)
    spring boot 策略模式实践
    Java中CAS详解(转)
    springMVC请求流程详解(转)
    7 vi 编辑器
    Linux 命令行快捷键
    Java
    3 Eclipse 查看不了源码
  • 原文地址:https://www.cnblogs.com/gamesacer/p/2491426.html
Copyright © 2020-2023  润新知