C++遗传算法类文件实例分析_C 语言

本文所述为C++实现的遗传算法的类文件实例。一般来说遗传算法可以解决许多问题,希望本文所述的C++遗传算法类文件,可帮助你解决更多问题,并且代码中为了便于读者更好的理解,而加入了丰富的注释内容,是新手学习遗传算法不可多得的参考代码。

具体代码如下所示:

#include "stdafx.h"
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>//把日期和时间转换为字符串
using namespace std;
//Parametes setting
#define POPSIZE 200   //population size
#define MAXGENS 1000  //max number of generation
#define NVARS 2     //no of problem variables
#define PXOVER  0.75 //probalility of crossover
#define PMUTATION 0.15 //probalility of mutation
#define TRUE 1
#define FALSE 0
#define LBOUND 0
#define UBOUND 12
#define STOP 0.001
int generation;     //current generation no
int cur_best;      //best individual
double diff;
FILE *galog;      //an output file
struct genotype
{
   double gene[NVARS];   //a string of variables基因变量
   double upper[NVARS];  //individual's variables upper bound 基因变量取值上确界
   double lower[NVARS];  //individual's batiables lower bound 基因变量取值下确界
   double fitness;     //individual's fitness个体适应值
   double rfitness;    //relative fitness个体适应值占种群适应值比例
   double cfitness;    //curmulation fitness个体适应值的累加比例
 };
struct genotype population[POPSIZE+1];
//population 当前种群 population[POPSIZE]用于存放个体最优值并假设最优个体能存活下去
//在某些遗传算法中最优值个体并不一定能够存活下去
struct genotype newpopulation[POPSIZE+1]; //new population replaces the old generation 子种群
 /*Declaration of procedures used by the gentic algorithm*/
 void initialize(void);          //初始化函数
 double randval(double,double);      //随机函数
 double funtion(double x1,double x2);  //目标函数
 void evaluate(void);          //评价函数
 void keep_the_best(void);        //保留最优个体
 void elitist(void);            //当前种群与子代种群最优值比较
 void select(void);
 void crossover(void);          //基因重组函数
 void swap(double *,double *);      //交换函数
 void mutate(void);            //基因突变函数
 double report(void);          //数据记录函数
void initialize(void)
 {
  int i,j;
   for(i=0;i<NVARS;i++)
   {
    for(j=0;j<POPSIZE+1;j++)
    {
       if(!i)
       {
        population[j].fitness=0;
        population[j].rfitness=0;
        population[j].cfitness=0;
       }
      population[j].lower[i]=LBOUND;
      population[j].upper[i]=UBOUND;
      population[j].gene[i]=randval(population[j].lower[i],population[j].upper[i]);
     }
   }
 }
//***************************************************************************
//Random value generator:generates a value within bounds
//***************************************************************************
 double randval(double low,double high)
 {
   double val;
   val=((double)(rand()%10000)/10000)*(high-low)+low;
  return val;
 }
//目标函数
 double funtion(double x,double y)
{
  double result1=sqrt(x*x+y*y)+sqrt((x-12)*(x-12)+y*y)+sqrt((x-8)*(x-8)+(y-6)*(y-6));
  return result1;
}
 //***************************************************************************
 //Evaluation function:evaluate the individual's fitness.评价函数给出个体适应值
//Each time the function is changes,the code has to be recompl
 //***************************************************************************
 void evaluate(void)
 {
  int mem;
  int i;
  double x[NVARS];
  for(mem=0;mem<POPSIZE;mem++)
   {

    for(i=0;i<NVARS;i++)
    x[i]=population[mem].gene[i];
    population[mem].fitness=funtion(x[0],x[1]);//将目标函数值作为适应值
  }
 }
 //***************************************************************************************
 //Keep_the_best function:This function keeps track of the best member of the population.
//找出种群中的个体最优值并将其移动到最后
//***************************************************************************************
 void keep_the_best()
 {
   int mem;
   int i;
   cur_best=0;
   for(mem=0;mem<POPSIZE;mem++)//找出最高适应值个体
  {
     if(population[mem].fitness<population[cur_best].fitness)
     {
       cur_best=mem;
    }
  }
  //将最优个体复制至population[POSIZE]
   if(population[cur_best].fitness<=population[POPSIZE].fitness||population[POPSIZE].fitness<1)//防止出现种群基因退化 故保留历史最优个体
  {
    population[POPSIZE].fitness=population[cur_best].fitness;
    for(i=0;i<NVARS;i++)
    population[POPSIZE].gene[i]=population[cur_best].gene[i];
  }
}
 //***************************************************************************
 //last in the array.If the best individual from the new populatin is better
//than the best individual from the previous population ,then copy the best
 //from the new population;else replace the worst individual from the current
 //population with the best one from the previous generation.防止种群最优值退化
//***************************************************************************
 void elitist()
{
   int i;
  double best,worst;//适应值
  int best_mem,worst_mem;//序号
  best_mem=worst_mem=0;
  best=population[best_mem].fitness;//最高适应值初始化
  worst=population[worst_mem].fitness;//最低适应值初始化
  for(i=1;i<POPSIZE;i++)//找出最高和最低适应值 算法有待改进
   {
     if(population[i].fitness<best)
     {
       best=population[i].fitness;
      best_mem=i;
     }
    if(population[i].fitness>worst)
     {
       worst=population[i].fitness;
      worst_mem=i;
    }
   }
  if(best<=population[POPSIZE].fitness)//赋值
   {
    for(i=0;i<NVARS;i++)
       population[POPSIZE].gene[i]=population[best_mem].gene[i];
    population[POPSIZE].fitness=population[best_mem].fitness;
   }
   else
  {
     for(i=0;i<NVARS;i++)
       population[worst_mem].gene[i]=population[POPSIZE].gene[i];
     population[worst_mem].fitness=population[POPSIZE].fitness;
   }
}
 //***************************************************************************
 //Select function:Standard proportional selection for maximization problems
//incorporating elitist model--makes sure that the best member survives.筛选函数并产生子代
//***************************************************************************
 void select(void)
 {
   int mem,i,j;
   double sum=0;
   double p;
   for(mem=0;mem<POPSIZE;mem++)//所有适应值求和
  {
     sum+=population[mem].fitness;
   }
   for(mem=0;mem<POPSIZE;mem++)
   {
    population[mem].rfitness=population[mem].fitness/sum;//个人认为还不如建一个种群类 把sum看成类成员
  }
  population[0].cfitness=population[0].rfitness;
  for(mem=1;mem<POPSIZE;mem++)
  {
    population[mem].cfitness=population[mem-1].cfitness+population[mem].rfitness;
  }
   for(i=0;i<POPSIZE;i++)
  {
     p=rand()%1000/1000.0;
     if(p<population[0].cfitness)
    {
       newpopulation[i]=population[0];
     }
     else
    {
      for(j=0;j<POPSIZE;j++)
         if(p>=population[j].cfitness&&p<population[j+1].cfitness)
           newpopulation[i]=population[j+1];
     }
   }
   for(i=0;i<POPSIZE;i++)//子代变父代
     population[i]=newpopulation[i];
}
//***************************************************************************
 //Crossover:performs crossover of the selected parents.
 //***************************************************************************
void Xover(int one,int two)//基因重组函数
{
   int i;
  int point;
  if(NVARS>1)
  {
     if(NVARS==2)
      point=1;
    else
      point=(rand()%(NVARS-1))+1;//两个都重组吗?
    for(i=0;i<point;i++)//只有第一个基因发生重组有待改进
      swap(&population[one].gene[i],&population[two].gene[i]);
   }
 }
//***************************************************************************
//Swapp: a swap procedure the helps in swappling 2 variables
//***************************************************************************
 void swap(double *x,double *y)
 {
  double temp;
  temp=*x;
  *x=*y;
  *y=temp;
}
 //***************************************************************************
 //Crossover function:select two parents that take part in the crossover.
 //Implements a single point corssover.杂交函数
 //***************************************************************************
void crossover(void)
 {
   int mem,one;
   int first=0;
   double x;
  for(mem=0;mem<POPSIZE;++mem)
  {
    x=rand()%1000/1000.0;
    if(x<PXOVER)
     {
       ++first;
      if(first%2==0)//选择杂交的个体对 杂交有待改进 事实上往往是强者与强者杂交 这里没有考虑雌雄与杂交对象的选择
        Xover(one,mem);
      else
         one=mem;
 }
  }
 }
