The Nature of Code閱讀心得與Python實作:7.2 Elementary Cellular...

更新於 發佈於 閱讀時間約 29 分鐘
這一節的標題是
Elementary Cellular Automata
因為方格子標題字數限制,所以沒完整顯現

最最簡單的CA長什麼樣子?網格、狀態、鄰域是構成CA的三個關鍵要素。最簡單的網格是由一串細胞所構成的1D網格;除了只有單一一個狀態的情況不論,因為一成不變的細胞沒啥好討論的,細胞可以擁有的狀態,最少會有2個;在1D網格中的細胞,其最簡單、單純的鄰域定義方式,是包括細胞本身,以及跟它相鄰的左、右兩個鄰居,共三個細胞。Wolfram把具備這些特點的1D CA叫做基礎CA (elementary CA)。所以,假設細胞的狀態以0、1來表示,基礎CA會長這樣:

raw-image

這裡要注意一下,位於左、右端點的細胞就只有一個鄰居,它們的鄰域定義方式需要另外處理;這個先不管,後面再說。

即便是像基礎CA這麼簡單的CA,當細胞的狀態隨時間而改變時,也會突現出複雜系統的特徵。接下來,就來看看要怎麼讓細胞的狀態可以隨時間而改變。

在CA的世界中,時間是以世代(generation)來表示。一開始的時候時間是0,這時候的CA是第0世代。接下來,利用某些事先定義好的規則,根據第0世代細胞的狀態,可以算出第1世代細胞的狀態;接著再根據第1世代細胞的狀態,算出第2世代細胞的狀態;如此不斷地迭代下去,就可以得到不同世代的CA。

CA的迭代規則,可以是數學計算式。例如,假設細胞b在第t世代時的狀態是bt,而其左右兩個鄰居細胞的狀態分別是at與ct。如果我們設定細胞b在下一世代時的狀態bt+1是透過下式計算出來的

bt+1 = (at + bt + ct) mod 2

那當

at = 0
bt = 1
ct = 0

時,細胞b在第t+1世代的狀態就會是

bt+1 = (0 + 1 + 0) mod 2 = 1

有別於數學計算式,Wolfram則是採用另一種方式來設定基礎CA的迭代規則;這些規則就統稱為規則集(ruleset)。

Wolfram的基礎CA迭代規則集設定方式很簡單,就只是針對鄰域細胞狀態值的所有可能排列組合,一一指定一個新的狀態值而已。對於某個細胞而言,它的鄰域共有3個細胞,所以鄰域細胞狀態值的所有可能排列組合共有8種,也就是

111  110  101  100  011  010  001  000

針對這8個不同的排列組合,分別指定對應的新狀態值,例如

0 1 0 1 1 0 1 0

這樣子就完成了規則集的制定。當某個細胞的鄰域細胞狀態值為010時,從規則集中可以找到對應的新狀態值是0,所以在下一世代時,這個細胞的狀態值就是0。畫張圖來看會更清楚一些:

raw-image

制定好基礎CA的迭代規則集之後,準備一個初代的CA,就可以利用規則集讓這個CA不斷地迭代產生新世代。這個初代的CA,依照Wolfram的標準做法,會是一個除了中間細胞的狀態值是1之外,其餘細胞的狀態值都是0的基礎CA。

以Wolfram標準做法中所使用的基礎CA作為初代CA,並使用前面圖中的規則集來迭代,然後將各世代的CA排列在一起,可以得到下面的結果:

raw-image

如果改用黑色方塊來表示狀態1,白色方塊表示狀態0,則畫出來的圖會長這樣:

raw-image

這個圖案是碎形(fractal)中著名的Sierpiński三角形(Sierpiński triangle)。把方塊縮小成像素大小讓解析度高一些,可以看得更清楚:

raw-image

Defining Rulesets

在制定基礎CA的迭代規則集時,我們先列出3個鄰域細胞狀態值的所有可能排列組合,然後一一指定對應的新狀態值;這整個過程和結果充滿了0和1,實在是過於冗長、繁雜。那有沒有什麼辦法能讓它比較簡潔一點呢?利用Wolfram所使用的技巧就可以了。接下來就來看看Wolfram是怎麼做的。

