ea-neurons.c
来自「一个在unix下运行的neurons EA小程序」· C语言 代码 · 共 272 行
C
272 行
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define Example 16 /* number of examples */
#define Input 5 /* the last input is always -1 */
#define Output 1 /* number of output neurons */
#define MaxHidden 20 /* maximum number of hidden neurons */
#define Generation 1000
#define PopSize 100
#define BitPerWeight 16
#define GeneLength 2040 /* (BitPerWeight+1)*MaxHidden*(Input+Output) */
#define Rc 0.8
#define Rm 0.001
#define DesiredFitness 0.99
#define lambda 10.0
#define A 20.0
#define B -10.0
#define Used 1
#define sigmoid(x) (1.0/(1.0+exp(-lambda*x)))
#define frand() (rand()%10000/10001.0)
#define randomize() srand((unsigned int)time(NULL))
typedef struct {
unsigned char genotype[GeneLength];
double fitness;
int size; /* the number of hidden neurons actually used */
} Individual;
Individual net[PopSize];
Individual new_net[PopSize];
Individual best_net;
double x[Example][Input]={
{0,0,0,0,-1},{0,0,0,1,-1},{0,0,1,0,-1},{0,0,1,1,-1},
{0,1,0,0,-1},{0,1,0,1,-1},{0,1,1,0,-1},{0,1,1,1,-1},
{1,0,0,0,-1},{1,0,0,1,-1},{1,0,1,0,-1},{1,0,1,1,-1},
{1,1,0,0,-1},{1,1,0,1,-1},{1,1,1,0,-1},{1,1,1,1,-1},
};
double d[Example][Output]={0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0};
double v[MaxHidden][Input];
double w[Output][MaxHidden];
double y[MaxHidden];
double o[Output];
void Initialization(void);
void Reconstruction(int);
int CheckNeuron(int);
double GetWeight(int,int);
void Evaluation(int);
void Reproduction(void);
void Crossover(int, int);
void Mutation(int);
void PrintResult(int);
/**************************************************************/
/* The main program */
/**************************************************************/
main(){
int i,i0,g=0;
Initialization();
for(g=1;g<Generation;g++){
i0=0;
for(i=1;i<PopSize;i++){
Evaluation(i);
if(net[i].fitness>net[i0].fitness) i0=i;
}
best_net=net[i0];
printf("Highest fitness [%d] = %f\n",g, best_net.fitness);
printf("Size of the best net [%d] = %d\n\n",g, best_net.size);
if(best_net.fitness>DesiredFitness) break;
Reproduction();
}
PrintResult(i0);
}
/**************************************************************/
/* Initialization of all individuals */
/**************************************************************/
void Initialization(void){
int i,j;
randomize();
for(i=0;i<PopSize;i++){
for(j=0;j<GeneLength;j++){
net[i].genotype[j]=rand()%2;
}
}
}
/**************************************************************/
/* Reconstruction of the individual from its genotype */
/* Return the number of hidden neurons actually used */
/**************************************************************/
void Reconstruction(int p){
int i,j,k;
int tag[MaxHidden];
net[p].size=0;
for(j=0;j<MaxHidden;j++){
if((tag[j]=CheckNeuron(p))==Used) net[p].size++;
for(i=0;i<Input;i++){
v[j][i]=GetWeight(p,tag[j]);
}
}
for(k=0;k<Output;k++){
for(j=0;j<MaxHidden;j++){
w[k][j]=GetWeight(p,tag[j]);
}
}
}
/**************************************************************/
/* Check if the current hidden neuron is used or not */
/**************************************************************/
int CheckNeuron(int p){
static int current_individual=0;
static int start=0;
int i;
if(current_individual!=p){
start=0;
current_individual=p;
}
i=start;
start=i+BitPerWeight*Input;
return net[p].genotype[i];
}
/**************************************************************/
/* Return a weight from the genotype of the p-th individual */
/**************************************************************/
double GetWeight(int p,int tag){
static int start=0;
double tmp1=0.5,tmp2=0,result=0;
int i;
if(tag==Used){
for(i=start;i<start+BitPerWeight;i++){
tmp2+=net[p].genotype[i]*tmp1;
tmp1*=0.5;
}
result=tmp2*A+B;
}
start+=BitPerWeight;
if(start>=GeneLength) start=0;
return result;
}
/**************************************************************/
/* Find the fitness of the p-th individual */
/**************************************************************/
void Evaluation(int p){
int i,j,k,q;
double Error;
double temp;
Reconstruction(p);
Error=0;
for(q=0; q<Example; q++){
for(j=0;j<MaxHidden-1;j++){
temp=0;
for(i=0;i<Input;i++)
temp+=v[j][i]*x[q][i];
y[j]=sigmoid(temp);
}
y[MaxHidden-1]=-1;
for(k=0; k<Output; k++){
temp=0;
for(j=0;j<MaxHidden;j++)
temp+=w[k][j]*y[j];
o[k]=sigmoid(temp);
Error+=0.5*pow(d[q][k]-o[k],2.0);
}
}
net[p].fitness=1/(1+Error);
}
/**************************************************************/
/* Reproduction of the individuals */
/**************************************************************/
void Reproduction(void){
int i,i0;
double total_fitness=0;
double r,sum;
for(i=0;i<PopSize;i++)
total_fitness+=net[i].fitness;
for(i=0;i<PopSize;i++){
r=total_fitness*frand();
i0=0;
sum=0;
while((sum+=net[i0].fitness)<r) i0++;
new_net[i]=net[i0];
}
for(i=0;i<PopSize;i+=2){
Crossover(i,i+1);
Mutation(i);
Mutation(i+1);
}
net[0]=best_net;
}
/**************************************************************/
/* Producing two sons from two parents using cross-over */
/**************************************************************/
void Crossover(int i1,int i2){
int i;
int crossover_point;
if(frand()<Rc){
crossover_point=rand()%(GeneLength-2)+1;
for(i=0;i<GeneLength;i++){
if(i<crossover_point){
net[i1].genotype[i]=new_net[i1].genotype[i];
net[i2].genotype[i]=new_net[i2].genotype[i];
}
else{
net[i1].genotype[i]=new_net[i2].genotype[i];
net[i2].genotype[i]=new_net[i1].genotype[i];
}
}
}
}
/**************************************************************/
/* Mutation of a given individual */
/**************************************************************/
void Mutation(int s){
int i;
for(i=0;i<GeneLength;i++){
if(frand()<Rm) net[s].genotype[i]=(net[s].genotype[i]+1)%2;
}
}
/**************************************************************/
/* Print out the final result */
/**************************************************************/
void PrintResult(int best){
int i,j,k;
Reconstruction(best);
printf("\n\n");
printf("The connection weights in the output layer:\n");
for(k=0;k<Output;k++){
for(j=0;j<MaxHidden;j++)
printf("%5f ",w[k][j]);
printf("\n");
}
printf("\n\n");
printf("The connection weights in the hidden layer:\n");
for(j=0; j<MaxHidden-1; j++){
for(i=0; i<Input; i++)
printf("%5f ",v[j][i]);
printf("\n");
}
printf("\n\n");
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?