真菌元胞自动机Python实现
2021年美赛A题真菌元胞自动机Python实现
import matplotlib.pyplot as plt
import random
import numpy as np
import matplotlib.animation as animationdef save_fungi_ca_gif(): # save the gif file to the pathtarget_gif_path = "E:/engineering space/figure/gif format/"target_gif_name = "aggressive_ca.gif"target_gif_full = target_gif_path + target_gif_nameanim_1.save(target_gif_full, writer='pillow') # save the animationprint('Saved')def calculate_random_neighbour(stay, left, up, right, down, no_reproduce): # get the relative location of the newlytotal_rate = stay + left + up + right + down + no_reproduce # reproduced fungi cellif total_rate == 0.0:total_rate = 1cap1 = stay / total_rate # cap 1 to 5 is the boundary of probability areacap2 = cap1 + left / total_ratecap3 = cap2 + up / total_ratecap4 = cap3 + right / total_ratecap5 = cap4 + down / total_raternd = random.random()if 0 <= rnd < cap1:return 0elif cap1 <= rnd < cap2: # divide the range into 6 partsreturn 1elif cap2 <= rnd < cap3: # randomly select one partreturn 2elif cap3 <= rnd < cap4:return 3elif cap4 <= rnd < cap5:return 4else:return 5def get_extension_parameters(i_get_extension_parameters): # get the extension parametersextension_parameters = extension_rate_list[fungi_list[i_get_extension_parameters][3]]return extension_parametersdef get_random_neighbour(i_get_random_neighbour): # calculate the density of neighbour mesh as well as self meshextension_rate_get_random_neighbour = get_extension_parameters(i_get_random_neighbour)stay_density = my_board[fungi_list[i_get_random_neighbour][0], fungi_list[i_get_random_neighbour][1]] / one_mesh_maxstay_rate = extension_rate_get_random_neighbour - stay_densityif fungi_list[i_get_random_neighbour][1] != 0:left_density = my_board[fungi_list[i_get_random_neighbour][0], fungi_list[i_get_random_neighbour][1] - 1] \/ one_mesh_maxleft_rate = extension_rate_get_random_neighbour * (1 - left_density + 0.1) # further calculate the transferring rate of# the new fungielse:left_density = 0.5left_rate = 0if fungi_list[i_get_random_neighbour][0] != 0:up_density = my_board[fungi_list[i_get_random_neighbour][0] - 1, fungi_list[i_get_random_neighbour][1]] \/ one_mesh_maxup_rate = extension_rate_get_random_neighbour * (1 - up_density + 0.1)else:up_density = 0.5up_rate = 0if fungi_list[i_get_random_neighbour][1] != patch_size - 1:right_density = my_board[fungi_list[i_get_random_neighbour][0], fungi_list[i_get_random_neighbour][1] + 1] \/ one_mesh_maxright_rate = extension_rate_get_random_neighbour * (1 - right_density + 0.1)else:right_density = 0.5right_rate = 0if fungi_list[i_get_random_neighbour][0] != patch_size - 1:down_density = my_board[fungi_list[i_get_random_neighbour][0] + 1, fungi_list[i_get_random_neighbour][1]] \/ one_mesh_maxdown_rate = extension_rate_get_random_neighbour * (1 - down_density + 0.1)else:down_density = 0.5down_rate = 0total_density = stay_density + left_density + up_density + right_density + down_densityno_reproduce_rate = total_density / 8neighbour_location = calculate_random_neighbour(stay_rate, left_rate, up_rate, right_rate, down_rate,no_reproduce_rate)return neighbour_locationdef reproduce_one_cell(i_reproduce_one_cell): # reproduce a single fungi celliterations = 0while True: # loop until the random neighbour meets the boundary conditionsiterations += 1# print('iteration:', iterations)reproduce_location = get_random_neighbour(i_reproduce_one_cell)# the followings are boundary conditionsif iterations < 3:if reproduce_location == 0: # stay in one meshcurrent_mesh_num = my_board[fungi_list[i_reproduce_one_cell][0], fungi_list[i_reproduce_one_cell][1]]if current_mesh_num < one_mesh_max:# haven't arrived the maximum of one meshbreak # this is the location wantedelse:# print(iterations) # how many loops have been takencontinue # random againif reproduce_location == 1: # go to left meshif fungi_list[i_reproduce_one_cell][1] == 0: # reaches the left boundary# print(iterations)continue # random againelif my_board[fungi_list[i_reproduce_one_cell][0], fungi_list[i_reproduce_one_cell][1] - 1] \< one_mesh_max:break # this is the location wantedelse:continueif reproduce_location == 2: # go to up meshif fungi_list[i_reproduce_one_cell][0] == 0: # reaches the up boundary# print(iterations)continue # random againelif my_board[fungi_list[i_reproduce_one_cell][0] - 1, fungi_list[i_reproduce_one_cell][1]] \< one_mesh_max:break # this is the location wantedelse:continueif reproduce_location == 3: # go to right meshif fungi_list[i_reproduce_one_cell][1] == patch_size - 1: # reaches the right boundary# print(iterations)continue # random againelif my_board[fungi_list[i_reproduce_one_cell][0], fungi_list[i_reproduce_one_cell][1] + 1] \< one_mesh_max:break # this is the location wantedelse:continueif reproduce_location == 4: # go to down meshif fungi_list[i_reproduce_one_cell][0] == patch_size - 1: # reaches the down boundarycontinue# print(iterations)elif my_board[fungi_list[i_reproduce_one_cell][0] + 1, fungi_list[i_reproduce_one_cell][1]] \< one_mesh_max:break # this is the location wantedelse:continueelse:reproduce_location = 5breakglobal fungi_num# take reproducing activityif reproduce_location != 5:if reproduce_location == 0:fungi_list.append([fungi_list[i_reproduce_one_cell][0], fungi_list[i_reproduce_one_cell][1], 0, fungi_list[i_reproduce_one_cell][3]])# print('Stayed')if reproduce_location == 1:fungi_list.append([fungi_list[i_reproduce_one_cell][0], fungi_list[i_reproduce_one_cell][1] - 1, 0,fungi_list[i_reproduce_one_cell][3]])if reproduce_location == 2:fungi_list.append([fungi_list[i_reproduce_one_cell][0] - 1, fungi_list[i_reproduce_one_cell][1], 0,fungi_list[i_reproduce_one_cell][3]])if reproduce_location == 3:fungi_list.append([fungi_list[i_reproduce_one_cell][0], fungi_list[i_reproduce_one_cell][1] + 1, 0,fungi_list[i_reproduce_one_cell][3]])if reproduce_location == 4:fungi_list.append([fungi_list[i_reproduce_one_cell][0] + 1, fungi_list[i_reproduce_one_cell][1], 0,fungi_list[i_reproduce_one_cell][3]])fungi_list[i_reproduce_one_cell][2] += 1 # the reproduced time of a fungiif fungi_list[i_reproduce_one_cell][2] == reproduce_time_to_die_list[fungi_list[i_reproduce_one_cell][3]]:# when reproduced an exact times to diemy_board[fungi_list[i_reproduce_one_cell][0]][fungi_list[i_reproduce_one_cell][1]] -= 1 # remove fungi# in number boarddel fungi_list[i_reproduce_one_cell] # the death of a fungifungi_num = len(fungi_list)update_board(fungi_num) # get a board according to the new fungi reproducedelse:fungi_list[i_reproduce_one_cell][2] += 1 # the life span of a fungidef reproduce_round(): # reproduce all the current fungi cellsfor i_reproduce_round in range(fungi_num):reproduce_one_cell(i_reproduce_round) # reproduce a single fungi celldef update_board(fungi_num_update_board): # get a number board according to the new fungimy_board[fungi_list[fungi_num_update_board - 1][0]][fungi_list[fungi_num_update_board - 1][1]] += 1def get_rgb_board():paint_rgb_board = [[[1.0 for k in range(3)] for j in range(patch_size)] for i in range(patch_size)] # initializeglobal red_fungi_numglobal green_fungi_numglobal blue_fungi_numred_fungi_num = 0green_fungi_num = 0blue_fungi_num = 0# color boardfor i_paint_rgb_board in range(fungi_num):if fungi_list[i_paint_rgb_board][3] == 0:red_fungi_num += 1paint_rgb_board[fungi_list[i_paint_rgb_board][0]][fungi_list[i_paint_rgb_board][1]][1] -= (0.99/ one_mesh_max)paint_rgb_board[fungi_list[i_paint_rgb_board][0]][fungi_list[i_paint_rgb_board][1]][2] -= (0.99/ one_mesh_max)elif fungi_list[i_paint_rgb_board][3] == 1:green_fungi_num += 1paint_rgb_board[fungi_list[i_paint_rgb_board][0]][fungi_list[i_paint_rgb_board][1]][0] -= (0.99/ one_mesh_max)paint_rgb_board[fungi_list[i_paint_rgb_board][0]][fungi_list[i_paint_rgb_board][1]][2] -= (0.99/ one_mesh_max)else:blue_fungi_num += 1paint_rgb_board[fungi_list[i_paint_rgb_board][0]][fungi_list[i_paint_rgb_board][1]][0] -= (0.99/ one_mesh_max)paint_rgb_board[fungi_list[i_paint_rgb_board][0]][fungi_list[i_paint_rgb_board][1]][1] -= (0.99/ one_mesh_max)return paint_rgb_boarddef attack_round():global fungi_numfor i_attack_round in range(fungi_num):if i_attack_round == fungi_num - 1:breakif fungi_list[i_attack_round][2] >= reproduce_time_to_die_list[fungi_list[i_attack_round][3]]:# when reproduced an exact times to diemy_board[fungi_list[i_attack_round][0]][fungi_list[i_attack_round][1]] -= 1 # remove fungi in number boarddel fungi_list[i_attack_round] # the death of a fungifungi_num = len(fungi_list)# update_board(fungi_num) # get a board according to the new fungi reproducedelse:continuedef update(): # update the board information and fungi list in a roundreproduce_round() # reproduce all the current fungi cellsrgb_board_update = get_rgb_board() # get a color board after a round of reproductionattack_round()return rgb_board_updatedef calculate_initial_position(): # calculate the initial position of cells for fair competitionradius_calculate_initial_position = patch_size / 6 # distance between initial cellsmiddle_point_initial_position = patch_size / 2for i_calculate_initial_position in range(initial_fungi_num):rotation_degree = i_calculate_initial_position / initial_fungi_num * 2 * np.pix_initial_position = middle_point_initial_position + np.cos(rotation_degree) * radius_calculate_initial_positiony_initial_position = middle_point_initial_position + np.sin(rotation_degree) * radius_calculate_initial_positionx_initial_list.append(int(round(x_initial_position)))y_initial_list.append(int(round(y_initial_position)))def animate_func(frame_sequence): # depict the animationax_1.imshow(update())update_extension_rate()# ax_1.text(patch_size / 12, patch_size / 12, frame_sequence, color='white', size=20)print('total:', fungi_num, 'red:', red_fungi_num, 'green:', green_fungi_num, 'blue:', blue_fungi_num)print('frame number:', frame_sequence + 1)def update_extension_rate():global extension_rate_listred_fungi_rate = red_fungi_num / fungi_numgreen_fungi_rate = green_fungi_num / fungi_numblue_fungi_rate = blue_fungi_num / fungi_numif red_fungi_rate <= rate_limit:extension_rate_list[0] = fungi_num / red_fungi_num# total_extension_rate = sum(extension_rate_list)# extension_rate_list = extension_rate_list / total_extension_rateelif green_fungi_rate <= rate_limit:extension_rate_list[1] = fungi_num / green_fungi_num# total_extension_rate = sum(extension_rate_list)# extension_rate_list = extension_rate_list / total_extension_rateelif blue_fungi_rate <= rate_limit:extension_rate_list[2] = fungi_num / blue_fungi_num# total_extension_rate = sum(extension_rate_list)# extension_rate_list = extension_rate_list / total_extension_rateif __name__ == '__main__':patch_size = 25 # size of our patch# frame_number = 30 # number of framesone_mesh_max = 7 # the maximum number of fungi cells in a single meshinitial_fungi_num = 3 # the initial number of fungi cells as well as speciesfungi_list = [] # list of cellsmy_board = np.zeros((patch_size, patch_size)) # initialize number boardx_initial_list = [] # the x, y position of initial cellsy_initial_list = []# calculate_initial_position() # calculate the initial position of cells for fair competitionred_fungi_num = 1 # number of each species of fungigreen_fungi_num = 1blue_fungi_num = 1rate_limit = 0.01for i_initial in range(initial_fungi_num): # initialize fungi listx_initial = np.random.randint(patch_size) # int(patch_size / 10) + i_initial * int(8 * patch_size / 10) #y_initial = np.random.randint(patch_size) # x_initial ## fungi_list.append([x_initial_list[i_initial], y_initial_list[i_initial], 0, i_initial]) # the indexes are# x, y,fungi_list.append([x_initial, y_initial, 0, i_initial])# reproduce time and species numupdate_board(i_initial + 1)fungi_num = initial_fungi_numextension_rate_list = [0.6, 0.2, 0.2] #extension_rate_list = np.array(extension_rate_list)# different species of fungi have different extension rateattack_parameter_list = [0.3, 0.1, 0.5] # density parameter of different species of fungireproduce_time_to_die_list = [2, 2, 2] # each cell reproduce two times until deathrgb_board = [[[1.0 for k in range(3)] for j in range(patch_size)] for i in range(patch_size)] # initialize color# boardfig_1 = plt.figure(1) # create a plotax_1 = fig_1.add_subplot(1, 1, 1) # create an axes# ims = [] # prepared for the frames to put in# anim_1 = animation.ArtistAnimation(fig_1, ims, repeat=False) # create an animation# save_fungi_ca_gif() # save the gif fileanim_2 = animation.FuncAnimation(fig_1, animate_func)plt.show()# print(my_board)
效果图
真菌元胞自动机Python实现相关推荐
- 简单元胞自动机实现—Python
一.简单元胞自动机简介 设定指定空间中的每个细胞的初始状态后依据一定生存规则演绎生命的变化,由于初始状态和迭代次数不同,将会得到令人叹服的优美图案. 二.游戏规则 (一)对于确定细胞的周边范围,我们将 ...
- python元胞自动机模拟交通_大师兄带你复现 -gt; 难度超高的二维CA元胞自动机模型...
最近过上了在家躺着就为祖国做贡献的生活. 然而,热心的知友们找我私信,询问"怎么画二维CA(元胞自动机)模型的仿真界面呀?""菜鸟如何做CA仿真?" 刚交完稿子 ...
- python元胞转list_[Python练习向] 简易元胞自动机框架
关于元胞自动机(Cellular Automata, CA)的原理这里就不再叙述了. 以前的学校地理系有用CA做城市发展研究的大牛,无论在课堂上还是在项目中都会用得到CA模型.虽然CA模型本身并不复杂 ...
- python元胞自动机模拟交通_结构专栏 | 解析DEFORM软件中的元胞自动机法
点击上方蓝色字体,关注我们 导语 金属材料的性能取决于内部的微观组织结构,而好的材料性能和价格是产品最大的优势.随着现代物理冶金.热成形技术.热处理技术和计算机技术的兴起与发展,使预测和控制金属材料热 ...
- python元胞自动机模拟交通_基于立体网格的放射性污染物扩散过程模拟与表达
作 者 信 息 施加松1,余接情2,常芸芬1,童晓冲3 (1.防化研究院,北京 102205:2.中国矿业大学 环境与测绘学院,江苏 徐州 221116:3.信息工程大学,河南 郑州 450001) ...
- python实现元胞自动机——超简单的流言模型
关于元胞自动机,这个ppt讲得挺不错的: https://wenku.baidu.com/view/86050cb9aeaad1f347933f28.html 下面实现一个流言模型: from mat ...
- MATLAB算法实战应用案例精讲-元胞自动机生命游戏(附Java、Python、C语言、C++和MATLAB代码实现)
目录 前言 知识储备 元胞自动机的构成 元胞空间 元胞状态 邻域
- 【机器学习】通俗的元胞自动机算法解析和应用
[机器学习]通俗的元胞自动机算法解析和应用 文章目录 1 元胞自动机的定义 2 元胞自动机的组成 3 元胞自动机的特征 4 Python实现元胞自动机(生命游戏) 5 总结 6 Github(华盛顿州 ...
- 元胞自动机:森林火灾模拟(Matlab:heatmap、colormap)
目录 1.元胞自动机(Cellular Automation,CA) 2.森林火灾 3.伪代码 4.元胞自动机模拟森林火灾(Matlab实现) (1)定义森林火灾函数 ①空位生长树木 (0 --> ...
最新文章
- Ubuntu16.04 安装Qt
- 共读计划 | 你有多久没读完一本书了?
- 在Linux下安装配置phpMyAdmin步骤
- 跟沈剑学习如何带领技术团队作战
- python基本语法:列表(列表和元组的区别)
- mysql 半同步 主主_MySQL主从,半同步,主主复制
- Sinkhorn算法,正矩阵与双随机矩阵之间的关系
- SQL Server中的空间SQL数据类型
- Linux下Socket网络编程send和recv使用注意事项
- java case用法_Go语言 | goroutine不只有基础的用法,还有这些你不知道的操作
- windows Mobile使用ActiveSync上网
- java 使用不同目录下的类_如何运行在不同目录下的java类文件? - Break易站
- python文本分析工具_可以用来分析文本数据的Python工具的完整指南
- java手机单机游戏_手机单机游戏推荐简介
- Hive 高频面试题 30 题
- 加权平均数的例子_加权平均值计算器
- LabVIEW如何将脚本插入Quick Drop
- 【转】京东商城思维导图
- Latex之在caption里加footnote
- springboot+Rabit实战二:(Rabbit MQ web 界面管理)
热门文章
- MatchNet: Unifying Feature and Metric Learning for Patch-Based Matching
- 时间精力管理4象限法
- 【NOIP2015模拟10.28B组】终章-剑之魂题解
- C++获取鼠标坐标并移动鼠标
- 详细分析本机号码一键登录原理!建议收藏
- 分摊的意思_十年分摊是什么意思
- 7-7 阿泽的交友标准 (10 分)
- C# 获取类的属性名
- RT-Thread 模拟器 simulator 搭建 LVGL 的开发调试环境
- Shutting down firmware services 报错