在規則集中,3個鄰域細胞狀態值的排列組合共有8種,而這8種排列組合是永遠不會變的。所以,在規則集中,會變動的,就只有指定給這些排列組合的新狀態值。既然如此,那就規定3個鄰域細胞狀態值的排列組合順序為

111  110  101  100  011  010  001  000

這樣子當指定的新狀態值時,不需多說,就會知道哪個排列組合是對應到哪個新狀態值了。例如,如果新狀態值是

0 1 0 1 1 0 1 0

那就表示對應的方式是

111  ⟶ 0
110  ⟶ 1
101  ⟶ 0
100  ⟶ 1
011  ⟶ 1
010  ⟶ 0
001  ⟶ 1
000 ⟶ 0

如果把上面那個對應的新狀態值看成是8位數的2進位整數,轉成10進位之後,可以得到整數90,也就是

010110102 = 90

Wolfram就把這組規則集叫做「規則90」(rule 90)。

既然規則集中的新狀態值是個8位數的2進位整數,那總共就會有256個不同的規則集。當看到「規則N」時,只要把N轉成2進位整數,就可以知道真正的規則集是長啥樣子了。例如,以規則222來說,因為

222 = 110111102

所以對應方式就是

111  ⟶ 1
110  ⟶ 1
101  ⟶ 0
100  ⟶ 1
011  ⟶ 1
010  ⟶ 1
001  ⟶ 1
000 ⟶ 0

而迭代畫出來的圖就長這樣:

raw-image

規則集總共有256個,雖然不是每一個都可以畫出像Sierpiński三角形那樣讓人驚嘆的圖案,但的確有些圖案跟自然界中常見的圖案極其類似。例如,規則30所畫出來的圖案長這樣:

raw-image

這個圖案就跟一種蝸牛外殼的花紋非常相像。從這個例子就可以看出來,CA在模擬和模式生成等領域中,是具有多麼大的價值了。

Programming an Elementary CA

寫細胞自動機程式時,可以用物件導向的方式來寫,也可以就用List這個資料結構來寫,畢竟CA就只是一堆0和1的組合而已。現在就先用List來寫,物件導向式的寫法,在後面會有一節專門來介紹。

要怎麼用List這個資料結構來表示1D CA呢?這其實挺簡單的,就這樣寫:

cells = [1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0]

這樣cells的每個元素,就對應網格中的一個細胞,而放在元素中的數字,就是細胞的狀態值。所以,cells[0]就是最左邊的那個細胞的狀態,而cells[-1]就是最右邊的那個細胞的狀態。

有了細胞的狀態值之後,就可以利用規則集來計算CA在下一個世代時的狀態值了。不過,在開始寫程式之前,要先解決一個問題:計算下一個世代的狀態值時,需要用到鄰域的3個細胞狀態值,但是位於最左和最右兩邊的細胞,它們的鄰域只有兩個細胞,那該怎麼辦?這個問題有三種處理法式:

  1. 首、尾細胞的狀態,不管是在哪一個世代,都維持不變。這大概是最容易、最簡單的處理方式了,因為不用傷腦筋去想新的狀態值要怎麼計算。
  2. 讓首、尾細胞相連。這也就是說,最前端那個細胞,也就是cells[0],它的鄰域會是cells[-1]cells[0]cells[1];而最尾端那個細胞,也就是cells[-1],它的鄰域會是cells[-2]cells[-1]cells[0]。這應該是最廣為採用的處理方式了。
  3. 另訂首、尾細胞的鄰域及狀態的計算方式。這種處理方式要多寫些程式,但其實並沒有什麼特別的好處。

在這裡,我們會採用第一種方式來處理首、尾細胞的狀態問題;這樣程式比較好寫,也比較容易閱讀。根據這樣子的設定,要計算CA在下一個世代時的狀態值,程式可以這樣寫:

next_generation = cells.copy()
for i in range(1, len(cells)-1):
left = cells[i-1]
middle = cells[i]
right = cells[i+1]
next_generation[i] = rules(left, middle, right)

cells = next_generation.copy()

這裡要注意的是,for迴圈是掐頭去尾從1len(cells)-1,並未包含首、尾兩個細胞,因為它們的狀態值跟上一代是一樣的,並不會改變,所以不用處理。另外,在最後一行,我們把CA在下一個世代時的狀態值複製到cells中,藉此將cells更新為最新一代的細胞,以便繼續進行下一次的迭代。除了這兩點之外,在程式裡頭,還有個用來計算新狀態值的函數rules()尚待完成。

