AES完工后,写SGA简单多了,加上算法本身又不难。主要是尝试用C++写一下,但感觉就是纯粹的C。要用到面向对象的,估计要将那四个算法给联合起来,才能体现出来吧~。

1。 SimpleGA.h

#ifndef paramOnce
#define paramOnce

class SimpleGA;

//轮转盘
typedef struct{
    double  m_dProperty;
    int     m_nPosition;
}Wheel;

//全局变量
class GlobalVariable
{
    private:
        GlobalVariable();
        int    m_nPopsize;         //种群规模
        int    m_nEliteLength;     //染色体长度
        int    m_nEliteByteLength; //染色体unsigned个数
        double m_dMutatioin;       //变异率
        double m_dCross;           //交叉率
    public:
        friend class SimpleGA;

};

//染色体
template <class T>
class Elite{
  public:
   Elite(): pElite(NULL),m_tEnergy(0){}
   ~Elite(){if(pElite != NULL) delete pElite;} //!.注意这里可能是delete[] pElite;
   //Getter and Setter
   unsigned* getPElite();
   void setPElite(int nEliteByteLength);
   T    getEnergy();
   void setEnergy(T tEnergy);

  private:
   unsigned *pElite;     //0-1 编码
   T         m_tEnergy; //能量
};

//处理类
class SimpleGA
{
    public:
        SimpleGA() {
           pOldPop = NULL;
           pNewPop = NULL;
           pModelElite = NULL;
           pWheel      = NULL;
        }
        ~SimpleGA(){
           if(pOldPop != NULL)
             delete[] pOldPop;
           if(pNewPop != NULL)
             delete[] pNewPop;
           if(pModelElite != NULL)
             delete[]   pModelElite;
           if(pWheel != NULL)
             delete[]   pWheel;
        }
        void goGoGo();

    private:
        //初始化种群空间,和每个染色体空间------
        void   initPopSpace();
        //初始化每个染色体的编码-----------
        //初始化每个染色体的编码-----------
        void   initEliteEncode();
        //实现编码
        void   completeEncode(unsigned *pElite);
        //以一定的概率产生0和1--------
        int    flip(double probability);
        //随机产生一个0到1之间的概率
        double produceRandom();
        //适值函数-----------------
        void   fitness();
        //计算能量值
        void   computeEnergy(Elite<int> *pElite);
        //计算一个unsigned中1的个数
        int    countOne(unsigned temp, int n);

        //开始进行下一代--------------
        //选择操作--×××轮转
        void   selectPop();
        //计算总的能量
        int    theWholeEnergy();
        //计算每个染色体的概率值
        void   theWheelProperty();
        //完成染色体的复制
        void   copyElite(Elite<int> *pNewElite, Elite<int> *pOldElite);

        //开始交换------------------
        void   crossPop();
        void   crossElite(unsigned* pElite1, unsigned* pElite2);
        void   crossEliteLastBit(unsigned& pElite, unsigned temp, int stop);

        //开始变异------------------
        void   mutationPop();

        //the last------------------
        void   lastStep();


        //!TestFunction
        void   outputElite(unsigned* pElite);
        void   outputEnergy(unsigned* pElite);


    private:
        Elite<int>     *pOldPop;
        Elite<int>     *pNewPop;
        unsigned       *pModelElite;
        GlobalVariable globalVariable;
        Wheel          *pWheel;         //每个染色体的×××概率

};
#endif

2. SimpleGA.cpp-----------------------------------------------------------------------------------

#include <iostream>
#include "SimpleGA.h"
#include <stdlib.h>
#include <algorithm>
#include <cstdio>

//#define _OutPut_
//#define _OutPut2_
//#define _OutPut3_
//#define _OutPut4_
#define _OutPut5_
//StaticVariable Function implements
GlobalVariable::GlobalVariable()
{
    m_nPopsize         = 100;
    m_nEliteLength     = 100;
    m_nEliteByteLength = m_nEliteLength / (8*sizeof(unsigned));
    if(m_nEliteLength%(8*sizeof(unsigned)))
       ++m_nEliteByteLength;
    m_dMutatioin       = 0.5;
    m_dCross           = 0.5;
}


//Elite Function implements
template <class T>
unsigned* Elite<T>::getPElite()
{
    if(pElite!=NULL)
      return pElite;
    else
      return NULL;
}

