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

数学计算

开发平台:

Visual C++

  1. #include  <stdio.h>
  2. #include  <stdlib.h>
  3. #include  <string.h>
  4. #include  <math.h>
  5. float  * datafield;
  6. int  vectornum;
  7. int  vectorsize;
  8. struct  GROUP
  9. {
  10. float  * center;
  11. float  D;
  12. float  variance;
  13. int  groupsize;
  14. int  flag;//代表这个数组单元是否被占用
  15. };
  16. struct  GROUP  group[100];
  17. int  maxindex;//最大聚类号
  18. int  groupnum;
  19. struct  CCD//记录各聚类中心的距离
  20. {
  21. float  dst;
  22. int  g1 , g2;//聚类编号
  23. }ccd  ,  * ccdhead;
  24. float  Dst;
  25. void  write (int i , int j , float data);//
  26. float  data (int i , int j);//
  27. float  * vector (int  i);//
  28. void  initiate ();//
  29. void  input ();//
  30. void  allocate ();//将模式样本分配给最近的聚类
  31. void  converge ();//
  32. void  diverge ();//
  33. void  renum ();//重新分配聚类号
  34. void  showresult ();
  35. float  distance (float  * x , float  * y);
  36. void  split (int i , int j);//
  37. void  insert (int i , int j , float D);
  38. int  K;//预期的聚类中心数目
  39. int  Nmin;//每一聚类中最少的样本数目,即如少于此数就不作为一个孤立的聚类
  40. float  Ds;//一个聚类域中样本距离分布的标准差
  41. float  Dm;//两个聚类中心之间的最小距离,如小于此数,两个聚类进行合并
  42. int  L;//在于此迭代运算中可以合并的聚类中心的最多对数
  43. int  I;//迭代运算的次数序号
  44. void  main ()
  45. {
  46. int  i;
  47. initiate ();//读入数据,初始化聚类中心,参数设定默认值
  48. for (i = 1 ; ; i++)
  49. {
  50. input ();//显示、修改参数
  51. allocate ();//完成第2-6步
  52. if (i == I)
  53. {
  54. Dm = 0;
  55. converge ();
  56. break;
  57. }
  58. if (groupnum <= K / 2)  diverge ();
  59. else 
  60. {
  61. if ((groupnum >= K * 2) | ( i % 2 == 0))
  62. converge ();
  63. else 
  64. diverge ();
  65. }
  66. renum ();
  67. }
  68. showresult ();
  69. free (datafield);
  70. free (ccdhead);
  71. for (i = 0 ; i < 100 ; i++)
  72. free (group[i].center);
  73. }
  74. void  initiate ()
  75. {
  76. int  i , j , size;
  77. FILE  * df;
  78. char  s[10];
  79. float  d;
  80. K = 2;
  81. Nmin = 1;
  82. Ds = 1;
  83. Dm = 4;
  84. L = 1;
  85. I = 5;
  86. maxindex = groupnum = 1;
  87. if ((df = fopen("data.txt" , "r")) == NULL)
  88. {
  89. printf ("Cannot open filen");
  90. exit (1);
  91. }
  92. fscanf (df , "%5d" , &vectornum);
  93. fscanf (df , "%5d" , &vectorsize);
  94. size = vectornum * (vectorsize + 1);
  95. datafield = (float *) malloc (size * sizeof (float));
  96. for (i = 0 ; i < vectornum ; i++)
  97. {
  98. for (j = 0 ; j < vectorsize ; j++)
  99. {
  100. fscanf (df , "%10f" , &d);
  101. write (i , j + 1 , d);
  102. }
  103. write (i , 0 , -1);
  104. }
  105. fscanf (df , "%10s" , s);
  106. if (strcmp (s , "end") != 0)
  107. {
  108. printf ("n程序初始化失败!");
  109. exit (1);
  110. }
  111. fclose (df);
  112. for (i = 0 ; i < 100 ; i++)
  113. {
  114. group[i].flag = 0;
  115. group[i].center = (float *) malloc ((vectorsize) * sizeof (float));
  116. group[i].groupsize = 0;
  117. group[i].variance = 0;
  118. group[i].D = 0;
  119. }
  120. for (i = 0 ; i < groupnum ; i++)
  121. {
  122. for (j = 0 ; j < vectorsize ; j++)
  123. {
  124. * (group[i].center + j) = data(i , j + 1);///////////////////////////////////////////
  125. }
  126. group[i].flag = 1;
  127. }
  128. }
  129. void  input ()
  130. {
  131. char  choice;
  132. printf ("nn现用的参数取值:n");
  133. printf ("K = %dn,Nmin=%dn,Ds=%fn,Dm=%fn,L=%dn,I=%dn",K,Nmin,Ds,Dm,L,I);
  134. showresult();
  135. printf ("是否需要进行修改?(Y/N)n");
  136. scanf("%s" , & choice);
  137. choice = toupper (choice);
  138. if (choice == 'Y')
  139. {
  140. printf ("n请输入预期的聚类中心数目:");
  141. scanf ("%d" , &K);
  142. printf ("n请输入每一聚类域中最少样本数:");
  143. scanf ("%d" , &Nmin);
  144. printf ("n请输入一个聚类域中样本距离分布的标准差:");
  145. scanf ("%f" , &Ds);
  146. printf("n请输入两聚类中心之间的最小距离:");
  147. scanf ("%f" , &Dm);
  148. printf ("n请输入一次迭代运算中可以合并的聚类中心的最多数目:");
  149. scanf ("%d" , &L);
  150. printf ("n请输入最大迭代次数:");
  151. scanf ("%d" , &I);
  152. }
  153. }
  154. void  allocate ()
  155. {
  156. int  i , j , k , num , index;
  157. float  D , D1 , sum;
  158. for (i = 0 ; i < 100 ; i++)//为各聚类中心值清零
  159. {
  160. group[i].D = 0;
  161. group[i].groupsize = 0;
  162. group[i].variance = 0;
  163. }
  164. for (i=0 ; i < vectornum ; i++)//按距离分配到各聚类域
  165. {
  166. D = distance (group[0].center , vector (i));
  167. k = 0;
  168. for (j = 1 ; j < groupnum ; j++)
  169. {
  170. D1 = distance (group[j].center , vector (i));
  171. if (D > D1)
  172. {
  173. k = j;
  174. D = D1;
  175. }
  176. }
  177. write (i , 0 , (float) k);
  178. group[k].groupsize++;
  179. }
  180. num = groupnum;
  181. for (i = 0 ; i < num ; i++)//当聚类中样本个数小于规定值时撤销聚类
  182. {
  183. if (group[i].groupsize < Nmin)
  184. {
  185. group[i].flag = 0;
  186. group[i].groupsize = 0;
  187. for (j = 0 ; j < vectornum ; j++)
  188. {
  189. if (data (j , 0) == i)
  190. {
  191. write (j , 0 , -1.0);
  192. }
  193. }
  194. groupnum--;
  195. }
  196. }
  197. for (i = 0 ; i < 100 ; i++)//为各聚类中心值清零
  198. {
  199. for (j = 0 ; j < vectorsize ; j++)
  200. * (group[i].center + j) = 0;
  201. }
  202. for (i = 0 ; i < vectornum ; i++)//计算新的聚类中心
  203. {
  204. index = (int) data (i , 0);
  205. if (index != -1)
  206. {
  207. sum = (float) group[index].groupsize;
  208. for (j = 0 ; j < vectorsize ; j++)
  209. {
  210. * (group[index].center + j) = * (group[index].center + j) + data(i , j + 1) / sum;
  211. }
  212. }
  213. }
  214. for (i = 0 ; i < vectornum ; i++)//计算各样点到聚类中心距离
  215. {
  216. index = (int) data (i , 0);
  217. if (index != -1)
  218. {
  219. sum = (float) group[index].groupsize;
  220. D = distance (group[index].center , vector (i));
  221. group[index].D = group[index].D + D / sum;
  222. }
  223. }
  224. Dst = 0;
  225. for (i = 0 ; i < maxindex ; i++)
  226. {
  227. if (group[i].flag != 0)
  228. Dst = Dst + group[i].D;
  229. }
  230. Dst = Dst / groupnum;
  231. }
  232. void  diverge ()
  233. {
  234. float  newvar , oldvar , center;
  235. int  i , j , k , l , flag;
  236. flag = 0;
  237. for (i = 0 ; i < maxindex ; i++)
  238. {
  239. if (group[i].flag != 0)
  240. {
  241. oldvar = 0;//标准差
  242. for (j = 0 , l = 0 ; j < vectorsize ; j++)
  243. {//计算同一聚类域中各分量对应的标准差中的最大值
  244. newvar = 0;
  245. center = * (group[i].center + j);
  246. for (k = 0 ; k < vectornum ; k++)
  247. {
  248. if (data (k , 0) == i)
  249. newvar = newvar +(center - data(k , j+1))*(center - data(k , j+1));
  250. }
  251. if (newvar > oldvar)
  252. {
  253. oldvar = newvar;
  254. l = j;
  255. }
  256. }
  257. group[i].variance = (float) sqrt( oldvar / group[i].groupsize);
  258. if (group[i].variance > Ds)
  259. {
  260. if ((groupnum <= K/2) | ((group[i].D > Dst) & (group[i].groupsize > 2 * (Nmin + 1))))
  261. {
  262. split (i , l);
  263. flag = 1;
  264. }
  265. }
  266. }
  267. }
  268. if (flag == 0)
  269. converge ();
  270. }
  271. void  split (int i , int j)
  272. {
  273. int  k , l;
  274. k = maxindex;
  275. group[k].flag = 1;
  276. for (l = 0 ; l < vectorsize ; l++)
  277. {
  278. * (group[k].center + l) = (* (group[i].center + l));
  279. }
  280. * (group[k].center + j) = (* (group[k].center + j) + group[i].variance);
  281. * (group[i].center + j) = (* (group[i].center + j) - group[i].variance);
  282. maxindex++;
  283. groupnum++;
  284. }
  285. void  converge ()
  286. {
  287. int  i , j , k , h , l;
  288. float  D , c1 , c2 , n1 , n2;
  289. ccdhead = (struct CCD *) malloc (sizeof (ccd) * L);
  290. for (i = 0 , k = 0 ; i < maxindex - 1 ; i++)
  291. {
  292. if (group[i].flag != 0)
  293. {
  294. for (j = i + 1 ; j < maxindex ; j++)
  295. {
  296. if (group[j].flag != 0)
  297. {
  298. D = distance (group[i].center , group[j].center);
  299. if (D < Dm)
  300. {
  301. if (k < L)
  302. {
  303. (ccdhead + k)->dst = D;
  304. (ccdhead + k)->g1 = i;
  305. (ccdhead + k)->g2 = j;
  306. k++;
  307. }
  308. else
  309. {
  310. insert (i,j,D);
  311. }
  312. break;
  313. }
  314. }
  315. }
  316. }
  317. }
  318. for (h = 0 ; h < k ;h++)
  319. {
  320. i = (ccdhead + h)->g1;
  321. j = (ccdhead + h)->g2;
  322. n1 = (float) group[i].groupsize;
  323. n2 = (float) group[j].groupsize;
  324. for (l = 0 ; l < vectorsize ; l++)
  325. {
  326. c1 = (* (group[i].center + l));
  327. c2 = (* (group[j].center + l));
  328. * (group[i].center + l) = (n1 * c1 + n2 * c2) / (n1 + n2);
  329. }
  330. group[i].groupsize = (int) (n1 + n2);
  331. for (l = 0 ; l < vectornum ; l++)
  332. if (data(l , 0) == j)
  333. write (l , 0 , (float) i);
  334. group[j].flag = 0;
  335. group[j].groupsize = 0;
  336. groupnum--;
  337. }
  338. }
  339. void  insert (int i , int j , float D)
  340. {
  341. int  h , l;
  342. for (h = 0 ; h < L ; h++)
  343. {
  344. if (D < (ccdhead + h)->dst)
  345. {
  346. for (l = L - 1 ; l > h ; l--)
  347. {
  348. (ccdhead + l)->dst = (ccdhead + l - 1)->dst;
  349. (ccdhead + l)->g1 = (ccdhead + l - 1)->g1;
  350. (ccdhead + l)->g2 = (ccdhead + l - 1)->g2;
  351. }
  352. (ccdhead + h)->dst = D;
  353. (ccdhead + h)->g1 = i;
  354. (ccdhead + h)->g2 = j;
  355. }
  356. }
  357. }
  358. void  renum ()
  359. {
  360. int  i , j , k;
  361. for (i = 0 ; i < maxindex - 1 ; i++)
  362. {
  363. if (group[i].flag == 0)
  364. {
  365. for (j = maxindex ; j > i ; j--)
  366. {
  367. if (group[j].flag == 1)
  368. {
  369. group[i].flag = 1;
  370. group[j].flag = 0;
  371. for (k = 0 ; k < vectorsize ; k++)
  372. {
  373. * (group[i].center + k) = (* (group[j].center + k));
  374. * (group[j].center + k) = 0;
  375. }
  376. }
  377. }
  378. }
  379. }
  380. maxindex = groupnum;
  381. }
  382. void  showresult ()
  383. {
  384. int  i , j , k , l;
  385. for (j = 1 , i = 0 ; i < maxindex ; i++)
  386. {
  387. if (group[i].flag != 0)
  388. {
  389. printf ("第%3d组聚类中心坐标为:" , j ++);
  390. for (k = 0 ; k < vectorsize ; k++)
  391. printf (" %10f " , *(group[i].center + k));
  392. printf (" n聚类包含的样本点的坐标为:n ");
  393. for (k = 0 ; k < vectornum ; k++)
  394. {
  395. if (data(k , 0) == i)
  396. {
  397. for (l = 0 ; l < vectorsize ; l++)
  398. {
  399. printf (" %10f " , data(k , l + 1));
  400. }
  401. printf (" n ");
  402. }
  403. }
  404. }
  405. }
  406. }
  407. float  data (int i , int j)
  408. {
  409. return  * (datafield + i * (vectorsize + 1) + j);
  410. }
  411. void  write (int i , int j , float data)
  412. {
  413. * (datafield + i * (vectorsize + 1) + j) = data;
  414. }
  415. float  * vector (int i)
  416. return  datafield + i * (vectorsize + 1) + 1;
  417. }
  418. float  distance (float  * x , float  * y)
  419. {
  420. int  i;
  421. float  z;
  422. for (i = 0 , z = 0 ; i < vectorsize ; i++)
  423. z = z + ((* (x + i)) - (* (y + i))) * ((* (x + i))-(* (y + i)));
  424. return  (float) sqrt(z);
  425. }