亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C語言中K-means算法實現代碼

2020-05-23 13:32:46
字體:
來源:轉載
供稿:網友

K-means算法是很典型的基于距離的聚類算法,采用距離作為相似性的評價指標,即認為兩個對象的距離越近,其相似度就越大。該算法認為簇是由距離靠近的對象組成的,因此把得到緊湊且獨立的簇作為最終目標。

算法過程如下:

1)從N個樣本隨機選取K個樣本作為質心
2)對剩余的每個樣本測量其到每個質心的距離,并把它歸到最近的質心的類
3)重新計算已經得到的各個類的質心
4)迭代2~3步直至新的質心與原質心相等或小于指定閾值,算法結束

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #include<math.h>  #define DIMENSIOM  2    //目前只是處理2維的數據 #define MAX_ROUND_TIME 100   //最大的聚類次數  typedef struct Item{   int dimension_1;    //用于存放第一維的數據   int dimension_2;    //用于存放第二維的數據   int clusterID;     //用于存放該item的cluster center是誰 }Item; Item* data;  typedef struct ClusterCenter{   double dimension_1;   double dimension_2;   int clusterID; }ClusterCenter; ClusterCenter* cluster_center_new;  int isContinue;  int* cluster_center;    //記錄center double* distanceFromCenter; //記錄一個“點”到所有center的距離 int data_size; char filename[200]; int cluster_count;  void initial(); void readDataFromFile(); void initial_cluster(); void calculateDistance_ToOneCenter(int itemID, int centerID, int count); void calculateDistance_ToAllCenter(int itemID); void partition_forOneItem(int itemID); void partition_forAllItem_OneCluster(int round); void calculate_clusterCenter(int round); void K_means(); void writeClusterDataToFile(int round); void writeClusterCenterToFile(int round); void compareNew_OldClusterCenter(double* new_X_Y); void test_1();  int main(int argc, char* argv[]){   if( argc != 4 )   {     printf("This application need other parameter to run:"         "/n/t/tthe first is the size of data set,"         "/n/t/tthe second is the file name that contain data"         "/n/t/tthe third indicate the cluster_count"         "/n");     exit(0);   }   srand((unsigned)time(NULL));   data_size = atoi(argv[1]);   strcat(filename, argv[2]);   cluster_count = atoi(argv[3]);    initial();   readDataFromFile();   initial_cluster();   //test_1();   //partition_forAllItem_OneCluster();   //calculate_clusterCenter();   K_means();   return 0; }  /*  * 對涉及到的二維動態數組根據main函數中傳入的參數分配空間  * */ void initial(){   data = (Item*)malloc(sizeof(struct Item) * (data_size + 1));   if( !data )   {     printf("malloc error:data!");     exit(0);   }   cluster_center = (int*)malloc(sizeof(int) * (cluster_count + 1));   if( !cluster_center )   {     printf("malloc error:cluster_center!/n");     exit(0);   }   distanceFromCenter = (double*)malloc(sizeof(double) * (cluster_count + 1));   if( !distanceFromCenter )   {     printf("malloc error: distanceFromCenter!/n");     exit(0);   }   cluster_center_new = (ClusterCenter*)malloc(sizeof(struct ClusterCenter) * (cluster_count + 1));   if( !cluster_center_new )   {     printf("malloc cluster center new error!/n");     exit(0);   } }  /*  * 從文件中讀入x和y數據  * */ void readDataFromFile(){   FILE* fread;   if( NULL == (fread = fopen(filename, "r")))   {     printf("open file(%s) error!/n", filename);     exit(0);   }   int row;   for( row = 1; row <= data_size; row++ )   {     if( 2 != fscanf(fread, "%d %d ", &data[row].dimension_1, &data[row].dimension_2))     {       printf("fscanf error: %d/n", row);     }     data[row].clusterID = 0;   } }  /*  * 根據從主函數中傳入的@cluster_count(聚類的個數)來隨機的選擇@cluster_count個  * 初始的聚類的起點  * */  void initial_cluster(){   //輔助產生不重復的數   int* auxiliary;   int i;   auxiliary = (int*)malloc(sizeof(int) * (data_size + 1));   if( !auxiliary )   {     printf("malloc error: auxiliary");     exit(0);   }   for( i = 1; i <= data_size; i++ )   {     auxiliary[i] = i;   }      //產生初始化的cluster_count個聚類   int length = data_size;   int random;   for( i = 1; i <= cluster_count; i++ )   {     random = rand()%length + 1;     //printf("%d /n", auxiliary[random]);     //data[auxiliary[random]].clusterID = auxiliary[random];     cluster_center[i] = auxiliary[random];     auxiliary[random] = auxiliary[length--];   }      for( i = 1; i <= cluster_count; i++ )   {     cluster_center_new[i].dimension_1 = data[cluster_center[i]].dimension_1;     cluster_center_new[i].dimension_2 = data[cluster_center[i]].dimension_2;     cluster_center_new[i].clusterID = i;     data[cluster_center[i]].clusterID = i;   } }  /*  * 計算一個點(還沒有劃分到cluster center的點)到一個cluster center的distance  *   @itemID:  不屬于任何cluster中的點  *   @centerID: center的ID  *   @count:   表明在計算的是itemID到第幾個@center的distance,并且指明了結果放在distanceFromCenter的第幾號元素  * */ void calculateDistance_ToOneCenter(int itemID,int centerID){   distanceFromCenter[centerID] = sqrt( (data[itemID].dimension_1-cluster_center_new[centerID].dimension_1)*(double)(data[itemID].dimension_1-cluster_center_new[centerID].dimension_1) + (double)(data[itemID].dimension_2-cluster_center_new[centerID].dimension_2) * (data[itemID].dimension_2-cluster_center_new[centerID].dimension_2) ); }  /*  * 計算一個點(還沒有劃分到cluster center的點)到每個cluster center的distance  * */ void calculateDistance_ToAllCenter(int itemID){   int i;   for( i = 1; i <= cluster_count; i++ )   {     calculateDistance_ToOneCenter(itemID, i);   } }  void test_1() {   calculateDistance_ToAllCenter(3);   int i;   for( i = 1; i <= cluster_count; i++ )   {     printf("%f ", distanceFromCenter[i]);   } }  /*  * 在得到任一的點(不屬于任一cluster的)到每一個cluster center的distance之后,決定它屬于哪一個cluster center,即取距離最小的  *   函數功能:得到一個item所屬的cluster center  * */ void partition_forOneItem(int itemID){   //操作對象是 distanceFromCenter和cluster_center   int i;   int min_index = 1;   double min_value = distanceFromCenter[1];   for( i = 2; i <= cluster_count; i++ )   {     if( distanceFromCenter[i] < min_value )     {       min_value = distanceFromCenter[i];       min_index = i;     }   }    data[itemID].clusterID = cluster_center_new[min_index].clusterID; }  /*  * 得到所有的item所屬于的cluster center , 在一輪的聚類中  * */ void partition_forAllItem_OneCluster(int round){        //changed!!!!!!!!!!!!!!!!!!!!!!!!   int i;   for( i = 1; i <= data_size; i++ )   {     if( data[i].clusterID != 0 )       continue;     else     {       calculateDistance_ToAllCenter(i);  //計算i到所有center的distance       partition_forOneItem(i);    //根據distance對i進行partition     }   }    //把聚類得到的數據寫入到文件中   writeClusterDataToFile(round); }  /*  * 將聚類得到的數據寫入到文件中,每一個類寫入一個文件中  *   @round: 表明在進行第幾輪的cluster,該參數的另一個作用是指定了文件名字中的第一個項.  * */ void writeClusterDataToFile(int round){   int i;   char filename[200];   FILE** file;   file = (FILE**)malloc(sizeof(FILE*) * (cluster_count + 1));   if( !file )   {     printf("malloc file error!/n");     exit(0);   }   for( i = 1; i <= cluster_count; i++ )   {     sprintf(filename, ".//ClusterProcess//round%d_cluster%d.data", round, i);     if( NULL == (file[i] = fopen(filename, "w")))     {       printf("file open(%s) error!", filename);       exit(0);     }   }      for( i = 1; i <= data_size; i++ )   {     //sprintf(filename, ".//ClusterProcess//round%d_cluster%d.data", round, data[i].clusterID);     fprintf(file[data[i].clusterID], "%d/t%d/n", data[i].dimension_1, data[i].dimension_2);   }   for( i = 1; i <= cluster_count; i++ )   {     //sprintf(filename, ".//ClusterProcess//round%d_cluster%d.data", round, i);     fclose(file[i]);   } }  /*  * 重新計算新的cluster center  * */ void calculate_clusterCenter(int round){          //changed!!!!!!!!!!!!!!!!!!!!!!   int i;   double* new_X_Y;  /*           用來計算和保存新的cluster center的值,同樣的,0號元素不用。1,2號元素分別用來           存放第一個聚類的所有的項的x和y的累加和。3,4號元素分別用來存放第二個聚類的所有           的項的x和y的累加和......         */   new_X_Y = (double*)malloc(sizeof(double) * (2 * cluster_count + 1));   if( !new_X_Y )   {     printf("malloc error: new_X_Y!/n");     exit(0);   }   //初始化為0   for( i = 1; i <= 2*cluster_count; i++ )     new_X_Y[i] = 0.0;    //用來統計屬于各個cluster的item的個數   int* counter;   counter = (int*)malloc(sizeof(int) * (cluster_count + 1));   if( !counter )   {     printf("malloc error: counter/n");     exit(0);   }   //初始化為0   for( i = 1; i <= cluster_count; i++ )     counter[i] = 0;    for( i = 1; i <= data_size; i++ )   {     new_X_Y[data[i].clusterID * 2 - 1] += data[i].dimension_1;     new_X_Y[data[i].clusterID * 2] += data[i].dimension_2;     counter[data[i].clusterID]++;   }    for( i = 1; i <= cluster_count; i++ )   {     new_X_Y[2 * i - 1] = new_X_Y[2 * i - 1] / (double)(counter[i]);     new_X_Y[2 * i] = new_X_Y[2 * i] / (double)(counter[i]);   }      //要將cluster center的值保存在文件中,后續作圖   writeClusterCenterToFile(round);      /*    * 在這里比較一下新的和舊的cluster center值的差別。如果是相等的,則停止K-means算法。    * */   compareNew_OldClusterCenter(new_X_Y);    //將新的cluster center的值放入cluster_center_new   for( i = 1; i <= cluster_count; i++ )   {     cluster_center_new[i].dimension_1 = new_X_Y[2 * i - 1];     cluster_center_new[i].dimension_2 = new_X_Y[2 * i];     cluster_center_new[i].clusterID = i;   }   free(new_X_Y);   free(counter);    //在重新計算了新的cluster center之后,意味著我們要重新來為每一個Item進行聚類,所以data中用于表示聚類ID的clusterID   //要都重新置為0。   for( i = 1; i <= data_size; i++ )   {     data[i].clusterID = 0;   } }  /*  * 將得到的新的cluster_count個cluster center的值保存在文件中。以便于觀察聚類的過程。  * */ void writeClusterCenterToFile(int round){   FILE* file;   int i;   char filename[200];   sprintf(filename, ".//ClusterProcess//round%d_clusterCenter.data", round);   if( NULL == (file = fopen(filename, "w")))   {     printf("open file(%s) error!/n", filename);     exit(0);   }    for( i = 1; i <= cluster_count; i++ )   {     fprintf(file, "%f/t%f/n", cluster_center_new[i].dimension_1, cluster_center_new[i].dimension_2);   }    for( i = 1; i <= cluster_count; i++ )   {     fclose(file);   } }  /*  * 比較新舊的cluster center的差異  * */ void compareNew_OldClusterCenter(double* new_X_Y){   int i;   isContinue = 0;       //等于0表示的是不要繼續   for( i = 1; i <= cluster_count; i++ )   {     if( new_X_Y[2 * i - 1] != cluster_center_new[i].dimension_1 || new_X_Y[2 * i] != cluster_center_new[i].dimension_2)     {       isContinue = 1;   //要繼續       break;     }   } }  /************************************************************************************************  *         K-means算法            *     ***********************************************************************************************/ void K_means(){   int times_cluster;   for( times_cluster = 1; times_cluster <= MAX_ROUND_TIME; times_cluster++ )   {     printf("/n            times : %d             /n", times_cluster);     partition_forAllItem_OneCluster(times_cluster);     calculate_clusterCenter(times_cluster);     if( 0 == isContinue )     {       break;       //printf("/n/nthe application can stop!/n/n");     }   } }

  C語言,Kmeans,代碼

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩在线观看免费高清| 国产精品99蜜臀久久不卡二区| 中文字幕欧美视频在线| 91美女片黄在线观看游戏| 欧美日韩亚洲精品一区二区三区| 日韩欧美亚洲一二三区| 国产精品爽爽爽爽爽爽在线观看| 国产成人亚洲精品| 欧美一区二区三区精品电影| 亚洲天堂开心观看| 久久人人爽人人爽人人片av高请| 97超级碰碰碰| 成人精品在线观看| 丝袜亚洲另类欧美重口| 黄网动漫久久久| 一区二区欧美日韩视频| 成人久久18免费网站图片| 欧美限制级电影在线观看| 国产精品九九九| 羞羞色国产精品| 亚洲国产中文字幕久久网| 成人a在线视频| 三级精品视频久久久久| 亚洲丝袜av一区| 亚洲视频在线观看视频| 欧美成人免费播放| 欧美丝袜美女中出在线| 亚洲成人性视频| 成人免费福利视频| 亚洲欧美国产另类| 98精品国产高清在线xxxx天堂| 亚洲欧美在线一区| 亚洲一区二区三区777| 在线亚洲国产精品网| zzjj国产精品一区二区| 91精品免费视频| 亚洲欧美日韩天堂| www.亚洲一二| 亚洲成人av片在线观看| 在线观看视频亚洲| 欧美日韩在线看| 久久久久久久久久久成人| 26uuu日韩精品一区二区| 国产精品一区二区性色av| 国产成人在线播放| 日韩精品在线免费观看| 中文字幕视频在线免费欧美日韩综合在线看| 热久久99这里有精品| 国产精品18久久久久久麻辣| 中文字幕日韩视频| 伊人男人综合视频网| 欧美极品xxxx| 成人久久精品视频| 亚洲香蕉在线观看| 精品亚洲一区二区三区在线播放| 久久久国产精品免费| 91在线无精精品一区二区| 91精品国产乱码久久久久久蜜臀| 中文字幕在线成人| 日本国产高清不卡| 欧美国产日韩中文字幕在线| 日韩欧美在线看| 国产男人精品视频| 亚洲欧美国产精品| 国产精品第10页| 成人午夜高潮视频| 国产精品久久久久久久电影| 亚洲精品www| 揄拍成人国产精品视频| 国产欧美日韩精品丝袜高跟鞋| 欧美大全免费观看电视剧大泉洋| 久久综合九色九九| 国产婷婷97碰碰久久人人蜜臀| 亚洲精品电影网在线观看| 国产精品国产三级国产专播精品人| 久久91亚洲精品中文字幕奶水| 亚洲国产美女久久久久| 欧美中文字幕在线观看| 欧美国产日本在线| 日韩精品极品视频| 久久精品中文字幕一区| 国产成人精品一区| 91欧美激情另类亚洲| 欧美精品videosex极品1| 亚洲最大福利视频| 久久久国产精彩视频美女艺术照福利| 136fldh精品导航福利| 尤物精品国产第一福利三区| 欧美精品在线观看91| 国产精品久久久久久影视| 91久久久久久久久久久| 欧美性猛交xxxx乱大交3| 国产精欧美一区二区三区| 成人欧美在线观看| 欧美一级片久久久久久久| 97精品伊人久久久大香线蕉| 国内精品久久久久久久久| 91午夜理伦私人影院| 欧美高清在线播放| 9.1国产丝袜在线观看| 国产精品视频中文字幕91| 91久久国产婷婷一区二区| 毛片精品免费在线观看| 久久在线观看视频| 人人澡人人澡人人看欧美| 国产精品日韩欧美大师| 欧美成人精品xxx| 亚洲自拍欧美色图| 欧美精品激情blacked18| 亚洲美女精品成人在线视频| 中日韩美女免费视频网站在线观看| 国产视频福利一区| 日韩国产欧美精品一区二区三区| 亚洲精品美女免费| 日本久久久久亚洲中字幕| 国产拍精品一二三| 国产精品久久久久久久久久新婚| 久久久久国产精品免费| 色婷婷综合成人av| 久久青草精品视频免费观看| 亚洲国产成人爱av在线播放| 国产香蕉精品视频一区二区三区| 久久精品美女视频网站| 精品久久久久久久久国产字幕| 最好看的2019的中文字幕视频| 色综合久综合久久综合久鬼88| 精品久久香蕉国产线看观看亚洲| …久久精品99久久香蕉国产| 91成人性视频| 国产精品偷伦视频免费观看国产| 国产97人人超碰caoprom| 欧美激情视频在线| 热久久免费视频精品| 欧美高清性猛交| 亚洲欧美在线一区二区| 日韩av在线高清| 亚洲第一视频网站| 欧美高跟鞋交xxxxxhd| 国产免费一区二区三区在线能观看| 久热精品视频在线观看一区| 国产成人精品免高潮费视频| 精品女同一区二区三区在线播放| 国产精品专区一| 日韩动漫免费观看电视剧高清| 日本成人激情视频| 国产精品久久久久久久久久久久| 日韩亚洲一区二区| 国产一区二区在线免费视频| 久久久久久久久国产精品| 疯狂做受xxxx欧美肥白少妇| 久久偷看各类女兵18女厕嘘嘘| 69久久夜色精品国产69乱青草| 一本大道香蕉久在线播放29| 精品国产乱码久久久久久婷婷| 久久久久亚洲精品国产| 日韩视频在线免费| 91精品国产91久久久久福利| 精品动漫一区二区| 亚洲黄色av网站| 亚洲图片制服诱惑| 久久国产精品影视| 韩国欧美亚洲国产| 亚洲一二在线观看| 亚洲系列中文字幕|