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; //每个染色体的轮盘概率 }; #endif2. 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。