python元胞转list_[Python练习向] 简易元胞自动机框架
關于元胞自動機(Cellular Automata, CA)的原理這里就不再敘述了。
以前的學校地理系有用CA做城市發展研究的大牛,無論在課堂上還是在項目中都會用得到CA模型。雖然CA模型本身并不復雜,但是每次從新寫起也是十分麻煩,因此一個通用的CA模型框架能夠減少很多工作量。幸好對于大多數CA模型的應用來說,其鄰域定義大同小異,最主要的不同在于元胞的轉換規則會根據問題和方法的不同而有所變化。因此這個通用框架的核心在于,用戶可以自行定義元胞的轉換規則。
PyCA構建CA模型的流程如下:
創建轉換規則類需要兩類參數:
1)?鄰域類型和大小
在PyCA中定義了三種類型的鄰域: von、moore和custom,分別對應Von Neumann鄰域(大小為1時即四鄰域)、Moore領域(大小為1時即八鄰域)和自定義鄰域。
其中2代表中心元胞。如果需要自定義領域,則需要如上圖所示自行定義鄰域矩陣,使用1代表有效鄰域,2代表中心元胞,其他位置則用0表示。需要注意的是,PyCA沒有其他依賴numpy,定義矩陣時必須使用原生的list。
2) 自定義轉換規則
在定義轉換規則時,用戶不需要了解具體的模型運行流程參數。需要處理的參數有三個,包括當前中心元胞的值、有效鄰域元胞的值和環境因子,并根據上述參數給出下一次循環時中心元胞的值。因此轉換規則的定義如下:
newvlaue = rule(oldvalue, neighborhood, envi)
neighborhood和envi為鄰域元胞值和環境參數。這個兩個參數會傳入和之前定義鄰域大小相一致的矩陣,有效鄰域中保留對應的元胞或環境參數,無效鄰域將賦值為None。由于該框架支持多層環境參數,當輸入的環境參數有多個圖層時,neighborhood是一個包含每一層鄰域的list。
以最簡單的生命游戲為例,其元胞轉換規則應該如下:
defrule_lifegame(pix, neighborhood, envi):#Replace all the None with 0
for r in range(3):for c in range(3):if neighborhood[r][c] ==None:
neighborhood[r][c]=0#1 means living, and 0 means dead
if pix == 1:#The central cell can not be counted.
live = numpy.sum(neighborhood) - 1
if live < 2:return0elif live <= 3:return 1
else:return0else:
live=numpy.sum(neighborhood)if agent == 3:return 255
else:return 0;
當定義好轉換規則時,就可以用rulebuilder類來創建模型規則。rulebuilder類有兩種初始化方法,分別對應預定義鄰域(von、moore)和自定義領域:
# Predefined neighborhood: 'von' and 'moore'
rulebuilder = PyCA.rulebuilder(rule, ntype, nsize)
# Custome neighborhood:
rulebuilder = PyCA.rulebuilder(rule, neighboorhoodregion)
當新建好rulebuilder類后就可以調用build()方法類創建模型規則,以上面的生命游戲為例:
rulebuilder = PyCA.rulebuilder(rule_lifegame, 'von', 1)
carule= rulebuilder.build()
最后一步是利用CA類來創建CA模型。新建CA類需要三個參數:由rulebuilder.build()生成的模型規則、初始元胞分布、環境參數:
ca = PyCA.CA(envi, initialcells, carule)
然后調用CA類中的evolve()方法來進行迭代:
ca.evolve(time, returnresult, storehistory)
其中time指定迭代次數,默認值為1。returnresult指定在完成所有迭代后是否返回當前元胞分布,默認為False。storehistory指定每次迭代后是否將元胞分布保存到ca.history中,默認值為False。ca.history是一個dict,定義為 ca.history = {time: result of that time}。用戶可以在完成迭代后調用ca.history得到每次迭代結果。
至此,一個完整的CA模型創建和運行流程完成。PyCA源碼地址:http://pan.baidu.com/s/1mgwjkLE
最后,給出一個完整生命游戲Demo:
importPyCA, numpy, randomfrom PIL importImage#rule for life game
defrule_lifegame(pix, neighborhood, envi):for r in range(3):for c in range(3):if neighborhood[r][c] ==None:
neighborhood[r][c]=0if pix == 255:
live= numpy.sum(neighborhood) - 255
if live < 2 * 255:return0elif live <= 3 * 255:return 255
else:return0else:
live=numpy.sum(neighborhoodn)if agent == 3 * 255:return 255
else:return0;#build initial cell distributioin, randomly pick up 3000 cells as living cells
(row, col) = (100, 100)
cells=numpy.zeros((row, col)).tolist()for i in range(3000):
cells[random.randint(0,99)][random.randint(0, 99)] = 255
#build trasformation rules
rulebuilder = PyCA.rulebuilder(rule_lifegame, 'von', 1)
carule=rulebuilder.build()#create CA model
ca =PyCA.CA(cells, cells, carule)
ca.evolve(50, False, True)#save the array of result as bmp file
for (time, result) inca.history.items():
arr= numpy.array(result, dtype =numpy.uint8)
im=Image.fromarray(arr)
im.save('time_{0}.bmp'.format(time))
P.S:?為避免嚴重的邊界效應,該模型會忽略處于邊界的元胞。
如有什么問題歡迎私信討論。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的python元胞转list_[Python练习向] 简易元胞自动机框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python使曲线变得平滑_如何在Pyt
- 下一篇: python跳槽工资_年薪45万阿里程序