template<class T>
void Elite<T>::setPElite(int nEliteByteLength)
{
    if(pElite == NULL)
      pElite = new unsigned[nEliteByteLength];
}

template<class T>
T  Elite<T>::getEnergy()
{
   return m_tEnergy;
}

template<class T>
void Elite<T>::setEnergy(T tEnergy)
{
    //this->m_tEnergy = tEnergy;
    m_tEnergy = tEnergy;
}

//SimpleSGA Function implements
void SimpleGA::goGoGo()
{
    initPopSpace();
    initEliteEncode();

    for(int i=0; i<100; i++){
        fitness();
        //产生下一代
        selectPop();
        crossPop();
        mutationPop();
        #ifdef _OutPut5_
        for(int i=0; i<globalVariable.m_nPopsize; i++){
            if(pOldPop[i].getEnergy() >= 70){
               std::cout<<"模板:\n";
               outputElite(pModelElite);
               std::cout<<"最佳智能体:\n";
               outputElite(pOldPop[i].getPElite());
            }
        }
        #endif
        lastStep();
    }
    //outputElite(pOldPop[99].getPElite());
    //outputElite(pModelElite);
}



void SimpleGA::initPopSpace()
{
    pOldPop = new Elite<int>[globalVariable.m_nPopsize];
    pNewPop = new Elite<int>[globalVariable.m_nPopsize];

    //!初始化每个染色体
    //1. 染色体占的空间大小
    for(int i=0; i<globalVariable.m_nPopsize; i++){
       (pOldPop+i)->setPElite(globalVariable.m_nEliteByteLength);
       (pNewPop+i)->setPElite(globalVariable.m_nEliteByteLength);
    }
    //!初始化模板
    pModelElite = new unsigned[globalVariable.m_nEliteByteLength];
    pWheel      = new Wheel[globalVariable.m_nPopsize];
}

void SimpleGA::initEliteEncode()
{
    for(int i=0; i<globalVariable.m_nPopsize; i++){
       //pOldPop -- 此处就不做NULL判断检查了,不要太麻烦了~。
       completeEncode( (pOldPop+i)->getPElite() );
    }
    completeEncode(pModelElite);
}

void   SimpleGA::completeEncode(unsigned *pElite)
{
       unsigned mask = 1;
       int stop = 8*sizeof(unsigned);
       for(int k=0; k<globalVariable.m_nEliteByteLength; k++){
          //是最后一个unsigned
          if(k == globalVariable.m_nEliteByteLength-1){
              stop = globalVariable.m_nEliteLength - (k * stop);
          }
          pElite[k] = 0;
          for(int h=0; h<stop; h++){
             pElite[k] <<= 1;
             if( flip(0.5) == 1 ){
                pElite[k] |= mask;
             }
          }
       }
}

int SimpleGA::flip(double probability)
{
    if( produceRandom() <= probability)
        return 1;
    else
        return 0;
}

double SimpleGA::produceRandom()
{
    return ( rand()%1000 ) / 1000.0 ;
}

void  SimpleGA::fitness()
{
      for(int i=0; i<globalVariable.m_nPopsize; i++){
         computeEnergy( (pOldPop+i) );
         #ifdef _OutPut_
         std::cout<<(pOldPop+i)->getEnergy()<<std::endl;
         #endif
      }
}

void SimpleGA::computeEnergy(Elite<int> *pElite)
{
    //异或,相同为0, 不同为1
    int stop;
    int n = 8*sizeof(unsigned);
    int nEnergy = 0;
    unsigned *pTempElite = pElite->getPElite();
    for(int k=0; k<globalVariable.m_nEliteByteLength; k++)
    {
        if( k != (globalVariable.m_nEliteByteLength-1))
        {
            nEnergy += countOne((pTempElite[k] ^ pModelElite[k]), n);
        }
        else
        {
            //最后一个字节,计算右移多少位
            stop =globalVariable.m_nEliteLength - k*n;
            nEnergy += countOne((pTempElite[k] ^ pModelElite[k]), stop);
        }
    }
    pElite->setEnergy(nEnergy);
}

