元胞自动机生命游戏C语言并行实现
简介
细胞自动机(又称元胞自动机),名字虽然很深奥,但是它的行为却是非常美妙的。所有这些怎样实现的呢?我们可以把计算机中的宇宙想象成是一堆方格子构成的封闭空间,尺寸为N的空间就有NN个格子。而每一个格子都可以看成是一个生命体,每个生命都有生和死两种状态,如果该格子生就显示蓝色,死则显示白色。每一个格子旁边都有邻居格子存在,如果我们把33的9个格子构成的正方形看成一个基本单位的话,那么这个正方形中心的格子的邻居就是它旁边的8个格子。
每个格子的生死遵循下面的原则:
1. 如果一个细胞周围有3个细胞为生(一个细胞周围共有8个细胞),则该细胞为生(即该细胞若原先为死,则转为生,若原先为生,则保持不变) 。
2. 如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;
3. 在其它情况下,该细胞为死(即该细胞若原先为生,则转为死,若原先为死,则保持不变)
实现思路
将全局矩阵分解为大小相等的(工作)块,这样我们就可以实现生命的游戏。
初始化:从文件中读取数据:一个包含游戏初始状态的m×n矩阵。
为了与其他处理器通信,我设置了一个局部矩阵和一个全局矩阵。局部矩阵是一种混合状态。对于处理器0,它可以从局部矩阵中获得全局矩阵。
MPI并行实现
#include <stdio.h>
#include <string.h>
#include "mpi.h"
#include <stdlib.h>static int MAX_M;
static int MAX_N;
static int epoch;
static int DEAD=0;
static int ALIVE=1;double exe_time;
int size, myid, s, ver, row, col, dir;int *local_matrix = NULL;
int *tmpmatrix = NULL;
int *global_matrix = NULL;
int *newglobal_matrix = NULL;
MPI_Request requests[4];
MPI_Status status[4];FILE * matrix;void display(int *local_matrix){int i, j;printf("%10c", ' ');printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");for (i = 0; i < MAX_M; i++){printf("\n%10c", ' ');for (j = 0; j < MAX_N; j++)if (local_matrix[i * MAX_N + j] == ALIVE)printf("+");elseprintf("-");}printf("\n%10c\n", ' ');
}int adj8(int neighbor, int row, int col){int res;if(neighbor == 2){return local_matrix[row * MAX_N + col];}else if(neighbor == 3){return ALIVE;}else{return DEAD;}
}int main(int argc,char *argv[]){MPI_Init(&argc, &argv);MPI_Comm_size(MPI_COMM_WORLD, &size);MPI_Comm_rank(MPI_COMM_WORLD, &myid);ver = MAX_M / size;epoch= atoi(argv[1]);MAX_M= atoi(argv[2]);MAX_N= atoi(argv[3]);local_matrix = (int*)malloc(sizeof(int) * (ver+2) * MAX_N);tmpmatrix = (int*)malloc(sizeof(int) * (ver+2) * MAX_N);for (row = 0; row < ver+2; row++) {for (col = 0; col < MAX_N; col++) {local_matrix[row*MAX_N+col] = DEAD;tmpmatrix[row*MAX_N+col] = DEAD;}}//Initializationif (myid == 0) {int i;global_matrix = (int*)malloc(sizeof(int) * MAX_M * MAX_N);newglobal_matrix = (int*)malloc(sizeof(int) * MAX_M * MAX_N);if((matrix = fopen("matrix.txt","r"))==NULL){printf("the file can not open.");return -1;}for(row = 0; row < MAX_M; row++){for(col = 0; col < MAX_N; col++){fscanf(matrix,"%d ", &global_matrix[row*MAX_N + col]);}fscanf(matrix,"\n");}memcpy(&local_matrix[MAX_N], &global_matrix[0], ver * MAX_N * sizeof(int));for (dir = 1; dir < size; dir++) {MPI_Send(&global_matrix[dir*ver*MAX_N], ver * MAX_N, MPI_INT, dir, 1, MPI_COMM_WORLD);}display(global_matrix);} else {//For each processor, there is a local matrix.MPI_Recv(&local_matrix[MAX_N], ver * MAX_N, MPI_INT, 0, 1, MPI_COMM_WORLD, status);}exe_time = -MPI_Wtime();for (int count=0; count<epoch;count++){int req_id = 0;if (myid == 0) {MPI_Isend(&local_matrix[(ver)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]);MPI_Irecv(&local_matrix[(ver+1)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]);printf("\n");display(local_matrix);} else {MPI_Irecv(local_matrix, MAX_N, MPI_INT, myid - 1, 1, MPI_COMM_WORLD, &requests[req_id++]);MPI_Isend(&local_matrix[(ver)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]);MPI_Irecv(&local_matrix[(ver+1)*MAX_N], MAX_N, MPI_INT, myid + 1, 1, MPI_COMM_WORLD, &requests[req_id++]);MPI_Isend(&local_matrix[MAX_N], MAX_N, MPI_INT, myid - 1, 1, MPI_COMM_WORLD, &requests[req_id++]);}MPI_Waitall(req_id, requests, status);for (row = 1; row < ver+1; row+=1){for (col = 0; col < MAX_N; col++){int neighbor = 0, c, r;for (r = row - 1; r <= row + 1; r++)for (c = col - 1; c <= col + 1; c++){if (c < 0 || c >= MAX_N) continue;if (local_matrix[r * MAX_N + c] == ALIVE) neighbor++;}if (local_matrix[row * MAX_N + col] == ALIVE)neighbor--;tmpmatrix[row * MAX_N + col] = adj8(neighbor, row, col);}}for (row = 1; row < ver+1; row+=1){for (col = 0; col < MAX_N; col++){local_matrix[row * MAX_N + col] = tmpmatrix[row * MAX_N + col];}}}if (myid == 0) {exe_time += MPI_Wtime();printf("Time: %lf \n", exe_time);memcpy(global_matrix, &local_matrix[MAX_N], ver * MAX_N * sizeof(int));for (dir = 1; dir < size; dir++) {MPI_Recv(&global_matrix[dir*ver*MAX_N], ver*MAX_N, MPI_INT, dir, 1, MPI_COMM_WORLD, status);}printf("Last Status:\n");display(global_matrix);}else {MPI_Send(&local_matrix[MAX_N], ver * MAX_N, MPI_INT, 0, 1, MPI_COMM_WORLD);}MPI_Finalize();return 0;
}
更多内容访问 omegaxyz.com
网站所有代码采用Apache 2.0授权
网站文章采用知识共享许可协议BY-NC-SA4.0授权
© 2022 • OmegaXYZ-版权所有 转载请注明出处
元胞自动机生命游戏C语言并行实现相关推荐
- MATLAB算法实战应用案例精讲-元胞自动机生命游戏(附Java、Python、C语言、C++和MATLAB代码实现)
目录 前言 知识储备 元胞自动机的构成 元胞空间 元胞状态 邻域
- 一维元胞自动机生命游戏
提示:某天在网络上看到生命游戏,好奇点进去,然后发现,一个小小的规则能衍生出很多复杂的东西,一个小小的方块竟能表现的跟生命一样, 有一种道生万物的奇妙体验, 我们人类是不上也是某种规则下的产物呢? 盆 ...
- 【元胞自动机】元胞自动机生命游戏【含Matlab源码 655期】
⛄一.元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 · 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 · 何 ...
- 【元胞自动机】元胞自动机模拟交通事故道路通行量【含Matlab源码 356期】
⛄一.元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 · 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 · 何 ...
- 【元胞自动机】元胞自动机地铁火灾疏散模型【含Matlab源码 246期】
⛄一.元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 · 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 · 何 ...
- 【元胞自动机】基于matlab元胞自动机多车道信号交叉口仿真【含Matlab源码 818期】
⛄一.元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 · 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 · 何 ...
- 【元胞自动机】元胞自动机双边教室疏散【含Matlab源码 1208期】
⛄一.元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 · 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 · 何 ...
- 学习常用模型及算法:2.元胞自动机和交通模型
元胞自动机在数模中的应用十分广泛. 元胞自动机原理 一维元胞自动机.给出任意一个状态,都能知道下一时刻的状态.规则已给出,总共有2^3 = 8种可能. 二维元胞自动机--生命游戏 元胞的状态是有限的- ...
- 【元胞自动机】保守策略元胞自动机三车道(不开放辅路,软件园影响)交通流模型matlab源码
一.元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 · 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 · 何顿 ...
- 【元胞自动机】激进策略元胞自动机三车道(开放辅路,软件园影响)交通流模型matlab源码
一.元胞自动机简介 1 元胞自动机发展历程 最初的元胞自动机是由冯 · 诺依曼在 1950 年代为模拟生物 细胞的自我复制而提出的. 但是并未受到学术界重视. 1970 年, 剑桥大学的约翰 · 何顿 ...
最新文章
- 体验Hadoop3.0生态圈-CDH6.1时代的来临
- faster rcnn 数据格式
- java 对象池 博客_Java对象池技术的原理及其实现的小结
- 从此明白了卷积神经网络(CNN)
- intel A20地址线
- 在html页面中使用模板继承,HTML静态模板的继承
- u盘安装centos 7.2
- 晚安,2017。你好,2018。
- Anaconda下载安装Pytorch遇到的几个问题及解决办法
- python DEA: by-product NDDF DEA模型
- vim 快捷键 总结-编辑文件
- 适合运动健身的蓝牙耳机推荐,六款适合运动健身的蓝牙耳机
- python打开word并定位_python自动化办公之 python操作Word
- boost::math::binomial_distribution用法的测试程序
- L - 芜湖塔台请求起飞
- 推土距离, Wasserstein distance
- 响应式极简新闻发布系统源码
- 【思维】Hzy's Rabbit Stick
- uni-app 结合云函数开发小程序博客(二):云函数实现登录注册
- 用NEON intrinsic实现RGB转YUV420SP(NV12)
热门文章
- C++11 列表初始化
- MySQL建表规范与常见问题
- cad连接不同线段的端点_Cad 首尾相连的线段连接成多段线
- 如何卸载jdk_Java新手怎样安装JDK,手把手教你如何安装JDK
- python中darks_YOLOv4: Darknet 如何于 Ubuntu 编译,及使用 Python 接口
- 过拟合和欠拟合_TensorFlow教程-过拟合和欠拟合
- 论文笔记_S2D.52_CMRNet++_运行记录
- arduino学习笔记(一)——bamboosir920
- Hadoop学习笔记(二):MapReduce的进度和状态
- C++调用mask rcnn进行实时检测--opencv4.0