利用演化算法,製作一個植物生長動畫,從種子開始直到生長為完全成熟的植物
從種子開始
設置宇宙為 50x100 的矩形細胞網格,其中下部 1/3 的區域為土壤
每個網格細胞都具有以下屬性:
- 葉含量 Leafiness:範圍 0~1,1 表示純葉子,0 表示純樹幹
- 能量 Energy:範圍 0~1,0 表示死細胞,呈現透明色
換言之,地平線上方的死細胞為藍色(天空),下方的死細胞為棕色(土壤)
- 營養 Nourishment:範圍 0~1
- 計算的日照 Calculated Sunlight
- 計算的水量 Calculated Water
從種子開始,種子會佔據三個垂直的網格,表示為 葉,莖,根,具體屬性如下:
Leafiness (for root): 0
Nourishment (for root): 1
Energy (for root): 1
Leafiness (for stem): 0.5
Nourishment (for stem): 1
Energy (for stem): 1
Leafiness (for leaf): 0
Nourishment (for leaf): 1
Energy (for leaf): 1
其他細胞的所有屬性值都是 0
調色板
要繪製植物,需要確定每個活細胞的顏色,構造一個調色板(RGB):
Fully leafy color (greenish) = [0, 255, 0]
Fully stem color (brownish) = [165, 42, 42]
Sky color (bluish) = [135, 206, 250]
Dirt color (grayish) = [96, 96, 96]
Root color (white) = [255,255,255]
根據葉含量來計算像素在全葉(綠色)和全莖(棕色)的顏色
植物生長動畫
需要兩個系統一起工作:
- 物理學系統控制植物結構完整性、光和水的吸收,以及植物內部的養分迴圈
- 植物生長系統根據植物的 DNA 來管理其發育
物理特征
植物的物理特征決定了植物如何吸收陽光和分配營養,葉含量較多的部分吸收更多陽光,根長得越深得到的水就越多
此外,我們還要保持宇宙的物理特征相對簡單
首先確定光和水的分佈。從上至下的方式來計算光,矩形頂部的光是最強的,用長度等於宇宙寬度的向量來表示光,並初始化為 1,自上而下計算每行的光向量,值會隨著植物的吸收而減少
設置衰減量等於葉含量乘以 0.1,假設 0.5 的光穿過 0.9 的葉,則衰減 0.9x0.1=0.09,穿過後的光即為 0.5x0.09=0.045
同樣的方法也可以自下而上的計算水向量
一旦光向量/水向量超過地平線,就將其置為 0 向量
接下來是植物內部的養分迴圈,這個過程允許來自陽光的能量到達根部,以及地下的營養到達葉子
能量 e 和養分 n 都是標量,每次迴圈,都要計算每個活著的細胞的 e 和 n
只考慮活著的細胞,我們的養分只沿單方向流動,營養向上,能量向下
能量是其上方三個細胞計算出的最大能量
營養是去下方三個細胞計算出的最大營養
當前細胞的計算營養值為養分迴圈營養值和水向量的最大值
當前細胞的計算能量值為養分迴圈能量值和光向量的最大值
此外設置一個閾值,當營養下降的閾值之下,細胞將死亡
植物生長
植物需要有 DNA,來決定其生長方式。植物 DNA 向量實質上是一個程式,植物運行該程式,以確定如何生長。
DNA 是 4 個長度為 4 的向量,共 16 個值
四個向量中的每一個都對應於一個細胞的 DNA 向量。細胞的狀態可以是死(空)或生(填充)
每個向量的 4 個數字表示:
- 0,高度,0~1
- 1,日照亮(地面上的細胞),水量(地面下的細胞)
- 2,鄰居的擁擠程度
- 3,營養
4 個向量:
- 0,莖期望
- 1,葉期望
- 2,生長選項 1
- 3,生長選項 2
向量 0 和 1 一起使用,對於每個活細胞,我們判斷其更接近 0 還是 1,如果更接近 0,我們會降低葉含量(只有葉子可以變成莖,莖無法變成葉)
向量 2 和 3 一起使用,當細胞符合生長條件時,它將評估所有相鄰位置,以選擇其生長位置。它會選擇最接近向量 2 或 3 的相鄰位置。如果候選位置不低於向量 2 或 3 的特定閾值,則不會發生增長。
判斷是否可以增長的方法:
root ratio = sum(root nourishment) / sum(leafiness)
如果該比率小於 0.5,則根可以生長;大於 0.5,則地面之上的細胞可以生長
演化植物
演化演算法可以演化 DNA 向量從而讓植物生長,這裡採用遺傳演算法
給植物計分
植物的綠色越明顯,得分越高。
我們採用活細胞的平均葉含量作為分數,根計 0.5 分
score = 0
count = 0
# Assume that universe contains cells after 100
# cycles of a particular plant growing.
for each cell in universe:
if cell is alive:
count = count + 1
if cell is root:
# Give partial credit for a root
score = score + 0.5
else:
score = score + cell.leafiness
# Calculate average leafiness and roots
score = score / count