//***************************************************************************
 //Mutation function:Random uniform mutation.a variable selected for mutation
 //变异函数 事实基因的变异往往具有某种局部性
 //is replaced by a random value between lower and upper bounds of the variables.
 //***************************************************************************
 void mutate(void)
 {
   int i,j;
   double lbound,hbound;
   double x;
   for(i=0;i<POPSIZE;i++)
     for(j=0;j<NVARS;j++)
     {
       x=rand()%1000/1000.0;
       if(x<PMUTATION)
      {
         lbound=population[i].lower[j];
         hbound=population[i].upper[j];
         population[i].gene[j]=randval(lbound,hbound);
       }
     }
 }
//***************************************************************************
 //Report function:Reports progress of the simulation.
 //***************************************************************************
 double report(void)
 {
  int i;
  double best_val;//种群内最优适应值
  double avg;//平均个体适应值
   //double stddev;
  double sum_square;//种群内个体适应值平方和
  //double square_sum;
  double sum;//种群适应值
  sum=0.0;
  sum_square=0.0;
  for(i=0;i<POPSIZE;i++)
   {
     sum+=population[i].fitness;
     sum_square+=population[i].fitness*population[i].fitness;
   }
  avg=sum/(double)POPSIZE;
   //square_sum=avg*avg*(double)POPSIZE;
   //stddev=sqrt((sum_square-square_sum)/(POPSIZE-1));
  best_val=population[POPSIZE].fitness;
  fprintf(galog,"%6d %6.3f %6.3f %6.3f %6.3f %6.3f\n",generation,best_val,population[POPSIZE].gene[0],population[POPSIZE].gene[1],avg,sum);
  return avg;
 }
 //***************************************************************************
//main function:Each generation involves selecting the best members,performing
 //crossover & mutation and then evaluating the resulting population,until the
//terminating condition is satisfied.
 //***************************************************************************
 void main(void)
 {
   int i;
   double temp;
   double temp1;
   if((galog=fopen("data.txt","w"))==NULL)
  {
    exit(1);
   }
  generation=1;
  srand(time(NULL));//产生随机数
  fprintf(galog,"number value  x1   x2   avg   sum_value\n");
  printf("generation best average standard\n");
  initialize();
  evaluate();
  keep_the_best();
  temp=report();//记录,暂存上一代个体平均适应值
   do
   {
     select();//筛选
     crossover();//杂交
     mutate();//变异
     evaluate();//评价
     keep_the_best();//elitist();
     temp1=report();
     diff=fabs(temp-temp1);//求浮点数x的绝对值
     temp=temp1;
     generation++;
   }while(generation<MAXGENS&&diff>=STOP);
   //fprintf(galog,"\n\n Simulation completed\n");
   //fprintf(galog,"\n Best member:\n");
   printf("\nBest member:\ngeneration:%d\n",generation);
   for(i=0;i<NVARS;i++)
   {
     //fprintf(galog,"\n var(%d)=%3.3f",i,population[POPSIZE].gene[i]);
     printf("X%d=%3.3f\n",i,population[POPSIZE].gene[i]);
   }
   //fprintf(galog,"\n\n Best fitness=%3.3f",population[POPSIZE].fitness);
   fclose(galog);
   printf("\nBest fitness=%3.3f\n",population[POPSIZE].fitness);
 }

感兴趣的读者可以动手测试一下代码,希望对大家学习C++算法能有所帮助。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c++
遗传算法
遗传算法实例、matlab遗传算法实例、遗传算法应用实例、遗传算法应用生活实例、实数编码遗传算法实例,以便于您获取更多的相关知识。

时间: 2024-09-15 01:51:32

C++遗传算法类文件实例分析_C 语言的相关文章

C语言的递归思想实例分析_C 语言

本文实例分析C语言的递归思想,分享给大家供大家参考之用.具体方法如下: 通俗点来说,递归就是自己调用自己. 递归的难点一是理解递归的执行调用过程,二是设置一个合理的递归结束条件. 下面来看一段摘自书中的简单程序: #include <STDIO.H> long fact(int n); long rfact(int n); int main(void) { int num; printf("This program calculates factorials.\n"); p

C语言创建链表错误之通过指针参数申请动态内存实例分析_C 语言