那個尚待完成的函數rules()要怎麼寫呢?這就要從規則集的設定方式談起了。我們在設定規則集時,會列出鄰域細胞狀態值的所有可能排列組合,也就是下列這8種排列組合:

111  110  101  100  011  010  001  000

然後分別指定對應的新狀態值給每一種排列組合。如果把這些排列組合看成是3位數的2進位整數,那這些整數會是

7 6 5 4 3 2 1 0

假設我們把規則集放在ruleset這個List中,那ruleset[0]裡頭放的,就是排列組合7的新狀態值;ruleset[1]裡頭放的,則是排列組合6的新狀態值,以此類推。所以,rules()這個函數,就可以這樣寫:

def rules(left, middle, right, ruleset):
idx = 4*left + 2*middle + right
return ruleset[7-idx]

之所以要把用來計算新狀態值的部分寫成函數,是考慮到如果新狀態值的計算方式有所不同時,只需修改rules()這個函數就可以,而不需動到程式的主架構。

接下來,要來看看關於規則集寫法的部分,這部分原書並未討論。

規則集有兩種表示方式,一種是直接寫出細胞狀態值,例如「01011010」;另一種則是使用10進位整數,例如「規則90」。這兩種寫法互相轉換的程式可以這樣寫:

# 從狀態值轉成整數
ruleset = [0, 1, 0, 1, 1, 0, 1, 0]
rule_string = ''.join(str(c) for c in ruleset)
rule_number = int(rule_string, 2)

# 從整數轉成狀態值
rule_number = 90
ruleset = [int(c) for c in f'{rule_number:08b}']

從整數轉成狀態值時需要先將整數轉成二進位字串,bin()函數也可以做到這一點,不過會在字串前面加上0b兩個字母,這樣會增加後續處理上的麻煩。所以,直接使用f-string來轉換,會是比較省時省力的做法。

Drawing an Elementary CA

要畫基礎CA的圖案,標準做法是把一代一代的CA堆疊在一起,並分別用黑色和白色方塊來呈現狀態值為1和0的細胞。下面這張圖,就是由規則90的CA所製作出來的圖案:

raw-image

這裡要注意的是,雖然這是張2D的圖片,但這並不代表它是個2D CA;它只是由1D CA的不同世代所堆疊而成,方便呈現CA迭代過程的一張圖片而已。所以,CA的圖案的畫法,並非是絕對的,完全可以依照實際的需要而加以改變。

下面這個例子所呈現的,是使用標準做法所畫出的規則90基礎CA圖案,不過為了減少一點計算量,就只畫出狀態值是1的細胞而已。

Example 7.1: Wolfram Elementary Cellular Automata

raw-image
def rules(left, middle, right, ruleset):
idx = 4*left + 2*middle + right
return ruleset[7-idx]


# python version 3.10.9
import sys

import pygame # version 2.3.0


pygame.init()

pygame.display.set_caption("Example 7.1: Wolfram Elementary Cellular Automata")

WHITE = (255, 255, 255)

screen_size = WIDTH, HEIGHT = 640, 240
screen = pygame.display.set_mode(screen_size)

FPS = 60
frame_rate = pygame.time.Clock()

# 細胞方塊邊長
cell_size = 10

# 細胞數量
n_cells = WIDTH // cell_size

# 世代數量
n_generation = HEIGHT // cell_size

# 規則90
rule_number = 90
ruleset = [int(c) for c in f'{rule_number:08b}']

