BP.C
上传用户:bjtelijie
上传日期:2010-01-01
资源大小:87k
文件大小:5k
源码类别:

数学计算

开发平台:

Visual C++

  1. #include "math.h"
  2. #include "time.h"
  3. #include "stdio.h"
  4. #include "stdlib.h"
  5. #define Ni 1
  6. #define Nm 4
  7. #define No 1
  8. #define L 100
  9. #define Enom 0.02
  10. #define loopmax 100000
  11. #define e 2.71828
  12. double E;
  13. double a,u,n;
  14. double W1[Ni][Nm],D1[Ni][Nm],W2[Nm][No],D2[Nm][No];
  15. double D22[Nm][No],D11[Ni][No];
  16. double a1[Ni][Nm],a2[Nm][No];
  17. double Pi[L][Ni],Pm[L][Nm],Po[L][No],T[L][No];
  18. double Xm[L][Nm],Xo[L][No];
  19. double Qm[L][Nm],Qo[L][No];
  20. void proceed();
  21. void proceedR();
  22. void forQ();
  23. void amend();
  24. void initiate();
  25. double newa(double a,double D);
  26. double cal(double d);
  27. double vcal(double d);
  28. main()
  29. {
  30.     long int i;
  31. int flag;
  32. char choice;
  33.     for(;;)
  34. {
  35. flag=0;
  36. initiate();
  37. for(i=0;;i++)
  38. {
  39. proceed();
  40. if( E < Enom )
  41. flag=1;
  42. break;
  43. }
  44. if( i >= loopmax)
  45. {
  46. flag = -1;
  47. break;
  48. }
  49. if(i%2500==0)
  50. printf("第%10d轮误差:%20f,学习速率:%10fn",i,E,a1[0][0]);
  51. forQ();
  52. amend();
  53. }
  54. if(flag>0)proceedR();
  55. else printf("训练失败!n");
  56. for(;;)
  57. {
  58. choice=getchar();
  59. printf("是否继续?(Y/N)n");
  60. choice=getchar();
  61. choice=toupper(choice);
  62. if(choice=='Y')break;
  63. if(choice=='N')exit(0);
  64. }
  65. }
  66. }
  67. void initiate()
  68. {
  69. int i,j;
  70. int random;
  71. double x;
  72. double step;
  73. int stime;
  74. long ltime;
  75. ltime=time(NULL);
  76. stime=(unsigned)ltime/2;
  77. srand(stime);
  78. a=0.02;
  79. u=1;
  80.     n=1;
  81. printf("本程序将用BP神经网络拟合函数:Y=sin(X)nn");
  82. for( i=0; i<Nm; i++)
  83. {
  84. for( j=0; j<Ni; j++)
  85. {
  86. random=rand()%100-50;
  87. x=random;
  88. x=x/100;
  89. W1[j][i]=x;
  90. D11[j][i]=0;
  91. D1[j][i]=0;
  92. a1[j][i]=0.01;
  93. }
  94. for( j=0; j<No; j++)
  95. {
  96. random=rand()%100-50;
  97. x=random;
  98. x=x/100;
  99. W2[i][j]=x;
  100. D22[i][j]=0;
  101. D2[i][j]=0;
  102. a2[i][j]=0.01;
  103. }
  104. }
  105.     step=1.0/L;
  106. for(i=0;i<L;i++)
  107. {
  108. x=i;
  109. Pi[i][0]=x*step;
  110. T[i][0]=sin(Pi[i][0]);
  111. }
  112. printf("初始化成功!nn下面将对神经网络进行训练请稍候。n");
  113. }
  114. void proceed()
  115. {
  116. int i, j, k;
  117. E=0 ;
  118. for( i=0; i<L; i++ )
  119. {
  120. for( j=0; j<Nm; j++ )
  121. {
  122. Pm[i][j] = 0;
  123. for( k=0; k<Ni; k++ )
  124. {
  125. Pm[i][j] = Pi[i][k] * W1[k][j] + Pm[i][j];
  126. }
  127. Xm[i][j] = cal( Pm[i][j] );
  128. }
  129. for( j=0; j<No; j++)
  130. {
  131. Po[i][j] = 0;
  132. for( k=0; k<Nm; k++)
  133. {
  134. Po[i][j] = Xm[i][k] * W2[k][j] + Po[i][j];
  135. }
  136. Xo[i][j] = cal( Po[i][j] );
  137.     E = E + ( Xo[i][j] - T[i][j] ) * ( Xo[i][j] - T[i][j] ) / 2;
  138. }
  139. }
  140. }
  141. void forQ()
  142. {
  143. int i,j,k;
  144. for( i=0; i<L; i++ )
  145. {
  146. for( j=0; j<No; j++)
  147. {
  148. Qo[i][j] = ( T[i][j] - Xo[i][j] )* vcal( Xo[i][j] );
  149. }
  150. for(j=0; j<Nm; j++)
  151. {
  152. Qm[i][j]=0;
  153. for( k=0; k<No; k++)
  154. {
  155. Qm[i][j] = Qo[i][k] * W2[j][k] + Qm[i][j];
  156. }
  157. Qm[i][j] = Qm[i][j] * vcal( Xm[i][j] );
  158. }
  159. }
  160. }
  161. void amend()
  162. {
  163. int i,j,k;
  164. double D;
  165. for( i=0; i<Nm; i++)
  166. {
  167. for( j=0; j<Ni; j++)
  168. {
  169. D1[j][i]=0;
  170. }
  171. for( j=0; j<No; j++)
  172. {
  173. D2[i][j]=0;
  174. }
  175. }
  176. for( i=0; i<Ni; i++)
  177. {
  178. for( j=0; j<Nm; j++)
  179. {
  180. for( k=0; k<L; k++)
  181. {
  182. D1[i][j] = Qm[k][j] * Pi[k][i] + D1[i][j];
  183. }
  184.              D = D1[i][j] * D11[i][j]  ;//为D11付初值
  185.  a1[i][j] = newa( a1[i][j] , D );  // a 付初值
  186.  W1[i][j] = W1[i][j] + a1[i][j] * ( n * D1[i][j] + ( 1 - n ) * D11[i][j] );
  187.  D11[i][j] = D1[i][j];
  188. }
  189. }
  190.     for( i=0; i<Nm; i++)
  191. {
  192. for( j=0; j<No; j++)
  193. {
  194. for( k=0; k<L; k++)
  195. {
  196. D2[i][j] = Qo[k][j] * Xm[k][i] + D2[i][j];
  197. }
  198. D = D2[i][j] * D22[i][j]  ;//为D11付初值
  199.             a2[i][j] = newa( a2[i][j] , D ); 
  200. W2[i][j] = W2[i][j] + a2[i][j] * ( n * D2[i][j] + ( 1 - n ) * D22[i][j] );
  201. D22[i][j] = D2[i][j];
  202. }
  203. }
  204. }
  205.  void proceedR()
  206. {
  207. int i, j;
  208. float x;
  209. double input,output;
  210. char choice;
  211. for(;;)
  212. {
  213. for(;;)
  214. {
  215. printf("在此输入需要计算的值(0,1):n");
  216. scanf("%f",&x);
  217. input=(double)x;
  218. if((input>=0)&(input<=1))break;
  219. printf("注意输入值应介于0、1之间!n");
  220. for(;;)
  221. {
  222. choice=getchar();
  223. printf("是否继续?(Y/N)n");
  224. choice=getchar();
  225. choice=toupper(choice);
  226. if(choice=='Y')break;
  227. if(choice=='N')exit(0);
  228. }
  229. }
  230. for(i=0;i<Nm;i++)
  231. {
  232. Pm[0][i]=0;
  233. for( j=0; j<Ni; j++ )
  234. {
  235. Pm[0][i] =  input* W1[j][i]+Pm[0][i] ;
  236. }
  237. Xm[0][i] = cal( Pm[0][i] );
  238. }
  239. for( i=0; i<No; i++)
  240. {
  241. Po[0][i] = 0;
  242. for( j=0; j<Nm; j++)
  243. {
  244. Po[0][i] = Xm[0][j] * W2[j][i]+Po[0][i];
  245. }
  246. }
  247. output=cal( Po[0][0] );
  248. printf("输入值为%20f对应的结果为%fn",input,output);
  249. printf("输入值为%20f对应的正常结果为%fn",input,sin(input));
  250. for(;;)
  251. {
  252. choice=getchar();
  253. printf("是否继续?(Y/N)n");
  254. choice=getchar();
  255. choice=toupper(choice);
  256. if(choice=='Y')break;
  257. if(choice=='N')exit(0);
  258. }
  259. }
  260. }
  261. double newa(double a, double D)
  262. {
  263. if( D > 0 )
  264. {
  265. {
  266. if(a<=0.04)
  267. a = a * 2;
  268. else a=0.08;
  269. }
  270. }
  271. else
  272. if ( D < 0)
  273. {
  274. if(a>=0.02)
  275. {
  276. a = a / 2;
  277. }
  278. else a=0.01;
  279. }
  280. return a;
  281. }
  282. double cal(double d)
  283. {
  284. d =  - (d * u);                                //              chushihua 
  285. d = exp( d );
  286. d = 1 / ( 1 + d );
  287. return d;
  288. }
  289. double vcal(double d)
  290. {
  291. return u * d * ( 1 - d );
  292. }