<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki.swarma.org/index.php?action=history&amp;feed=atom&amp;title=%E4%BD%BF%E7%94%A8pythony%E5%AE%9E%E7%8E%B0%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95</id>
	<title>使用pythony实现遗传算法 - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.swarma.org/index.php?action=history&amp;feed=atom&amp;title=%E4%BD%BF%E7%94%A8pythony%E5%AE%9E%E7%8E%B0%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95"/>
	<link rel="alternate" type="text/html" href="https://wiki.swarma.org/index.php?title=%E4%BD%BF%E7%94%A8pythony%E5%AE%9E%E7%8E%B0%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95&amp;action=history"/>
	<updated>2026-11-03T00:31:29Z</updated>
	<subtitle>本wiki的该页面的版本历史</subtitle>
	<generator>MediaWiki 1.35.0</generator>
	<entry>
		<id>https://wiki.swarma.org/index.php?title=%E4%BD%BF%E7%94%A8pythony%E5%AE%9E%E7%8E%B0%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95&amp;diff=34746&amp;oldid=prev</id>
		<title>2024年5月21日 (二) 07:39 18810648466</title>
		<link rel="alternate" type="text/html" href="https://wiki.swarma.org/index.php?title=%E4%BD%BF%E7%94%A8pythony%E5%AE%9E%E7%8E%B0%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95&amp;diff=34746&amp;oldid=prev"/>
		<updated>2024-05-21T07:39:00Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2024年5月21日 (二) 07:39的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l273&quot; &gt;第273行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第273行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[category:python]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[category:python]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[category:旧词条迁移]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[category:旧词条迁移]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:集智相关]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>18810648466</name></author>
	</entry>
	<entry>
		<id>https://wiki.swarma.org/index.php?title=%E4%BD%BF%E7%94%A8pythony%E5%AE%9E%E7%8E%B0%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95&amp;diff=17404&amp;oldid=prev</id>
		<title>Qige96：/* 技术难点及解决方案 */</title>
		<link rel="alternate" type="text/html" href="https://wiki.swarma.org/index.php?title=%E4%BD%BF%E7%94%A8pythony%E5%AE%9E%E7%8E%B0%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95&amp;diff=17404&amp;oldid=prev"/>
		<updated>2020-10-29T10:15:36Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;技术难点及解决方案&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2020年10月29日 (四) 10:15的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l18&quot; &gt;第18行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第18行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==技术难点及解决方案==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==技术难点及解决方案==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;   --[[用户:Qige96|Ricky]]（[[用户讨论:Qige96|讨论]]）这一部分讲到的案例属于遗传编程，即用遗传算法的原理获得一个计算机程序。个人认为是一种相当高级的应用，不利于入门级读者了解遗传算法。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===使用树结构表达方程===&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===使用树结构表达方程===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l55&quot; &gt;第55行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第58行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[File:generticalgorithm6.png|500px]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[File:generticalgorithm6.png|500px]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==python实现==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==python实现==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Qige96</name></author>
	</entry>
	<entry>
		<id>https://wiki.swarma.org/index.php?title=%E4%BD%BF%E7%94%A8pythony%E5%AE%9E%E7%8E%B0%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95&amp;diff=15470&amp;oldid=prev</id>
		<title>思无涯咿呀咿呀：创建页面，内容为“==理论==  600px  遗传算法（Genetic Algorithms）是一种很有趣的理论，由密歇根大学的约翰·霍兰德（John Ho…”</title>
		<link rel="alternate" type="text/html" href="https://wiki.swarma.org/index.php?title=%E4%BD%BF%E7%94%A8pythony%E5%AE%9E%E7%8E%B0%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95&amp;diff=15470&amp;oldid=prev"/>
		<updated>2020-10-16T09:27:09Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“==理论==  &lt;a href=&quot;/index.php/%E6%96%87%E4%BB%B6:Generticalgorithm1.png&quot; title=&quot;文件:Generticalgorithm1.png&quot;&gt;600px&lt;/a&gt;  遗传算法（Genetic Algorithms）是一种很有趣的理论，由密歇根大学的约翰·霍兰德（John Ho…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==理论==&lt;br /&gt;
&lt;br /&gt;
[[File:generticalgorithm1.png|600px]]&lt;br /&gt;
&lt;br /&gt;
遗传算法（Genetic Algorithms）是一种很有趣的理论，由密歇根大学的约翰·霍兰德（John Holland）和他的同事于二十世纪六十年代在对元胞自动机（cellular automata）研究时提出。在八十年代前，对于遗传算法的研究还仅仅限于理论方面，直到在匹兹堡召开了第一届世界遗传算法大会。随着计算机计算能力的发展和实际应用需求的增多，遗传算法逐渐进入实际应用阶段。&lt;br /&gt;
&lt;br /&gt;
遗传算法的基本思想，是让程序像生物那样在交配，变异中进化，产生出更适宜环境的（逼近目标函数的）程序。&lt;br /&gt;
&lt;br /&gt;
==应用场景==&lt;br /&gt;
&lt;br /&gt;
遗传算法有很多不同的实现形式，一般都是用一个01串表达一个程序，但《集体智慧编程》（programming collective intelligence）里介绍了一种非常有意思的应用：用来寻找数据拟合的最优方程。&lt;br /&gt;
&lt;br /&gt;
假如我们有如下数据：&lt;br /&gt;
&lt;br /&gt;
[[File:generticalgorithm2.png|600px]]&lt;br /&gt;
&lt;br /&gt;
许多人的第一直觉是使用多元回归来拟合方程f(x,y)，但我们这里要用遗传算法来做这件事。我们打算用一个程序代表一个方程，然后让方程之间交配、变异，最终进化出一个最符合数据的方程。&lt;br /&gt;
&lt;br /&gt;
==技术难点及解决方案==&lt;br /&gt;
&lt;br /&gt;
===使用树结构表达方程===&lt;br /&gt;
&lt;br /&gt;
要用程序表达方程，显然不可能直接用01串实现，因为任意构造的01串及其交配变异是没有数学意义的。我们要用解析树（parse tree）的概念&lt;br /&gt;
&lt;br /&gt;
[[File:generticalgorithm3.png|500px]]&lt;br /&gt;
&lt;br /&gt;
树上的每个节点或者表达一种对它子节点进行的数学操作，或者表达一个参数或变量。运算时，树从下往上收缩。&lt;br /&gt;
&lt;br /&gt;
上述树就可以表达如下程序：&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    def func(x,y)&lt;br /&gt;
         if x&amp;gt;3:&lt;br /&gt;
         return y + 5&lt;br /&gt;
         else:&lt;br /&gt;
         return y - 2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