int SimpleGA::countOne(unsigned temp, int n)
{
    int count = 0;
    for(int i=0; i<n; i++)
    {
        if( (temp & 1) ==0)
        {
            //相同
            count++;
        }
        temp>>=1;
    }
    return count;
}

//!开始产生下一代
void SimpleGA::selectPop()
{
    //策略探讨
    //×××的话,用累积的话,最好就是要排序了。而且还有个累计查找过程。
    //用堆,加上二分树实现快--Wrong
    //用哈夫曼树
    theWheelProperty();
    //计算累积概率值
    double  dAccumulative[globalVariable.m_nPopsize];
    dAccumulative[0] = pWheel->m_dProperty;
    for(int i=1; i<globalVariable.m_nPopsize; i++){
        dAccumulative[i] = dAccumulative[i-1] + (pWheel+i)->m_dProperty;
    }
    #ifdef _OutPut_
    std::cout<<"\n累积概率值:\n";
    for(int i=0; i<globalVariable.m_nPopsize; i++){
       std::cout<<dAccumulative[i]<<" ";
    }
    std::cout<<std::endl;
    #endif
    double dRand = produceRandom();
    #ifdef _OutPut_
    std::cout<<"\n随机产生一个0-1的×××概率\n";
    std::cout<<std::endl<<dRand<<std::endl;
    #endif
    //开始选择下一代
    int nPosition;
    for(int i=0; i<globalVariable.m_nPopsize; i++){
        if(dRand < dAccumulative[i]){
             nPosition = (pWheel+i)->m_nPosition;
             //产生下一代的一个个体
             copyElite((pNewPop+i), (pOldPop+i));
             #ifdef _OutPut2_
             std::cout<<"\n输出新的染色体\n";
             outputElite((pNewPop+i)->getPElite());
             std::cout<<std::endl;
             #endif
        }
    }
}

int SimpleGA::theWholeEnergy()
{
    int n = 0;
    for(int i=0; i<globalVariable.m_nPopsize; i++){
        n += (pOldPop+i)->getEnergy();
    }
    return n;
}

int  CompareFunction(const void *p1, const void *p2)
{
     return (((Wheel *)p1)->m_dProperty > ((Wheel *)p2)->m_dProperty) ? 1 : -1;
}

void SimpleGA::theWheelProperty()
{
    int wholeEnergy = theWholeEnergy();
    for(int i=0; i<globalVariable.m_nPopsize; i++){
        //printf("%lf ",((pOldPop+i)->getEnergy() / wholeEnergy));
        //对于求double的运算,一定要注意类型转化问题。
       (pWheel+i)->m_dProperty = (double) (pOldPop+i)->getEnergy() / wholeEnergy;
       (pWheel+i)->m_nPosition = i;
    }
    qsort(pWheel, globalVariable.m_nPopsize, sizeof(pWheel[0]), CompareFunction);

    #ifdef _OutPut_
    std::cout<<"\n每个染色体的概率值:\n";
    for(int i=0; i<globalVariable.m_nPopsize; i++){
      std::cout<<(pWheel+i)->m_dProperty<<" ";
      std::cout<<(pWheel+i)->m_nPosition<<" ";
    }
    std::cout<<std::endl;
    #endif
}

void SimpleGA::copyElite(Elite<int> *pNewElite, Elite<int> *pOldElite)
{
     for(int k=0; k<globalVariable.m_nEliteByteLength; k++){
         pNewElite->getPElite()[k] = pOldElite->getPElite()[k];
     }
     //这一步是用来计算新一代能量值可以省点
     //pNewElite->setEnergy(pOldElite->getEnergy());
}


//! 开始交换--是对选择后产生的新群体进行交叉和变异~
void SimpleGA::crossPop()
{
     //计算要交换的染色体对数
     int nCouple = globalVariable.m_dCross * globalVariable.m_nPopsize;
     int rand_1;
     int rand_2;
     for(int i=0; i<nCouple; i++){
         rand_1 = rand() % globalVariable.m_nPopsize;
         rand_2 = rand() % globalVariable.m_nPopsize;
         if(rand_1 != rand_2){
            //交换概率
            if( flip(0.5) ){
               crossElite((pNewPop+rand_1)->getPElite(), (pNewPop+rand_2)->getPElite());
            }
         }
     }
}