# 初代CA
cells = [0]*n_cells
cells[n_cells//2] = 1

next_generation = cells.copy()

screen.fill(WHITE)

for generation in range(n_generation):
for i in range(n_cells):
# 只畫出狀態值為1的細胞
if cells[i] == 1:
rect = pygame.Rect(i*cell_size, generation*cell_size, cell_size, cell_size)
pygame.draw.rect(screen, (0, 0, 0), rect)

for i in range(1, n_cells-1):
left = cells[i-1]
middle = cells[i]
right = cells[i+1]
next_generation[i] = rules(left, middle, right, ruleset)

cells = next_generation.copy()

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

pygame.display.update()
frame_rate.tick(FPS)

Exercise 7.1

為了避免畫面更換速度太快而看不清楚,所以把FPS設定為1

def rules(left, middle, right, ruleset):
idx = 4*left + 2*middle + right
return ruleset[7-idx]


# python version 3.10.9
import random
import sys

import pygame # version 2.3.0


pygame.init()

pygame.display.set_caption("Exercise 7.1")

WHITE = (255, 255, 255)

screen_size = WIDTH, HEIGHT = 640, 240
screen = pygame.display.set_mode(screen_size)

FPS = 1
frame_rate = pygame.time.Clock()

# 細胞方塊邊長
cell_size = 10

# 細胞數量
n_cells = WIDTH // cell_size

# 世代數量
n_generation = HEIGHT // cell_size

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

screen.fill(WHITE)

# 隨機選取的規則集
ruleset = [random.randint(0, 1) for _ in range(8)]

# 初代CA
cells = [0]*n_cells
cells[n_cells//2] = 1

next_generation = cells.copy()

for generation in range(n_generation):
for i in range(n_cells):
if cells[i] == 1:
rect = pygame.Rect(i*cell_size, generation*cell_size, cell_size, cell_size)
pygame.draw.rect(screen, (0, 0, 0), rect)

for i in range(1, n_cells-1):
left = cells[i-1]
middle = cells[i]
right = cells[i+1]
next_generation[i] = rules(left, middle, right, ruleset)

cells = next_generation.copy()

pygame.display.update()
frame_rate.tick(FPS)


Exercise 7.2

使用規則90,以下為其中一張圖片

raw-image
def rules(left, middle, right, ruleset):
idx = 4*left + 2*middle + right
return ruleset[7-idx]


# python version 3.10.9
import random
import sys

import pygame # version 2.3.0


pygame.init()

pygame.display.set_caption("Exercise 7.2")

WHITE = (255, 255, 255)

screen_size = WIDTH, HEIGHT = 640, 240
screen = pygame.display.set_mode(screen_size)

FPS = 1
frame_rate = pygame.time.Clock()

# 細胞方塊邊長
cell_size = 10

# 細胞數量
n_cells = WIDTH // cell_size

# 世代數量
n_generation = HEIGHT // cell_size

rule_number = 199
ruleset = [int(c) for c in f'{rule_number:08b}']

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

screen.fill(WHITE)

# 初代CA的細胞狀態是隨機的
cells = [random.randint(0, 1) for _ in range(n_cells)]

next_generation = cells.copy()

for generation in range(n_generation):
for i in range(n_cells):
if cells[i] == 1:
rect = pygame.Rect(i*cell_size, generation*cell_size, cell_size, cell_size)
pygame.draw.rect(screen, (0, 0, 0), rect)

for i in range(1, n_cells-1):
left = cells[i-1]
middle = cells[i]
right = cells[i+1]
next_generation[i] = rules(left, middle, right, ruleset)

cells = next_generation.copy()

pygame.display.update()
frame_rate.tick(FPS)


Exercise 7.3

細胞圍繞畫面中心排成圓形,不同世代的細胞顏色不同。

raw-image
def rules(left, middle, right, ruleset):
idx = 4*left + 2*middle + right
return ruleset[7-idx]


# python version 3.10.9
import random
import sys

import pygame # version 2.3.0


pygame.init()

pygame.display.set_caption("Exercise 7.3")

WHITE = (255, 255, 255)

screen_size = WIDTH, HEIGHT = 640, 360
screen = pygame.display.set_mode(screen_size)
screen_center = pygame.Vector2(WIDTH//2, HEIGHT//2)

FPS = 60
frame_rate = pygame.time.Clock()

# 細胞方塊邊長
cell_size = 2

# 細胞數量
n_cells = WIDTH // cell_size

# 世代數量
n_generation = HEIGHT // cell_size

# 規則90
rule_number = 90
ruleset = [int(c) for c in f'{rule_number:08b}']

# 初代CA
cells = [0]*n_cells
cells[n_cells//2] = 1

screen.fill(WHITE)

next_generation = cells.copy()

for generation in range(n_generation):
for i in range(n_cells):
if cells[i] == 1:
# 細胞所在位置
r, theta = generation*cell_size/2.3, i*cell_size
position = screen_center + pygame.Vector2.from_polar((r, theta))

# 細胞顏色
r, g, b = 7*generation%255, 17*generation%255, 37*generation%255
color = (r, g, b)

pygame.draw.circle(screen, color, position, cell_size/2)

for i in range(1, n_cells-1):
left = cells[i-1]
middle = cells[i]
right = cells[i+1]
next_generation[i] = rules(left, middle, right, ruleset)

cells = next_generation.copy()

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

pygame.display.update()
frame_rate.tick(FPS)


Exercise 7.4

儲存每幀畫面的第1代CA,並將其作為下一幀畫面的初代CA即可。

def rules(left, middle, right, ruleset):
idx = 4*left + 2*middle + right
return ruleset[7-idx]


# python version 3.10.9
import random
import sys

import pygame # version 2.3.0


pygame.init()

pygame.display.set_caption("Exercise 7.4")

WHITE = (255, 255, 255)

screen_size = WIDTH, HEIGHT = 640, 240
screen = pygame.display.set_mode(screen_size)

FPS = 60
frame_rate = pygame.time.Clock()

# 細胞方塊邊長
cell_size = 1

# 細胞數量
n_cells = WIDTH // cell_size

# 世代數量
n_generation = HEIGHT // cell_size

rule_number = 90
ruleset = [int(c) for c in f'{rule_number:08b}']

# 初代CA
cells_start = [0]*n_cells
cells_start[n_cells//2] = 1

cells = cells_start.copy()
next_generation = cells.copy()

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

screen.fill(WHITE)

cells = cells_start.copy()

for generation in range(n_generation):
# 儲存第1代CA,作為下一幀畫面中的初代CA
if generation == 1:
cells_start = cells.copy()

for i in range(n_cells):
if cells[i] == 1:
rect = pygame.Rect(i*cell_size, generation*cell_size, cell_size, cell_size)
pygame.draw.rect(screen, (0, 0, 0), rect)

for i in range(1, n_cells-1):
left = cells[i-1]
middle = cells[i]
right = cells[i+1]
next_generation[i] = rules(left, middle, right, ruleset)

cells = next_generation.copy()

pygame.display.update()
frame_rate.tick(FPS)


avatar-img
15會員
139內容數
寫點東西自娛娛人
留言
avatar-img
留言分享你的想法!
ysf的沙龍 的其他內容
細胞自動機的英文是cellular automaton,複數型態為cellular automata,簡稱CA,是一種由細胞物件所組成的系統模型。
這一章介紹的是細胞自動機(cellular automaton),一種不是植基於物理定律的複雜系統。
細胞自動機的英文是cellular automaton,複數型態為cellular automata,簡稱CA,是一種由細胞物件所組成的系統模型。
這一章介紹的是細胞自動機(cellular automaton),一種不是植基於物理定律的複雜系統。
你可能也想看
Google News 追蹤
Thumbnail
全新 vocus 挑戰活動「方格人氣王」來啦~四大挑戰任你選,留言 / 愛心 / 瀏覽數大 PK,還有新手專屬挑戰!無論你是 vocus 上活躍創作者或剛加入的新手,都有機會被更多人看見,獲得站上版位曝光&豐富獎勵!🏆
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 九 為能清晰說明,我們給範疇次序標號 (即置頂的 1-5),使整個推導過程看似一個矩陣﹕ 1.4.1_5.3 艾杜凱維茨的推導矩陣 第 2 行的 gr:1 (C1, C2) 是說 gr 用於第 1 行的 C
數學系的訓練,與上面閱讀原始碼的優先順序,本質上是反過來的。在數學的訓練中,是先把函數定義的非常清楚,再進一步去看函數應用在具體的數據上會發生什麼行為,然後就到此為止,不太會再有進一步的討論。但如上面西尾泰和所述,工程師看事情的角度,是先掌握全局,然後再進一步細化每一層的細節。
Thumbnail
這一節談的是向量的定義,以及如何運用向量來建立模擬物體運動時,關於位置和速度間的關係式。
隨機漫步看似簡單,但卻是模擬許多自然界現象的基礎,相關的觀念及程式實作方式,對於瞭解亂數、機率、Perlin noise等工具,會有相當大的幫助。
Thumbnail
目錄 序 導論: 一個西方觀點的評述 1.0 從函數到函數算法 ......1.1 句子成份
TAOCP第四卷已經有了 4A 和 4B 兩個子卷,內容涵蓋了組合數學和計算機科學的各個主題,並引領讀者深入了解相關理論和應用。Knuth將逐步推出 4C 的內容,並期待從讀者那裡獲得反饋。這是一場關於組合算法的深度探索之旅,讓我們一起期待這一系列的問世!
Thumbnail
這篇文章,會帶著大家複習以前學過的前綴和框架, 並且以區間和的概念與應用為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個演算法框架。 前綴和 prefix sum框架 與 區間和計算的關係式 接下來,我們會用這個上面這種框架,貫穿一些同類型,有關聯的題目 (請讀者、或觀眾
計算機組織不難,但東西很多 這個科目也是我比較不熟悉的,在此之前都是自學,所以會寫的更詳細一點 1.計算機組織在學什麼? 想像計算機的架構就像一個蛋糕有好多層,上半是軟體下半則是硬體,對我來說,軟硬體的兩端是電腦的核心(應用程式&半導體),而中間的每一層都是串接兩端的橋樑;那計算機組織就是要探
Thumbnail
上篇進一步認識基本的圖形架構與三大 Graph 算法,那首先從 shortest path 開始,我們會陸續去理解這些算法,以及可能的應用,如果還沒有看過上一篇的,可以點以下連結~那我們就開始吧! 【圖論Graph】Part1:初探圖形與圖形演算法之應用
Thumbnail
全新 vocus 挑戰活動「方格人氣王」來啦~四大挑戰任你選,留言 / 愛心 / 瀏覽數大 PK,還有新手專屬挑戰!無論你是 vocus 上活躍創作者或剛加入的新手,都有機會被更多人看見,獲得站上版位曝光&豐富獎勵!🏆
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 九 為能清晰說明,我們給範疇次序標號 (即置頂的 1-5),使整個推導過程看似一個矩陣﹕ 1.4.1_5.3 艾杜凱維茨的推導矩陣 第 2 行的 gr:1 (C1, C2) 是說 gr 用於第 1 行的 C
數學系的訓練,與上面閱讀原始碼的優先順序,本質上是反過來的。在數學的訓練中,是先把函數定義的非常清楚,再進一步去看函數應用在具體的數據上會發生什麼行為,然後就到此為止,不太會再有進一步的討論。但如上面西尾泰和所述,工程師看事情的角度,是先掌握全局,然後再進一步細化每一層的細節。
Thumbnail
這一節談的是向量的定義,以及如何運用向量來建立模擬物體運動時,關於位置和速度間的關係式。
隨機漫步看似簡單,但卻是模擬許多自然界現象的基礎,相關的觀念及程式實作方式,對於瞭解亂數、機率、Perlin noise等工具,會有相當大的幫助。
Thumbnail
目錄 序 導論: 一個西方觀點的評述 1.0 從函數到函數算法 ......1.1 句子成份
TAOCP第四卷已經有了 4A 和 4B 兩個子卷,內容涵蓋了組合數學和計算機科學的各個主題,並引領讀者深入了解相關理論和應用。Knuth將逐步推出 4C 的內容,並期待從讀者那裡獲得反饋。這是一場關於組合算法的深度探索之旅,讓我們一起期待這一系列的問世!
Thumbnail
這篇文章,會帶著大家複習以前學過的前綴和框架, 並且以區間和的概念與應用為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個演算法框架。 前綴和 prefix sum框架 與 區間和計算的關係式 接下來,我們會用這個上面這種框架,貫穿一些同類型,有關聯的題目 (請讀者、或觀眾
計算機組織不難,但東西很多 這個科目也是我比較不熟悉的,在此之前都是自學,所以會寫的更詳細一點 1.計算機組織在學什麼? 想像計算機的架構就像一個蛋糕有好多層,上半是軟體下半則是硬體,對我來說,軟硬體的兩端是電腦的核心(應用程式&半導體),而中間的每一層都是串接兩端的橋樑;那計算機組織就是要探
Thumbnail
上篇進一步認識基本的圖形架構與三大 Graph 算法,那首先從 shortest path 開始,我們會陸續去理解這些算法,以及可能的應用,如果還沒有看過上一篇的,可以點以下連結~那我們就開始吧! 【圖論Graph】Part1:初探圖形與圖形演算法之應用