ga.c
上传用户:bjtelijie
上传日期:2010-01-01
资源大小:87k
文件大小:7k
源码类别:

数学计算

开发平台:

Visual C++

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #define SUM 20            //总共的染色体数量
  6. #define MAXloop 1200       //最大循环次数
  7. #define error 0.01        //若两次最优值之差小于此数则认为结果没有改变
  8. #define crossp 0.7        //交叉概率
  9. #define mp 0.04           //变异概率
  10. struct gen                //定义染色体结构
  11. {
  12. int info;        
  13. float suitability;
  14. };
  15. struct gen gen_group[SUM];//定义一个含有20个染色体的组
  16. struct gen gen_new[SUM];  
  17. struct gen gen_result;    //记录最优的染色体
  18. int result_unchange_time; //记录在error前提下最优值为改变的循环次数
  19. struct log                //形成链表,记录每次循环所产生的最优的适应度
  20. {
  21. float suitability;
  22. struct log *next;
  23. }llog,*head,*end;
  24. int log_num;              //链表长度
  25. void initiate();          
  26. void evaluation(int flag);
  27. void cross();
  28. void selection();
  29. int  record();
  30. void mutation();
  31. void showresult(int);
  32. int   randsign(float p);
  33. int   randbit(int i,int j);
  34. int   randnum();
  35. int   convertionD2B(float x);
  36. float convertionB2D(int x);
  37. int   createmask(int a);
  38. void main()
  39. {
  40. int i,flag;
  41. flag=0;
  42. initiate();
  43.     evaluation( 0 );
  44. for( i = 0 ; i < MAXloop ; i++ )
  45. {
  46. cross();
  47. evaluation( 1 );
  48. selection();
  49. if( record() == 1 )
  50. {
  51. flag = 1;
  52. break;
  53. }
  54. mutation();
  55. }
  56. showresult( flag );
  57. }
  58. void initiate()
  59. {
  60. int i , stime;
  61. long ltime;
  62. ltime=time(NULL);
  63. stime=(unsigned)ltime/2;
  64. srand(stime);
  65. for( i = 0 ; i < SUM ; i++ )
  66. {
  67. gen_group[i].info = randnum();  
  68. }
  69. gen_result.suitability=1000;
  70. result_unchange_time=0;
  71. head=end=(struct log *)malloc(sizeof(llog));
  72. if(head==NULL)
  73. {
  74. printf("n内存不够!n");
  75. exit(0);
  76. }
  77. end->next = NULL;
  78. log_num = 1;
  79. }
  80. void evaluation(int flag)
  81. {
  82. int i,j;
  83. struct gen *genp;
  84. int gentinfo;
  85. float gentsuitability;
  86. float x;
  87. if( flag == 0 )
  88. genp = gen_group;
  89. else genp = gen_new;
  90. for(i = 0 ; i < SUM ; i++)//计算各染色体对应的表达式值
  91. {
  92. x = convertionB2D( genp[i].info );
  93. genp[i].suitability = x*(x*(x*(x*(x*(x-10)-26)+344)+193)-1846)-1680;
  94. }
  95. for(i = 0 ; i < SUM - 1 ; i++)//按表达式的值进行排序,
  96. {
  97. for(j = i + 1 ; j < SUM ; j++)
  98. {
  99. if( genp[i].suitability > genp[j].suitability )
  100. {
  101. gentinfo = genp[i].info;
  102. genp[i].info = genp[j].info;
  103. genp[j].info = gentinfo;
  104. gentsuitability = genp[i].suitability;
  105. genp[i].suitability = genp[j].suitability;
  106. genp[j].suitability = gentsuitability;
  107. }
  108. }
  109. }
  110. }
  111. void cross()
  112. {
  113. int i , j , k ;
  114. int mask1 , mask2;
  115. int a[SUM];
  116. for(i = 0 ; i < SUM ; i++)  a[i] = 0;
  117. k = 0;
  118. for(i = 0 ; i < SUM ; i++)
  119. {
  120. if( a[i] == 0)
  121. {
  122. for( ; ; )//随机找到一组未进行过交叉的染色体与a[i]交叉
  123. {
  124.     j = randbit(i + 1 , SUM - 1);
  125. if( a[j] == 0) break;
  126. }
  127. if(randsign(crossp) == 1)
  128. {
  129. mask1 = createmask(randbit(0 , 14));
  130. mask2 = ~mask1;
  131. gen_new[k].info = (gen_group[i].info) & mask1 + (gen_group[j].info) & mask2;
  132. gen_new[k+1].info=(gen_group[i].info) & mask2 + (gen_group[j].info) & mask1;
  133. k = k + 2;
  134. }
  135. else 
  136. {
  137. gen_new[k].info=gen_group[i].info;
  138. gen_new[k+1].info=gen_group[j].info;
  139. k=k+2;
  140. }
  141. a[i] = a[j] = 1;
  142. }
  143. }
  144. }
  145. void selection()
  146. {
  147. int i , j , k;
  148. j = 0;
  149. i = SUM/2-1;
  150. if(gen_group[i].suitability < gen_new[i].suitability)
  151. {
  152. for(j = 1 ; j < SUM / 2 ; j++)
  153. {
  154. if(gen_group[i+j].suitability > gen_new[i-j].suitability)
  155. break;
  156. }
  157. }
  158. else
  159. if(gen_group[i].suitability>gen_new[i].suitability)
  160. {
  161. for(j=-1;j>-SUM/2;j--)
  162. {
  163. if(gen_group[i+j].suitability<=gen_new[i-j].suitability)
  164. break;
  165. }
  166. }
  167. for(k=j;k<SUM/2+1;k++)
  168. {
  169. gen_group[i+k].info = gen_new[i-k].info;
  170. gen_group[i+k].suitability = gen_new[i-k].suitability;
  171. }
  172. }
  173. int record()
  174. {
  175. float x;
  176. struct log *r;
  177. r=(struct log *)malloc(sizeof(llog));
  178. if(r==NULL)
  179. {
  180. printf("n内存不够!n");
  181. exit(0);
  182. }
  183. r->next = NULL;
  184. end->suitability = gen_group[0].suitability;
  185. end->next = r;
  186. end = r;
  187. log_num++;
  188. x = gen_result.suitability - gen_group[0].suitability;
  189. if(x < 0)x = -x;
  190. if(x < error)
  191. {
  192. result_unchange_time++;
  193. if(result_unchange_time >= 20)return 1;
  194. }
  195. else
  196. {
  197. gen_result.info = gen_group[0].info;
  198. gen_result.suitability = gen_group[0].suitability;
  199. result_unchange_time=0;
  200. }
  201. return 0;
  202. }
  203. void mutation()
  204. {
  205. int i , j , m;
  206. float x;
  207. float gmp;
  208. int gentinfo;
  209. float gentsuitability;
  210. gmp = 1 - pow(1 - mp , 11);//在基因变异概率为mp时整条染色体的变异概率
  211. for(i = 0 ; i < SUM ; i++)
  212. {
  213. if(randsign(gmp) == 1)
  214. {
  215. j = randbit(0 , 14);
  216. m = 1 << j;
  217. gen_group[i].info = gen_group[i].info^m;
  218. x = convertionB2D(gen_group[i].info);
  219. gen_group[i].suitability = x*(x*(x*(x*(x*(x-10)-26)+344)+193)-1846)-1680;
  220. }
  221. }
  222. for(i = 0 ; i < SUM - 1 ; i++)
  223. {
  224. for(j = i + 1 ; j < SUM ; j++)
  225. {
  226. if(gen_group[i].suitability > gen_group[j].suitability)
  227. {
  228. gentinfo = gen_group[i].info;
  229. gen_group[i].info = gen_group[j].info;
  230. gen_group[j].info = gentinfo;
  231. gentsuitability = gen_group[i].suitability;
  232. gen_group[i].suitability = gen_group[j].suitability;
  233. gen_group[j].suitability = gentsuitability;
  234. }
  235. }
  236. }
  237. }
  238. void showresult(int flag)//显示搜索结果并释放内存
  239. {
  240. int i , j;
  241. struct log *logprint,*logfree;
  242. FILE *logf;
  243. if(flag == 0)
  244. printf("已到最大搜索次数,搜索失败!");
  245. else 
  246. {
  247. printf("当取值%f时表达式达到最小值为%fn",convertionB2D(gen_result.info),gen_result.suitability);
  248. printf("收敛过程记录于文件log.txt");
  249. if((logf = fopen("log.txt" , "w+")) == NULL)
  250. {
  251. printf("Cannot create/open file");
  252. exit(1);
  253. }
  254. logprint=head;
  255. for(i = 0 ; i < log_num ; i = i + 5)//对收敛过程进行显示
  256. {
  257. for(j = 0 ; (j < 5) & ((i + j) < log_num-1) ; j++)
  258. {
  259. fprintf(logf , "%20f" , logprint->suitability);
  260. logprint=logprint->next;
  261. }
  262. fprintf(logf,"nn");
  263. }
  264. }
  265. for(i = 0 ; i< log_num ; i++)//释放内存
  266. {
  267. logfree=head;
  268. head=head->next;
  269. free(logfree);
  270. fclose(logf);
  271. }
  272. getchar();
  273. }
  274. int randsign(float p)//按概率p返回1
  275. {
  276. if(rand() > (p * 32768))
  277. return 0;
  278. else return 1;
  279. }
  280. int randbit(int i, int j)//产生在i与j之间的一个随机数
  281. {
  282. int a , l;
  283. l = j - i + 1;
  284. a = i + rand() * l / 32768;
  285. return a;
  286. }
  287. int randnum()
  288. {
  289. int x;
  290. x = rand() / 2;
  291. return x;
  292. }
  293. float convertionB2D(int x)
  294. {
  295. float y;
  296. y = x;
  297. y = (y - 8192) / 1000;
  298. return y;
  299. }
  300. int convertionD2B(float x)
  301. {
  302. int g;
  303. g = (x * 1000) + 8192;
  304. return g;
  305. }
  306. int createmask(int a)
  307. {
  308. int mask;
  309. mask=(1 << (a + 1)) - 1;
  310. return mask;
  311. }