void SimpleGA::crossElite(unsigned* pElite1, unsigned* pElite2)
{
    #ifdef _OutPut3_
    std::cout<<"第一个:\n";
    outputElite(pElite1);
    std::cout<<"第二个:\n";
    outputElite(pElite2);
    #endif
    //交叉位置: 随机选取
    // 每位交叉概率
    int position;
    //buddy,随机选取位置
    position = rand() % globalVariable.m_nEliteLength;
    //1. 计算字节
    int nByte = position / (8*sizeof(unsigned));
    if( position % (8*sizeof(unsigned))){
        nByte++;
    }
    //2. 开始交叉吧
    int stop;
    unsigned tempElite;
    for(int k=0; k<nByte; k++){
        if(k != (nByte-1)){
        //不是最后一个字节,要最大智能体的部分
           tempElite  = pElite1[k];
           pElite1[k] = pElite2[k];
           pElite2[k] = tempElite;
        }else{
           tempElite = pElite1[k];
           stop = position - k*8*sizeof(unsigned);
           crossEliteLastBit(pElite1[k], pElite2[k], stop);
           crossEliteLastBit(pElite2[k], tempElite,  stop);
        }
    }
    #ifdef _OutPut3_
    std::cout<<"交换后第一个:\n";
    outputElite(pElite1);
    std::cout<<"交换后第二个:\n";
    outputElite(pElite2);
    #endif
}

void  SimpleGA::crossEliteLastBit(unsigned& pElite , unsigned temp, int stop)
{
        unsigned mask = 1;
        for(int h=0; h<stop; h++){
        //判断相应的那位是0还是1
        if( (pElite & mask)!=0)
            //是1 , 所以逻辑是反的
            pElite = pElite ^ ( ((temp& mask)!=0) ? 0 : 1);
        else
            //是0,
            pElite = pElite ^ ( ((temp& mask)!=0) ? 1 : 0);
        mask <<= 1;
        }
}

//! 开始变异----------------是对选择后的染色体进行变异
void SimpleGA::mutationPop()
{
    //突变位数
    int mutationNum = globalVariable.m_dMutatioin * globalVariable.m_nPopsize * globalVariable.m_nEliteLength;
    //选串 和 选 位
    int randElite, randPosition, nBytePosition, nPosition;
    unsigned mask;
    unsigned *pElite;
    for(int i=0; i<mutationNum; i++){
         randElite    = rand()%globalVariable.m_nPopsize;     //选染色体
         randPosition = rand()%globalVariable.m_nEliteLength; //选突变位
        //计算所在的字节
        nBytePosition = randPosition / (8 * sizeof(unsigned));
        if( randPosition % (8*sizeof(unsigned)))
            ++nBytePosition;
        //从0开始
        --nBytePosition;
        //计算所在的位
        nPosition = randPosition - nBytePosition * (8*sizeof(unsigned));
        mask = 1;
        mask <<= nPosition;
        pElite = (pNewPop+randElite)->getPElite();
        #ifdef _OutPut4_
        std::cout<<"变异前:\n";
        outputElite(pElite);
        std::cout<<randPosition<<std::endl;
        #endif
        //燃烧吧,变异吧
        pElite[nBytePosition] ^= mask;
        #ifdef _OutPut4_
        std::cout<<"变异后:\n";
        outputElite(pElite);
        #endif
    }
}

void SimpleGA::lastStep()
{
     Elite<int> *pTempElite;
     pTempElite = pOldPop;
     pOldPop    = pNewPop;
     pNewPop    = pTempElite;
}


//! testFunction
void SimpleGA::outputElite(unsigned* pElite)
{


    int      stop = 8*sizeof(unsigned);;
    unsigned mask = 1;
    unsigned tmp;
    for(int k=0; k<globalVariable.m_nEliteByteLength; k++)
    {
        tmp = pElite[k];
        if(k == (globalVariable.m_nEliteByteLength-1))
            stop = globalVariable.m_nEliteLength - k*stop;
        for(int i=0; i<stop; i++)
        {
            if(tmp&mask)
                std::cout<<"1";
            else
                std::cout<<"0";
            tmp >>= 1;
        }
    }
    std::cout<<std::endl;
}

------------------------------------------------------------------------------------------------------

收敛程度不是很好, 最大适应值不超过80,勉强挺进70。