zoukankan      html  css  js  c++  java
  • C语言实现penna模型

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

      1 # include <stdio.h>
      2 # include <stdlib.h>
      3 # include <time.h>
      4 # include <stdbool.h>
      5 # include <windows.h>
      6 
      7 # define N0 1000    //初始时刻种群数量为1000
      8 # define Nmax 100000    //种群最大数量为100000
      9 # define R 6    //最低繁殖年龄为8
     10 # define B 32   //老死年龄即位串长度为32
     11 # define b 1    //每次繁殖子代个数为1
     12 # define T 4    //最大疾病次数为2
     13 # define M 2    //突变强度为2
     14 # define LEN sizeof(GENE)   //宏替换一个结构体的大小
     15 clock_t start, finish;
     16 double duration;
     17 int t;
     18 typedef struct Gene
     19 {
     20     bool Gene[B];   //用布尔类型数组表示位串
     21     int Age;    //年龄
     22     int SickNum;    //患病次数
     23     struct Gene *next;  //存放一个连接链表的节点指针
     24 }GENE;
     25 int Nt = N0;    //定义一个全局变量,表示t时刻种群的数量
     26 double M_rate = (double)M/B;    //M_rate表示基因遗传突变率
     27 GENE *pHead = NULL, *pFore = NULL, *pNext = NULL, *p = NULL, *pTail = NULL;
     28 //定义五个指针:pHead指向头节点pFore为节点的前驱指针,pNext建立新节点,p游标指针,pTail尾节点指针
     29 GENE Gene_Str;  //定义一个GENE类型的结构体Gene_Str
     30 
     31 void Initialize(void)   //构造链表及种群初始状态
     32 {
     33     pHead = (GENE *)malloc(LEN);//为头节点指针分配空间
     34     p = pHead;  //头节点指针赋值给游标指针
     35     for (int i=1; i<N0; i++)
     36     {
     37         p->Age = 0; //初始时刻年龄为0(t=0)
     38         p->SickNum = 0; //患病次数为0
     39         for (int j=0; j<B; j++)
     40         {
     41             p->Gene[j] = (rand()%2);    //  对第一代个体基因随机规定
     42         }
     43         pNext = (GENE *)malloc(LEN);    //为新节点开辟存储空间
     44         p->next = pNext;    //将前驱节点指向下一结构体地址
     45         p = pNext;  //将新节点赋值给游标指针
     46     }
     47     pTail = p;
     48     pNext = p = NULL;
     49     pTail->next = NULL; //尾节点下一指向为空
     50 }
     51 void Aging(void)    //执行年龄增长机制,每次调用,所有个体年龄加一
     52 {
     53     p = pHead;  //游标指针指向头指针
     54     while (p != NULL)   //遍历每个个体
     55     {
     56         if (p->Gene[p->Age] == 1)
     57         {
     58             p->SickNum++;
     59         }   //如果该年龄位置为坏基因,则患病次数加一
     60         p->Age++;   //每个个体年龄加一
     61         p = p->next;    //游标指针指向下一个体
     62     }
     63 }
     64 void Die(void)  //执行死亡机制,每次调用,满足条件的个体死去,链表节点删除
     65 {
     66     pFore = p = pHead;  //游标指针指向头指针,并创建一个和游标指针同步的前驱指针
     67     while (p != NULL)   //遍历每个个体
     68     {
     69         double RandOfLive = (double)rand()/(double)RAND_MAX;    //构造一个随机概率
     70         if (p->SickNum>=T || p->Age>=(B-1) || RandOfLive>=(1-(double)Nt/Nmax))
     71         //满足三种情况之一即死亡:年龄到达老死年龄,达到最大患病次数,因环境压力随机死亡
     72         {
     73             Nt--;   //每次死亡导致种群数量减一          
     74             if (p == pHead)//当p为头节点
     75             {
     76                 pHead = p->next;
     77                 free(p);    //节点删除后释放占用的空间
     78                 pFore = p = pHead;
     79                 p = p->next;    //重新初始化
     80             }
     81             else if (p->next == NULL)//当p为尾节点
     82             {
     83                 pFore->next = NULL; //将前一个节点设置为尾节点
     84                 free(p);    //释放删除后的节点
     85                 p = NULL;
     86             }
     87             else    //既不是头节点又不是尾节点
     88             {
     89                 pFore->next = p->next;  //跳过p节点,前后相连接
     90                 free(p);    //释放删除了的节点
     91                 p = pFore;
     92                 pFore = p;
     93                 p = p->next;    //重新初始化
     94             }
     95         }
     96         else    //如果个体不满足死亡条件
     97         {
     98             pFore = p;
     99             p = p->next;    //指针向下一节点移动并始终存储前一节点以备删除中间节点
    100         }
    101     }   //结束后p == NULL,是尾节点的节点指针
    102     pNext = NULL;
    103     pFore = NULL;   //遍历之后将这两个指针置为空,防止错误调用
    104 }
    105 void RePreduction(void) //执行繁殖机制
    106 {
    107     p = pHead;  //p指向链表的头指针
    108     while (p != NULL)   //遍历每个个体
    109     {
    110         double RandOfChange = (double)rand()/(double)RAND_MAX;  //构造一个随机数
    111         if (p->Age >= R)    //如果年龄达到最低繁殖年龄
    112         {
    113             pNext = p;  //为了方便操作,将每一个新生个体对应的节点连在尾节点后
    114             while (pNext->next != NULL)
    115                 pNext = pNext->next;    //此时pNext为尾节点
    116             
    117             for (int k=0; k<b; k++) //每次繁殖将产生b个新个体
    118             {
    119                 while (pNext->next != NULL)
    120                     pNext = pNext->next;
    121                 
    122                 pTail = (GENE *)malloc(LEN);    //开辟一个存储空间
    123                 pNext->next = pTail;    //尾节点的next指向该存储空间
    124                 pTail->next = NULL; //将这个新节点设为尾节点         
    125                 for (int i=0; i<B; i++)
    126                 {
    127                     if (RandOfChange < M_rate)  //达到要求则发生突变
    128                         pTail->Gene[i] = !p->Gene[i];
    129                     else    //否则执行拷贝复制
    130                         pTail->Gene[i] = p->Gene[i];
    131                 }
    132                 pTail->Age = 0;
    133                 pTail->SickNum = 0; //新生个体的这两项也要初始化,开始一直忘了!!!!!!!!
    134                 Nt+=1;  //个体数加一
    135             }
    136             p = p->next;
    137         }
    138         else
    139             p = p->next;    //执行完继续下一个体
    140     }
    141 }
    142 
    143 int main(void)
    144 {
    145     FILE* fp = fopen("resultr6.txt", "w");
    146     if (fp == NULL)
    147         printf("error
    ");
    148     Sleep(2000);    //挂起两秒钟
    149     srand((unsigned)time(NULL));    //随机种子
    150     Initialize();   //对初始个体进行初始化操作
    151     for (t=0; t<1000; t++)  //种群在该机制下演化一千个时间步
    152     {
    153         Aging();    //执行年龄增长机制
    154         Die();  //执行死亡机制
    155         RePreduction(); //执行繁殖机制
    156         printf("A");
    157         fprintf(fp, "%d	", Nt);
    158     }
    159     fclose(fp);
    160     return 0;
    161 }
    View Code

      附图

  • 相关阅读:
    拓扑排序问题
    向陈越姥姥哭诉----关键活动
    最小生成树之Prim算法和Kruskal算法
    1212. Team Scores in Football Tournament
    1205. 每月交易II
    1098. 小众书籍
    1204. Last Person to Fit in the Elevator
    579. 查询员工的累计薪水
    1127. User Purchase Platform
    1225. 报告系统状态的连续日期
  • 原文地址:https://www.cnblogs.com/zhaoyu1995/p/5557840.html
Copyright © 2011-2022 走看看