<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 十一、進化 > 原文:[Chapter 11 Evolution](http://greenteapress.com/complexity2/html/thinkcomplexity2012.html) > 譯者:[飛龍](https://github.com/wizardforcel) > 協議:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) > 自豪地采用[谷歌翻譯](https://translate.google.cn/) 生物學乃至整個科學最重要的思想,是通過自然選擇的進化論,它聲稱由于自然選擇而創造出新的物種并改變現有的物種。自然選擇是個體間遺傳差異導致生存和繁殖差異的過程。 在了解生物學的人中,進化論被廣泛認為是一個事實,也就是它足以接近事實,如果將來得到糾正,糾正將使中心思想基本保持完整。 盡管如此,許多人并不相信進化論。在皮尤研究中心進行的一項調查中,被調查者被問到,以下哪些斷言更貼近他們的觀點: + 人類和其他生物隨時間而進化。 + 起初,人類和其他生物就以其現在的形式存在。 約有 34% 的美國人選擇了第二個(見 <http://www.thearda.com/Archive/Files/Codebooks/RELLAND14_CB.asp>)。 即使在那些認為生物已經進化的人中,只有一半以上的人認為進化的原因是自然選擇。 換句話說,只有三分之一的美國人相信進化論是真實的。 這怎么可能? 在我看來,促成因素包括: + 有些人認為進化論與他們的宗教信仰之間有沖突。 感覺就像他們不得不拒絕一個,他們拒絕了進化論。 + 其他人經常被第一組成員積極誤導,以至于他們對進化論的許多認識都是錯誤的。 + 許多人根本就不了解進化。 對于第一組,我可能沒有太多可以做的事,但我認為我可以幫助其他人。 經驗上,進化論很難讓人理解。 同時,它非常簡單:對很多人來說,一旦他們了解進化論,它似乎既明顯又無可辯駁。 為了幫助人們從困惑轉變為清晰,我找到的最強大的工具就是計算。 我們看到,理論上很難理解的想法,在模擬中出現時很容易理解。 這是本章的目標。 本章的代碼位于`chap11.ipynb`中,該書是本書倉庫中的 Jupyter 筆記本。使用此代碼的更多信息,請參見第?節。 ## 11.1 簡單的進化 我將從一個簡單的模型開始,演示一種基本的進化形式。 根據該理論,以下特征足以產生進化: + 復制者:我們需要一批能夠以某種方式復制的智能體。 我們將以復制者開始,它們生成它們自己的完美的副本。 稍后我們將添加不完美的副本,即突變。 + 突變:我們還需要一些種群中的變化,也就是個體之間的差異。 + 生存和繁殖差異:個體之間的差異必須影響其生存或繁殖的能力。 為了模擬這些特征,我們將定義智能體種群,智能體代表個體。 每個智能體都有遺傳信息,稱為基因型,這是智能體繁殖時復制的信息。 在我們的模型中 [1],基因型由`N`個二進制數字(零和一)的序列表示,其中`N`是我們選擇的參數。 > [1] 模型是主要由 Stuart Kauffman 開發的 NK 模型的變體(參見 <https://en.wikipedia.org/wiki/NK_model>)。 為了產生突變,我們創建了具有多種基因型的種群;稍后我們將探討創造或增加突變的機制。 最后,為了產生生存和繁殖差異,我們定義了一個函數,將每個基因型映射為一個適應度,其中適應度是一個數量,有關智能體的生存或繁殖能力。 ## 11.2 適應性景觀 將基因型映射為適應性函數,稱為適應性景觀。 在景觀的隱喻中,每個基因型對應于`N`維空間中的一個位置,并且適應性對應于該位置處的景觀的“高度”。對于能夠解釋這個隱喻的可視化,參見 <https://en.wikipedia.org/wiki/Fitness_landscape>。 在生物學術語中,適應性景觀代表一種信息,它是生物體的基因型與其物理形式和能力的關系,后者稱為其表現型,以及表現型如何與其環境相互作用。 在現實世界中,適應性景觀很復雜,但我們不需要建立現實模型。 為了誘導進化,我們需要基因型和適應性之間的某種關系,但事實證明它可以是任何關系。 為了證明它,我們將使用完全隨機的適應性景觀。 這是代表適應性景觀的類的定義: ```py class FitnessLandscape: def __init__(self, N): self.N = N self.one_values = np.random.random(N) self.zero_values = np.random.random(N) def fitness(self, loc): fs = np.where(loc, self.one_values, self.zero_values) return fs.mean() ``` 智能體的基因型,對應其在適應性景觀中的位置,由一個 NumPy 的零一數組來表示,稱為`loc`。 給定基因型的適應性,是`N`個適應性貢獻的平均值,`loc`的每個元素都是一個。 為了計算基因型的適應性,`FitnessLandscape`使用兩個數組:`one_values`,其中包含`loc`的每個元素都為 1 時的適應性貢獻,以及`zero_values`,其中包含為 0 時的適應度貢獻。 `fitness`方法使用`np.where`,如果`loc`中的值為 1,它從`one_values`中選擇一個值,如果`loc`中的值為 0,它從`zero_values`中選擇一個值。 例如,假設`N=3`: ```py one_values = [0.1, 0.2, 0.3] zero_values = [0.4, 0.7, 0.9] ``` 這種情況下,`loc = [0, 1, 0]`的適應性是`[0.4, 0.2, 0.9]`的均值,為 0.5。 ## 11.3 智能體 接下來我們需要智能體,這是類定義: ```py class Agent: def __init__(self, loc, fit_land): self.loc = loc self.fit_land = fit_land self.fitness = fit_land.fitness(self.loc) def copy(self): return Agent(self.loc, self.fit_land) ``` 智能體的屬性是: `loc`:智能體在適應性景觀中的位置。 `fit_land`:`FitnessLandscape`對象的引用。 `fitness`:智能體在`FitnessLandscape`中的適應性,表示為 0 到 1 之間的數字。 `Agent`的這個定義提供了一種簡單的`copy`方法,可以精確復制基因型;之后,我們將看到一個帶有突變的版本,但突變對于進化來說不是必需的。 ## 11.4 模擬 現在我們有了智能體和適應性景觀,我將定義一個名為`Simulation`的類,用于模擬智能體的創建,繁殖和死亡。 為了避免陷入困境,我將在這里提供一個簡化版本的代碼;你可以在本章的筆記本上看到細節。 這是`Simulation`的定義: ```py class Simulation: def __init__(self, fit_land, agents): self.fit_land = fit_land self.agents = agents ``` `Simulation`的屬性是: + `fit_land`:`FitnessLandscape`對象的引用。 + `agents`:`Agent`對象的數組。 `Simulation`中最重要的函數是`step`,它模擬了單個時間步驟: ```py # class Simulation: def step(self): n = len(self.agents) fits = self.get_fitnesses() # see who dies index_dead = self.choose_dead(fits) num_dead = len(index_dead) # replace the dead with copies of the living replacements = self.choose_replacements(num_dead, fits) self.agents[index_dead] = replacements ``` 在每個時間步驟中,一些智能體死亡,一些智能體繁殖。 `step`使用另外三個方法: + `get_fitnesses`返回一個數組,包含每個智能體的適應性,按照它們在智能體數組中出現的順序。 + `choose_dead`決定哪些智能體在此時間步中死亡,并返回一個數組,包含死亡智能體的索引。 + `choose_replacements`決定哪些智能體在此時間步中繁殖,在每個智能體上調用`copy`,并返回一個新的`Agent`對象的數組。 在這個版本的模擬中,每個時間步中新智能體的數量等于死亡智能體的數量,所以活動智能體的數量是恒定的。 ## 11.5 沒有差異 在我們運行模擬之前,我們必須指定`choose_dead`和`choose_replacements`的行為。 我們將從這些函數的簡單版本開始,它們不依賴于適應性: ```py # class Simulation def choose_dead(self, fits): n = len(self.agents) is_dead = np.random.random(n) < 0.1 index_dead = np.nonzero(is_dead)[0] return index_dead def choose_replacements(self, n, fits): agents = np.random.choice(self.agents, size=n, replace=True) replacements = [agent.copy() for agent in agents] return replacements ``` 在`choose_dead`中,`n`是智能體的數量,`is_dead`是一個布爾數組,對于此時間步驟內死亡的智能體為`True`。 在這個版本中,每個智能體都有相同的死亡概率:0.1。 `choose_dead`使用`np.nonzero`來查找`is_dead`的非零元素的索引(`True`被視為非零)。 在`choose_replacements`中,`n`是在此時間步驟中復制的智能體數量。 它使用`np.random.choice`帶替換地選擇`n`個智能體。 然后它在每個上調用`copy`,并返回一個新的`Agent`對象列表。 這些方法不依賴于適應性,所以這種模擬沒有生存或繁殖差異。 因此,我們不應期待看到進化。 但是,我們怎么辨別呢? ## 11.6 進化的證據 進化的最具包容性的定義是,種群中基因型分布的變化。 進化是一種聚合效應:換句話說,個體不會進化;但種群會。 在這個模擬中,基因型是高維空間中的位置,因此很難將其分布中的變化可視化。 但是,如果基因型改變,我們預計它們的適應性也會改變。 所以我們將將適應性分布的變化用作進化的證據。 具體來說,我們將看看種群中適應性的均值和標準差。 在我們運行模擬之前,我們必須添加一個`Instrument`,它是在每個時間步驟后更新的對象,計算一個感興趣的統計量,并將結果存儲在一個序列中,我們稍后可以繪制它。 這是所有儀器的父類: ```py class Instrument: def __init__(self): self.metrics = [] ``` 下面是`MeanFitness`的定義,`MeanFitness`是一個儀器,計算每個時間步的種群平均適應性: ```py class MeanFitness(Instrument): def update(self, sim): mean = np.nanmean(sim.get_fitnesses()) self.metrics.append(mean) ``` 現在我們準備好運行模擬了。 為了最小化起始種群中隨機變化的影響,我們使用同一組智能體啟動每個模擬。 為了確保我們探索整個適應性景觀,我們由每個位置的一個智能體開始。 以下是創建模擬的代碼: ```py N = 8 fit_land = FitnessLandscape(N) agents = make_all_agents(fit_land, Agent) sim = Simulation(fit_land, agents) ``` `make_all_agents`為每個位置創建一個智能體; 本章的實現在筆記本中。 現在我們可以創建并添加`MeanFitness`儀器,運行模擬并繪制結果: ```py instrument = MeanFitness() sim.add_instrument(instrument) sim.run() sim.plot(0) ``` 模擬維護了`Instrument`對象列表。 在每個時間步之后,它在列表中的每個儀器上調用`update`。 模擬運行后,我們使用`Simulation.plot`繪制結果,它接受索引作為參數,使用索引從列表中選擇一個`Instrument`并繪制結果。 在這個例子中,只有一個`Instrument`,索引為 0。 ![](https://img.kancloud.cn/35/c0/35c03e5533860c9b861967197a2596a4_454x305.png) 圖 11.1:隨著時間的推移,10 次模擬的平均適應性,沒有生存或繁殖差異 圖?顯示了運行這個模擬 10 次的結果。 種群的平均適應性隨機移動。 由于適應性的分布隨時間變化,我們推斷表現型的分布也在變化。 按照最具包容性的定義,這種隨機游走是一種進化。 但它不是一個特別有趣的類型。 特別是,這種進化并不能解釋生物物種如何隨時間變化,或者如何出現新的物種。 進化論是強大的,因為它解釋了我們在自然界看到的似乎無法解釋的現象: + 適應性:物種與其環境的相互作用似乎太復雜,太巧妙,并且偶然發生。 自然系統的許多特征看起來好像是設計出來的。 + 增加的多樣性:地球上的物種數量隨時間而普遍增加(盡管有幾個時期的大規模滅絕)。 + 增加的復雜性:地球上的生命史起始于相對簡單的生命形式,后來在地質記錄中出現了更復雜的生物體。 這些是我們想要解釋的現象。 到目前為止,我們的模型并沒有完成這個任務。 ## 11.7 生存差異 讓我們再添加一種成分,生存差異。 以下是繼承`Simulation`并覆蓋`choose_dead`的類的定義: ```py class SimWithDiffSurvival(Simulation): def choose_dead(self, fits): n = len(self.agents) is_dead = np.random.random(n) > fits index_dead = np.nonzero(is_dead)[0] return index_dead ``` 現在生存的概率取決于適應性;事實上,在這個版本中,智能體在每個時間步驟中幸存的概率是其適應性。 由于適應性低的智能體更有可能死亡,因此適應性高的智能體更有可能生存足夠長的時間來繁殖。 我們預計適應性低的智能體的數量會隨時間而減少,適應性高的智能體的數量會增加。 ![](https://img.kancloud.cn/d8/33/d833390208d030e9329e4cb50cd8bc3f_454x305.png) 圖 11.2:隨著時間的推移,10 次模擬中的適應性均值,帶有生存差異 圖?顯示了隨著時間的推移,10 次模擬中的適應性均值,帶有生存差異。 平均適應性起初會迅速增加,但會逐漸平穩。 你或許可以弄清楚為什么它會平穩:如果在特定位置只有一個智能體并且它死了,它就會使這個位置變空。沒有突變,就沒有辦法讓它再次被占領。 在`N = 8`的情況下,該模擬以 256 個智能體開始,它們占用了所有可能位置。 占用位置的數量隨時間而減少;如果模擬運行時間足夠長,最終所有智能體將占用相同的位置。 所以這個模擬開始解釋適應性:增加的適應性意味著,物種在它的環境中生存得更好。 但是占用位置的數量隨時間而減少,所以這個模型根本無法解釋增加的多樣性。 在本章的筆記本中,你將看到差異化繁殖的效果。 正如你所預料的那樣,差異化繁殖也會增加平均適應性。但沒有突變,我們仍然沒有看到增加的多樣性。 ## 11.8 突變 在目前的模擬中,我們以可能的最大多樣性開始 - 在景觀的每個位置都有一個智能體 - 并以可能的最小多樣性結束,所有智能體都在一個位置。 這與自然界發生的情況幾乎相反,它顯然以單個物種開始,這種物種隨時間而分化為今天的地球上數百萬甚至數十億物種(見 <https://en.wikipedia.org/wiki/Global_biodiversity>)。 使用我們模型的完美復制,我們從未看到增加的多樣性。 但是如果我們加上突變,再加上生存和繁殖差異,我們距離理解自然界的進化就更近了一步。 以下是繼承`Agent`并覆蓋`copy`的類定義: ```py class Mutant(Agent): prob_mutate = 0.05 def copy(self): if np.random.random() > self.prob_mutate: loc = self.loc.copy() else: direction = np.random.randint(self.fit_land.N) loc = self.mutate(direction) return Mutant(loc, self.fit_land) ``` 在這種突變模型中,每次我們調用`copy`時,都有 5% 的突變機會。 在突變的情況下,我們從當前位置選擇一個隨機方向 - 即基因型中的一個隨機位 - 并翻轉它。 這是`mutate`: ```py def mutate(self, direction): new_loc = self.loc.copy() new_loc[direction] ^= 1 return new_loc ``` 運算符`^=`計算“異或”;操作數 1 具有翻轉一位的效果(請參閱 <https://en.wikipedia.org/wiki/Exclusive_or#Bitwise_operation>)。 現在我們有了突變,我們不必在每個位置都放置一個智能體。 相反,我們可以以最小變化開始:所有智能體在同一位置。 ![](https://img.kancloud.cn/96/66/9666d1bae49f03080b7176328dcfa739_454x305.png) 圖 11.3:隨著時間的推移,10 次模擬中的適應性均值,帶有突變、生存繁殖差異 圖?顯示了 10 次模擬的結果,帶有突變和生存繁殖差異。 在任何情況下,種群都會向最大適應性的位置進化。 ![](https://img.kancloud.cn/15/df/15df17a8bf9912156144a7f544cd052b_454x305.png) 圖 11.4:隨著時間的推移,10 次模擬的占用位置的數量,帶有突變和生存繁殖差異。 為了測量種群的多樣性,我們可以繪制每個時間步后占用位置的數量。 圖?展示了結果。 我們以同一地點的 100 個智能體開始。 隨著突變的發生,占用位置的數量迅速增加。 當智能體發現適應性高的位置時,它更有可能生存和繁殖。 適應性較低的位置上的智能體最終消失。 種群在整個景觀中隨時間而移動,直到大多數智能體處于適合性最高的位置。 此時,系統達到平衡,突變以相同的速率占據新的位置,生存差異導致適合性低的位置清空。 平衡中的占用位置的數量,取決于突變率和生存差異的程度。 在這些模擬中,任何點處的獨特占用位置的數量通常為 10-20。 重要的是要記住,這個模型中的智能體不會移動,就像生物體的基因型沒有改變一樣。 當智能體死亡時,它可能會留下一個空位。 當發生突變時,它可以占據一個新的位置。 當智能體從某些地方消失并出現在其他地方時,種群會在景觀中移動,就像生命游戲中的滑翔機一樣。 但生命體不會進化;但種群可以。 ## 11.9 物種形成 進化論說,自然選擇改變了現有的物種并創造了新的物種。 在我們的模型中,我們看到了變化,但我們并沒有看到新的物種。 在模型中,還不清楚新物種是什么樣。 在有性繁殖的物種中,如果兩種生物能夠繁殖并產生豐富的后代,則被視為同一物種。 但是模型中的智能體不會再現性行為,所以這個定義不適用。 在無性繁殖的生物中,如細菌,物種的定義并不明確。 一般來說,如果一個種群的基因型形成一個簇,那么它就被認為是一個物種,也就是說,如果種群內的遺傳差異比種群間的差異小。 在我們可以對新物種建模之前,我們需要能夠識別景觀中的智能體簇,這意味著我們需要定義位置之間的距離。 由于位置是用二進制數字串表示的,因此我們將距離定義為基因型中不同的位數。 `FitnessLandscape`提供了`distance `方法: ```py # class FitnessLandscape def distance(self, loc1, loc2): return np.sum(np.logical_xor(loc1, loc2)) ``` ![](https://img.kancloud.cn/e4/47/e447ce09459fc7a2c76be1e51c8489c4_454x305.png) 圖 11.5:智能體隨時間變化的平均距離 `logical_xor`函數計算“異或”,不同的元素為`True`,相同的元素為`False`。 為了量化種群的分散,我們可以計算每對智能體之間距離的平均值。 在本章的筆記本中,你會看到`MeanDistance`儀器,它會在每個時間步驟后計算這個度量。 圖? 展示了智能體隨時間的平均距離。 因為我們從相同的突變開始,所以初始距離為 0。隨著突變的發生,平均距離增加,在種群遍布景觀時達到最大值。 一旦智能體發現最佳位置,平均距離就會減小,直到種群達到平衡,由于突變引起的距離增加通過距離的減小而平衡,因為遠離最佳位置的智能體更有可能死亡。 在這些模擬中,平衡時的平均距離接近 1.5;也就是說,大多數智能體距離最佳位置只有 1-2 個突變。 現在我們準備尋找新的物種。 為了模擬一種簡單的物種形成,假設一個種群在不變的環境中演化,直到它達到穩定狀態(就像我們在自然界發現的一些物種,似乎在很長一段時間內變化很小)。 現在假設我們改變環境,或者將種群轉移到新的環境中。 一些舊環境中適應性較高的特性,可能會在新環境中適應性較低,反之亦然。 我們可以通過運行模擬來模擬這些情景,直到種群達到穩定狀態,然后改變適應性景觀,然后恢復模擬,直到種群再次達到穩定狀態。 ![](https://img.kancloud.cn/88/bf/88bff1dd9f1d19f46575ad868c154b8a_454x305.png) 圖 11.6:隨時間變化的適應性均值。在 500 步之后,我們改變了適應性景觀 圖?展示了這樣的模擬結果。 再次,我們從隨機位置開始,使用 100 個相同的突變體,并運行 500 個時間步驟的模擬。 在這個時候,許多智能體處于最佳位置,在這個例子中,其適應性接近 0.65。 智能體的基因型形成一個簇,智能體之間的平均距離接近 1。 經過 500 步之后,我們運行`FitnessLandscape.set_values`,這改變了適應性景觀; 然后我們恢復模擬。 平均適應性會立即下降,因為舊景觀中的最佳位置并不比新景觀中的隨機位置好。 然而,當種群遷移到新景觀時,平均適應性會迅速增加,最終會找到新的最佳值,其適應度接近 0.75(在這個例子中恰好更高,但不一定是)。 一旦種群達到穩定狀態,它就會形成一個新的簇,智能體之間的平均距離再次接近 1。 現在,如果我們計算智能體之前和之后的位置之間的距離,平均而言,它們相差超過 6。 簇之間的距離遠大于每個簇內的距離,因此我們可以將這些簇解釋為不同的物種。 ## 11.10 總結 我們已經看到,突變以及生存和繁殖差異,足以導致適應性的增加,多樣性的增加,并產生簡單形式的物種。 這種模型并不是現實的;自然系統中的進化要比這復雜得多。 相反,它意味著一個“充足定理”;也就是說,模型的特征足以產生我們試圖解釋的行為(參見 <https://en.wikipedia.org/wiki/Necessity_and_sufficiency>)。 從邏輯上講,這個“定理”并不能證明,自然界中的進化僅僅由這些機制引起,但是由于這些機制確實以多種形式出現在生物系統中,所以認為它們至少有助于自然進化,是合理的。 同樣,該模型并不能證明這些機制總是會導致進化。 但是我們在這里看到的結果是可靠的:在幾乎所有包含這些特征的模型中 - 不完美的復制者,變異性和繁殖差異 - 發生了進化。 我希望這一觀察有助于揭開進化的神秘面紗。 當我們觀察自然系統時,進化看起來很復雜。 而且由于我們主要看到了進化的結果,而沒有看到這個過程,所以難以想象和相信。 但在模擬中,我們看到整個過程,而不僅僅是結果。 通過包含最少的一系列特征來產生進化 - 暫時忽略了生物生命的巨大復雜性 - 我們可以將進化看作是一個令人驚訝的簡單,不可避免的想法。 ## 11.11 練習 本章的代碼位于本書倉庫的 Jupyter 筆記本`chap11.ipynb`中。 打開筆記本,閱讀代碼并運行單元格。 筆記本包含本章的練習。 我的解決方案在`chap11soln.ipynb`中。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看