本文实例讲述了C语言创建链表中经典错误的通过指针参数申请动态内存,分享给大家供大家参考之用.具体实例如下: #include <stdio.h> #include <stdlib.h>// 用malloc要包含这个头文件 typedef struct node { int data; struct node* next;// 这个地方注意结构体变量的定义规则 } Node; void createLinklist(Node* pHder, int length) { int i =

websocket++简单使用及实例分析_C 语言

前言 html5支持使用websocket协议与服务器保持一个长连接,方便双方互相传输数据,而且服务器也能主动发送信息给客户端,而在这之前使用HTTP是很难做到的.下面介绍使用C++实现的websocket++的简单使用.websocket++更详细介绍点此. websocket++需要boost的支持,所以工程中需要包含boost的头文件和库.boost在VS中的如何使用参考此文章. C++代码 #include "stdafx.h" #include <iostream>

C++线程同步实例分析_C 语言

本文实例分析了C++线程同步问题,分享给大家供大家参考.具体分析如下: 该实例设置全局变量g_bContinue,在主线程中设置全局变量g_bContinue,工作线程检测该全局变量,实现主线程控制工作线程的目的. 打印出的g_cnt1与g_cnt2的数值不同,是因为线程调试时时间片的切换. 具体代码如下: // countError.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> DWORD

C++回溯法实例分析_C 语言

本文实例讲述了C++的回溯法,分享给大家供大家参考之用.具体方法分析如下: 一般来说,回溯法是一种枚举状态空间中所有可能状态的系统方法,它是一个一般性的算法框架. 解向量a=(a1, a2, ..., an),其中每个元素ai取自一个有限序列集Si,这样的解向量可以表示一个排列,其中ai是排列中的第i个元素,也可以表示子集S,其中ai为真当且仅当全集中的第i个元素在S中:甚至可以表示游戏的行动序列或者图中的路径. 在回溯法的每一步,我们从一个给定的部分解a={a1, a2, ..., ak}开始

C++二进制翻转实例分析_C 语言

本文实例讲述了C++二进制翻转的方法,将常用的几种解决方法罗列出来供大家比较选择.具体如下: 首先来看看一个相对笨拙的算法: #include <iostream> using namespace std; void printBinary(unsigned char str, int size = 1) { int flag = 0x01; for (int i = 0; i < size; i++) { for (int i = 0; i < 8; i++) { if (str

C语言中自动隐式转换与类型强制转换实例分析_C 语言

本文通过一个C程序实例对C语言中自动隐式转换与类型强制转换的注意点进行深入分析,详情如下: 先看一个C程序: #include<stdlib.h> #include<stdio.h> #include<conio.h> double proc(int q){ int n; double sum,t;//本例的关键就在这几个变量的类型上 sum = 2.0; while(sum<=q){ t=sum; //sum = sum+(n+1)/n;//自动隐式转换 sum

C++编译器无法捕捉到的8种错误实例分析_C 语言

本文实例分析了C++编译器无法捕捉到的8种错误,分享给大家供大家参考之用.有助于深入理解C++运行原理,具体分析如下: 众所周知,C++是一种复杂的编程语言,其中充满了各种微妙的陷阱.在C++中几乎有数不清的方式能把事情搞砸.幸运的是,如今的编译器已经足够智能化了,能够检测出相当多的这类编程陷阱并通过编译错误或编译警告来通知程序员.最终,如果处理得当的话,任何编译器能检查到的错误都不会是什么大问题,因为它们在编译时会被捕捉到,并在程序真正运行前得到解决.最坏的情况下,一个编译器能够捕获到的错误只

C++虚函数表实例分析_C 语言

多态是C++面向对象程序设计的一个重要特性.以前看到虚函数觉得很神奇,为什么就能实现多态了呢.最初的时候曾设想,要实现运行时多态,应该让对象的某个部分始终指向一个固定的地址,子类继承的时候,就修改这个地址的内容.这样,父类和子类都是到同一个固定地址去读取内容,在运行时就能表现不同行为. 在看了<深度探索c++对象模型>之后,发现思路是类似的.在对象中,有一个指针指向一张虚函数表,里面按照次序存放了每一个虚函数,当子类继承的时候,即到虚函数表的指定位置去修改函数地址.当我们通过父类指针来操作一个