📄 sofm-2.cpp
字号:
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
double AbsoluteValue(double n);
double Initialize(double w);
void main()
{
int K,K1; //第K组输入P[i][K];K=1~q
int i,j; //输入层第i个值,竞争层第j个神经元
int q=5; //输入的组数为q个组
double P[20]; //输入向量
int t,T=100; //学习次数其中1000次是粗调和细调的分界
int N,M,m; //输入层为N个神经元,竞争层为M=m*m个神经元
int G,d,p; //确定获胜神经元为第G个,d中间计算量,p为选择换行位置的量
double g[500]; //学习速率g[t]
double W[10][100],D[100]; //权值向量W[i][j],欧氏距离向量
int SumOfP=0; //输入向量的模,用于归一化
double SumOfWeight=0,SumOfD=0,X; //权值向量的模,用于归一化;欧氏距离中间用到量
int NG[500]; //领域NG[t],以G为中心包含若干个神经元的区域范围
///////////////////////////////////////////////////
//举例设定一些初值
K=0; K1=0;
N=3;
m=4;
M=m*m;
p=0;
///////////////////////////////////////////////////
//初始化:W[i][j];G[0];NG[0];T
std::cout<<"权值初始化如下"<<endl;
for(i=0;i<N;i++)
for(j=0;j<M;j++)
{
W[i][j]=Initialize(W[i][j]);
std::cout<<"W["<<i<<"]["<<j<<"]="<<setprecision(5)<<W[i][j]<<" ";
p++;
if(p%N==0)
std::cout<<endl;
}
g[0]=0.5;
NG[0]=M;
///////////////////////////////////////////////////
//条件判断
do
{
///////////////////////////////////////////////////
////输入P[K][NUM];归一化;NUM++
std::cout<<"第"<<K1<<"组输入"<<endl;
std::cout<<"输入层共"<<N<<"个值"<<endl;
for(K=0;K<N;K++)
{
std::cout<<"请输入第"<<K<<"个值";
std::cin>>P[K];
}
for(K=0;K<N;K++)
{
SumOfP+=P[K]*P[K];
}
SumOfP=sqrt(SumOfP);
std::cout<<"输入归一化处理结果:"<<endl;
for(K=0;K<N;K++)
{
P[K]=P[K]/SumOfP;
std::cout<<P[K]<<endl;
}
t=0;
do
{
t++;
////////////////////////////////////////////////////
//处理权值W[i][j],并且对其归一化
for(j=0;j<M;j++)
{
for(i=0;i<N;i++)
{
SumOfWeight+=W[i][j]*W[i][j];
}
}
SumOfWeight=sqrt(SumOfWeight);
std::cout<<"权值归一化处理结果:"<<endl;
for(j=0;j<M;j++)
{
p=0;
for(i=0;i<N;i++)
{
W[i][j]=W[i][j]/SumOfWeight;
std::cout<<"W["<<i<<"]["<<j<<"]="<<setprecision(5)<<W[i][j]<<" ";
p++;
if(p%N==0)
std::cout<<endl;
}
}
//////////////////////////////////////////////////////
//计算欧氏距离,找出最小距离,确定获胜神经元G
std::cout<<"找出最小欧氏距离,确定神经元G"<<endl;
p=0;
for (j=0;j<M;j++)
{
for(i=0;i<N;i++)
{
SumOfD+=(P[i]-W[i][j])*(P[i]-W[i][j]);
}
D[j]=sqrt(SumOfD);
std::cout<<"D["<<j<<"]"<<D[j]<<" ";
p++;
if(p%N==0)
std::cout<<endl;
}
d=1;
for (j=0;j<M;j++)
{
if(D[j+1]<D[j])
d=j+1;
}
G=d;
std::cout<<"获胜神经元是第"<<G<<"个"<<endl;
/////////////////////////////////////////////////////////
//更新学习效率g[t]领域NG[t]
X=t/T;
g[t]=g[0]*(1-X);
NG[t]=int (NG[0]*(1-t/T));
/////////////////////////////////////////////////////////
//对竞争层领域 NG[t]内的所有神经元与输入层神经元之间的连接权进行修正
std::cout<<"权值修正第"<<t<<"次处理结果:"<<endl;
p=0;
for(j=0;j<M;j++)
{
for(i=0;i<N;i++)
{
W[i][j]+=g[t]*(P[i]-W[i][j]);
std::cout<<"W["<<i<<"]["<<j<<"]="<<setprecision(5)<<W[i][j]<<" ";
p++;
if(p%N==0)
std::cout<<endl;
}
}
std::cout<<endl;
//////////////////////////////////////////////////////////
//判别是否完成
}while(t!=T);
K1++;
}while(K1!=q);
}
double AbsoluteValue(double n)
{
if(n<0) n=-n;
return n;
}
double Initialize(double w)
{
w=AbsoluteValue(cos(rand()%360));
return w;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -