evolvable 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +2 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +44 -25
- data/README.md +498 -190
- data/README_YARD.md +85 -166
- data/bin/console +10 -19
- data/docs/Evolvable/ClassMethods.html +1233 -0
- data/docs/Evolvable/Community/ClassMethods.html +708 -0
- data/docs/Evolvable/Community.html +1342 -0
- data/docs/Evolvable/CountGene.html +886 -0
- data/docs/Evolvable/EqualizeGoal.html +347 -0
- data/docs/Evolvable/Error.html +134 -0
- data/docs/Evolvable/Evaluation.html +773 -0
- data/docs/Evolvable/Evolution.html +616 -0
- data/docs/Evolvable/Gene/ClassMethods.html +413 -0
- data/docs/Evolvable/Gene.html +522 -0
- data/docs/Evolvable/GeneCluster/ClassMethods.html +431 -0
- data/docs/Evolvable/GeneCluster.html +280 -0
- data/docs/Evolvable/GeneCombination.html +515 -0
- data/docs/Evolvable/GeneSpace.html +619 -0
- data/docs/Evolvable/Genome.html +1070 -0
- data/docs/Evolvable/Goal.html +500 -0
- data/docs/Evolvable/MaximizeGoal.html +348 -0
- data/docs/Evolvable/MinimizeGoal.html +348 -0
- data/docs/Evolvable/Mutation.html +729 -0
- data/docs/Evolvable/PointCrossover.html +444 -0
- data/docs/Evolvable/Population.html +2826 -0
- data/docs/Evolvable/RigidCountGene.html +501 -0
- data/docs/Evolvable/Selection.html +594 -0
- data/docs/Evolvable/Serializer.html +293 -0
- data/docs/Evolvable/UniformCrossover.html +286 -0
- data/docs/Evolvable.html +1619 -0
- data/docs/_index.html +341 -0
- data/docs/class_list.html +54 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +503 -0
- data/docs/file.README.html +750 -0
- data/docs/file_list.html +59 -0
- data/docs/frames.html +22 -0
- data/docs/index.html +750 -0
- data/docs/js/app.js +344 -0
- data/docs/js/full_list.js +242 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +1302 -0
- data/docs/top-level-namespace.html +110 -0
- data/evolvable.gemspec +6 -6
- data/examples/ascii_art.rb +5 -9
- data/examples/stickman.rb +25 -33
- data/{examples/hello_world.rb → exe/hello_evolvable_world} +46 -30
- data/lib/evolvable/community.rb +190 -0
- data/lib/evolvable/count_gene.rb +65 -0
- data/lib/evolvable/equalize_goal.rb +2 -9
- data/lib/evolvable/evaluation.rb +113 -14
- data/lib/evolvable/evolution.rb +38 -15
- data/lib/evolvable/gene.rb +124 -25
- data/lib/evolvable/gene_cluster.rb +106 -0
- data/lib/evolvable/gene_combination.rb +57 -16
- data/lib/evolvable/gene_space.rb +111 -0
- data/lib/evolvable/genome.rb +32 -4
- data/lib/evolvable/goal.rb +19 -24
- data/lib/evolvable/maximize_goal.rb +2 -9
- data/lib/evolvable/minimize_goal.rb +3 -9
- data/lib/evolvable/mutation.rb +87 -41
- data/lib/evolvable/point_crossover.rb +24 -4
- data/lib/evolvable/population.rb +258 -84
- data/lib/evolvable/rigid_count_gene.rb +36 -0
- data/lib/evolvable/selection.rb +68 -14
- data/lib/evolvable/serializer.rb +46 -0
- data/lib/evolvable/uniform_crossover.rb +30 -6
- data/lib/evolvable/version.rb +2 -1
- data/lib/evolvable.rb +268 -107
- metadata +57 -36
- data/examples/images/diagram.png +0 -0
- data/exe/hello +0 -16
- data/lib/evolvable/error/undefined_method.rb +0 -7
- data/lib/evolvable/search_space.rb +0 -181
@@ -0,0 +1,750 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>
|
7
|
+
File: README
|
8
|
+
|
9
|
+
— Documentation by YARD 0.9.37
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
16
|
+
|
17
|
+
<script type="text/javascript">
|
18
|
+
pathId = "README";
|
19
|
+
relpath = '';
|
20
|
+
</script>
|
21
|
+
|
22
|
+
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
24
|
+
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
26
|
+
|
27
|
+
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<div class="nav_wrap">
|
31
|
+
<iframe id="nav" src="file_list.html?1"></iframe>
|
32
|
+
<div id="resizer"></div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="main" tabindex="-1">
|
36
|
+
<div id="header">
|
37
|
+
<div id="menu">
|
38
|
+
|
39
|
+
<a href="_index.html">Index</a> »
|
40
|
+
<span class="title">File: README</span>
|
41
|
+
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<div id="search">
|
45
|
+
|
46
|
+
<a class="full_list_link" id="class_list_link"
|
47
|
+
href="class_list.html">
|
48
|
+
|
49
|
+
<svg width="24" height="24">
|
50
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
51
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
52
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
+
</svg>
|
54
|
+
</a>
|
55
|
+
|
56
|
+
</div>
|
57
|
+
<div class="clear"></div>
|
58
|
+
</div>
|
59
|
+
|
60
|
+
<div id="content"><div id='filecontents'><h1 id="evolvable">Evolvable 🧬</h1>
|
61
|
+
|
62
|
+
<p><a href="https://badge.fury.io/rb/evolvable"><img src="https://badge.fury.io/rb/evolvable.svg" alt="Gem Version"></a></p>
|
63
|
+
|
64
|
+
<p><strong>Code Version: 2.0.0</strong></p>
|
65
|
+
|
66
|
+
<p>Evolvable is a Ruby gem that brings genetic algorithms to Ruby objects through simple, flexible APIs. Define genes, implement fitness criteria, and let evolution discover optimal solutions through selection, combination, and mutation.</p>
|
67
|
+
|
68
|
+
<p>Perfect for optimization problems, creative content generation, machine learning, and simulating complex systems.</p>
|
69
|
+
|
70
|
+
<h2 id="why-evolvable">Why Evolvable?</h2>
|
71
|
+
|
72
|
+
<p>Evolvable is ideal when the solution space is too large or complex for brute-force methods. Instead of hardcoding solutions, you define constraints and let evolution discover optimal configurations over time.</p>
|
73
|
+
|
74
|
+
<p><strong>The Evolvable Approach:</strong></p>
|
75
|
+
|
76
|
+
<ul>
|
77
|
+
<li>Explore vast solution spaces efficiently without examining every possibility</li>
|
78
|
+
<li>Discover novel solutions that might not be obvious to human designers</li>
|
79
|
+
<li>Adapt to changing conditions through continuous evolution</li>
|
80
|
+
<li>Balance diverse objectives with communities of different populations</li>
|
81
|
+
<li>Integrate evolutionary concepts directly into your Ruby object model</li>
|
82
|
+
<li>Generate creative content like music, art, and text, not just numerical optimization</li>
|
83
|
+
</ul>
|
84
|
+
|
85
|
+
<p>Whether you're optimizing parameters, generating creative content, or simulating complex systems, Evolvable provides a natural, object-oriented approach to evolutionary algorithms.</p>
|
86
|
+
|
87
|
+
<p><strong>Creative Applications</strong></p>
|
88
|
+
|
89
|
+
<p>Evolvable treats creative, object-oriented representations as first-class citizens. The same API that optimizes numeric parameters can evolve music compositions, UI layouts, or game content with equal fluency. Examples include:</p>
|
90
|
+
|
91
|
+
<ul>
|
92
|
+
<li><strong>Generative art</strong>: Evolve visual compositions based on aesthetic criteria</li>
|
93
|
+
<li><strong>Music composition</strong>: Create melodies, chord progressions, and rhythms</li>
|
94
|
+
<li><strong>Game design</strong>: Generate levels, characters, or game mechanics</li>
|
95
|
+
<li><strong>Natural language</strong>: Evolve text with specific tones, styles, or constraints</li>
|
96
|
+
<li><strong>UI/UX design</strong>: Discover intuitive layouts and color schemes</li>
|
97
|
+
</ul>
|
98
|
+
|
99
|
+
<h2 id="table-of-contents">Table of Contents</h2>
|
100
|
+
|
101
|
+
<ul>
|
102
|
+
<li><a href="#installation">Installation</a></li>
|
103
|
+
<li><a href="#getting-started">Getting Started</a></li>
|
104
|
+
<li><a href="#concepts">Concepts</a></li>
|
105
|
+
<li><a href="#genes">Genes</a></li>
|
106
|
+
<li><a href="#populations">Populations</a></li>
|
107
|
+
<li><a href="#evaluation">Evaluation</a></li>
|
108
|
+
<li><a href="#evolution">Evolution</a></li>
|
109
|
+
<li><a href="#selection">Selection</a></li>
|
110
|
+
<li><a href="#combination">Combination</a></li>
|
111
|
+
<li><a href="#mutation">Mutation</a></li>
|
112
|
+
<li><a href="#gene-clusters">Gene Clusters</a></li>
|
113
|
+
<li><a href="#community">Community</a></li>
|
114
|
+
<li><a href="#serialization">Serialization</a></li>
|
115
|
+
<li><a href="https://mattruzicka.github.io/evolvable">Documentation</a></li>
|
116
|
+
</ul>
|
117
|
+
|
118
|
+
<h2 id="installation">Installation</h2>
|
119
|
+
|
120
|
+
<p>Add <a href="https://rubygems.org/gems/evolvable">gem "evolvable"</a> to your Gemfile and run <code>bundle install</code> or install it yourself with: <code>gem install evolvable</code></p>
|
121
|
+
|
122
|
+
<p><strong>Ruby Compatibility:</strong> Evolvable officially supports Ruby 3.0 and higher.</p>
|
123
|
+
|
124
|
+
<h2 id="getting-started">Getting Started</h2>
|
125
|
+
|
126
|
+
<p><strong>Quick start</strong>:</p>
|
127
|
+
|
128
|
+
<ol>
|
129
|
+
<li>Include <code>Evolvable</code> in your Ruby class</li>
|
130
|
+
<li>Define genes with the macro-style <code>gene</code> method</li>
|
131
|
+
<li>Have the <code>#fitness</code> method return a numeric value</li>
|
132
|
+
<li>Initialize a population and evolve it</li>
|
133
|
+
</ol>
|
134
|
+
|
135
|
+
<p>Example population of "shirts" with various colors, buttons, and collars.</p>
|
136
|
+
|
137
|
+
<pre class="code ruby"><code class="ruby"><span class='comment'># Step 1
|
138
|
+
</span><span class='kw'>class</span> <span class='const'>Shirt</span>
|
139
|
+
<span class='id identifier rubyid_include'>include</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span>
|
140
|
+
|
141
|
+
<span class='comment'># Step 2
|
142
|
+
</span> <span class='id identifier rubyid_gene'>gene</span> <span class='symbol'>:color</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='const'>ColorGene</span> <span class='comment'># count: 1 default
|
143
|
+
</span> <span class='id identifier rubyid_gene'>gene</span> <span class='symbol'>:buttons</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='const'>ButtonGene</span><span class='comma'>,</span> <span class='label'>count:</span> <span class='int'>0</span><span class='op'>..</span><span class='int'>10</span> <span class='comment'># Builds an array of genes that can vary in size
|
144
|
+
</span> <span class='id identifier rubyid_gene'>gene</span> <span class='symbol'>:collar</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='const'>CollarGene</span><span class='comma'>,</span> <span class='label'>count:</span> <span class='int'>0</span><span class='op'>..</span><span class='int'>1</span> <span class='comment'># Collar optional
|
145
|
+
</span>
|
146
|
+
<span class='comment'># Step 3
|
147
|
+
</span> <span class='id identifier rubyid_attr_accessor'>attr_accessor</span> <span class='symbol'>:fitness</span>
|
148
|
+
<span class='kw'>end</span>
|
149
|
+
|
150
|
+
<span class='comment'># Step 4
|
151
|
+
</span><span class='id identifier rubyid_population'>population</span> <span class='op'>=</span> <span class='const'>Shirt</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span><span class='label'>size:</span> <span class='int'>10</span><span class='rparen'>)</span>
|
152
|
+
<span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_evolvables'>evolvables</span><span class='period'>.</span><span class='id identifier rubyid_each'>each</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_shirt'>shirt</span><span class='op'>|</span> <span class='id identifier rubyid_shirt'>shirt</span><span class='period'>.</span><span class='id identifier rubyid_fitness'>fitness</span> <span class='op'>=</span> <span class='id identifier rubyid_style_rating'>style_rating</span> <span class='rbrace'>}</span>
|
153
|
+
</code></pre>
|
154
|
+
|
155
|
+
<p>You are free to tailor the genes to your needs and find a style that suits you.</p>
|
156
|
+
|
157
|
+
<p>The <code>ColorGene</code> could be as simple as this:</p>
|
158
|
+
|
159
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>ColorGene</span>
|
160
|
+
<span class='id identifier rubyid_include'>include</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/Gene.html" title="Evolvable::Gene (module)">Gene</a></span></span>
|
161
|
+
|
162
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_to_s'>to_s</span>
|
163
|
+
<span class='ivar'>@to_s</span> <span class='op'>||=</span> <span class='qwords_beg'>%w[</span><span class='tstring_content'>red</span><span class='words_sep'> </span><span class='tstring_content'>green</span><span class='words_sep'> </span><span class='tstring_content'>blue</span><span class='tstring_end'>]</span></span><span class='period'>.</span><span class='id identifier rubyid_sample'>sample</span>
|
164
|
+
<span class='kw'>end</span>
|
165
|
+
<span class='kw'>end</span>
|
166
|
+
</code></pre>
|
167
|
+
|
168
|
+
<p>Shirts aren't your style?</p>
|
169
|
+
|
170
|
+
<p>Here's a <a href="https://github.com/mattruzicka/evolvable/blob/main/exe/hello_evolvable_world">Hello World</a>
|
171
|
+
command line demo.</p>
|
172
|
+
|
173
|
+
<h2 id="concepts">Concepts</h2>
|
174
|
+
|
175
|
+
<p>Evolvable is built on these core concepts:</p>
|
176
|
+
|
177
|
+
<ul>
|
178
|
+
<li><strong>Genes</strong>: Ruby objects that represent traits or behaviors and are passed down during evolution.</li>
|
179
|
+
<li><strong>Evolvables</strong>: Your Ruby classes that include "Evolvable" and delegate to genes</li>
|
180
|
+
<li><strong>Populations</strong>: Groups of evolvables instances that evolve together</li>
|
181
|
+
<li><strong>Evaluation</strong>: Sorts evolvables by fitness</li>
|
182
|
+
<li><strong>Evolution</strong>: Selection → Combination → Mutation to generate new evolvables</li>
|
183
|
+
<li><strong>Communities</strong>: Encapsulate evolvable populations</li>
|
184
|
+
</ul>
|
185
|
+
|
186
|
+
<p>The framework offers built-in implementations while allowing domain-specific customization through its extensible and swapable components.</p>
|
187
|
+
|
188
|
+
<h2 id="genes">Genes</h2>
|
189
|
+
|
190
|
+
<p>Genes are the building blocks of evolvable objects, encapsulating individual characteristics
|
191
|
+
that can be combined and mutated during evolution. Each gene represents a trait or behavior
|
192
|
+
that can influence an evolvable's performance.</p>
|
193
|
+
|
194
|
+
<p><strong>To define a gene class:</strong></p>
|
195
|
+
|
196
|
+
<ol>
|
197
|
+
<li>Include the <code>Evolvable::Gene</code> module</li>
|
198
|
+
<li>Define how the gene's value is determined</li>
|
199
|
+
</ol>
|
200
|
+
|
201
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>BehaviorGene</span>
|
202
|
+
<span class='id identifier rubyid_include'>include</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/Gene.html" title="Evolvable::Gene (module)">Gene</a></span></span>
|
203
|
+
|
204
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_value'>value</span>
|
205
|
+
<span class='ivar'>@value</span> <span class='op'>||=</span> <span class='qwords_beg'>%w[</span><span class='tstring_content'>explore</span><span class='words_sep'> </span><span class='tstring_content'>gather</span><span class='words_sep'> </span><span class='tstring_content'>attack</span><span class='words_sep'> </span><span class='tstring_content'>defend</span><span class='words_sep'> </span><span class='tstring_content'>build</span><span class='tstring_end'>]</span></span><span class='period'>.</span><span class='id identifier rubyid_sample'>sample</span>
|
206
|
+
<span class='kw'>end</span>
|
207
|
+
<span class='kw'>end</span>
|
208
|
+
</code></pre>
|
209
|
+
|
210
|
+
<p>Then use it in an evolvable class:</p>
|
211
|
+
|
212
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>Robot</span>
|
213
|
+
<span class='id identifier rubyid_include'>include</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span>
|
214
|
+
|
215
|
+
<span class='id identifier rubyid_gene'>gene</span> <span class='symbol'>:behaviors</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='const'>BehaviorGene</span><span class='comma'>,</span> <span class='label'>count:</span> <span class='int'>3</span><span class='op'>..</span><span class='int'>5</span>
|
216
|
+
<span class='id identifier rubyid_gene'>gene</span> <span class='symbol'>:speed</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='const'>SpeedGene</span><span class='comma'>,</span> <span class='label'>count:</span> <span class='int'>1</span>
|
217
|
+
|
218
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_fitness'>fitness</span>
|
219
|
+
<span class='id identifier rubyid_run_simulation'>run_simulation</span><span class='lparen'>(</span><span class='label'>behaviors:</span> <span class='id identifier rubyid_behaviors'>behaviors</span><span class='period'>.</span><span class='id identifier rubyid_map'>map</span><span class='lparen'>(</span><span class='op'>&</span><span class='symbol'>:value</span><span class='rparen'>)</span><span class='comma'>,</span> <span class='label'>speed:</span> <span class='id identifier rubyid_speed'>speed</span><span class='period'>.</span><span class='id identifier rubyid_value'>value</span><span class='rparen'>)</span>
|
220
|
+
<span class='kw'>end</span>
|
221
|
+
<span class='kw'>end</span>
|
222
|
+
</code></pre>
|
223
|
+
|
224
|
+
<p><strong>Gene Count</strong></p>
|
225
|
+
|
226
|
+
<p>You can control how many copies of a gene are created using the <code>count:</code> parameter:</p>
|
227
|
+
|
228
|
+
<ul>
|
229
|
+
<li><code>count: 1</code> (default) creates a single instance.</li>
|
230
|
+
<li>A numeric value (e.g. <code>count: 5</code>) creates a fixed number of genes using <code>RigidCountGene</code>.</li>
|
231
|
+
<li>A range (e.g. <code>count: 2..8</code>) creates a variable number of genes using <code>CountGene</code>, allowing the count to evolve over time.</li>
|
232
|
+
</ul>
|
233
|
+
|
234
|
+
<p>Evolves melody length:</p>
|
235
|
+
|
236
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_gene'>gene</span> <span class='symbol'>:notes</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='const'>NoteGene</span><span class='comma'>,</span> <span class='label'>count:</span> <span class='int'>4</span><span class='op'>..</span><span class='int'>12</span>
|
237
|
+
</code></pre>
|
238
|
+
|
239
|
+
<p><strong>Custom Combination</strong></p>
|
240
|
+
|
241
|
+
<p>By default, the <code>combine</code> method randomly picks one of the two parent genes.
|
242
|
+
A gene class can implement custom behavior by overriding <code>.combine</code>.</p>
|
243
|
+
|
244
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>SpeedGene</span>
|
245
|
+
<span class='id identifier rubyid_include'>include</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/Gene.html" title="Evolvable::Gene (module)">Gene</a></span></span>
|
246
|
+
|
247
|
+
<span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_combine'>combine</span><span class='lparen'>(</span><span class='id identifier rubyid_gene_a'>gene_a</span><span class='comma'>,</span> <span class='id identifier rubyid_gene_b'>gene_b</span><span class='rparen'>)</span>
|
248
|
+
<span class='id identifier rubyid_new_gene'>new_gene</span> <span class='op'>=</span> <span class='id identifier rubyid_new'>new</span>
|
249
|
+
<span class='id identifier rubyid_new_gene'>new_gene</span><span class='period'>.</span><span class='id identifier rubyid_value'>value</span> <span class='op'>=</span> <span class='lparen'>(</span><span class='id identifier rubyid_gene_a'>gene_a</span><span class='period'>.</span><span class='id identifier rubyid_value'>value</span> <span class='op'>+</span> <span class='id identifier rubyid_gene_b'>gene_b</span><span class='period'>.</span><span class='id identifier rubyid_value'>value</span><span class='rparen'>)</span> <span class='op'>/</span> <span class='int'>2</span>
|
250
|
+
<span class='id identifier rubyid_new_gene'>new_gene</span>
|
251
|
+
<span class='kw'>end</span>
|
252
|
+
|
253
|
+
<span class='id identifier rubyid_attr_writer'>attr_writer</span> <span class='symbol'>:value</span>
|
254
|
+
|
255
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_value'>value</span>
|
256
|
+
<span class='ivar'>@value</span> <span class='op'>||=</span> <span class='id identifier rubyid_rand'>rand</span><span class='lparen'>(</span><span class='int'>1</span><span class='op'>..</span><span class='int'>100</span><span class='rparen'>)</span>
|
257
|
+
<span class='kw'>end</span>
|
258
|
+
<span class='kw'>end</span>
|
259
|
+
</code></pre>
|
260
|
+
|
261
|
+
<p><strong>Design Patterns</strong></p>
|
262
|
+
|
263
|
+
<p>Effective gene design typically follows these principles:</p>
|
264
|
+
|
265
|
+
<ul>
|
266
|
+
<li><strong>Immutability</strong>: Cache values after initial sampling (e.g., <code>@value ||= ...</code>)</li>
|
267
|
+
<li><strong>Self-Contained</strong>: Genes should encapsulate their logic and state</li>
|
268
|
+
<li><strong>Composable</strong>: You can build complex structures using multiple genes or clusters</li>
|
269
|
+
<li><strong>Domain-Specific</strong>: Genes should map directly to your problem’s traits or features</li>
|
270
|
+
</ul>
|
271
|
+
|
272
|
+
<p>Genes come in various types, each representing different aspects of a solution.
|
273
|
+
Common examples include numeric genes for quantities, selection genes for choices
|
274
|
+
from sets, boolean genes for binary decisions, structural genes for architecture,
|
275
|
+
and parameter genes for configuration settings.</p>
|
276
|
+
|
277
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/Gene">Gene Documentation</a></p>
|
278
|
+
|
279
|
+
<h2 id="populations">Populations</h2>
|
280
|
+
|
281
|
+
<p>Populations orchestrate the evolutionary process through four key components:</p>
|
282
|
+
|
283
|
+
<ol>
|
284
|
+
<li><strong>Evaluation</strong>: Sorts evolvable instances by fitness</li>
|
285
|
+
<li><strong>Selection</strong>: Chooses parents for combination</li>
|
286
|
+
<li><strong>Combination</strong>: Creates new evolvables from selected parents</li>
|
287
|
+
<li><strong>Mutation</strong>: Introduces variation to maintain genetic diversity</li>
|
288
|
+
</ol>
|
289
|
+
|
290
|
+
<p><strong>Features</strong>:</p>
|
291
|
+
|
292
|
+
<p>Initialize a population with default or custom parameters:</p>
|
293
|
+
|
294
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span> <span class='op'>=</span> <span class='const'>YourEvolvable</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span>
|
295
|
+
<span class='label'>size:</span> <span class='int'>50</span><span class='comma'>,</span>
|
296
|
+
<span class='label'>evaluation:</span> <span class='lbrace'>{</span> <span class='label'>equalize:</span> <span class='int'>0</span> <span class='rbrace'>}</span><span class='comma'>,</span>
|
297
|
+
<span class='label'>selection:</span> <span class='lbrace'>{</span> <span class='label'>size:</span> <span class='int'>10</span> <span class='rbrace'>}</span><span class='comma'>,</span>
|
298
|
+
<span class='label'>mutation:</span> <span class='lbrace'>{</span> <span class='label'>probability:</span> <span class='float'>0.2</span><span class='comma'>,</span> <span class='label'>rate:</span> <span class='float'>0.02</span> <span class='rbrace'>}</span>
|
299
|
+
<span class='rparen'>)</span>
|
300
|
+
</code></pre>
|
301
|
+
|
302
|
+
<p>Or inject fully customized strategy objects:</p>
|
303
|
+
|
304
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span> <span class='op'>=</span> <span class='const'>YourEvolvable</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span>
|
305
|
+
<span class='label'>evaluation:</span> <span class='const'>Your</span><span class='op'>::</span><span class='const'>Evaluation</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='comma'>,</span>
|
306
|
+
<span class='label'>evolution:</span> <span class='const'>Your</span><span class='op'>::</span><span class='const'>Evolution</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='comma'>,</span>
|
307
|
+
<span class='label'>selection:</span> <span class='const'>Your</span><span class='op'>::</span><span class='const'>Selection</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='comma'>,</span>
|
308
|
+
<span class='label'>combination:</span> <span class='const'>Your</span><span class='op'>::</span><span class='const'>Combination</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='comma'>,</span>
|
309
|
+
<span class='label'>mutation:</span> <span class='const'>Your</span><span class='op'>::</span><span class='const'>Mutation</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span>
|
310
|
+
<span class='rparen'>)</span>
|
311
|
+
</code></pre>
|
312
|
+
|
313
|
+
<p>Evolve your population:</p>
|
314
|
+
|
315
|
+
<pre class="code ruby"><code class="ruby">population.evolve(count: 20) # Run for 20 generations
|
316
|
+
population.evolve_to_goal # Run until the current goal is met
|
317
|
+
population.evolve_to_goal(0.0) # Run until a specific goal is met
|
318
|
+
population.evolve_forever # Run indefinitely, ignoring any goal
|
319
|
+
population.evolve_selected([...]) # Use a custom subset of evolvables
|
320
|
+
</code></pre>
|
321
|
+
|
322
|
+
<p>Create new evolvables:</p>
|
323
|
+
|
324
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_new'>new</span> <span class='op'>=</span> <span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_new_evolvable'>new_evolvable</span>
|
325
|
+
<span class='id identifier rubyid_many'>many</span> <span class='op'>=</span> <span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_new_evolvables'>new_evolvables</span><span class='lparen'>(</span><span class='label'>count:</span> <span class='int'>10</span><span class='rparen'>)</span>
|
326
|
+
<span class='id identifier rubyid_with_genome'>with_genome</span> <span class='op'>=</span> <span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_new_evolvable'>new_evolvable</span><span class='lparen'>(</span><span class='label'>genome:</span> <span class='id identifier rubyid_another'>another</span><span class='period'>.</span><span class='id identifier rubyid_genome'>genome</span><span class='rparen'>)</span>
|
327
|
+
</code></pre>
|
328
|
+
|
329
|
+
<p>Customize the evolution lifecycle by implementing hooks:</p>
|
330
|
+
|
331
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_before_evaluation'>before_evaluation</span><span class='lparen'>(</span><span class='id identifier rubyid_pop'>pop</span><span class='rparen'>)</span><span class='semicolon'>;</span> <span class='kw'>end</span>
|
332
|
+
<span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_before_evolution'>before_evolution</span><span class='lparen'>(</span><span class='id identifier rubyid_pop'>pop</span><span class='rparen'>)</span><span class='semicolon'>;</span> <span class='kw'>end</span>
|
333
|
+
<span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_after_evolution'>after_evolution</span><span class='lparen'>(</span><span class='id identifier rubyid_pop'>pop</span><span class='rparen'>)</span><span class='semicolon'>;</span> <span class='kw'>end</span>
|
334
|
+
</code></pre>
|
335
|
+
|
336
|
+
<p>Evaluate progress:</p>
|
337
|
+
|
338
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_best'>best</span> <span class='op'>=</span> <span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_best_evolvable'>best_evolvable</span> <span class='kw'>if</span> <span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_met_goal?'>met_goal?</span>
|
339
|
+
</code></pre>
|
340
|
+
|
341
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/Population">Population Documentation</a></p>
|
342
|
+
|
343
|
+
<h2 id="evaluation">Evaluation</h2>
|
344
|
+
|
345
|
+
<p>Evaluation sorts evolvables based on their fitness and provides mechanisms to
|
346
|
+
change the goal type and value (fitness goal). Goals define the success criteria
|
347
|
+
for evolution. They allow you to specify what your population is evolving toward,
|
348
|
+
whether it's maximizing a value, minimizing a value, or seeking a specific value.</p>
|
349
|
+
|
350
|
+
<p><strong>How It Works</strong></p>
|
351
|
+
|
352
|
+
<ol>
|
353
|
+
<li><p>Your evolvable class defines a <code>#fitness</code> method that returns a
|
354
|
+
<a href="https://docs.ruby-lang.org/en//3.4/Comparable.html">Comparable</a> object.</p>
|
355
|
+
|
356
|
+
<ul>
|
357
|
+
<li>Preferably a numeric value like an integer or float.</li>
|
358
|
+
</ul></li>
|
359
|
+
<li><p>During evolution, evolvables are sorted by your goal's fitness interpretation</p>
|
360
|
+
|
361
|
+
<ul>
|
362
|
+
<li>The default goal type is <code>:maximize</code>, see goal types below for other options</li>
|
363
|
+
</ul></li>
|
364
|
+
<li><p>If a goal value is specified, evolution will stop when it is met</p></li>
|
365
|
+
</ol>
|
366
|
+
|
367
|
+
<p><strong>Goal Types</strong></p>
|
368
|
+
|
369
|
+
<ul>
|
370
|
+
<li>Maximize (higher is better)</li>
|
371
|
+
</ul>
|
372
|
+
|
373
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_robots'>robots</span> <span class='op'>=</span> <span class='const'>Robot</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span><span class='label'>evaluation:</span> <span class='symbol'>:maximize</span><span class='rparen'>)</span> <span class='comment'># Defaults to infinity
|
374
|
+
</span><span class='id identifier rubyid_robots'>robots</span><span class='period'>.</span><span class='id identifier rubyid_evolve_to_goal'>evolve_to_goal</span><span class='lparen'>(</span><span class='int'>100</span><span class='rparen'>)</span> <span class='comment'># Evolve until fitness reaches 100+
|
375
|
+
</span>
|
376
|
+
<span class='comment'># Same as above
|
377
|
+
</span><span class='const'>Robot</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span><span class='label'>evaluation:</span> <span class='lbrace'>{</span> <span class='label'>maximize:</span> <span class='int'>100</span> <span class='rbrace'>}</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_evolve_to_goal'>evolve_to_goal</span>
|
378
|
+
</code></pre>
|
379
|
+
|
380
|
+
<ul>
|
381
|
+
<li>Minimize (lower is better)</li>
|
382
|
+
</ul>
|
383
|
+
|
384
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_errors'>errors</span> <span class='op'>=</span> <span class='const'>ErrorModel</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span><span class='label'>evaluation:</span> <span class='symbol'>:minimize</span><span class='rparen'>)</span> <span class='comment'># Defaults to -infinity
|
385
|
+
</span><span class='id identifier rubyid_errors'>errors</span><span class='period'>.</span><span class='id identifier rubyid_evolve_to_goal'>evolve_to_goal</span><span class='lparen'>(</span><span class='float'>0.01</span><span class='rparen'>)</span> <span class='comment'># Evolve until error rate reaches 0.01 or less
|
386
|
+
</span>
|
387
|
+
<span class='comment'># Same as above
|
388
|
+
</span><span class='const'>ErrorModel</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span><span class='label'>evaluation:</span> <span class='lbrace'>{</span> <span class='label'>minimize:</span> <span class='float'>0.01</span> <span class='rbrace'>}</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_evolve_to_goal'>evolve_to_goal</span>
|
389
|
+
</code></pre>
|
390
|
+
|
391
|
+
<ul>
|
392
|
+
<li>Equalize (closer to target is better)</li>
|
393
|
+
</ul>
|
394
|
+
|
395
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_targets'>targets</span> <span class='op'>=</span> <span class='const'>TargetMatcher</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span><span class='label'>evaluation:</span> <span class='symbol'>:equalize</span><span class='rparen'>)</span> <span class='comment'># Defaults to 0
|
396
|
+
</span><span class='id identifier rubyid_targets'>targets</span><span class='period'>.</span><span class='id identifier rubyid_evolve_to_goal'>evolve_to_goal</span><span class='lparen'>(</span><span class='int'>42</span><span class='rparen'>)</span> <span class='comment'># Evolve until we match the target value
|
397
|
+
</span>
|
398
|
+
<span class='comment'># Same as above
|
399
|
+
</span><span class='const'>TargetMatcher</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span><span class='label'>evaluation:</span> <span class='lbrace'>{</span> <span class='label'>equalize:</span> <span class='int'>42</span> <span class='rbrace'>}</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_evolve_to_goal'>evolve_to_goal</span>
|
400
|
+
</code></pre>
|
401
|
+
|
402
|
+
<p><strong>Custom Goals</strong></p>
|
403
|
+
|
404
|
+
<p>You can create custom goals by subclassing <code>Evolvable::Goal</code> and implementing:</p>
|
405
|
+
|
406
|
+
<ul>
|
407
|
+
<li><code>evaluate(evolvable)</code>: Return a value that for sorting evolvables</li>
|
408
|
+
<li><code>met?(evolvable)</code>: Returns true when the goal value is reached</li>
|
409
|
+
</ul>
|
410
|
+
|
411
|
+
<p>Example goal implementation that prioritizes evolvables with fitness values within a specific range:</p>
|
412
|
+
|
413
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>YourRangeGoal</span> <span class='op'><</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/Goal.html" title="Evolvable::Goal (class)">Goal</a></span></span>
|
414
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_value'>value</span>
|
415
|
+
<span class='ivar'>@value</span> <span class='op'>||=</span> <span class='int'>0</span><span class='op'>..</span><span class='int'>100</span>
|
416
|
+
<span class='kw'>end</span>
|
417
|
+
|
418
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_evaluate'>evaluate</span><span class='lparen'>(</span><span class='id identifier rubyid_evolvable'>evolvable</span><span class='rparen'>)</span>
|
419
|
+
<span class='kw'>return</span> <span class='int'>1</span> <span class='kw'>if</span> <span class='id identifier rubyid_value'>value</span><span class='period'>.</span><span class='id identifier rubyid_include?'>include?</span><span class='lparen'>(</span><span class='id identifier rubyid_evolvable'>evolvable</span><span class='period'>.</span><span class='id identifier rubyid_fitness'>fitness</span><span class='rparen'>)</span>
|
420
|
+
|
421
|
+
<span class='id identifier rubyid_min'>min</span><span class='comma'>,</span> <span class='id identifier rubyid_max'>max</span> <span class='op'>=</span> <span class='id identifier rubyid_value'>value</span><span class='period'>.</span><span class='id identifier rubyid_minmax'>minmax</span>
|
422
|
+
<span class='op'>-</span><span class='lbracket'>[</span><span class='lparen'>(</span><span class='id identifier rubyid_min'>min</span> <span class='op'>-</span> <span class='id identifier rubyid_evolvable'>evolvable</span><span class='period'>.</span><span class='id identifier rubyid_fitness'>fitness</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_abs'>abs</span><span class='comma'>,</span> <span class='lparen'>(</span><span class='id identifier rubyid_max'>max</span> <span class='op'>-</span> <span class='id identifier rubyid_evolvable'>evolvable</span><span class='period'>.</span><span class='id identifier rubyid_fitness'>fitness</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_abs'>abs</span><span class='rbracket'>]</span><span class='period'>.</span><span class='id identifier rubyid_min'>min</span>
|
423
|
+
<span class='kw'>end</span>
|
424
|
+
|
425
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_met?'>met?</span><span class='lparen'>(</span><span class='id identifier rubyid_evolvable'>evolvable</span><span class='rparen'>)</span>
|
426
|
+
<span class='id identifier rubyid_value'>value</span><span class='period'>.</span><span class='id identifier rubyid_include?'>include?</span><span class='lparen'>(</span><span class='id identifier rubyid_evolvable'>evolvable</span><span class='period'>.</span><span class='id identifier rubyid_fitness'>fitness</span><span class='rparen'>)</span>
|
427
|
+
<span class='kw'>end</span>
|
428
|
+
<span class='kw'>end</span>
|
429
|
+
</code></pre>
|
430
|
+
|
431
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/Evaluation">Evaluation Documentation</a></p>
|
432
|
+
|
433
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/Goal">Goal Documentation</a></p>
|
434
|
+
|
435
|
+
<h2 id="evolution">Evolution</h2>
|
436
|
+
|
437
|
+
<p><strong>Evolution</strong> moves a population from one generation to the next.
|
438
|
+
It runs in three steps: selection, combination, and mutation.
|
439
|
+
You can swap out any step with your own strategy.</p>
|
440
|
+
|
441
|
+
<p>Default pipeline:</p>
|
442
|
+
|
443
|
+
<ol>
|
444
|
+
<li><strong>Selection</strong> – keep the most fit evolvables</li>
|
445
|
+
<li><strong>Combination</strong> – create offspring by recombining genes</li>
|
446
|
+
<li><strong>Mutation</strong> – add random variation to preserve diversity</li>
|
447
|
+
</ol>
|
448
|
+
|
449
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/Evolution">Evolution Documentation</a></p>
|
450
|
+
|
451
|
+
<h2 id="selection">Selection</h2>
|
452
|
+
|
453
|
+
<p>Selection determines which evolvables will serve as parents for the next
|
454
|
+
generation. You can control the selection process in several ways:</p>
|
455
|
+
|
456
|
+
<p>Set the selection size during population initialization:</p>
|
457
|
+
|
458
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span> <span class='op'>=</span> <span class='const'>MyEvolvable</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span>
|
459
|
+
<span class='label'>selection:</span> <span class='lbrace'>{</span> <span class='label'>size:</span> <span class='int'>3</span> <span class='rbrace'>}</span>
|
460
|
+
<span class='rparen'>)</span>
|
461
|
+
</code></pre>
|
462
|
+
|
463
|
+
<p>Adjust the selection size after initialization:</p>
|
464
|
+
|
465
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_selection_size'>selection_size</span> <span class='op'>=</span> <span class='int'>4</span>
|
466
|
+
</code></pre>
|
467
|
+
|
468
|
+
<p>Manually assign the selected evolvables:</p>
|
469
|
+
|
470
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_selected_evolvables'>selected_evolvables</span> <span class='op'>=</span> <span class='lbracket'>[</span><span class='id identifier rubyid_evolvable1'>evolvable1</span><span class='comma'>,</span> <span class='id identifier rubyid_evolvable2'>evolvable2</span><span class='rbracket'>]</span>
|
471
|
+
</code></pre>
|
472
|
+
|
473
|
+
<p>Or evolve a custom selection directly:</p>
|
474
|
+
|
475
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_evolve_selected'>evolve_selected</span><span class='lparen'>(</span><span class='lbracket'>[</span><span class='id identifier rubyid_evolvable1'>evolvable1</span><span class='comma'>,</span> <span class='id identifier rubyid_evolvable2'>evolvable2</span><span class='rbracket'>]</span><span class='rparen'>)</span>
|
476
|
+
</code></pre>
|
477
|
+
|
478
|
+
<p>This flexibility lets you implement custom selection strategies,
|
479
|
+
overriding or augmenting the built-in behavior.</p>
|
480
|
+
|
481
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/Selection">Selection Documentation</a></p>
|
482
|
+
|
483
|
+
<h2 id="combination">Combination</h2>
|
484
|
+
|
485
|
+
<p>Combination is the process of creating new evolvables by mixing the genes
|
486
|
+
of selected parents. This step drives the creation of the next generation
|
487
|
+
by recombining traits in novel ways.</p>
|
488
|
+
|
489
|
+
<p>You can choose from several built-in combination strategies or implement your own.
|
490
|
+
By default, Evolvable uses <code>Evolvable::GeneCombination</code>, which delegates
|
491
|
+
gene-level behavior to individual gene classes.</p>
|
492
|
+
|
493
|
+
<p>To define custom combination logic for a gene type, implement:</p>
|
494
|
+
|
495
|
+
<pre class="code ruby"><code class="ruby"><span class='const'>YourGeneClass</span><span class='period'>.</span><span class='id identifier rubyid_combine'>combine</span><span class='lparen'>(</span><span class='id identifier rubyid_parent_1_gene'>parent_1_gene</span><span class='comma'>,</span> <span class='id identifier rubyid_parent_2_gene'>parent_2_gene</span><span class='rparen'>)</span>
|
496
|
+
</code></pre>
|
497
|
+
|
498
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/Combination">Combination Documentation</a></p>
|
499
|
+
|
500
|
+
<p><strong>Point Crossover</strong></p>
|
501
|
+
|
502
|
+
<p>A classic genetic algorithm strategy that performs single or multi-point crossover
|
503
|
+
by selecting random positions in the genome and swapping gene segments between parents.</p>
|
504
|
+
|
505
|
+
<ul>
|
506
|
+
<li><strong>Single-point crossover (default):</strong> Swaps all genes after a randomly chosen position.</li>
|
507
|
+
<li><strong>Multi-point crossover:</strong> Alternates segments between multiple randomly chosen points.</li>
|
508
|
+
</ul>
|
509
|
+
|
510
|
+
<p>Best for:</p>
|
511
|
+
|
512
|
+
<ul>
|
513
|
+
<li>Preserving beneficial gene blocks</li>
|
514
|
+
<li>Problems where related traits are located near each other</li>
|
515
|
+
</ul>
|
516
|
+
|
517
|
+
<p>Set your population to use this strategy during initialization with:</p>
|
518
|
+
|
519
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span> <span class='op'>=</span> <span class='const'>MyEvolvable</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span>
|
520
|
+
<span class='label'>combination:</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/PointCrossover.html" title="Evolvable::PointCrossover (class)">PointCrossover</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Evolvable/PointCrossover.html#initialize-instance_method" title="Evolvable::PointCrossover#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='label'>points_count:</span> <span class='int'>2</span><span class='rparen'>)</span>
|
521
|
+
<span class='rparen'>)</span>
|
522
|
+
</code></pre>
|
523
|
+
|
524
|
+
<p>Or update an existing population:</p>
|
525
|
+
|
526
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_combination'>combination</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/PointCrossover.html" title="Evolvable::PointCrossover (class)">PointCrossover</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'><span class='object_link'><a href="Evolvable/PointCrossover.html#initialize-instance_method" title="Evolvable::PointCrossover#initialize (method)">new</a></span></span><span class='lparen'>(</span><span class='label'>points_count:</span> <span class='int'>3</span><span class='rparen'>)</span>
|
527
|
+
</code></pre>
|
528
|
+
|
529
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/PointCrossover">PointCrossover Documentation</a></p>
|
530
|
+
|
531
|
+
<p><strong>Uniform Crossover</strong></p>
|
532
|
+
|
533
|
+
<p>Chooses genes independently at each position, selecting randomly from either
|
534
|
+
parent with equal probability. No segments are preserved—each gene is treated
|
535
|
+
in isolation.</p>
|
536
|
+
|
537
|
+
<p>Best for:</p>
|
538
|
+
|
539
|
+
<ul>
|
540
|
+
<li>Problems where gene order doesn't matter</li>
|
541
|
+
<li>High genetic diversity and exploration</li>
|
542
|
+
<li>Complex interdependencies across traits</li>
|
543
|
+
</ul>
|
544
|
+
|
545
|
+
<p>Uniform crossover is especially effective when good traits are scattered across the genome.</p>
|
546
|
+
|
547
|
+
<p>Set your population to use this strategy during initialization with:</p>
|
548
|
+
|
549
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span> <span class='op'>=</span> <span class='const'>MyEvolvable</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span>
|
550
|
+
<span class='label'>combination:</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/UniformCrossover.html" title="Evolvable::UniformCrossover (class)">UniformCrossover</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span>
|
551
|
+
<span class='rparen'>)</span>
|
552
|
+
</code></pre>
|
553
|
+
|
554
|
+
<p>Or update an existing population:</p>
|
555
|
+
|
556
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_combination'>combination</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/UniformCrossover.html" title="Evolvable::UniformCrossover (class)">UniformCrossover</a></span></span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span>
|
557
|
+
</code></pre>
|
558
|
+
|
559
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/UniformCrossover">UniformCrossover Documentation</a></p>
|
560
|
+
|
561
|
+
<h2 id="mutation">Mutation</h2>
|
562
|
+
|
563
|
+
<p>Mutation introduces genetic variation by randomly replacing genes with new
|
564
|
+
ones. This helps the population explore new areas of the solution space
|
565
|
+
and prevents premature convergence on suboptimal solutions.</p>
|
566
|
+
|
567
|
+
<p>Mutation is controlled by two key parameters:</p>
|
568
|
+
|
569
|
+
<ul>
|
570
|
+
<li><strong>probability</strong>: Likelihood that an individual will undergo mutation (range: 0.0–1.0)</li>
|
571
|
+
<li><strong>rate</strong>: Fraction of genes to mutate within those individuals (range: 0.0–1.0)</li>
|
572
|
+
</ul>
|
573
|
+
|
574
|
+
<p>A typical strategy is to start with higher mutation to encourage exploration:</p>
|
575
|
+
|
576
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span> <span class='op'>=</span> <span class='const'>MyEvolvable</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span><span class='lparen'>(</span>
|
577
|
+
<span class='label'>mutation:</span> <span class='lbrace'>{</span> <span class='label'>probability:</span> <span class='float'>0.4</span><span class='comma'>,</span> <span class='label'>rate:</span> <span class='float'>0.2</span> <span class='rbrace'>}</span>
|
578
|
+
<span class='rparen'>)</span>
|
579
|
+
</code></pre>
|
580
|
+
|
581
|
+
<p>Then later reduce the mutation rate to focus on refinement and convergence:</p>
|
582
|
+
|
583
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_mutation_probability'>mutation_probability</span> <span class='op'>=</span> <span class='float'>0.1</span>
|
584
|
+
<span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_mutation_rate'>mutation_rate</span> <span class='op'>=</span> <span class='float'>0.05</span>
|
585
|
+
</code></pre>
|
586
|
+
|
587
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/Mutation">Mutation Documentation</a></p>
|
588
|
+
|
589
|
+
<h2 id="gene-clusters">Gene Clusters</h2>
|
590
|
+
|
591
|
+
<p>Gene clusters group related genes into reusable components that can be applied
|
592
|
+
to multiple evolvable classes. This promotes clean organization, eliminates
|
593
|
+
naming conflicts, and simplifies gene access.</p>
|
594
|
+
|
595
|
+
<p><strong>Benefits:</strong></p>
|
596
|
+
|
597
|
+
<ul>
|
598
|
+
<li>Reuse gene groups across multiple evolvables</li>
|
599
|
+
<li>Prevent name collisions via automatic namespacing</li>
|
600
|
+
<li>Treat clusters as structured subcomponents of a genome</li>
|
601
|
+
<li>Access all genes in a cluster with a single method call</li>
|
602
|
+
</ul>
|
603
|
+
|
604
|
+
<p>The <code>ColorPaletteCluster</code> below defines a group of genes commonly used for styling themes:</p>
|
605
|
+
|
606
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>ColorPaletteCluster</span>
|
607
|
+
<span class='id identifier rubyid_include'>include</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/GeneCluster.html" title="Evolvable::GeneCluster (module)">GeneCluster</a></span></span>
|
608
|
+
|
609
|
+
<span class='id identifier rubyid_gene'>gene</span> <span class='symbol'>:primary</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>ColorGene</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>count:</span> <span class='int'>1</span>
|
610
|
+
<span class='id identifier rubyid_gene'>gene</span> <span class='symbol'>:secondary</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>ColorGene</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>count:</span> <span class='int'>1</span>
|
611
|
+
<span class='id identifier rubyid_gene'>gene</span> <span class='symbol'>:accent</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>ColorGene</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>count:</span> <span class='int'>1</span>
|
612
|
+
<span class='id identifier rubyid_gene'>gene</span> <span class='symbol'>:neutral</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>ColorGene</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>count:</span> <span class='int'>1</span>
|
613
|
+
<span class='kw'>end</span>
|
614
|
+
</code></pre>
|
615
|
+
|
616
|
+
<p>Use the <code>cluster</code> macro to apply the cluster to your evolvable class:</p>
|
617
|
+
|
618
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>Theme</span>
|
619
|
+
<span class='id identifier rubyid_include'>include</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span>
|
620
|
+
|
621
|
+
<span class='id identifier rubyid_cluster'>cluster</span> <span class='symbol'>:colors</span><span class='comma'>,</span> <span class='label'>type:</span> <span class='const'>ColorPaletteCluster</span>
|
622
|
+
|
623
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_inspect_colors'>inspect_colors</span>
|
624
|
+
<span class='id identifier rubyid_colors'>colors</span><span class='period'>.</span><span class='id identifier rubyid_join'>join</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>, </span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
625
|
+
<span class='kw'>end</span>
|
626
|
+
<span class='kw'>end</span>
|
627
|
+
</code></pre>
|
628
|
+
|
629
|
+
<p>When a cluster is applied, its genes are automatically namespaced with the cluster name:</p>
|
630
|
+
|
631
|
+
<ul>
|
632
|
+
<li>Access the full group: <code>theme.colors</code> → returns all genes in the colors cluster</li>
|
633
|
+
<li>Access individual genes: <code>theme.find_gene("colors-primary")</code></li>
|
634
|
+
</ul>
|
635
|
+
|
636
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/GeneCluster">GeneCluster Documentation</a></p>
|
637
|
+
|
638
|
+
<h2 id="community">Community</h2>
|
639
|
+
|
640
|
+
<p>The <code>Community</code> module provides a framework for coordinating multiple evolvable populations
|
641
|
+
under a unified interface. Each population represents a distinct type of evolvable, and
|
642
|
+
each key returns a single evolvable instance drawn from its corresponding population.</p>
|
643
|
+
|
644
|
+
<p>Communities are ideal for simulations or systems where different components evolve
|
645
|
+
in parallel but interact as part of a larger whole - such as ecosystems, design systems,
|
646
|
+
or modular agents. Evolvables from different populations can co-evolve, influencing each other's fitness.</p>
|
647
|
+
|
648
|
+
<p>Use the <code>evolvable_community</code> macro to declare the set of named populations in the community.
|
649
|
+
Each population will have a corresponding method (e.g., <code>fish_1</code>, <code>plant</code>, <code>shrimp</code>) that
|
650
|
+
returns a single evolvable instance. You can evolve all populations together using the
|
651
|
+
<code>evolve</code> method, or per population.</p>
|
652
|
+
|
653
|
+
<p><strong>Key Features</strong></p>
|
654
|
+
|
655
|
+
<ul>
|
656
|
+
<li>Define a community composed of named populations</li>
|
657
|
+
<li>Automatically generate accessors for each evolvable instance</li>
|
658
|
+
<li>Coordinate evolution across populations through a shared interface</li>
|
659
|
+
<li>Evolve all populations in a single call with <code>evolve(...)</code></li>
|
660
|
+
</ul>
|
661
|
+
|
662
|
+
<p>This <code>FishTank</code> example sets up a community with four named populations:</p>
|
663
|
+
|
664
|
+
<pre class="code ruby"><code class="ruby"><span class='kw'>class</span> <span class='const'>FishTank</span>
|
665
|
+
<span class='id identifier rubyid_include'>include</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/Community.html" title="Evolvable::Community (module)">Community</a></span></span>
|
666
|
+
|
667
|
+
<span class='id identifier rubyid_evolvable_community'>evolvable_community</span> <span class='label'>fish_1:</span> <span class='const'>Fish</span><span class='comma'>,</span>
|
668
|
+
<span class='label'>fish_2:</span> <span class='const'>Fish</span><span class='comma'>,</span>
|
669
|
+
<span class='label'>plant:</span> <span class='const'>AquariumPlant</span><span class='comma'>,</span>
|
670
|
+
<span class='label'>shrimp:</span> <span class='const'>CleanerShrimp</span>
|
671
|
+
|
672
|
+
<span class='kw'>def</span> <span class='id identifier rubyid_describe_tank'>describe_tank</span>
|
673
|
+
<span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>🐟 Fish 1: </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_fish_1'>fish_1</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span><span class='embexpr_end'>}</span><span class='tstring_content'> (</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_fish_1'>fish_1</span><span class='period'>.</span><span class='id identifier rubyid_color'>color</span><span class='embexpr_end'>}</span><span class='tstring_content'>)</span><span class='tstring_end'>"</span></span>
|
674
|
+
<span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>🐟 Fish 2: </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_fish_2'>fish_2</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span><span class='embexpr_end'>}</span><span class='tstring_content'> (</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_fish_2'>fish_2</span><span class='period'>.</span><span class='id identifier rubyid_color'>color</span><span class='embexpr_end'>}</span><span class='tstring_content'>)</span><span class='tstring_end'>"</span></span>
|
675
|
+
<span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>🌿 Plant: </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_plant'>plant</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span><span class='embexpr_end'>}</span><span class='tstring_content'> (</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_plant'>plant</span><span class='period'>.</span><span class='id identifier rubyid_color'>color</span><span class='embexpr_end'>}</span><span class='tstring_content'>)</span><span class='tstring_end'>"</span></span>
|
676
|
+
<span class='id identifier rubyid_puts'>puts</span> <span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>🦐 Shrimp: </span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_shrimp'>shrimp</span><span class='period'>.</span><span class='id identifier rubyid_name'>name</span><span class='embexpr_end'>}</span><span class='tstring_content'> (</span><span class='embexpr_beg'>#{</span><span class='id identifier rubyid_shrimp'>shrimp</span><span class='period'>.</span><span class='id identifier rubyid_color'>color</span><span class='embexpr_end'>}</span><span class='tstring_content'>)</span><span class='tstring_end'>"</span></span>
|
677
|
+
<span class='kw'>end</span>
|
678
|
+
<span class='kw'>end</span>
|
679
|
+
</code></pre>
|
680
|
+
|
681
|
+
<p>Initialize the community, describe the tank, and evolve each population:</p>
|
682
|
+
|
683
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_tank'>tank</span> <span class='op'>=</span> <span class='const'>FishTank</span><span class='period'>.</span><span class='id identifier rubyid_new_community'>new_community</span>
|
684
|
+
<span class='id identifier rubyid_tank'>tank</span><span class='period'>.</span><span class='id identifier rubyid_describe_tank'>describe_tank</span>
|
685
|
+
<span class='id identifier rubyid_tank'>tank</span><span class='period'>.</span><span class='id identifier rubyid_evolve'>evolve</span>
|
686
|
+
</code></pre>
|
687
|
+
|
688
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/Community">Community Documentation</a></p>
|
689
|
+
|
690
|
+
<h2 id="serialization">Serialization</h2>
|
691
|
+
|
692
|
+
<p>Evolvable supports saving and restoring the state of both populations
|
693
|
+
and individual evolvable instances through a built-in <code>Serializer</code>.
|
694
|
+
By default, it uses Ruby's <code>Marshal</code> class for fast, portable binary serialization.</p>
|
695
|
+
|
696
|
+
<p>Serialization is useful for:</p>
|
697
|
+
|
698
|
+
<ul>
|
699
|
+
<li>Saving progress during long-running evolution</li>
|
700
|
+
<li>Storing champion solutions for later reuse</li>
|
701
|
+
<li>Transferring evolved populations between systems</li>
|
702
|
+
<li>Creating checkpoints you can revert to</li>
|
703
|
+
</ul>
|
704
|
+
|
705
|
+
<p>Both <code>Population</code> and individual evolvables expose <code>dump</code> and <code>load</code> methods
|
706
|
+
that use the <code>Serializer</code> internally.</p>
|
707
|
+
|
708
|
+
<p>Save a population to a file:</p>
|
709
|
+
|
710
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_population'>population</span> <span class='op'>=</span> <span class='const'>YourEvolvable</span><span class='period'>.</span><span class='id identifier rubyid_new_population'>new_population</span>
|
711
|
+
<span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_evolve'>evolve</span><span class='lparen'>(</span><span class='label'>count:</span> <span class='int'>100</span><span class='rparen'>)</span>
|
712
|
+
<span class='const'>File</span><span class='period'>.</span><span class='id identifier rubyid_write'>write</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>population.marshal</span><span class='tstring_end'>"</span></span><span class='comma'>,</span> <span class='id identifier rubyid_population'>population</span><span class='period'>.</span><span class='id identifier rubyid_dump'>dump</span><span class='rparen'>)</span>
|
713
|
+
</code></pre>
|
714
|
+
|
715
|
+
<p>Restore and continue evolution:</p>
|
716
|
+
|
717
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_data'>data</span> <span class='op'>=</span> <span class='const'>File</span><span class='period'>.</span><span class='id identifier rubyid_read'>read</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>population.marshal</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
718
|
+
<span class='id identifier rubyid_restored'>restored</span> <span class='op'>=</span> <span class='const'><span class='object_link'><a href="Evolvable.html" title="Evolvable (module)">Evolvable</a></span></span><span class='op'>::</span><span class='const'><span class='object_link'><a href="Evolvable/Population.html" title="Evolvable::Population (class)">Population</a></span></span><span class='period'>.</span><span class='id identifier rubyid_load'><span class='object_link'><a href="Evolvable/Population.html#load-class_method" title="Evolvable::Population.load (method)">load</a></span></span><span class='lparen'>(</span><span class='id identifier rubyid_data'>data</span><span class='rparen'>)</span>
|
719
|
+
<span class='id identifier rubyid_restored'>restored</span><span class='period'>.</span><span class='id identifier rubyid_evolve'>evolve</span><span class='lparen'>(</span><span class='label'>count:</span> <span class='int'>100</span><span class='rparen'>)</span>
|
720
|
+
</code></pre>
|
721
|
+
|
722
|
+
<p>Save an individual evolvable's genome:</p>
|
723
|
+
|
724
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_best'>best</span> <span class='op'>=</span> <span class='id identifier rubyid_restored'>restored</span><span class='period'>.</span><span class='id identifier rubyid_best_evolvable'>best_evolvable</span>
|
725
|
+
<span class='const'>File</span><span class='period'>.</span><span class='id identifier rubyid_write'>write</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>champion.marshal</span><span class='tstring_end'>"</span></span><span class='comma'>,</span> <span class='id identifier rubyid_best'>best</span><span class='period'>.</span><span class='id identifier rubyid_dump_genome'>dump_genome</span><span class='rparen'>)</span>
|
726
|
+
</code></pre>
|
727
|
+
|
728
|
+
<p>Restore genome into a new evolvable:</p>
|
729
|
+
|
730
|
+
<pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_raw'>raw</span> <span class='op'>=</span> <span class='const'>File</span><span class='period'>.</span><span class='id identifier rubyid_read'>read</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>"</span><span class='tstring_content'>champion.marshal</span><span class='tstring_end'>"</span></span><span class='rparen'>)</span>
|
731
|
+
<span class='id identifier rubyid_champion'>champion</span> <span class='op'>=</span> <span class='const'>YourEvolvable</span><span class='period'>.</span><span class='id identifier rubyid_new_evolvable'>new_evolvable</span>
|
732
|
+
<span class='id identifier rubyid_champion'>champion</span><span class='period'>.</span><span class='id identifier rubyid_load_genome'>load_genome</span><span class='lparen'>(</span><span class='id identifier rubyid_raw'>raw</span><span class='rparen'>)</span>
|
733
|
+
</code></pre>
|
734
|
+
|
735
|
+
<p><a href="https://mattruzicka.github.io/evolvable/Evolvable/Serializer">Serializer Documentation</a></p>
|
736
|
+
|
737
|
+
<h2 id="contributing">Contributing</h2>
|
738
|
+
|
739
|
+
<p>Bug reports and pull requests are welcome on GitHub at <a href="https://github.com/mattruzicka/evolvable">https://github.com/mattruzicka/evolvable</a>.</p>
|
740
|
+
</div></div>
|
741
|
+
|
742
|
+
<div id="footer">
|
743
|
+
Generated on Sat May 10 18:39:22 2025 by
|
744
|
+
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
745
|
+
0.9.37 (ruby-3.4.2).
|
746
|
+
</div>
|
747
|
+
|
748
|
+
</div>
|
749
|
+
</body>
|
750
|
+
</html>
|