lalapanda 2018-03-01 14:27 采纳率: 0%
浏览 1020
已结题

关于遗传算法的代码的内存溢出问题

关于遗传算法的函数优化应用方面问题,出现了内存溢出,没找到哪里错误
参考的代码地址为http://blog.csdn.net/ebowtang/article/details/50938396
很多人应该是看这个代码入门遗传算法的
自己的运行代码如下
头文件

 #include<vector>
#include "math.h"
#include "string.h"//不知道为什么要加这个,明明模板没加也没错,这边不加就会报错unexpected token(s) preceding ';'
using namespace std;

const double pi=3.1415926;
class Genome
{
  public:
      friend class GenAlg; //种群全部基因
      friend class GenEngine;
      Genome()  /*没加这个花括号的话会有
                function operation.obj : error LNK2001: 
                unresolved external symbol "public: __thiscall Genome::Genome(void)" (??0Genome@@QAE@XZ)提示*/

      {
      }
      Genome(vector<double> vec , double f)
     {
          vecGenome=vec;
          fitness=f;
      }
     ~Genome()
     {}

  private:
      vector<double> vecGenome; //在求函数最优单解时,定义基因组至于要double 就行了,用vector是为了扩展以后会碰到的情况
      double fitness;
};

class GenAlg
{
   public:
       vector<Genome> vecPop;       //整个种群的基因组
       int popsize; //种群的个数
       int Genomelength;//一个基因组中基因的总数目,每条染色体上基因的总数目

       double totalfitness;
       double bestfitness;
       double averagefitness;
       double worstfitness;
       Genome bestone;

       double maxperturtation;//最大的变异步长
       double leftpoint,rightpoint;//左右值域
       double mutationrate;//这个为基因突变的概率
       double crossoverRate;//基因交叉的概率
       GenAlg();//不明白为什么要设置这个初始化函数
       void Reset();//暂时也不知道拿来干嘛用
       void init(int popSize,double MutRate,double CrossRate,int GenLenght,
           double LeftPoint,double RightPoint);
       void report(int numgen);
       void Calculatebestworstavetol();
       Genome GetGenomeRoulette();//轮盘赌算法
       void Mutate(vector<double> &chrome);//基因突变函数
       void Epoch(vector<Genome> &vecNewPop);
       ~GenAlg()
       {}

};

class Curve    
{
public:
    double function(vector<double> input)//这里不用引用与常量符号应该也没事吧
    {
        double x=input[0];
        double output=0;
        output=x*sin(10*pi*x)+2.0;
        return output;
    }
    ~Curve()
    {}
private:
};

class GenEngine
{
public:
    GenEngine(int popSize,double MutRate,double CrossRate,int GenLenght,int Generation,
           double LeftPoint,double RightPoint);//这里的形参与GenAlg.init里的一样,尝试
    void OnStartGenAlg();
    ~GenEngine()
    {}
private:
    GenAlg genAlg;
    //这里特意不包含Curve的变量以测试在不包含相应类的变量情况下是否能使用类的函数,看来似乎不行
    Curve curve;

    vector<Genome> g_population;  //新的种群基因库
    int g_popSize;
    double g_MutRate;
    double g_CrossRate;
    int g_GenLenght;
    int g_Generation;
    int numgeneration;//迭代的计数器
    double g_LeftPoint;
    double g_RightPoint;
};


操作文件

 #include<vector>

#include<stdio.h>
#include <stdlib.h>
#include <time.h>
#include<iostream>
#include"class.h"

using namespace std;

double random()
{
    double randNum;
    randNum=rand()*1.0/RAND_MAX;
    return randNum;
}

void GenAlg::init(int popSize,double MutRate,double CrossRate,int GenLenght,
           double LeftPoint,double RightPoint)
{

        popsize=popSize;
        Genomelength=GenLenght;

       totalfitness=0;
       bestfitness=0;
       averagefitness=0;
       worstfitness=999;


       maxperturtation=0.004;
       leftpoint=LeftPoint;
       rightpoint=RightPoint;
       mutationrate=MutRate;//这个为基因突变的概率
       crossoverRate=CrossRate;
       vecPop.clear();
       //这里要加上初始化种群基因库的部分
       for(int i=0;i<popsize;i++)
       {
           vecPop.push_back(Genome());//不能用 vecPop[i].push_back(Genome());
           for(int j=0;j<Genomelength;j++)
           {
               vecPop[i].vecGenome[j]=random()*(rightpoint-leftpoint)+leftpoint;
           }
       }



}

GenAlg::GenAlg()
{
}


void GenAlg::Reset()
{
    totalfitness=0;
    averagefitness=0;
}

void GenAlg::report(int numgen)
{
    cout<<"第"<<numgen<<"代"<<endl;
    cout<<"最佳适应度为:"<<bestone.fitness<<endl;//bestone由CalculateBestWorstAveTol()计算出
    cout<<"最佳适应度基因为:"<<bestone.vecGenome[0]<<endl;
    cout<<"平均适应度为:"<<averagefitness<<endl;
}

