基于遗传算法(GA)的神经网络训练算法

硕士毕业已近三年,除了年龄的增长,没觉得自己的生活有其他方面的变化。曾经梦想毕业之后可以做自己喜欢做的事情,可以改变自己喜欢领域的某个方面,现如今,梦想依然是梦想,个人的激情却在慢慢消退。前几天看CSDN,发现很多人都在利用这个平台分享自己工作上的某些经验,觉得这是个不错的选择,通过文章的分享和交流,一方面有助于自身能力的提升,另一方面,还有可能找到同自己志同道合的朋友,拉近和梦想的距离。


废话就不多说了,这是我的第一篇博文,和大家分享一下BP神经网络的训练过程。

1、BP神经网络介绍

传统的BP神经网络是一个三层网络:输入层、隐含层、输出层,如下图:


    与人的大脑类比不难看出这三层的作用,输入层相当于连接现实世界与人的大脑的一个接口,输入层的维度就是我们所能够感知到的外部信息(比如物体的形状、颜色、纹理、声音、气味等),输出层节点的个数取决于我们的先验知识(BP神经网络属于一种有监督学习方式),比如说我们要对人按照性别进行分类,那么根据先验知识已经知道这个世界上的人分为男人和女人,只有这两种情况,这时输出层只需要一个节点就可以表达这两种状态,也即输出层的节点个数为1。而隐含层,我个人认为就好像是我们考虑问题的深度,是连接输入层和输出层的纽带。隐层节点个数的选择是需要优化的,过少就好像考虑问题太过简单,对于复杂一点儿的问题,难免顾此失彼,也就是网络欠学习,而如果节点个数过多的话,就好像我们考试的时候是死记硬背记住的,只能分析特定模式,即我们背过的那一套试题,超出范围则无分析能力,也就是网络泛化能力太差,造成网络过学习。

    除此之外,要实现网络的非线性映射必然要用到的是传递函数(也称为激活函数),常用到的传递函数有tansig,purelin(不能实现非线性映射),sigmoid,选用哪一种传递函数要看具体的应用,也即输入向量空间的样本分布情况。

2、遗传算法介绍

    遗传算法是由达尔文进化论抽象出来的,虽然个人比较怀疑达尔文进化论的真实性,不过遗传算法确实可以说是一个非常好的全局优化算法。

    遗传算法分为四个主要的部分:1、编码;2、交叉;3、变异;4、解码。

    编码----编码的形式多种多样,最常见的是二进制编码,二进制的长度则为基因的长度,比如说10编码后变成1010

    交叉----交叉就是将染色体上某个点位的遗传信息与另一条染色体某个点位的遗传信息互换,比如说两条染色体A:10000101,B:11001110,红色标注为交叉位置,经过交叉操作之后两条染色体分别变为A:10001101,B:10001110

    变异----变异就是基因上某个点位的遗传信息以一定概率改变其成分,比如染色体10001100,经变异后变为10001110

    解码----将染色体变为生物体的性状,比如1010解码之后变成10


    那么遗传算法中优胜劣汰是怎么体现的呢?在这里,我觉得概率是一个很好的东西,很多时候我都认为概率是一把通往成功之路的万能钥匙,就像我们做一件事情一样,一次不成功,两次,三次.......,从概率学角度来讲,只要这件事情是概率事件,那么你总会成功。在这里我们构造一个效能函数f(x1,x2,....,xn),因为优化问题最终都可以转化为求极值的问题,甚至极大极小值都是不重要的(他们是可以相互转化的),每一个个体在经过遗传之后,从性状上都会通过一个效能函数反应出来,那么假设我们每一次遗传都会有M个个体存活下来,对应的适应度值分别为f1,f2,f3.....fm,他们遗传到下一代的概率可以表达为fi/sum(fi),在这里我们是假设最终的优化问题变为求效能函数的极大值问题,也就是说适应度函数值越大,遗传到下一代的概率也就越大。


    经过遗传,问题就会得到不断的优化。


    先上传一段用GA训练BP神经网络的代码,代码的分析有时间再写

BpNet.h

#ifndef __BPNET_H__
#define __BPNET_H__

#define USE_GA
#define MAX_GROUP_NUM      (80)
typedef struct tagBPNetParams
{
	/*样本个数*/
	int sampleNum;
	/*输入层神经元个数(向量维数)*/
	int inputDim;
	/*输入向量(内存由外部分配)*/
	double *inputVector;
	/*输入层到隐含层间的权重*/
	double *W_in_hid;
	/*隐含层神经元个数*/
	int hidenDim;
    /*隐含层节点值*/
	double *hidenVector;
	/*隐含层阈值*/
	double thresh_hid;
	/*隐含层到输出层间的权重*/
	double *W_hid_out;
	/*输出层神经元个数*/
	int outputDim;
	/*目标输出向量(内存由外部分配)*/
	double *outputVectorObj;
	/*输出向量*/
	double *outputVector;
    /*输出层阈值*/
	double thresh_out;
	/*训练最大容许误差*/
	double eps;
	/*训练最大迭代次数*/
	int maxIteration;
	/*学习速率*/
	double alpha;

}BP_PARAMS;

typedef struct tagGAParams
{
	/*基因长度*/
	int gene_Len[2];
	/*交叉概率*/
	double cross_prob;
	/*变异概率*/
	double mutation_prob;
	/*输入层和隐含层之间权值的码字*/
	char *code0;
	/*隐含层和输出层之间权值的码字*/
	char *code1;
	/*网络参数*/
	BP_PARAMS bp_params;

}GA_PARAMS;

#ifdef USE_GA

typedef struct tagGABP
{
	/*种群数目*/
	int groupNum;
	/*最大繁殖代数*/
	int maxGeneration;
	/*最好的物种*/
	BP_PARAMS best_bp_params;
	GA_PARAMS ga[MAX_GROUP_NUM];
	GA_PARAMS ga_next[MAX_GROUP_NUM];
	void GA_BP_setParams(int sampleNum, int inputDim, int hidenDim, int outputDim, 
		                 double thresh_hid, double thresh_out, double eps, int maxIteration,
			   		     double alpha);
	int  GA_BP_init();
	int  GA_BP_setInOutput(double *input, double *output);
	void GA_BP_train();
	void GA_BP_predict(double *input, double *output);
	void GA_BP_free();
	void GA_setParams(int gene_Len[], int groupNum, int maxGeneration, double cross_prob, double mutation_prob);
	void GA_BP_saveweight(const char *filename);
	void GA_BP_readweight(const char *filename);
	/*交叉函数*/
	void GA_cross(int g_num);
	/*变异函数*/
	void GA_mutation(int g_num);
	/*选择函数*/
	void GA_selection();
	/*编码函数*/
	void GA_encode(int g_num);
	/*解码函数*/
	void GA_decode(int g_num);
}GABP;

#else

typedef struct tagBPNet
{
    BP_PARAMS bp_params;
	void BP_setParams(int sampleNum, int inputDim, int hidenDim, int outputDim, 
		              double thresh_hid, double thresh_out, double eps, int maxIteration,
					  double alpha);
	int  BP_init();
	int  BP_setInOutput(double *input, double *output);
	void BP_train();
	void BP_free();
	void BP_predict(double *input, double *output);
	void BP_saveweight(const char *filename);
	void BP_readweight(const char *filename);
}BP_NET;

#endif

#endif


BpNet.cpp

#include "malloc.h"
#include "string.h"
#include "math.h"
#include "BPNet.h"

#define  BP_MALLOC(size) malloc(size)
#define  BP_FREE(p) free(p)

#define  GA_BP_MALLOC(size) malloc(size)
#define  GA_BP_FREE(p) free(p)

#define  TRAN_FUN(x)       (1.0/(1+exp(-x)))

#ifdef   USE_GA

double min_e = 10000;


#define  MAX_WEIGHT        (10 )
#define  MIN_WEIGHT        (-10)
#define  GENE_BIT          (8  )
#define  RANGE             (1<<GENE_BIT)

#define  ENCODE_STYLE(x)   ((x) * (RANGE-1))/(MAX_WEIGHT - MIN_WEIGHT) 
#define  DECODE_STYLE(x)   ((x) * (MAX_WEIGHT - MIN_WEIGHT)/(RANGE-1))  

void GABP::GA_BP_setParams(int sampleNum, int inputDim, int hidenDim, int outputDim, 
	  					   double thresh_hid = 0, double thresh_out = 0, double eps = 10e-6, 
						   int maxIteration = 500, double alpha = .9)
{
	int i;

	for(i = 0; i < MAX_GROUP_NUM; i++)
	{
		this->ga[i].bp_params.sampleNum    = sampleNum;
	    this->ga[i].bp_params.inputDim     = inputDim;
	    this->ga[i].bp_params.hidenDim     = hidenDim;
	    this->ga[i].bp_params.outputDim    = outputDim;
	    this->ga[i].bp_params.thresh_hid   = thresh_hid;
	    this->ga[i].bp_params.thresh_out   = thresh_out;
	    this->ga[i].bp_params.eps          = eps;
	    this->ga[i].bp_params.maxIteration = maxIteration;
	    this->ga[i].bp_params.alpha        = alpha;
	}

	this->best_bp_params.sampleNum    = sampleNum;
	this->best_bp_params.inputDim     = inputDim;
	this->best_bp_params.hidenDim     = hidenDim;
	this->best_bp_params.outputDim    = outputDim;
	this->best_bp_params.thresh_hid   = thresh_hid;
	this->best_bp_params.thresh_out   = thresh_out;
	this->best_bp_params.eps          = eps;
	this->best_bp_params.maxIteration = maxIteration;
	this->best_bp_params.alpha        = alpha;

	return;
}

void GABP::GA_setParams(int gene_Len[], int groupNum = 40, int maxGeneration = 50000, double cross_prob = .4, double mutation_prob = .3)
{
	int i;

	for(i = 0; i < MAX_GROUP_NUM; i++)
	{
		this->ga[i].cross_prob       = cross_prob;
		this->ga[i].mutation_prob    = mutation_prob;
		this->ga[i].gene_Len[0]      = gene_Len[0];
		this->ga[i].gene_Len[1]      = gene_Len[1];
	}
	this->groupNum = groupNum;
	this->maxGeneration = maxGeneration;

	return;
}

int  GABP::GA_BP_init()
{
	int size;
	int i;

	size = this->best_bp_params.inputDim*this->best_bp_params.hidenDim*sizeof(double);
    if(NULL == (this->best_bp_params.W_in_hid = (double*)GA_BP_MALLOC(size)))
	{
		return -1;
	}
	memset(this->best_bp_params.W_in_hid, 0, size);

	size = this->best_bp_params.outputDim*this->best_bp_params.hidenDim*sizeof(double);
    if(NULL == (this->best_bp_params.W_hid_out = (double*)GA_BP_MALLOC(size)))
	{
		return -1;
	}
	memset(this->best_bp_params.W_hid_out, 0, size);

	size = this->best_bp_params.hidenDim*sizeof(double);
	if(NULL == (this->best_bp_params.hidenVector = (double*)GA_BP_MALLOC(size)))
	{
		return -1;
	}
	memset(this->best_bp_params.hidenVector, 0, size);

	for(i = 0; i < MAX_GROUP_NUM; i++)
	{
		size = this->ga[i].bp_params.inputDim*this->ga[i].bp_params.hidenDim*sizeof(double);
		if(NULL == (this->ga[i].bp_params.W_in_hid = (double*)GA_BP_MALLOC(size)))
		{
			return -1;
		}

		if(NULL == (this->ga_next[i].bp_params.W_in_hid = (double*)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		/*权重初始化*/
		for(int k = 0; k < this->ga[i].bp_params.inputDim*this->ga[i].bp_params.hidenDim; k++)
		{
			this->ga[i].bp_params.W_in_hid[k] = 1;
		}

		size = this->ga[i].bp_params.hidenDim*this->ga[i].bp_params.outputDim*sizeof(double);
		if(NULL == (this->ga[i].bp_params.W_hid_out = (double*)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		if(NULL == (this->ga_next[i].bp_params.W_hid_out = (double*)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		/*权重初始化*/
		for(k = 0; k < this->ga[i].bp_params.outputDim*this->ga[i].bp_params.hidenDim; k++)
		{
			this->ga[i].bp_params.W_hid_out[k] = -1;
		}

		size = this->ga[i].bp_params.hidenDim*sizeof(double);
		if(NULL == (this->ga[i].bp_params.hidenVector = (double*)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		if(NULL == (this->ga_next[i].bp_params.hidenVector = (double*)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		memset(this->ga[i].bp_params.hidenVector, 0, size);

		size = this->ga[i].bp_params.outputDim*sizeof(double);
		if(NULL == (this->ga[i].bp_params.outputVector = (double*)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		if(NULL == (this->ga_next[i].bp_params.outputVector = (double*)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		memset(this->ga[i].bp_params.outputVector, 0, size);

		size = this->ga[i].bp_params.inputDim*this->ga[i].bp_params.hidenDim*8;
		if(NULL == (this->ga[i].code0 = (char *)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		if(NULL == (this->ga_next[i].code0 = (char *)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		memset(this->ga[i].code0, 0, size);
		memset(this->ga_next[i].code0, 0, size);


		size = this->ga[i].bp_params.outputDim*this->ga[i].bp_params.hidenDim*8;
		if(NULL == (this->ga[i].code1 = (char *)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		if(NULL == (this->ga_next[i].code1 = (char *)GA_BP_MALLOC(size)))
		{
			return -1;
		}
		memset(this->ga[i].code1, 0, size);
	}

	return 0;
}

void GABP::GA_BP_free()
{
	
	for(int i = 0; i < MAX_GROUP_NUM; i++)
	{
		if(NULL != this->ga[i].code0)
		{
			GA_BP_FREE(&this->ga[i].code0[0]);
		}
		
		if(NULL != this->ga[i].code1)
		{
			GA_BP_FREE(&this->ga[i].code1[0]);
		}
		
		
		if(NULL != this->ga_next[i].code0)
		{
			GA_BP_FREE(&this->ga_next[i].code0[0]);
		}

		if(NULL != this->ga_next[i].code1)
		{
			GA_BP_FREE(&this->ga_next[i].code1[0]);
		}

		if(NULL != this->ga[i].bp_params.W_in_hid)
		{
			GA_BP_FREE(this->ga[i].bp_params.W_in_hid);
		}

		if(NULL != this->ga_next[i].bp_params.W_in_hid)
		{
			GA_BP_FREE(this->ga_next[i].bp_params.W_in_hid);
		}

		if(NULL != this->ga[i].bp_params.W_hid_out)
		{
			GA_BP_FREE(this->ga[i].bp_params.W_hid_out);

		}

		if(NULL != this->ga_next[i].bp_params.W_hid_out)
		{
			GA_BP_FREE(this->ga_next[i].bp_params.W_hid_out);
		}

		if(NULL != this->ga[i].bp_params.hidenVector)
		{
			GA_BP_FREE(this->ga[i].bp_params.hidenVector);
		}

		if(NULL != this->ga_next[i].bp_params.hidenVector)
		{
			GA_BP_FREE(this->ga_next[i].bp_params.hidenVector);
		}

		if(NULL != this->ga[i].bp_params.outputVector)
		{
			GA_BP_FREE(this->ga[i].bp_params.outputVector);
		}

		if(NULL != this->ga_next[i].bp_params.outputVector)
		{
			GA_BP_FREE(this->ga_next[i].bp_params.outputVector);
		}
		
	}

	return;
}

int GABP::GA_BP_setInOutput(double *input, double *output)
{
	if(NULL == input || NULL == output)
	{
		return -1;
	}

	for(int i = 0; i < MAX_GROUP_NUM; i++)
	{
		this->ga[i].bp_params.inputVector     = input;
	    this->ga[i].bp_params.outputVectorObj = output;
	}

	return 0;
}

void GABP::GA_encode(int g_num)
{
	int i,j,k,q;
	int w;
	/*对权重编码,为保证权重为正,加一个偏移*/

	for(j = 0; j < this->ga[g_num].bp_params.hidenDim; j++)
	{
		for(k = 0; k < this->ga[g_num].bp_params.inputDim; k++)
		{
			i = j*this->ga[g_num].bp_params.inputDim + k;
			w = (int)ENCODE_STYLE(this->ga[g_num].bp_params.W_in_hid[i] - MIN_WEIGHT);
			for(q = 0; q < GENE_BIT; q++)
			{
				this->ga[g_num].code0[i*GENE_BIT+q]=(w>>q)&0x1;
			}
		}
	}

	for(j = 0; j < this->ga[g_num].bp_params.outputDim; j++)
	{
		for(k = 0; k < this->ga[g_num].bp_params.hidenDim; k++)
		{
			i = j*this->ga[g_num].bp_params.outputDim + k;
			w = (int)ENCODE_STYLE(this->ga[g_num].bp_params.W_hid_out[i] - MIN_WEIGHT);
			for(q = 0; q < GENE_BIT; q++)
			{
				this->ga[g_num].code1[i*GENE_BIT+q]=(w>>q)&0x1;
			}
		}
	}

	return;
}

void GABP::GA_decode(int g_num)
{
	int i,j,k,q;

	memset(this->ga[g_num].bp_params.W_in_hid, 0, 
		   this->ga[g_num].bp_params.hidenDim*this->ga[g_num].bp_params.inputDim*sizeof(double));
	memset(this->ga[g_num].bp_params.W_hid_out, 0, 
		   this->ga[g_num].bp_params.hidenDim*this->ga[g_num].bp_params.outputDim*sizeof(double));
	
	for(j = 0; j < this->ga[g_num].bp_params.hidenDim; j++)
	{
		for(k = 0; k < this->ga[g_num].bp_params.inputDim; k++)
		{
			i = j*this->ga[g_num].bp_params.inputDim + k;
			for(q = 0; q < GENE_BIT; q++)
			{
				this->ga[g_num].bp_params.W_in_hid[i] += this->ga[g_num].code0[i*GENE_BIT+q]<<q;
			}
			this->ga[g_num].bp_params.W_in_hid[i] = DECODE_STYLE(this->ga[g_num].bp_params.W_in_hid[i]) + MIN_WEIGHT;
		}
	}

	for(j = 0; j < this->ga[g_num].bp_params.outputDim; j++)
	{
		for(k = 0; k < this->ga[g_num].bp_params.hidenDim; k++)
		{
			i = j*this->ga[g_num].bp_params.outputDim + k;
			for(q = 0; q < GENE_BIT; q++)
			{
				this->ga[g_num].bp_params.W_hid_out[i] += this->ga[g_num].code1[i*GENE_BIT+q]<<q;
			}
			this->ga[g_num].bp_params.W_hid_out[i] = DECODE_STYLE(this->ga[g_num].bp_params.W_hid_out[i]) + MIN_WEIGHT;
		}
	}
}

void GABP::GA_cross(int g_num)
{
	int i;
	int decision;
	int pos1,pos2;
	char *code1,*code2;
	char temp_code;

	for(i = 0; i < this->ga[g_num].gene_Len[0]*8 + this->ga[g_num].gene_Len[1]*8; i++)
	{
		decision = (rand()%10) + 1;
		if(decision <= 10*this->ga[g_num].cross_prob)
		{
			pos1 = i;
			pos2 = (int)((rand()%100/99.0)*(this->ga[g_num].gene_Len[0] + this->ga[g_num].gene_Len[1] - 1));

			if(pos1 > this->ga[g_num].gene_Len[0]*8 - 1)
			{
				code1 = &this->ga[g_num].code1[pos1 - 8*this->ga[g_num].gene_Len[0]];
			}
			else
			{
				code1 = &this->ga[g_num].code0[pos1];
			}

			if(pos2 > this->ga[g_num].gene_Len[0]*8 - 1)
			{
				code2 = &this->ga[g_num].code1[pos2 - 8*this->ga[g_num].gene_Len[0]];
			}
			else
			{
				code2 = &this->ga[g_num].code0[pos2];
			}

			temp_code = *code1;
			*code1    = *code2;
			*code2    = temp_code;

		}
	}

	return;
}

void GABP::GA_mutation(int g_num)
{
	int i;
	int decision;

    for(i = 0; i < this->ga[g_num].gene_Len[0]*8; i++)
	{
		decision = rand()%10 + 1;
		if(decision <= 10*this->ga[g_num].mutation_prob)
		{
			this->ga[g_num].code0[i] = 1 - this->ga[g_num].code0[i];
		}
	}
	for(i = 0; i < this->ga[g_num].gene_Len[1]*8; i++)
	{
		decision = rand()%10 + 1;
		if(decision <= 10*this->ga[g_num].mutation_prob)
		{
			this->ga[g_num].code1[i] = 1 - this->ga[g_num].code1[i];
		}
	}

	return;
}

void GABP::GA_selection()
{
	int i,j,k,l;
	double *input;
	double *output;
	double e = 0;

	double *f = (double*)GA_BP_MALLOC(this->groupNum*sizeof(double));

	if(NULL == f)
	{
		return;
	}

	memset(f, 0, this->groupNum*sizeof(double));
	/*遍历种群中所有个体,按照适应度函数排序*/
	for(i = 0; i < this->groupNum; i++)
	{
		input = &this->ga[i].bp_params.inputVector[0];
		output = &this->ga[i].bp_params.outputVectorObj[0];
		e = 0;
		for(j = 0; j < this->ga[i].bp_params.sampleNum; j++)
		{
			double max_input = -1000000;
			double min_input = 1000000;
			for(k = 0; k < this->ga[i].bp_params.inputDim; k++)
			{
				if(input[k] > max_input)
				{
					max_input = input[k];
				}
				if(input[k] < min_input)
				{
					min_input = input[k];
				}
			}
			for(k = 0; k < this->ga[i].bp_params.inputDim; k++)
			{
				input[k] = input[k]/(max_input - min_input);
			}

			memset(this->ga[i].bp_params.hidenVector, 0, this->ga[i].bp_params.hidenDim*sizeof(double));
			memset(this->ga[i].bp_params.outputVector, 0, this->ga[i].bp_params.outputDim*sizeof(double));
			for(k = 0; k < this->ga[i].bp_params.hidenDim; k++)
			{
				for(l = 0; l < this->ga[i].bp_params.inputDim; l++)
				{
					this->ga[i].bp_params.hidenVector[k] += this->ga[i].bp_params.W_in_hid[k*this->ga[i].bp_params.inputDim + l]*
						                                    input[l];
				}
				this->ga[i].bp_params.hidenVector[k] = TRAN_FUN(this->ga[i].bp_params.hidenVector[k] - this->ga[i].bp_params.thresh_hid);
			}
			/*隐含-->输出层*/
			for(k = 0; k < this->ga[i].bp_params.outputDim; k++)
			{
				for(l = 0; l < this->ga[i].bp_params.hidenDim; l++)
				{
					this->ga[i].bp_params.outputVector[k] += this->ga[i].bp_params.W_hid_out[k*this->ga[i].bp_params.hidenDim + l]*
						                                     this->ga[i].bp_params.hidenVector[l];
				}
				this->ga[i].bp_params.outputVector[k] = TRAN_FUN(this->ga[i].bp_params.outputVector[k] - this->ga[i].bp_params.thresh_out);
			}

			/*计算误差*/
			for(k = 0; k < this->ga[i].bp_params.outputDim; k++)
			{
				e += (this->ga[i].bp_params.outputVector[k] - output[k])*
					  (this->ga[i].bp_params.outputVector[k] - output[k]);
			}

			

			input += this->ga[i].bp_params.inputDim;
		    output += this->ga[i].bp_params.outputDim;
		}

		e = e/(this->ga[i].bp_params.outputDim*this->ga[i].bp_params.sampleNum);
		f[i] = e/2;
		if(min_e > e/2)
		{
			min_e = e/2;
			for(k = 0; k < this->ga[i].bp_params.outputDim; k++)
			{
				memcpy(this->best_bp_params.W_in_hid, this->ga[i].bp_params.W_in_hid, 
					   this->best_bp_params.inputDim*this->best_bp_params.hidenDim*sizeof(double));
				memcpy(this->best_bp_params.W_hid_out, this->ga[i].bp_params.W_hid_out, 
					   this->best_bp_params.outputDim*this->best_bp_params.hidenDim*sizeof(double));
			}
		}
	}
	double sumf = 0;
	for(i = 0; i < this->groupNum; i++)
	{
		for(j = i; j < this->groupNum; j++)
		{
			double temp = 0;
			if(f[i] > f[j])
			{
				temp = f[i];
				f[i] = f[j];
				f[j] = temp;
			}
		}
	}

	for(i = 0; i < this->groupNum; i++)
	{
		f[i] = f[this->groupNum - 1] - f[i];
		sumf += f[i];
	}

	for(i = 0; i < this->groupNum; i++)
	{
		f[i] /= sumf;
	}

	for(i = 0; i < this->groupNum - 1; i++)
	{
		f[i+1] = f[i] + f[i+1];
	}

	/*按照适应度复制到下一代*/

	for(i = 0; i < this->groupNum; i++)
	{
		double decision;
		decision = rand()%100/99.0;
		for(j = 1; j < this->groupNum; j++)
		{
			if(f[j] > decision)
			{
				memcpy(&this->ga_next[i].code0[0], &this->ga[j-1].code0[0], 
					   this->ga[i].bp_params.inputDim*this->ga[i].bp_params.hidenDim*8);
				memcpy(&this->ga_next[i].code1[0], &this->ga[j-1].code1[0], 
					   this->ga[i].bp_params.outputDim*this->ga[i].bp_params.hidenDim*8);
					   
				break;
			}
		}
	}
	GA_BP_FREE(f);

	return;
}

void GABP::GA_BP_train()
{
	int i;
	int generation = 0;

	while(generation < this->maxGeneration && min_e > this->best_bp_params.eps)
	{
		generation++;
		GA_selection();
		for(int j = 0; j < this->groupNum; j++)
		{	
			memcpy(&this->ga[j].code0[0], &this->ga_next[j].code0[0], 
				   this->ga[j].bp_params.inputDim*this->ga[j].bp_params.hidenDim*8);
			memcpy(&this->ga[j].code1[0], &this->ga_next[j].code1[0], 
				   this->ga[j].bp_params.outputDim*this->ga[j].bp_params.hidenDim*8);
			
		}
		for(i = 0; i < this->groupNum; i++)
		{
			if(i==0)
			{
				GA_encode(i);
			}
			
			GA_cross(i);
			
			GA_mutation(i);
			
			GA_decode(i);
			
		}
		printf("generation = %d, %.10f\n",generation,min_e);
	}
	
	return;
}

void GABP::GA_BP_predict(double *input, double *output)
{
	int i,j;
	double max_input = -1000000;
	double min_input = 1000000;

    
	memset(this->best_bp_params.hidenVector, 0, this->best_bp_params.hidenDim*sizeof(double));
	for(i = 0; i < this->best_bp_params.inputDim; i++)
	{
		if(input[i] > max_input)
		{
			max_input = input[i];
		}
		if(input[i] < min_input)
		{
			min_input = input[i];
		}
	}
	for(i = 0; i < this->best_bp_params.inputDim; i++)
	{
		input[i] = input[i]/(max_input - min_input);
	}

	for(i = 0; i < this->best_bp_params.hidenDim; i++)
	{
		for(j = 0; j < this->best_bp_params.inputDim; j++)
		{
			this->best_bp_params.hidenVector[i] += this->best_bp_params.W_in_hid[i*this->best_bp_params.inputDim + j]*
						                           input[j];
		}
		this->best_bp_params.hidenVector[i] = TRAN_FUN(this->best_bp_params.hidenVector[i] - this->best_bp_params.thresh_hid);
	}
	/*隐含-->输出层*/
	for(i = 0; i < this->best_bp_params.outputDim; i++)
	{
		for(j = 0; j < this->best_bp_params.hidenDim; j++)
		{
			output[i] += this->best_bp_params.W_hid_out[i*this->best_bp_params.hidenDim + j]*
						 this->best_bp_params.hidenVector[j];
		}
		output[i] = TRAN_FUN(output[i] - this->best_bp_params.thresh_out);
	}

}

void main()
{
	GABP ga_bp;
	int len[2];
	ga_bp.GA_BP_setParams(9,50,62,1);
	len[0] = 50*62;
	len[1] = 62;
	ga_bp.GA_setParams(&len[0]);
	if( -1 == ga_bp.GA_BP_init())
	{
		printf("malloc error!\n");
		return;
	}

	double aa[9][50] = {{0.021,0.0297,0.0212,0.017,0.0297,0.0212,0.0127,0.017,0.072,0.0297,0.0593,0.0297,0.0212,0.0212,0.017,0.0127,0.0254,0.0635,0.034,0.0932,0.0127,0.0212,0.025,0.0212,0.0127,0.0212,0.0212,0.0212,0.017,0.0042,0.0254,0.025,0.034,0.0382,0.029,0.0212,0.0297,0.072,0.017,0.072,0.0213,0.0213,0.017,0,0.03,0.03,0.03,0.021,0.021,0.0383},
	{0.0260,0.0087,0.0606,0.0216,0.0693,0.0390,0.0216,0.0216,0.0649,0.0693,0.0303,0.0087,0.0130,0.0390,0,0.0260,0.0303,0.0303,0.0346,0.0606,0.0130,0.0130,0.0303,0.0303,0.0130,0.0303, 0.0087,0.0173,0.0087,0.0043,0.0303,0.0390,0.0087,0.0216,0.0260,0.0303,0.0086,0.0819,0.0216,0.0690,0.0388,0.0216,0.0216,0.0129,0.0690,0.0388,0.0086,0.0129,0.0388,0.0345},
	{0.0573,0.0176,0.0176,0,0.0308,0.0220,0,0.0220,0.1101,0.0793,0.0308,0.0441,0.0088,0.0573,0,0.0308,0.0220,0.0485,0.0661,0.0088,0,0,0.0220,0.0132,0.0264,0.0352,0.0661,0.0793,0,0,0.0264,0.0176,0.0044,0,0.0088,0.0264,0.0175,0.0219,0,0.0088,0.0219,0.0351,0.0219,0.0439,0.0789,0.0965,0.0439,0.0921,0.0570,0.0219},
	{0.0472,0.0215,0.0086,0.0172,0.0343,0.0086,0.0043,0.0129,0.0429,0.0429,0.0472,0.0043,0,0.0429,0.0086,0.0215,0.0515,0.0558,0.0558,0.0472,0.0343,0.0043,0.0558,0.0172,0.0129,0.0129,0.0386,0.0558,0.0043,0.0386,0.0215,0.0429,0.0172,0.0300,0.0043,0.0343,0.0211,0.0253,0.0169,0.0169,0.0084,0.0169,0.0127,0.0295,0.0422,0.0380,0.0042,0.0422,0.0422,0.0211},
	{0.0125,0.0583,0.0458,0.0250,0.0083,0.0208,0.0083,0.0250,0.0708,0.0208,0.0333,0.0250,0.0458,0.0083,0.0125,0.0125,0.0542,0.0500,0.0333,0.0417,0.0167,0.0042,0.0125,0.0083,0,0.0125,0.0208,0.0583,0.0167,0.0250,0.0208,0.0250,0.0292,0.0500,0.0542,0.0333,0.0593,0.0551,0.0254,0.0763,0.0212,0.0212,0.0254,0.0212,0.0212,0.0254,0.0254,0.0127,0.0085,0.0169},
	{0.0042,0.0549,0.0464,0.0084,0.0084,0.0338,0.0464,0.0169,0.0464,0.0042,0.0380,0.0717,0.0084,0.0169,0.0127,0.0127,0.0253,0.0295,0.0253,0.0253,0.0084,0.0127,0,0.0169,0.0506,0,0.0169,0.0422,0.0802,0.0591,0.0422,0.0464,0.0169,0.0380,0.0211,0.0127,0.0542,0,0.0083,0,0.0333,0.0208,0.0167,0.0042,0.0042,0.0583,0.0708,0.0792,0.0167,0.0167},
	{0.0171,0.0256,0.0256,0.0342,0.0128,0,0.0256,0.0299,0.0342,0.0085,0.0641,0.0556,0.0043,0,0.0128,0.0043,0.0342,0.0299,0.0684,0.0171,0.0598,0.0342,0.0085,0.0171,0.0427,0.1154,0.0085,0.0128,0.0043,0.0427,0.0299,0.0641,0.0256,0,0.0171,0.0128,0.0253,0,0.0338,0.0084,0,0,0.0295,0.0380,0.0084,0.0084,0.0549,0.0464,0,0.0084},
	{0,0,0,0.0356,0,0.0267,0.0133,0.0089,0.0489,0.1067,0.0711,0.0533,0.0756,0.0178,0.0222,0.0178,0.1156,0.0133,0.0222,0.0178,0,0,0.0044,0.0222,0,0.0267,0.0578,0.0667,0.0133,0.0533,0.0489,0.0044,0.0267,0.0044,0.0044,0,0,0.0370,0.0370,0,0.0278,0.0093,0.0093,0.0185,0.1111,0.0463,0.0556,0.0602,0.0185,0.0694},
	{0.0101,0,0,0,0.0152,0.0455,0.0051,0.0202,0.0404,0.1111,0.1616,0.1364,0.0202,0.0152,0,0.0051,0.0152,0.0303,0.0202,0.0152,0,0.0202,0.0101,0,0.0051,0.0202,0.0859,0.1162,0.0202,0.0303,0.0202,0.0051,0,0,0,0,0,0.0489,0,0.0133,0.0400,0.0978,0.0178,0.0756,0.0978,0.0222,0.1200,0.0444,0.0133,0.0178}};
	double bb[9] = {1,1,1,1,1,0,0,0,0};
	ga_bp.GA_BP_setInOutput(&aa[0][0], &bb[0]);
	ga_bp.GA_BP_train();

	double sa[7][50] = {{0.0083,0.0207,0.0124,0.0124,0.0041,0.0537,0.0207,0.0372,0.0372,0.0455,0.0455,0.0289,0.0207,0.0083,0.0455,0.0165,0.0785,0.0289,0.0331,0.0289,0,0.0165,0.0207,0.0372,0.0083,0.0289,0.0372,0.0372,0.0537,0.0372,0.0248,0.0248,0.0496,0.0124,0.0083,0.0165,0.0213,0.0213,0.0128,0.0128,0.0553,0.0170,0.0383,0.0298,0.0468,0.0298,0.0298,0.0553,0.0085,0.0340},
	{0.0126,0.0126,0.0251,0.0167,0.0335,0.0167,0.0126,0.0167,0.0586,0.0669,0.0377,0.0126,0.0042,0.0460,0.0084,0.0335,0.0502,0.0335,0.0628,0.0377,0.0377,0,0.0377,0.0126,0.0084,0.0209,0.0251,0.0586,0.0167,0.0209,0.0042,0.0251,0.0293,0.0335,0.0377,0.0335,0.0129,0.0690,0.0172,0.0388,0.0172,0.0259,0.0172,0.0043,0.0690,0.0129,0.0129,0,0.0474,0.0129},
	{0.0420,0.0126,0.0462,0.0336,0.0546,0.0378,0.0210,0.0042,0.0504,0.0714,0.0378,0.0084,0.0084,0.0168,0.0210,0.0168,0.0252,0.0588,0.0336,0.0756,0.0336,0.0042,0.0252,0.0126,0.0210,0.0084,0.0168,0.0714,0.0084,0.0042,0.0252,0.0168,0.0042,0.0294,0.0252,0.0168,0.0126,0.1050,0.0336,0.0882,0.0378,0.0210,0.0042,0,0.0714,0.0084,0.0084,0,0.0168,0.0210},
	{0.0169,0.0253,0.0211,0.0127,0.0549,0.0506,0.0211,0.0084,0.1013,0.0591,0.0422,0,0.0042,0.0253,0.0042,0.0211,0.0042,0.0675,0.0464,0.0970,0.0338,0.0127,0.0169,0.0338,0.0127,0,0.0295,0.0211,0.0084,0,0.0295,0.0169,0.0042,0.0169,0.0295,0.0506,0.0248,0.0248,0.0124,0.0041,0.0496,0.0248,0.0083,0,0.0579,0.0744,0,0.0124,0.0248,0.0455},
	{0.0044,0.0133,0,0.0267,0.0222,0.0444,0.0044,0.0578,0.1333,0.1111,0.0667,0.0667,0.0044,0.0133,0.0400,0.0044,0.0089,0.0089,0.0267,0.0133,0.0178,0.0089,0,0,0.0311,0.0178,0.0622,0.0756,0.0133,0.0222,0.0356,0.0044,0.0178,0.0044,0.0133,0.0044,0.0130,0,0.0261,0,0.0435,0.0870,0.0565,0.0304,0.1087,0.0870,0.0652,0.0870,0.0130,0.0174},
	{0.0418,0.0377,0.0084,0,0.0167,0.0126,0.0042,0.0084,0.0460,0.0377,0.0502,0.0293,0.0126,0.0544,0.0209,0.0126,0.0460,0.0502,0.0251,0.0293,0.0377,0.0209,0.0251,0.0335,0.0167,0.0084,0.0795,0.1130,0.0126,0.0126,0.0167,0.0209,0.0167,0.0251,0.0126,0.0042,0.0373,0.0083,0,0.0041,0.0124,0.0124,0.0083,0.0166,0.0373,0.0332,0.0290,0.0124,0.0539,0.0166},
	{0.0217,0.0391,0.0435,0.1130,0.0130,0.0304,0.0217,0.0174,0.0478,0.0043,0.0348,0.0043,0.0957,0.0174,0.0304,0.0348,0.0261,0.0261,0.0783,0.0696,0.0217,0.0304,0.0043,0.0043,0.0130,0.0261,0,0,0.0043,0.0565,0.0043,0,0.0087,0.0304,0.0130,0.0130,0.0375,0.0167,0.1083,0.0167,0.0292,0.0583,0.0167,0.0083,0.0042,0.0125,0.0042,0.0208,0.0167,0.0292}};
	double out = 0;
	for(int i=0;i<7;i++)
	{
	    ga_bp.GA_BP_predict(&sa[i][0], &out);
	    printf("out = %.30f\n", out);
	}
	
	ga_bp.GA_BP_free();
	return;
}

#else

void BP_NET::BP_setParams(int sampleNum, int inputDim, int hidenDim, int outputDim, 
						  double thresh_hid = 0, double thresh_out = 0, double eps = 10e-5, 
						  int maxIteration = 500000, double alpha = .8)
{
	this->bp_params.sampleNum    = sampleNum;
	this->bp_params.inputDim     = inputDim;
	this->bp_params.hidenDim     = hidenDim;
	this->bp_params.outputDim    = outputDim;
	this->bp_params.thresh_hid   = thresh_hid;
	this->bp_params.thresh_out   = thresh_out;
	this->bp_params.eps          = eps;
	this->bp_params.maxIteration = maxIteration;
	this->bp_params.alpha        = alpha;

	return;
}
int BP_NET::BP_init()
{
	int size;
	int i;

	size = this->bp_params.inputDim*this->bp_params.hidenDim*sizeof(double);
	if(NULL == (this->bp_params.W_in_hid = (double*)BP_MALLOC(size)))
	{
		return -1;
	}
	/*权重初始化*/
	for(i = 0; i < this->bp_params.inputDim*this->bp_params.hidenDim; i++)
	{
		/*随机很重要,否则会陷入局部极小或极大值,导致网络不收敛,可考虑用遗传算法进行训练*/
		this->bp_params.W_in_hid[i] = rand()%10/10.0;
	}

	size = this->bp_params.hidenDim*this->bp_params.outputDim*sizeof(double);
	if(NULL == (this->bp_params.W_hid_out = (double*)BP_MALLOC(size)))
	{
		return -1;
	}
	/*权重初始化*/
	for(i = 0; i < this->bp_params.hidenDim*this->bp_params.outputDim; i++)
	{ 
		this->bp_params.W_hid_out[i] = rand()%10/10.0;
	}

	size = this->bp_params.hidenDim*sizeof(double);
	if(NULL == (this->bp_params.hidenVector = (double*)BP_MALLOC(size)))
	{
		return -1;
	}
	memset(this->bp_params.hidenVector, 0, size);

	size = this->bp_params.outputDim*sizeof(double);
	if(NULL == (this->bp_params.outputVector = (double*)BP_MALLOC(size)))
	{
		return -1;
	}
	memset(this->bp_params.outputVector, 0, size);

	return 0;
}
void BP_NET::BP_free()
{
	if(NULL != this->bp_params.W_in_hid)
	{
		BP_FREE(this->bp_params.W_in_hid);
	}

	if(NULL != this->bp_params.W_hid_out)
	{
		BP_FREE(this->bp_params.W_hid_out);
	}

	if(NULL != this->bp_params.hidenVector)
	{
		BP_FREE(this->bp_params.hidenVector);
	}
	
	return;
}
int BP_NET::BP_setInOutput(double *input, double *output)
{
	if(NULL == input || NULL == output)
	{
		return -1;
	}
	this->bp_params.inputVector     = input;
	this->bp_params.outputVectorObj = output;

	return 0;
}
void BP_NET::BP_train()
{
	int i, j, k;
	double err = 100000;
	double e = 0;
	int iteration = 0;
	double *input;
	double *output;
	double *err_out = (double*)BP_MALLOC(this->bp_params.outputDim*sizeof(double));
	double *err_hid = (double*)BP_MALLOC(this->bp_params.hidenDim*sizeof(double));
	double *err_hidtemp = (double*)BP_MALLOC(this->bp_params.hidenDim*sizeof(double));

	if(NULL == err_out || NULL == err_hid)
	{
		return;
	}

	while(iteration < this->bp_params.maxIteration && err > this->bp_params.eps)
	{
		printf("it = %d,err = %f\n",iteration,err);
		input = &this->bp_params.inputVector[0];
		output = &this->bp_params.outputVectorObj[0];
		iteration++;
		e = 0;
		for(i = 0; i < this->bp_params.sampleNum; i++)
		{
			/*遍历每一个样本*/
			/*归一化输入向量*/
			double max_input = -1000000;
			double min_input = 1000000;
			
			for(j = 0; j < this->bp_params.inputDim; j++)
			{
				if(input[j] > max_input)
				{
					max_input = input[j];
				}
				if(input[j] < min_input)
				{
					min_input = input[j];
				}
			}
			for(j = 0; j < this->bp_params.inputDim; j++)
			{
				input[j] = input[j]*.005/(max_input - min_input);
			}
			/*正向*/
			/*输入-->隐含层*/
			memset(err_out, 0, this->bp_params.outputDim*sizeof(double));
	        memset(err_hid, 0, this->bp_params.hidenDim*sizeof(double));
			memset(err_hidtemp, 0, this->bp_params.hidenDim*sizeof(double));
			memset(this->bp_params.hidenVector, 0, this->bp_params.hidenDim*sizeof(double));
			memset(this->bp_params.outputVector, 0, this->bp_params.outputDim*sizeof(double));
			for(k = 0; k < this->bp_params.hidenDim; k++)
			{
				for(j = 0; j < this->bp_params.inputDim; j++)
				{
					this->bp_params.hidenVector[k] += this->bp_params.W_in_hid[k*this->bp_params.inputDim + j]*
						                             input[j];
				}
				double vl = this->bp_params.hidenVector[k];
				this->bp_params.hidenVector[k] = TRAN_FUN(this->bp_params.hidenVector[k] - this->bp_params.thresh_hid);
				vl = this->bp_params.hidenVector[k];
			}
			/*隐含-->输出层*/
			for(k = 0; k < this->bp_params.outputDim; k++)
			{
				for(j = 0; j < this->bp_params.hidenDim; j++)
				{
					this->bp_params.outputVector[k] += this->bp_params.W_hid_out[k*this->bp_params.hidenDim + j]*
						                              this->bp_params.hidenVector[j];
				}
				this->bp_params.outputVector[k] = TRAN_FUN(this->bp_params.outputVector[k] - this->bp_params.thresh_out);
			}
			/*反向*/
			for(k = 0; k < this->bp_params.outputDim; k++)
			{
				for(j = 0; j < this->bp_params.hidenDim; j++)
				{
					err_out[k] = -this->bp_params.alpha*(output[k] - this->bp_params.outputVector[k])*
						          this->bp_params.outputVector[k]*this->bp_params.hidenVector[j]*
								 (1-this->bp_params.outputVector[k]);
					err_hidtemp[j]+=this->bp_params.W_hid_out[k*this->bp_params.hidenDim + j]*err_out[k];

				    this->bp_params.W_hid_out[k*this->bp_params.hidenDim + j] = this->bp_params.W_hid_out[k*this->bp_params.hidenDim + j]-err_out[k]; 
				}
			}

			for(k = 0; k < this->bp_params.hidenDim; k++)
			{
				for(j = 0; j < this->bp_params.inputDim; j++)
				{
					err_hid[k] = err_hidtemp[k]*this->bp_params.hidenVector[k]*
						         (1-this->bp_params.hidenVector[k])*input[j];
					this->bp_params.W_in_hid[k*this->bp_params.inputDim + j] = this->bp_params.W_in_hid[k*this->bp_params.inputDim + j] - err_hid[k];
				}
			}

			/*计算误差*/
			for(k = 0; k < this->bp_params.outputDim; k++)
			{
				e += (this->bp_params.outputVector[k] - output[k])*
					  (this->bp_params.outputVector[k] - output[k]);
			}

			input += this->bp_params.inputDim;
		    output += this->bp_params.outputDim;
		}
		e = e/(this->bp_params.outputDim*this->bp_params.sampleNum);
		err = e/2;
	}
	printf("err:%.20f,it:%d\n",err,iteration);

	BP_FREE(err_out);
	BP_FREE(err_hid);

	return;
}
void BP_NET::BP_predict(double *input, double *output)
{
	int i,j;
	double max_input = -1000000;
	double min_input = 1000000;

    
	memset(this->bp_params.hidenVector, 0, this->bp_params.hidenDim*sizeof(double));
	
	for(i = 0; i < this->bp_params.inputDim; i++)
	{
		if(input[i] > max_input)
		{
			max_input = input[i];
		}
		if(input[i] < min_input)
		{
			min_input = input[i];
		}
	}
	for(i = 0; i < this->bp_params.inputDim; i++)
	{
		input[i] = input[i]*.005/(max_input - min_input);
	}

	for(i = 0; i < this->bp_params.hidenDim; i++)
	{
		for(j = 0; j < this->bp_params.inputDim; j++)
		{
			this->bp_params.hidenVector[i] += this->bp_params.W_in_hid[i*this->bp_params.inputDim + j]*
						                     input[j];
		}
		this->bp_params.hidenVector[i] = TRAN_FUN(this->bp_params.hidenVector[i] - this->bp_params.thresh_hid);
	}
	/*隐含-->输出层*/
	for(i = 0; i < this->bp_params.outputDim; i++)
	{
		for(j = 0; j < this->bp_params.hidenDim; j++)
		{
			output[i] += this->bp_params.W_hid_out[i*this->bp_params.hidenDim + j]*
						this->bp_params.hidenVector[j];
		}
		output[i] = TRAN_FUN(output[i] - this->bp_params.thresh_out);
	}

}
void main()
{
	double a = 0;
	BP_NET bp_net;

    double aa[11][50] = {{0.021,0.0297,0.0212,0.017,0.0297,0.0212,0.0127,0.017,0.072,0.0297,0.0593,0.0297,0.0212,0.0212,0.017,0.0127,0.0254,0.0635,0.034,0.0932,0.0127,0.0212,0.025,0.0212,0.0127,0.0212,0.0212,0.0212,0.017,0.0042,0.0254,0.025,0.034,0.0382,0.029,0.0212,0.0297,0.072,0.017,0.072,0.0213,0.0213,0.017,0,0.03,0.03,0.03,0.021,0.021,0.0383},
	{0.0260,0.0087,0.0606,0.0216,0.0693,0.0390,0.0216,0.0216,0.0649,0.0693,0.0303,0.0087,0.0130,0.0390,0,0.0260,0.0303,0.0303,0.0346,0.0606,0.0130,0.0130,0.0303,0.0303,0.0130,0.0303, 0.0087,0.0173,0.0087,0.0043,0.0303,0.0390,0.0087,0.0216,0.0260,0.0303,0.0086,0.0819,0.0216,0.0690,0.0388,0.0216,0.0216,0.0129,0.0690,0.0388,0.0086,0.0129,0.0388,0.0345},
	{0.0573,0.0176,0.0176,0,0.0308,0.0220,0,0.0220,0.1101,0.0793,0.0308,0.0441,0.0088,0.0573,0,0.0308,0.0220,0.0485,0.0661,0.0088,0,0,0.0220,0.0132,0.0264,0.0352,0.0661,0.0793,0,0,0.0264,0.0176,0.0044,0,0.0088,0.0264,0.0175,0.0219,0,0.0088,0.0219,0.0351,0.0219,0.0439,0.0789,0.0965,0.0439,0.0921,0.0570,0.0219},
	{0.0472,0.0215,0.0086,0.0172,0.0343,0.0086,0.0043,0.0129,0.0429,0.0429,0.0472,0.0043,0,0.0429,0.0086,0.0215,0.0515,0.0558,0.0558,0.0472,0.0343,0.0043,0.0558,0.0172,0.0129,0.0129,0.0386,0.0558,0.0043,0.0386,0.0215,0.0429,0.0172,0.0300,0.0043,0.0343,0.0211,0.0253,0.0169,0.0169,0.0084,0.0169,0.0127,0.0295,0.0422,0.0380,0.0042,0.0422,0.0422,0.0211},
	{0.0125,0.0583,0.0458,0.0250,0.0083,0.0208,0.0083,0.0250,0.0708,0.0208,0.0333,0.0250,0.0458,0.0083,0.0125,0.0125,0.0542,0.0500,0.0333,0.0417,0.0167,0.0042,0.0125,0.0083,0,0.0125,0.0208,0.0583,0.0167,0.0250,0.0208,0.0250,0.0292,0.0500,0.0542,0.0333,0.0593,0.0551,0.0254,0.0763,0.0212,0.0212,0.0254,0.0212,0.0212,0.0254,0.0254,0.0127,0.0085,0.0169},
	{0.0042,0.0549,0.0464,0.0084,0.0084,0.0338,0.0464,0.0169,0.0464,0.0042,0.0380,0.0717,0.0084,0.0169,0.0127,0.0127,0.0253,0.0295,0.0253,0.0253,0.0084,0.0127,0,0.0169,0.0506,0,0.0169,0.0422,0.0802,0.0591,0.0422,0.0464,0.0169,0.0380,0.0211,0.0127,0.0542,0,0.0083,0,0.0333,0.0208,0.0167,0.0042,0.0042,0.0583,0.0708,0.0792,0.0167,0.0167},
	{0.0171,0.0256,0.0256,0.0342,0.0128,0,0.0256,0.0299,0.0342,0.0085,0.0641,0.0556,0.0043,0,0.0128,0.0043,0.0342,0.0299,0.0684,0.0171,0.0598,0.0342,0.0085,0.0171,0.0427,0.1154,0.0085,0.0128,0.0043,0.0427,0.0299,0.0641,0.0256,0,0.0171,0.0128,0.0253,0,0.0338,0.0084,0,0,0.0295,0.0380,0.0084,0.0084,0.0549,0.0464,0,0.0084},
	{0,0,0,0.0356,0,0.0267,0.0133,0.0089,0.0489,0.1067,0.0711,0.0533,0.0756,0.0178,0.0222,0.0178,0.1156,0.0133,0.0222,0.0178,0,0,0.0044,0.0222,0,0.0267,0.0578,0.0667,0.0133,0.0533,0.0489,0.0044,0.0267,0.0044,0.0044,0,0,0.0370,0.0370,0,0.0278,0.0093,0.0093,0.0185,0.1111,0.0463,0.0556,0.0602,0.0185,0.0694},
	{0.0101,0,0,0,0.0152,0.0455,0.0051,0.0202,0.0404,0.1111,0.1616,0.1364,0.0202,0.0152,0,0.0051,0.0152,0.0303,0.0202,0.0152,0,0.0202,0.0101,0,0.0051,0.0202,0.0859,0.1162,0.0202,0.0303,0.0202,0.0051,0,0,0,0,0,0.0489,0,0.0133,0.0400,0.0978,0.0178,0.0756,0.0978,0.0222,0.1200,0.0444,0.0133,0.0178},
	{0.0418,0.0377,0.0084,0,0.0167,0.0126,0.0042,0.0084,0.0460,0.0377,0.0502,0.0293,0.0126,0.0544,0.0209,0.0126,0.0460,0.0502,0.0251,0.0293,0.0377,0.0209,0.0251,0.0335,0.0167,0.0084,0.0795,0.1130,0.0126,0.0126,0.0167,0.0209,0.0167,0.0251,0.0126,0.0042,0.0373,0.0083,0,0.0041,0.0124,0.0124,0.0083,0.0166,0.0373,0.0332,0.0290,0.0124,0.0539,0.0166},
	{0.0217,0.0391,0.0435,0.1130,0.0130,0.0304,0.0217,0.0174,0.0478,0.0043,0.0348,0.0043,0.0957,0.0174,0.0304,0.0348,0.0261,0.0261,0.0783,0.0696,0.0217,0.0304,0.0043,0.0043,0.0130,0.0261,0,0,0.0043,0.0565,0.0043,0,0.0087,0.0304,0.0130,0.0130,0.0375,0.0167,0.1083,0.0167,0.0292,0.0583,0.0167,0.0083,0.0042,0.0125,0.0042,0.0208,0.0167,0.0292}};
	double bb[11] = {1,1,1,1,1,0,0,0,0,1,1};

	bp_net.BP_setParams(11, 50, 40, 1);
	if(-1 == bp_net.BP_init())
	{
		printf("malloc error!!\n");
		return;
	}
	
	bp_net.BP_setInOutput(&aa[0][0], &bb[0]);
	bp_net.BP_train();

	double sa[5][50] = {{0.0083,0.0207,0.0124,0.0124,0.0041,0.0537,0.0207,0.0372,0.0372,0.0455,0.0455,0.0289,0.0207,0.0083,0.0455,0.0165,0.0785,0.0289,0.0331,0.0289,0,0.0165,0.0207,0.0372,0.0083,0.0289,0.0372,0.0372,0.0537,0.0372,0.0248,0.0248,0.0496,0.0124,0.0083,0.0165,0.0213,0.0213,0.0128,0.0128,0.0553,0.0170,0.0383,0.0298,0.0468,0.0298,0.0298,0.0553,0.0085,0.0340},
	{0.0126,0.0126,0.0251,0.0167,0.0335,0.0167,0.0126,0.0167,0.0586,0.0669,0.0377,0.0126,0.0042,0.0460,0.0084,0.0335,0.0502,0.0335,0.0628,0.0377,0.0377,0,0.0377,0.0126,0.0084,0.0209,0.0251,0.0586,0.0167,0.0209,0.0042,0.0251,0.0293,0.0335,0.0377,0.0335,0.0129,0.0690,0.0172,0.0388,0.0172,0.0259,0.0172,0.0043,0.0690,0.0129,0.0129,0,0.0474,0.0129},
	{0.0420,0.0126,0.0462,0.0336,0.0546,0.0378,0.0210,0.0042,0.0504,0.0714,0.0378,0.0084,0.0084,0.0168,0.0210,0.0168,0.0252,0.0588,0.0336,0.0756,0.0336,0.0042,0.0252,0.0126,0.0210,0.0084,0.0168,0.0714,0.0084,0.0042,0.0252,0.0168,0.0042,0.0294,0.0252,0.0168,0.0126,0.1050,0.0336,0.0882,0.0378,0.0210,0.0042,0,0.0714,0.0084,0.0084,0,0.0168,0.0210},
	{0.0169,0.0253,0.0211,0.0127,0.0549,0.0506,0.0211,0.0084,0.1013,0.0591,0.0422,0,0.0042,0.0253,0.0042,0.0211,0.0042,0.0675,0.0464,0.0970,0.0338,0.0127,0.0169,0.0338,0.0127,0,0.0295,0.0211,0.0084,0,0.0295,0.0169,0.0042,0.0169,0.0295,0.0506,0.0248,0.0248,0.0124,0.0041,0.0496,0.0248,0.0083,0,0.0579,0.0744,0,0.0124,0.0248,0.0455},
	{0.0044,0.0133,0,0.0267,0.0222,0.0444,0.0044,0.0578,0.1333,0.1111,0.0667,0.0667,0.0044,0.0133,0.0400,0.0044,0.0089,0.0089,0.0267,0.0133,0.0178,0.0089,0,0,0.0311,0.0178,0.0622,0.0756,0.0133,0.0222,0.0356,0.0044,0.0178,0.0044,0.0133,0.0044,0.0130,0,0.0261,0,0.0435,0.0870,0.0565,0.0304,0.1087,0.0870,0.0652,0.0870,0.0130,0.0174}};
	
	double out = 0;
	bp_net.BP_predict(sa[0], &out);
	printf("out = %f\n", out);
	out = 0;
    bp_net.BP_predict(sa[1], &out);
	printf("out = %f\n", out);
	out = 0;
    bp_net.BP_predict(sa[2], &out);
	printf("out = %f\n", out);
	out = 0;
    bp_net.BP_predict(sa[3], &out);
	printf("out = %f\n", out);
	out = 0;
    bp_net.BP_predict(sa[4], &out);
	printf("out = %f\n", out);
	bp_net.BP_free();
}
#endif



    

  • 13
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值