听闻遗传算法NB,我就小试了一下,一开始没有设置遗传概率,让每一次迭代都发生变异,效果很不好。后来设置了有概率的变异,发现妙呀。直接上代码啦。
头文件:
InheritanceAlgorithm.h
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cmath>
using namespace std;
//#define f(x) - (x * x) + 16 * x + 16 // Aim Function
#define f(x) - (x * x) + 6 * x - 1
#define SOLUTION_RANGE 31
#define POPULATION_SIZE 8 // The Size of Population
#define ITERATION_NUM 1000 // iteration 1000 times
#define PROBABILITY_VARIATION 0.1 // The probability of variation
int SOLUTION_RANGE_BINARY_DIGIT = 1;
int group[POPULATION_SIZE][2];
void InitPopulation ();
void CalculateFitness ();
void ChooseNewGroup ();
void Reproduction ();
int BornChild (int father, int mother);
int DecimalToBinary (int decimal);
int BinaryToDecimal (int binary);
int Variation ();
源文件:
InheritanceAlgorithm.cc
#include "InheritanceAlgorithm.h"
int main ()
{
InitPopulation ();
int TIMES = 0;
while (TIMES < ITERATION_NUM) {
CalculateFitness ();
ChooseNewGroup ();
Reproduction ();
Variation ();
cout << "The " << TIMES << " time : " << endl;
for (int icount = 0; icount < POPULATION_SIZE; icount++) {
cout << group[icount][0] << endl;
}
TIMES++;
}
return 1;
}
void InitPopulation () {
int total_range = SOLUTION_RANGE;
while (total_range != 1 && total_range != 0) {
SOLUTION_RANGE_BINARY_DIGIT += 1;
total_range /= 2;
}
srand (time (NULL));
for (int icount = 0; icount < POPULATION_SIZE; icount++) {
group[icount][0] = (int) (rand () % SOLUTION_RANGE);
group[icount][1] = 0; // Set init fitness is zero
}
}
void CalculateFitness () {
for (int icount = 0; icount < POPULATION_SIZE; icount++) {
group[icount][1] = f(group[icount][0]);
if (group[icount][1] < 0) {
group[icount][1] = 0;
}
}
}
void ChooseNewGroup () {
int sumFitness = 0; // Total fitnesses
for (int icount = 0; icount < POPULATION_SIZE; icount++) {
sumFitness += group[icount][1];
}
if (sumFitness == 0) {
return;
}
double newGroupPro[POPULATION_SIZE]; // pro
for (int icount = 0; icount < POPULATION_SIZE; icount++) {
newGroupPro[icount] = (double) group[icount][1] / sumFitness;
}
for (int icount = 1; icount < POPULATION_SIZE; icount++) {
newGroupPro[icount] = newGroupPro[icount - 1] + newGroupPro[icount];
}
int SAVE_GROUP_NUM[POPULATION_SIZE];
for (int icount = 0; icount < POPULATION_SIZE; icount++) {
double m_rand = rand () / double (RAND_MAX);
for (int ientry = 0; ientry < POPULATION_SIZE; ientry++) {
if (newGroupPro[ientry] >= m_rand) {
SAVE_GROUP_NUM[icount] = ientry;
break;
}
}
continue;
}
int newGroup[POPULATION_SIZE][2];
for (int icount = 0; icount < POPULATION_SIZE; icount++) {
newGroup[icount][0] = group[SAVE_GROUP_NUM[icount]][0];
newGroup[icount][1] = f(newGroup[icount][0]);
}
memcpy (group, newGroup, POPULATION_SIZE * 2 * sizeof (int));
}
void Reproduction () {
int father_num, mother_num, child;
father_num = rand () % POPULATION_SIZE;
mother_num = rand () % POPULATION_SIZE;
child = BornChild (group[father_num][0], group[mother_num][0]);
// Though we have a child but it may can not alive, which by its fitness
int avgFitness = 0, sumFitness = 0;
for (int icount = 0; icount < POPULATION_SIZE; icount ++) {
sumFitness += group[icount][1];
}
avgFitness = sumFitness / POPULATION_SIZE;
if (f(child) < avgFitness) { // This child dead
return;
} else { // Lucky dog
int deadNum = rand () % POPULATION_SIZE;
group[deadNum][0] = child;
group[deadNum][1] = 0;
}
}
int BornChild (int father, int mother) {
int changePoint = pow (10, (rand () % SOLUTION_RANGE_BINARY_DIGIT + 1));
int father_binary, mother_binary, child_binary;
int sperm, egg;
int child;
father_binary = DecimalToBinary (father);
mother_binary = DecimalToBinary (mother);
// Child gets father's first half and mother's bottom half
sperm = (father_binary / changePoint) * changePoint;
egg = mother_binary % changePoint;
child_binary = sperm + egg;
child = BinaryToDecimal (child_binary);
return child;
}
int DecimalToBinary (int decimal) {
int binary = 0;
int digit = 1;
while (decimal != 0) {
binary += (decimal % 2) * digit;
decimal /= 2;
digit *= 10;
}
return binary;
}
int BinaryToDecimal (int binary) {
int index_10 = 10, index_2 = 0;
int decimal = 0;
while (binary != 0) {
decimal += (binary % index_10) * pow (2, index_2);
index_2 += 1;
binary /= 10;
}
return decimal;
}
int Variation () {
// My opinion is variation will happen in every time
if (rand () / double (RAND_MAX) <= PROBABILITY_VARIATION)
{
int varistionPosition = rand () % 20;
int individualPosition = varistionPosition / 5;
int innerPosition = varistionPosition % 5;
int varistionIndivdual = group[individualPosition][0];
int varistionIndivdualBinary = DecimalToBinary (varistionIndivdual);
int preNum = varistionIndivdualBinary / pow (10, innerPosition + 1);
int sufNum = varistionIndivdualBinary % (int) pow (10, innerPosition);
int aimPos = (varistionIndivdualBinary - preNum - sufNum ) / pow (10, innerPosition);
if (aimPos == 0) {
aimPos = 1;
} else {
aimPos = 0;
}
int aimNum = BinaryToDecimal (preNum + sufNum + aimPos * pow (10, innerPosition));
group[individualPosition][0] = aimNum;
}
}
以为会很难,发现还好,请多指教!!!