void GenAlg::Calculatebestworstavetol()
{ 
    for(int i=0;i<popsize;i++)
    {
        totalfitness+=vecPop[i].fitness;
        if(vecPop[i].fitness>=bestfitness)
            {
                bestfitness=vecPop[i].fitness;
                bestone.vecGenome=vecPop[i].vecGenome;
                bestone.fitness=bestfitness;
            }
        if(vecPop[i].fitness<=worstfitness)
                worstfitness=vecPop[i].fitness;

    }
    averagefitness=totalfitness/popsize;
}

void GenAlg::Mutate(vector<double> &chrome)
 {

     for(int i=0;i<Genomelength;i++)    //单个人的基因突变
     {
         if(random()<mutationrate)
         {
             chrome[i]+=(random()-0.5)*maxperturtation;
         }
         if(chrome[i]>rightpoint)chrome[i]=leftpoint;
         if(chrome[i]<leftpoint)chrome[i]=rightpoint;
     }
 }


Genome GenAlg::GetGenomeRoulette()
 {
     Genome vecnewGenome;
     double slice=random()*totalfitness;
     double fitnesssofar=0;
     for(int i=0;i<popsize;i++)
     {
         if(fitnesssofar>=slice)
         {
             vecnewGenome=vecPop[i];//不是vecnewGenome=vecPop[i].vecGenome;
             break;
         }
         else fitnesssofar=fitnesssofar+vecPop[i].fitness;
     }
     return vecnewGenome;
 }

 GenEngine::GenEngine(int popSize,double MutRate,double CrossRate,int GenLenght,int Generation,
           double LeftPoint,double RightPoint)
{
     //genAlg();不要用genAlg(),curve(),m_population(),不知道模板那边为什么可以用,这三个是成员而不是函数,不能用函数调用方式


     g_population.clear();  //新的种群基因库,vector(Genome)类
    g_popSize=popSize;
    g_MutRate=MutRate;
    g_CrossRate=CrossRate;
    g_GenLenght=GenLenght;//Genome中基因的个数
    g_Generation=Generation;//迭代的总次数
    //应该不需要了numgeneration=0;迭代的计数器,直接在OnStartGenAlg中用临时变量实现
    g_LeftPoint=LeftPoint;
    g_RightPoint=RightPoint;
}

void GenAlg::Epoch(vector<Genome> &vecNewPop) //vecNewPop引用在g_population上
{
     vecPop=vecNewPop;//    不是g_population=vecNewPop;/
    Reset();//为了避免totalfitness被叠加,但是感觉也可以在OnStartGenAlg中用genAlg.Reset实现
    //源代码CalculateBestWorstAvTol()被加在这处,感觉也可以在OnStartGenAlg中用genAlg.CalculateBestWorstAvTol()实现
    vecNewPop.clear();
    for(int i=0;i<popsize;i++)
    {
       //   Genome mum=GetGenomeRoulette();因为不存在交叉,所以不设父母双方,并且要是同时生成两个子代要是
        Genome dad=GetGenomeRoulette();
        vector<double> baby1=dad.vecGenome;
        //Genome baby2=dad;
        Mutate(baby1);
        vecNewPop.push_back(Genome(baby1,0));//不能这样写vecNewPop.push_back(baby1,0);
    }
}

void GenEngine::OnStartGenAlg()
{
    srand( (unsigned)time( NULL ) );
    genAlg.init(g_popSize,g_MutRate,g_CrossRate,g_GenLenght,g_LeftPoint,g_RightPoint);//用GenEngine中的元素是因为genAlg是GenEngine
    //的元素,这样初始化GenEngine后,数值就可以流向genAlg
    //这里不用g_population.clear是因为在GenEngine.init时就把其清空了
    g_population.clear();//加clear函数是为了
    g_population=genAlg.vecPop;
    vector<double> input;
    double output;
    for(int Generation=0;Generation<g_Generation;Generation++)
    {
      for(int i=0;i<g_popSize;i++)
        {
            input=g_population[i].vecGenome;
            output=(double)curve.function(input);//这里不能用output=(double)Curve.function(input)
            g_population[i].fitness=output;
        }
      genAlg.Epoch(g_population);
      genAlg.Calculatebestworstavetol();
      genAlg.report(Generation+1);
    }
}

主函数

 #include<iostream>
#include"class.h"

using namespace std;
void main()
{

    GenEngine genEngine(50,0.8,0.8,1,100,-1,2);
    genEngine.OnStartGenAlg();

}

不知道为什么运行出来会有
Damage:after Normal block(#58) at 0x00832B08的提示

0x00832B08是代表行数吗

  • 写回答

1条回答 默认 最新

  • threenewbee 2018-03-01 15:03
    关注

    调试下,看报错的是哪一行。你这么贴出一大段,谁愿意帮你看。

    评论

报告相同问题?

悬赏问题

  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题
  • ¥15 multisim电路设计
  • ¥20 用keil,写代码解决两个问题,用库函数
  • ¥50 ID中开关量采样信号通道、以及程序流程的设计
  • ¥15 U-Mamba/nnunetv2固定随机数种子
  • ¥15 vba使用jmail发送邮件正文里面怎么加图片
  • ¥15 vb6.0如何向数据库中添加自动生成的字段数据。