📄 bp1.cpp
字号:
//BP算法
//学习标准sin曲线(y=sin(x)),BP网络见报告
//2004.11.23
//interma
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define PI 3.14159
#define E 2.71828
#define N 20 // 隐层的节点数目
#define M 100 // 标准样本的数目(5 * M)
//共5 * M个学习样本
double in[M][5][2]; //标准样本的输入
double out[M][5][2]; //标准样本的期待输出
//权值
double wl[2][N];
double wr[N][2];
double F(double x); //f(x)=1/(1+e^(-x))
double Fd(double x); //f`(x)= e^(-x)/(1+e^(-x))^2
double Random(); //返回0~1之间的数
void Init(void); //初始化标准样本
void Study(int n); //学习标准样本, 输入为学习次数
bool IsIn(double x, double y); //判定是否在sin曲线上
int main(void)
{
srand((unsigned)time( NULL));
Init();
int n;
printf("请输入学习次数(推荐不要超过100次):\n");
scanf("%d", &n);
Study(n);
printf("学习完毕!\n");
do
{
double x;
printf("请输入点的X坐标:\n");
scanf("%lg", &x);
double y;
printf("请输入点的Y坐标:\n");
scanf("%lg", &y);
if (IsIn(x, y))
printf("此点在sin曲线上!\n");
else
printf("此点不在sin曲线上!\n");
}
while (true);
}
double F(double x)
{
double d = pow(E, -x);
return 1 / (d + 1);
}
double Fd(double x)
{
double d = pow(E, -x);
return d / pow((1 + d), 2);
}
double Random()
{
double d = (rand() * 1.0) / RAND_MAX;
return d;
}
void Init(void)
{
double d = (2 * PI) / (M);
for (int i = 0; i < M; i++)
{
in[i][0][0] = d * (i);
in[i][0][1] = sin(d * (i)) + 0.4;
out[i][0][0] = 0;
out[i][0][1] = 1;
in[i][1][0] = d * (i);
in[i][1][1] = sin(d * (i)) + 0.1;
out[i][1][0] = 0.5;
out[i][1][1] = 0.5;
in[i][2][0] = d * (i);
in[i][2][1] = sin(d * (i));
out[i][2][0] = 1;
out[i][2][1] = 0;
in[i][3][0] = d * (i);
in[i][3][1] = sin(d * (i)) - 0.1;
out[i][3][0] = 0.5;
out[i][3][1] = 0.5;
in[i][4][0] = d * (i);
in[i][4][1] = sin(d * (i)) - 0.4;
out[i][4][0] = 0;
out[i][4][1] = 1;
}
for (int i = 0; i < 2; i++)
{
for (int j=0; j < N; j++)
{
wl[i][j] = Random();
wr[j][i] = Random();
}
}
}
void Study(int n)
{
while (n-- > 0)
{
for (int i = 0; i < M; i++)
{
double e5 = 0;
for (int j = 0; j < 5; j++)
{
double x1 = in[i][j][0];
double x2 = in[i][j][1];
double h[N];
for (int k = 0; k < N; k++)
{
h[k] = F(x1) * wl[0][k] + F(x2) * wl[1][k];
}
double u = 0;
double v = 0;
for (int k = 0; k < N; k++)
{
u += F(h[k]) * wr[k][0];
v += F(h[k]) * wr[k][1];
}
double y1 = F(u);
double y2 = F(v);
double e = (pow(out[i][j][0] - y1, 2) + pow(out[i][j][1] - y2, 2)) / 2;
e5 += e;
double du = (out[i][j][0] - y1) * Fd(u);
double dv = (out[i][j][1] - y2) * Fd(v);
double dh[N];
for (int k = 0; k < N; k ++)
{
dh[k] = (du * wr[k][0] + dv * wr[k][1]) * Fd(h[k]);
}
for (int k = 0; k< N; k++)
{
wr[k][0] -= du * F(h[k]);
wr[k][1] -= dv * F(h[k]);
wl[0][k] -= dh[k] * F(x1);
wl[1][k] -= dh[k] * F(x2);
}
}
if (e5 < 0.0001)
goto End;
}
}
End: ;
}
bool IsIn(double x, double y)
{
double x1 = x;
double x2 = y;
double h[N];
for (int k = 0; k < N; k++)
{
h[k] = F(x1) * wl[0][k] + F(x2) * wl[1][k];
}
double u = 0;
double v = 0;
for (int k = 0; k < N; k++)
{
u += F(h[k]) * wr[k][0];
v += F(h[k]) * wr[k][1];
}
double y1 = F(u);
double y2 = F(v);
if (y1 >= y2)
return true;
else
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -