一年前写的代码,偶然翻出来。发现自己当时水平还不赖吗。

 # include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <stdbool.h>
# include <windows.h> # define N0 //初始时刻种群数量为1000
# define Nmax //种群最大数量为100000
# define R //最低繁殖年龄为8
# define B //老死年龄即位串长度为32
# define b //每次繁殖子代个数为1
# define T //最大疾病次数为2
# define M //突变强度为2
# define LEN sizeof(GENE) //宏替换一个结构体的大小
clock_t start, finish;
double duration;
int t;
typedef struct Gene
{
bool Gene[B]; //用布尔类型数组表示位串
int Age; //年龄
int SickNum; //患病次数
struct Gene *next; //存放一个连接链表的节点指针
}GENE;
int Nt = N0; //定义一个全局变量,表示t时刻种群的数量
double M_rate = (double)M/B; //M_rate表示基因遗传突变率
GENE *pHead = NULL, *pFore = NULL, *pNext = NULL, *p = NULL, *pTail = NULL;
//定义五个指针:pHead指向头节点pFore为节点的前驱指针,pNext建立新节点,p游标指针,pTail尾节点指针
GENE Gene_Str; //定义一个GENE类型的结构体Gene_Str void Initialize(void) //构造链表及种群初始状态
{
pHead = (GENE *)malloc(LEN);//为头节点指针分配空间
p = pHead; //头节点指针赋值给游标指针
for (int i=; i<N0; i++)
{
p->Age = ; //初始时刻年龄为0(t=0)
p->SickNum = ; //患病次数为0
for (int j=; j<B; j++)
{
p->Gene[j] = (rand()%); // 对第一代个体基因随机规定
}
pNext = (GENE *)malloc(LEN); //为新节点开辟存储空间
p->next = pNext; //将前驱节点指向下一结构体地址
p = pNext; //将新节点赋值给游标指针
}
pTail = p;
pNext = p = NULL;
pTail->next = NULL; //尾节点下一指向为空
}
void Aging(void) //执行年龄增长机制,每次调用,所有个体年龄加一
{
p = pHead; //游标指针指向头指针
while (p != NULL) //遍历每个个体
{
if (p->Gene[p->Age] == )
{
p->SickNum++;
} //如果该年龄位置为坏基因,则患病次数加一
p->Age++; //每个个体年龄加一
p = p->next; //游标指针指向下一个体
}
}
void Die(void) //执行死亡机制,每次调用,满足条件的个体死去,链表节点删除
{
pFore = p = pHead; //游标指针指向头指针,并创建一个和游标指针同步的前驱指针
while (p != NULL) //遍历每个个体
{
double RandOfLive = (double)rand()/(double)RAND_MAX; //构造一个随机概率
if (p->SickNum>=T || p->Age>=(B-) || RandOfLive>=(-(double)Nt/Nmax))
//满足三种情况之一即死亡:年龄到达老死年龄,达到最大患病次数,因环境压力随机死亡
{
Nt--; //每次死亡导致种群数量减一
if (p == pHead)//当p为头节点
{
pHead = p->next;
free(p); //节点删除后释放占用的空间
pFore = p = pHead;
p = p->next; //重新初始化
}
else if (p->next == NULL)//当p为尾节点
{
pFore->next = NULL; //将前一个节点设置为尾节点
free(p); //释放删除后的节点
p = NULL;
}
else //既不是头节点又不是尾节点
{
pFore->next = p->next; //跳过p节点,前后相连接
free(p); //释放删除了的节点
p = pFore;
pFore = p;
p = p->next; //重新初始化
}
}
else //如果个体不满足死亡条件
{
pFore = p;
p = p->next; //指针向下一节点移动并始终存储前一节点以备删除中间节点
}
} //结束后p == NULL,是尾节点的节点指针
pNext = NULL;
pFore = NULL; //遍历之后将这两个指针置为空,防止错误调用
}
void RePreduction(void) //执行繁殖机制
{
p = pHead; //p指向链表的头指针
while (p != NULL) //遍历每个个体
{
double RandOfChange = (double)rand()/(double)RAND_MAX; //构造一个随机数
if (p->Age >= R) //如果年龄达到最低繁殖年龄
{
pNext = p; //为了方便操作,将每一个新生个体对应的节点连在尾节点后
while (pNext->next != NULL)
pNext = pNext->next; //此时pNext为尾节点 for (int k=; k<b; k++) //每次繁殖将产生b个新个体
{
while (pNext->next != NULL)
pNext = pNext->next; pTail = (GENE *)malloc(LEN); //开辟一个存储空间
pNext->next = pTail; //尾节点的next指向该存储空间
pTail->next = NULL; //将这个新节点设为尾节点
for (int i=; i<B; i++)
{
if (RandOfChange < M_rate) //达到要求则发生突变
pTail->Gene[i] = !p->Gene[i];
else //否则执行拷贝复制
pTail->Gene[i] = p->Gene[i];
}
pTail->Age = ;
pTail->SickNum = ; //新生个体的这两项也要初始化,开始一直忘了!!!!!!!!
Nt+=; //个体数加一
}
p = p->next;
}
else
p = p->next; //执行完继续下一个体
}
} int main(void)
{
FILE* fp = fopen("resultr6.txt", "w");
if (fp == NULL)
printf("error\n");
Sleep(); //挂起两秒钟
srand((unsigned)time(NULL)); //随机种子
Initialize(); //对初始个体进行初始化操作
for (t=; t<; t++) //种群在该机制下演化一千个时间步
{
Aging(); //执行年龄增长机制
Die(); //执行死亡机制
RePreduction(); //执行繁殖机制
printf("A");
fprintf(fp, "%d\t", Nt);
}
fclose(fp);
return ;
}

  附图

