(一)複雜系統的簡單例子

本章節較短,是上一章介紹性文章的下半部分。

在上一章(零)複雜系統的入門我們提到的現象中,可以總結出複雜系統的一些共同特徵:

  1. 有大量能交互的作用個體(agent)。(數量眾多永遠是複雜系統難以處理實現的困難之一
  2. 會出現湧現(Emergence),是一種難以從作用個體(agent)的行為預測出的自組織(Self-organization,又被稱為「自發有序」)集體行為。(你不能從一個細節猜出整個群體會產生多麼瑰麗的集體現象)
  3. 其湧現行為並不是由某個「總機」(central controller)的存在而導致的。(沒有一個首領發號施令,沒有一個長官訓練他們)

接下來我們將展示一些有趣的,而且大家都可以自己在電腦上實踐的例子:

第一個例子是著名的數學遊戲:生命遊戲(Conways Game of Life)。這個由普林斯頓數學教授John Horton Conway提出的遊戲有很簡單的規則:在二維網格中,我們對每個小格子進行黑白染色,白色代表活細胞,黑色代表死細胞。細胞周圍有8個相鄰的細胞,如果活細胞相鄰細胞中活細胞大於三個,那麼活細胞會由於營養不足而死亡;如果活細胞相鄰細胞少於2個,那麼他會由於太孤獨而死掉;如果死細胞周圍的活細胞數目大於等於3個,那麼死細胞的會由於活細胞的繁殖重新活過,其他情況不變。

在簡單規則下,細胞間的相互作用會產生一些美麗的,意想不到的圖案,我們用pygame做了相應的模擬:

這是一個簡單的初始模型,我在隨機產生的點陣中運算經常可以出現這個圖案,出現之後會不斷地周期性重複下面的這兩個形狀。

這個圖案被稱為Glider,他會按周期性的向右下方平移。

這是Gosper glider gun,有兩個大飛船在兩個目的地之間來回運輸,每運輸一次就會向外發射一個Glider。

我們只是選取了幾個動態的小模型,生命遊戲中還存在更大規模的周期律圖案或者有特定特點的結構。更多模型的動圖可以在這個網站看到。

這就是一種最簡單的元胞自動機,這種有趣的圖形變化似乎隱含著遠超於幾行代碼的意義。於是有人就認為這個遊戲的表現形式和宇宙的本質有關,即宇宙的本質就是計算,在簡單的條件約束下就能產生出各種規律性的文明體,總之不明覺厲。

第二個例子是一個搬運木頭的螞蟻模型:在一個100x100的空地上有散落的木屑,螞蟻在格子間隨機走動,頭碰到木屑就會搬起木屑,頭碰到下一個木屑就會把搬起的木屑隨機放在周邊的空格中。在這些簡單規則的約束下,所有的木頭最終會被搬運成一個近乎於圓形的整體,然而這個東西的周期可能太長了,我把100x100都改成更小的結構了,跑了幾十萬輪還是沒有得到相似的結果。。。

我的幾十萬輪後的最終狀態:

書中的標準狀況:

左邊是初始狀態,右邊是運算後。

本屆內容應該與上一篇是一起的,都屬於介紹並吸引興趣的開頭部分,我們可以嘗試自己編寫一下這兩個最為簡單的小遊戲,可以用python也可以用Excel就能輕鬆實現,下一期會直接講到prey-predator模型,不會再拖了……

附上我炒雞粗陋的代碼:

import pygamefrom pygame.locals import *from sys import exitfrom random import randintimport timeimport copypygame.init()screen = pygame.display.set_mode((960, 600), 0, 32)mylist = [([0] * 160) for i in range(120)]for i in range(1000): mylist[randint(0, 119)][randint(0, 159)] = 1mylist_2 =copy.deepcopy(mylist)while True: for event in pygame.event.get(): if event.type == QUIT: exit() pressed_keys = pygame.key.get_pressed() pressed_mouse = pygame.mouse.get_pressed() position = pygame.mouse.get_pos() if pressed_mouse[0]: print(position) mylist_2[((position[1])//5)+1][((position[0])//6)+ 1] = 1 for j in range(157): for i in range(117): if mylist_2[i + 1][j + 1] == 1: pygame.draw.line(screen, (255, 255, 255), (6 * j, 3 + 5 * i), (6 * j + 5, 3 + 5 * i), 5) else: pygame.draw.line(screen, (0, 0, 0), (6 * j, 3 + 5 * i), (6 * j + 5, 3 + 5 * i), 5) if pressed_mouse[2]: print(position) mylist_2[((position[1])//5)+1][((position[0])//6)+ 1] = 0 for j in range(157): for i in range(117): if mylist_2[i + 1][j + 1] == 1: pygame.draw.line(screen, (255, 255, 255), (6 * j, 3 + 5 * i), (6 * j + 5, 3 + 5 * i), 5) else: pygame.draw.line(screen, (0, 0, 0), (6 * j, 3 + 5 * i), (6 * j + 5, 3 + 5 * i), 5) if pressed_keys[K_SPACE]: for j in range(157): for i in range(117): if mylist[i + 1][j + 1] == 0: if mylist[i + 1][j + 2] + mylist[i + 1][j] + mylist[i + 2][j + 1] + mylist[i][j + 1] + mylist[i + 2][j + 2] + mylist[i][j] + mylist[i + 2][j] + mylist[i][j + 2] == 3: mylist_2[i + 1][j + 1] = 1 else: pass elif mylist[i + 1][j + 1] == 1: if mylist[i + 1][j + 2] + mylist[i + 1][j] + mylist[i + 2][j + 1] + mylist[i][j + 1] + mylist[i + 2][j + 2] + mylist[i][j] + mylist[i + 2][j] + mylist[i][j + 2] == 2 or mylist[i + 1][j + 2] + mylist[i + 1][j] + mylist[i + 2][j + 1] + mylist[i][ j + 1] + mylist[i + 2][j + 2] + mylist[i][j] + mylist[i + 2][j] + mylist[i][ j + 2] == 3: pass else: mylist_2[i + 1][j + 1] = 0 for j in range(157): for i in range(117): if mylist_2[i + 1][j + 1] == 1: pygame.draw.line(screen, (255, 255, 255), (6 * j, 3 + 5 * i), (6 * j + 5, 3 + 5 * i), 5) else: pygame.draw.line(screen, (0, 0, 0), (6 * j, 3 + 5 * i), (6 * j + 5, 3 + 5 * i), 5) mylist = copy.deepcopy(mylist_2) # if pygame.mouse.get_pressed()[0]: # pygame.draw.circle(screen,(0,0,0),pygame.mouse.get_pos(),2) # screen.set_at(pygame.mouse.get_pos(),(0,0,0)) # time.sleep(0.01) elif pressed_keys[K_p]: mylist_2 = [([0] * 160) for i in range(120)] for j in range(157): for i in range(117): if mylist_2[i + 1][j + 1] == 1: pygame.draw.line(screen, (255, 255, 255), (6 * j, 3 + 5 * i), (6 * j + 5, 3 + 5 * i), 5) else: pygame.draw.line(screen, (0, 0, 0), (6 * j, 3 + 5 * i), (6 * j + 5, 3 + 5 * i), 5) mylist = copy.deepcopy(mylist_2) elif pressed_keys[K_r]: for i in range(1000): mylist[randint(0, 119)][randint(0, 159)] = 1 mylist_2 = copy.deepcopy(mylist) pygame.display.update()

按住空格鍵開始計算,r鍵隨機產生點,p鍵清除點,滑鼠左鍵激活格子,右鍵熄滅格子。


推薦閱讀:

Arxiv網路科學論文摘要10篇(2018-03-07)
複雜性思維中文第二版 五、細胞自動機
協調動力學:樂隊如何奏出和諧音樂?| 複雜性文摘6篇
Arxiv網路科學論文摘要15篇(2018-04-13)
Arxiv網路科學論文摘要26篇(2018-02-13)

TAG:Python | 複雜系統 | 生命遊戲GameofLife |