因此，也就表达了一个方程。实际上，大多数程序语言在使用机器编译（compile）或解释（interpret）的时候，都是先变成这样一棵树。也许只有Lisp是例外，因为它相当于要求程序员直接写出这样的树结构。看起来树似乎只能表达比较简单的运算，但如果考虑到节点位置上的数学操作可以很复杂，例如欧式距离或者高斯函数，并且叶节点可以引用根节点，构成loop，树将可以表达非常复杂的运算。&lt;br /&gt;
&lt;br /&gt;
===变异（mutation）===&lt;br /&gt;
&lt;br /&gt;
变异对于01串表达程序的遗传算法模型来说就是随机地把一些0变成1或者相反。但在树结构里，我们定义两种变异：&lt;br /&gt;
&lt;br /&gt;
一种是改变节点上的操作符号：&lt;br /&gt;
&lt;br /&gt;
[[File:generticalgorithm4.png|500px]]&lt;br /&gt;
&lt;br /&gt;
一种是替换树的一部分枝干&lt;br /&gt;
&lt;br /&gt;
[[File:generticalgorithm5.png|500px]]&lt;br /&gt;
&lt;br /&gt;
===交配(crossover)===&lt;br /&gt;
&lt;br /&gt;
交配就是让两棵树相遇，互换一部分枝干，拼接出一棵新的树&lt;br /&gt;
&lt;br /&gt;
[[File:generticalgorithm6.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==python实现==&lt;br /&gt;
&lt;br /&gt;
我们先定义树的基本结构&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    from random import random,randint,choice&lt;br /&gt;
    from copy import deepcopy&lt;br /&gt;
    import numpy as np&lt;br /&gt;
    &lt;br /&gt;
    class fwrapper:&lt;br /&gt;
        def __init__(self,function,childcount,name):&lt;br /&gt;
            self.function=function&lt;br /&gt;
            self.childcount=childcount&lt;br /&gt;
            self.name=name&lt;br /&gt;
     &lt;br /&gt;
    class node:&lt;br /&gt;
        def __init__(self,fw,children):&lt;br /&gt;
            self.function=fw.function&lt;br /&gt;
            self.name=fw.name&lt;br /&gt;
            self.children=children&lt;br /&gt;
        def evaluate(self,inp):&lt;br /&gt;
            results=[n.evaluate(inp) for n in self.children]&lt;br /&gt;
            return self.function(results)&lt;br /&gt;
        def display(self,indent=0):&lt;br /&gt;
            print (' '*indent)+self.name&lt;br /&gt;
            for c in self.children:&lt;br /&gt;
                c.display(indent+1)&lt;br /&gt;
     &lt;br /&gt;
    class paramnode:&lt;br /&gt;
        def __init__(self,idx):&lt;br /&gt;
            self.idx=idx&lt;br /&gt;
        def evaluate(self,inp):&lt;br /&gt;
            return inp[self.idx]&lt;br /&gt;
        def display(self,indent=0):&lt;br /&gt;
            print '%sp%d' % (' '*indent,self.idx)&lt;br /&gt;
     &lt;br /&gt;
    class constnode:&lt;br /&gt;
        def __init__(self,v):&lt;br /&gt;
            self.v=v&lt;br /&gt;
        def evaluate(self,inp):&lt;br /&gt;
            return self.v&lt;br /&gt;
        def display(self,indent=0):&lt;br /&gt;
            print '%s%d' % (' '*indent,self.v)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
其中fwrapper代表着一种运算，它接受三个参数：函数的定义，函数里参数的个数，函数的名字。node就是一个节点，它的evaluate函数可以接受子节点的输入，并把fawapper定义的函数运用在子节点上，得到输出结果。它的display函数可以打印出节点以下的树的形式，方便我们分析程序内部表达的函数。paramnode是参数节点，总是返回输入的参数idx，constnode是常数节点，不管输入时什么，总是返回一个常数。&lt;br /&gt;
&lt;br /&gt;
接下来我们定义一些基本的运算：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    addw=fwrapper(lambda l:l[0]+l[1],2,'add')&lt;br /&gt;
    subw=fwrapper(lambda l:l[0]-l[1],2,'subtract')&lt;br /&gt;
    mulw=fwrapper(lambda l:l[0]*l[1],2,'multiply')&lt;br /&gt;
    &lt;br /&gt;
    def iffunc(l):&lt;br /&gt;
        if l[0]&amp;gt;0: return l[1]&lt;br /&gt;
        else: return l[2]&lt;br /&gt;
    ifw=fwrapper(iffunc,3,'if')&lt;br /&gt;
    &lt;br /&gt;
    def isgreater(l):&lt;br /&gt;
        if l[0]&amp;gt;l[1]: return 1&lt;br /&gt;
        else: return 0&lt;br /&gt;
    gtw=fwrapper(isgreater,2,'isgreater')&lt;br /&gt;
    &lt;br /&gt;
    flist=[addw,mulw,ifw,gtw,subw]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
其中加减乘都可以使用lambda一句话实现，但分段函数和比较函数要先定义一个函数，然后再用fwrapper。在flist里我们把这些函数都装起来，以便将来使用。&lt;br /&gt;
&lt;br /&gt;
有了这些函数，其实我们已经可以定义一个示例树并观察其运算后果了&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    def exampletree( ):&lt;br /&gt;
        return node(ifw,[&lt;br /&gt;
        node(gtw,[paramnode(0),constnode(3)]),&lt;br /&gt;
         node(addw,[paramnode(1),constnode(5)]),&lt;br /&gt;
         node(subw,[paramnode(1),constnode(2)]),&lt;br /&gt;
         ]&lt;br /&gt;
     )&lt;br /&gt;
     &lt;br /&gt;
    exampletree=exampletree( )&lt;br /&gt;
    exampletree.evaluate([2,3])&lt;br /&gt;
    exampletree.evaluate([5,3])&lt;br /&gt;
    exampletree.display( )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
我们还可以制造随机树，用来作为演化的初始值&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    def makerandomtree(pc,maxdepth=4,fpr=0.5,ppr=0.6):&lt;br /&gt;
         if random( )&amp;lt;fpr and maxdepth&amp;gt;0:&lt;br /&gt;
             f=choice(flist)&lt;br /&gt;
             children=[makerandomtree(pc,maxdepth-1,fpr,ppr)&lt;br /&gt;
             for i in range(f.childcount)]&lt;br /&gt;
             return node(f,children)&lt;br /&gt;
         elif random( )&amp;lt;ppr:&lt;br /&gt;
             return paramnode(randint(0,pc-1))&lt;br /&gt;
         else:&lt;br /&gt;
             return constnode(randint(0,10))&lt;br /&gt;
    &lt;br /&gt;
    random1=makerandomtree(2)&lt;br /&gt;
    random1.evaluate([7,1])&lt;br /&gt;
    random1.evaluate([2,4])&lt;br /&gt;
    random2=makerandomtree(2)&lt;br /&gt;
    random2.evaluate([5,3])&lt;br /&gt;
    random2.evaluate([5,20])&lt;br /&gt;
    random1.display( )&lt;br /&gt;
    random2.display( )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
接下来我们定义变异和交配函数来对树结构进行操作。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    def mutate(t,pc,probchange=0.1):&lt;br /&gt;
         if random( )&amp;lt;probchange:&lt;br /&gt;
             return makerandomtree(pc)&lt;br /&gt;
         else:&lt;br /&gt;
             result=deepcopy(t)&lt;br /&gt;
             if isinstance(t,node):&lt;br /&gt;
                 result.children=[mutate(c,pc,probchange) for c in t.children]&lt;br /&gt;
             return result&lt;br /&gt;
    &lt;br /&gt;
    def crossover(t1,t2,probswap=0.7,top=1):&lt;br /&gt;
         if random( )&amp;lt;probswap and not top:&lt;br /&gt;
             return deepcopy(t2)&lt;br /&gt;
         else:&lt;br /&gt;
             result=deepcopy(t1)&lt;br /&gt;
             if isinstance(t1,node) and isinstance(t2,node):&lt;br /&gt;
                 result.children=[crossover(c,choice(t2.children),probswap,0) for c in t1.children]&lt;br /&gt;
         return result&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    random2.display( )&lt;br /&gt;
    muttree=mutate(random2,2)&lt;br /&gt;
    muttree.display( )&lt;br /&gt;
    cross=crossover(random1,random2)&lt;br /&gt;
    cross.display( )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
为了准备测试数据，我们使用事先给定的函数制造一个数据。其实上面那张表里面的数据就是这么制造出来的。为了便于评估数据，我们还需要准备相应的衡量一棵树拟合数据的结果的函数。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    def hiddenfunction(x,y):&lt;br /&gt;
         return x**2+2*y+3*x+5&lt;br /&gt;
    &lt;br /&gt;
    def buildhiddenset( ):&lt;br /&gt;
         rows=[]&lt;br /&gt;
         for i in range(200):&lt;br /&gt;
             x=randint(0,10)&lt;br /&gt;
             y=randint(0,10)&lt;br /&gt;
             rows.append([x,y,hiddenfunction(x,y)])&lt;br /&gt;
         return rows&lt;br /&gt;
    &lt;br /&gt;
    def scorefunction(tree,s):&lt;br /&gt;
         dif=0&lt;br /&gt;
         for data in s:&lt;br /&gt;
             v=tree.evaluate([data[0],data[1]])&lt;br /&gt;
             dif+=abs(v-data[2])&lt;br /&gt;
         return dif&lt;br /&gt;
    &lt;br /&gt;
    def getrankfunction(dataset):&lt;br /&gt;
         def rankfunction(population):&lt;br /&gt;
             scores=[(scorefunction(t,dataset),t) for t in population]&lt;br /&gt;
             scores.sort( )&lt;br /&gt;
             return scores&lt;br /&gt;
         return rankfunction&lt;br /&gt;
    &lt;br /&gt;
    hiddenset=buildhiddenset( )&lt;br /&gt;
    scorefunction(random2,hiddenset)&lt;br /&gt;
    scorefunction(random1,hiddenset)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
一切都准备好，就可以开始进行遗传算法的迭代了：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
    def evolve(pc,popsize,rankfunction,maxgen=500,&lt;br /&gt;
         mutationrate=0.1,breedingrate=0.4,pexp=0.7,pnew=0.05):&lt;br /&gt;
         # Returns a random number, tending towards lower numbers. The lower pexp&lt;br /&gt;
         # is, more lower numbers you will get&lt;br /&gt;
         def selectindex( ):&lt;br /&gt;
             return int(np.log(random( ))/np.log(pexp))&lt;br /&gt;
         # Create a random initial population&lt;br /&gt;
         population=[makerandomtree(pc) for i in range(popsize)]&lt;br /&gt;
         for i in range(maxgen):&lt;br /&gt;
             scores=rankfunction(population)&lt;br /&gt;
             print scores[0][0]&lt;br /&gt;
             if scores[0][0]==0: break&lt;br /&gt;
             # The two best always make it&lt;br /&gt;
             newpop=[scores[0][1],scores[1][1]]&lt;br /&gt;
             # Build the next generation&lt;br /&gt;
             while len(newpop)&amp;lt;popsize:&lt;br /&gt;
                 if random( )&amp;gt;pnew:&lt;br /&gt;
                     newpop.append(mutate(&lt;br /&gt;
                     crossover(scores[selectindex( )][1],&lt;br /&gt;
                     scores[selectindex( )][1],&lt;br /&gt;
                     probswap=breedingrate),&lt;br /&gt;
                     pc,probchange=mutationrate))&lt;br /&gt;
                 else:&lt;br /&gt;
                     # Add a random node to mix things up&lt;br /&gt;
                     newpop.append(makerandomtree(pc))&lt;br /&gt;
             population=newpop&lt;br /&gt;
         scores[0][1].display( )&lt;br /&gt;
         return scores[0][1]&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    rf=getrankfunction(buildhiddenset( ))&lt;br /&gt;
    final = evolve(2,500,rf,mutationrate=0.2,breedingrate=0.1,pexp=0.7,pnew=0.1)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
有趣的是，许多时候我们会找到和原始公式一模一样，但比原始公式复杂的树。其实对树本身的变换，也就是符号计算背后的原理。这样，我们就更理解为什么说数学系统其实也是一个图灵机了。&lt;br /&gt;
&lt;br /&gt;
[[category:python]]&lt;br /&gt;
[[category:旧词条迁移]]&lt;/div&gt;</summary>
		<author><name>思无涯咿呀咿呀</name></author>
	</entry>
</feed>