C语言实现penna模型的更多相关文章

  1. R语言︱LDA主题模型——最优主题...

    R语言︱LDA主题模型——最优主题...:https://blog.csdn.net/sinat_26917383/article/details/51547298#comments

  2. 基于R语言的ARIMA模型

    A IMA模型是一种著名的时间序列预测方法,主要是指将非平稳时间序列转化为平稳时间序列,然后将因变量仅对它的滞后值以及随机误差项的现值和滞后值进行回归所建立的模型.ARIMA模型根据原序列是否平稳以及 ...

  3. 11 The Go Memory Model go语言内置模型

    The Go Memory Model go语言内置模型 Version of May 31, 2014 Introduction 介绍 Advice 建议 Happens Before 在发生之前 ...

  4. Simulink仿真入门到精通(八) M语言对Simulink模型的自动化操作及配置

    8.1 M语言控制模型的仿真 M语言与Simulink结合的方式: 在Simulink模型或模块中使用回调函数 在M语言中调用与模型相关的命令,控制模型的建立,设置模块的属性,增删信号线,以及运行模型 ...

  5. C语言与内存模型初探

    #include<stdio.h> #include<string.h> int main(){ long long int a = 2<<30; char str ...

  6. R语言︱LDA主题模型——最优主题数选取(topicmodels)+LDAvis可视化(lda+LDAvis)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 笔者寄语:在自己学LDA主题模型时候,发现该模 ...

  7. C语言复习:内存模型1

    数据类型本质分析 数据类型概念 "类型"是对数据的抽象; 类型相同的数据有相同的表现形式/存储格式以及相关的操作; 程序中使用的所有数据都必定属于某一种数据类型; 数据类型本质思考 ...

  8. Go语言 | CSP并发模型与Goroutine的基本使用

    今天是golang专题的第13篇文章,我们一起来聊聊golang当中的并发与Goroutine. 在之前的文章当中我们介绍完了golang当中常用的使用方法和规范,在接下来的文章当中和大家聊聊gola ...

  9. 有 va_arg宏 中数组下标-1 引发的思考 - C 语言中内存模型

    va_arg宏,是头文件 stdarg.h 中定义的,获取可变参数的当前参数. #define va_arg(list, mode) ((mode*)(list+=sizeof(mode)))[-1] ...

随机推荐

  1. JAVA JPA - 示例用法

    JPA(Java Persistence API)是JSR(Java Specification Requests)的一部分,定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate. ...

  2. location.href 实现点击下载功能

    如果页面上要实现一个点击下载的功能,传统做法是使用一个 a 标签,然后将该标签的 href 属性地址指向下载文件在服务端的地址(相对地址或者绝对地址),比如这样: 能这样实现是因为,在浏览器地址栏输入 ...

  3. Redis百亿级Key存储方案

    1 需求背景 该应用场景为DMP缓存存储需求,DMP需要管理非常多的第三方id数据,其中包括各媒体cookie与自身cookie(以下统称supperid)的mapping关系,还包括了supperi ...

  4. 基于DDD的.NET开发框架 - ABP的Entity设计思想

    返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...

  5. 从语言到库到框架,再到API,再到标记最后到DSL语言

    计算机技术发展很快,而且越来越快,结果也是越来越复杂,那么我们到底怎么搞定复杂性并重用代码? 很明显,这是个大难题.一开始我们要解决计算问题,发展了基本的编程语言. 很快,编程语言不能满足需求,我们需 ...

  6. JAVA多线程(二)

    Synchronized的使用: (一)synchronized:  Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当某个方法或者代 ...

  7. Windows去除快捷箭头

    美化桌面 bat代码: reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shel ...

  8. Android Intent应用

    1. 显示Intent // 直接设置Content和到下一个的Actvity的名字 Intent i = new Intent(MainActivity.this, AnotherAty.class ...

  9. sqlite之聚合函数的使用

    聚合函数对一组值执行计算并返回单一的值.聚合函数对一组值执行计算,并返回单个值.除了 COUNT 以外,聚合函数都会忽略空值. 聚合函数经常与 SELECT 语句的 GROUP BY 子句一起使用. ...

  10. 在Ubuntu 14.04中安装最新版Eclipse

    1.下载eclipse从官网http://www.eclipse.org/downloads/下载Eclipse IDE for Java EE Developers的Linux版本eclipse-S ...