📄
字号:
<TD width="24%">指令</TD>
<TD width="34%">状态</TD>
<TD width="42%">画图动作</TD></TR>
<TR>
<TD>起始时刻</TD>
<TD>(2,0,90)</TD>
<TD>无</TD></TR>
<TR>
<TD>F</TD>
<TD>(2,1,90)</TD>
<TD>向上画一条长为1的线段</TD></TR>
<TR>
<TD>F</TD>
<TD>(2,2,90)</TD>
<TD>向上画一条长为1的线段</TD></TR>
<TR>
<TD>+</TD>
<TD>(2,2,180)</TD>
<TD>逆时针旋转90度,不画图</TD></TR>
<TR>
<TD>F</TD>
<TD>(1,2,180)</TD>
<TD>向左画一条长为1的线段</TD></TR></TBODY></TABLE>
<P> 下面看看比较复杂的画图指令:FF[+F][-F],起始状态和刚才一样仍然是(2,0,90),且l为1,转角为90度。<BR> 前两个F和上面叙述的执行情况差不多,下面开始讲"["操作,"["操作的含义就是把当前的画图状态先存起来,假设有一个大皮包M可以存放这些状态,那么当执行完操作FF的时候,画图状态是(2,2,90),下面遇到了"["<BR>命令,那么我们把这个状态存到皮包M中,这样M={(2,2,90)},表示M中有一个状态为(2,2,90),"["指令除了存储状态到皮包中其他什么动作也不做,当前的状态仍然是(2,2,90)。接下来执行+命令,逆时针旋转90度,则状态变成(2,2,180),然后是F则往左画一条线段,状态为(1,2,180)。接下来执行指令"]",它表示从皮包中取出一个状态作为当前的状态,这样,皮包中有一个状态(2,2,90),因此当前的状态就变为了(2,2,90),也就是说我们的铅笔回到了(2,2)点,并且方向朝上,这个时候由于从皮包M中取走了东西,所以皮包就空了。结下的指令为[依然把状态(2,2,90)存到皮包中,然后-则顺时针旋转90度,状态变为(2,2,0),执行F则往右画一条线段,所以我们最后能够得到下面的图形:</P>
<P align=center><IMG height=149
src="电脑中的花园.files/l2.gif" width=150></P>
<P
align=left> 画这个图形的命令执行、当前状态、存储情况如下表:</P>
<TABLE borderColor=#000000 width="70%" align=center
border=1>
<TBODY>
<TR bgColor=#cccccc>
<TD width="21%"><FONT color=#000000>指令</FONT></TD>
<TD width="21%"><FONT color=#000000>状态</FONT></TD>
<TD width="19%"><FONT
color=#000000>M中存储的值</FONT></TD>
<TD width="39%"><FONT
color=#000000>画图情况</FONT></TD></TR>
<TR>
<TD>起始时刻</TD>
<TD>(2,0,90)</TD>
<TD>空</TD>
<TD>无</TD></TR>
<TR>
<TD>F</TD>
<TD>(2,1,90)</TD>
<TD>空</TD>
<TD>向上画一条长为1的线段</TD></TR>
<TR>
<TD>F</TD>
<TD>(2,2,90)</TD>
<TD>空</TD>
<TD>向上画一条长为1的线段</TD></TR>
<TR>
<TD>[</TD>
<TD>(2,2,90)</TD>
<TD>(2,2,90)</TD>
<TD>无</TD></TR>
<TR>
<TD>+</TD>
<TD>(2,2,180)</TD>
<TD>(2,2,90)</TD>
<TD>逆时针旋转90度,不画图</TD></TR>
<TR>
<TD>F</TD>
<TD>(2,1,180)</TD>
<TD>(2,2,90)</TD>
<TD>向左画一条长为1的线段</TD></TR>
<TR>
<TD>]</TD>
<TD>(2,2,90)</TD>
<TD>空</TD>
<TD>无</TD></TR>
<TR>
<TD>[</TD>
<TD>(2,2,90)</TD>
<TD>(2,2,90)</TD>
<TD>无</TD></TR>
<TR>
<TD>-</TD>
<TD>(2,2,0)</TD>
<TD>(2,2,90)</TD>
<TD>无</TD></TR>
<TR>
<TD>F</TD>
<TD>(2,3,0)</TD>
<TD>(2,2,90)</TD>
<TD>向右画一条长为1的线段</TD></TR>
<TR>
<TD>]</TD>
<TD>(2,2,90)</TD>
<TD>空</TD>
<TD>无</TD></TR></TBODY></TABLE>
<P> 我们已经知道了由F,+,-,[,]这样的符号可以构成一串画图的指令指导机器画图,也就是说给定一个符号串就能对应的画出这个符号串代表的图形,那么如果用一种办法能够生成这样的符号串序列,那么相当于可以构造出图形来。这种生成指令的办法是什么呢?答案就是产生式系统。</P>
<P> 产生式(也叫做规则)是形如X->Y的式子,其中X叫做左件,Y叫做右件。X->Y表示X能够推导出Y。如果X是一个字符串,Y也是字符串,那么X->Y表示能够用Y来替换X。例如如果给定一个初始时刻的字符串ABXXTT,那么运用规则X->Y就能把这个字符串变成ABYYTT。如果产生式的右件多于一个字符,那么就能推导出比原来字符串更长的字符串来。例如如果X->YYY,那么ABXXTT会被替换成ABYYYTT,显然后来的字符串比原来的长。我们已经看到了从简单的字符串生成复杂字符串的可行性了。</P>
<P> 接下来,要说明的是产生式可以进行嵌套的表示,比如说X->XY就是一种嵌套的形式。因为当你用右件XY代替前件X的时候产生的新字符又会产生X,而X又可以运用规则X->XY,这样可以无限次的迭代下去。</P>
<P> 好了,有了产生式就不难理解产生式系统了,它就是由若干个产生式构成的一组语句。并且各个产生式之间可以相互替换字符串。比如如下的产生式系统:X->YF,
Y->+FX,开始时刻的字符串是X,用这两个规则跌代1次就能得到字符串:+FXF,迭代2次就是+F+FXFF,3次是+F+F+FXFFF,……。(这里跌代一次表示的是用产生式系统中的所有产生式规则都来替换当前的字符串)。我们已经看到,最后的式子就是形如我们上面列举的指令例子,如果把最后的X忽略掉,这个指令串就能指导机器画图了!这就是L系统的工作原理!下面我们以画出下面的枝条为例,再看看L系统是如何运行的。</P>
<P align=center><IMG height=195
src="电脑中的花园.files/l3.gif" width=100></P>
<P
align=left> 已知这个图形的产生式系统是:F->F[+F]F[-F]F,开始的时候字符串是F。转角为-25.7341度。这样,我们跌代6次就可以得到最终的画图指令(太长,此处略去),再把这个指令字符串对应的指导机器画出图形,就能得到上面的图。你可以点击程序中单步运行的按钮,看看系统跌代不同的次数能够产生什么样的图形。</P>
<P align=left><STRONG>引申</STRONG>:</P>
<P
align=left> 在这里我们看到了产生式系统是如何产生复杂的符号串序列,而符号串序列又是如何指导画图的。整个这个过程都体现了复杂系统的思想,也就是简单的规则孕育着复杂的行为。不难看出来,程序里的图形大部分都是类似于植物的,那么L系统的方法就给了我们启示,植物的生长是受类似于产生式规则指导的生成过程。如果我们完全把图形上画一条线段理解成植物枝干的一次生长,那么运用L系统的方法我们不难生成类似于真正植物的人工植物。</P>
<P
align=left> L系统的方法还能回答这个问题:为什么小小的种子可以孕育整个的植物呢?要知道,自然界的植物形态是非常非常复杂的,因此植物所包含的信息量也是很大的,种子这个小东西怎么能包含整个树木的信息呢?如果你理解了L系统的工作原理,你就不难回答这个问题了,那就是种子中包含的信息不是整个树的信息,而是生成这个树木的规则!而这个规则是简单的,信息量是很小的。这样,树木的生长就是一个根据种子中的规则和自然界的相互作用产生复杂树木的过程。</P>
<P
align=left> 聪明的人可能会继续问,那种子中的规则从哪里来的呢?答案是自然进化来的,如果把树木理解为指令的生成结果,那么自然选择就是发生在规则层面的事情。也就是说自然选择不是简单的对树木进行直接选择,而是对种子中所蕴含的规则进行选择的。那么,在自然界,规则又是如何决定树木的生长的呢?答案是物理规律!正是自然界中的物理规律完成了从植物种子中解码指导植物生成的过程。</P>
<P
align=left> 进一步,生命体也是这样,基因记载了指令,也就是生成动物特征的规则,物理规律决定了基因生成生命个体的过程。</P>
<P align=left>源程序下载:<A
href="file:///E:/clustering/thesis/program/java_ifs.zip">java_ifs.zip</A></P>
<P align=left>有关分形的其他文章:</P>
<P align=center><A
onclick="return js_callpage(this.href);"
href="file:///E:/clustering/complex/down2top/fractal/ifs.htm">出水芙蓉(函数跌代系统)</A></P>
<P align=center><A
onclick="return js_callpage(this.href);"
href="file:///E:/clustering/complex/down2top/fractal/intro.htm">奇异世界之旅</A></P>
<P>相关的论文及程序:</P>
<TABLE borderColor=#3366ff height=200 width="100%"
border=1>
<TBODY>
<TR>
<TD><IFRAME align=top|left marginWidth=0
marginHeight=0 src="电脑中的花园.files/disp.asp"
frameBorder=0 width="100%" scrolling=yes
height="100%">
</IFRAME></TD></TR></TBODY></TABLE><!-- #EndEditable --></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD width="100%" background=电脑中的花园.files/topic_04.gif
height=14>
</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR>
<TR></TR></TBODY></TABLE><!-- #BeginLibraryItem "/Library/framebottom.lbi" --><TD
background="电脑中的花园.files/default_02.gif" valign="top">
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD background=电脑中的花园.files/bottom.gif
height=21> </TD></TR></TBODY></TABLE><IFRAME align=top|left marginWidth=0
marginHeight=0 src="res://C:\WINNT\System32\shdoclc.dll/dnserror.htm"
frameBorder=0 width=1 scrolling=no height=1>
</IFRAME></TD><!-- #EndLibraryItem -->
<TABLE cellSpacing=0 cellPadding=0 width=760 border=0>
<TBODY></TBODY></TABLE><!-- InstanceEnd --></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -