#include <iostream>
using namespace std;
//向量维度
int dimention=2;
//样本数
int n=4;
//样本
double inputLayer[4][2]={{5,1},{10,5},{1,10},{10,1}};
////初始网络参数 内部强度值为 weight[2]=1;
double weight[3]={1,1,1};
//先验信息标签即分类
int label[4]={1,1,1,-1};
//学习速度
double yita=0.1;
//感知器输出函数
double outputLayer(double* w , double *p)
{
return w[0]*p[0]+w[1]*p[1]+w[2];
}
//判别函数
int Sign(double a)
{
if(a>=0) return 1;
else return -1;
}
//权值修正函数
double amendW( double w,double e,double p,double yita)
{
return w+yita*e*p;
}
//误差修正函数
double amendE( double b,double e)
{
return b+e;
}
void main()
{
double error; //误差
double output[4];//= new double [n]; //网络输出
int discriminant[4];// = new int [n];//判别值
bool stop[5];//=new bool [n+1];//训练终止条件stop[4]=stop[0]&&stop[1]&&stop[2]&&stop[3]==true;
//初始化终止条件
for(int i=0;i<n+1;i++)
{ stop[i]=false;}
int k=0;//循环控制变量
while(stop[n]==false)//循环开始
{
for(int ii=k;ii<k+n;ii++)//从第k个开始,做n个点循环
{
int i=ii%n;//对n个点循环往复使得输入点首尾相连可无限循环
bool changed=false;//权值是否有修改
static int count=0;//循环计数器
while(stop[i]==false)//当前样本点是否处理完成
{
cout<<count++<<endl;//输出计数的次数 可注释掉
output[i]= outputLayer(weight,inputLayer[i]);//计算网络输出
discriminant[i]=Sign( output[i]);//判别函数判断输出
stop[i]=(discriminant[i]==label[i]);//判别函数判断结果是否与标签一致
if(stop[i]){break;}//一致则退出当前循环
//不一致则 修正权值
error=label[i]-discriminant[i];//先计算强度
for(int m=0;m<dimention;m++)
weight[m]=amendW(weight[m],error,inputLayer[i][m],yita);//循环修正权值
weight[2]=amendE(weight[2],error);//修正强度
changed=true;//有修正则记录
}
if(changed)//运行到此处,对当前点的修正已经完成,如果有修正则设置其它剩余点的状态为不符合终止条件
{
for(int iii=1;iii<n;iii++)//记录其它点为未修正
stop[(iii+i)%n]=false;
k=(ii+1)%n;//当前点的网络参数已经合适,跳至下一点
break;//跳出循环
}
}
//记算终止条件
stop[n]=stop[0];
for(int i=0;i<n;i++)
stop[n]=stop[n]&&stop[i];
}
}
运行结果如下图所示:

9次循环就收敛到合适的结果了, 收敛速度可以通过yita进行控制。为了便于调试采用固定大小数组形式设计,后期为了方便可改用new来分配动态大小数组。注意误差收敛速度,与权值收敛速度,可不一致
浙公网安备 33010602011771号