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

首頁 > 編程 > C > 正文

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

2020-01-26 13:45:44
字體:
來源:轉載
供稿:網友

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");     }   } }

 

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情啊啊啊| 国产精品国模在线| 国产婷婷97碰碰久久人人蜜臀| 亚州精品天堂中文字幕| 久久99久国产精品黄毛片入口| 欧美精品中文字幕一区| 日韩欧美在线第一页| 欧美黑人一级爽快片淫片高清| 97福利一区二区| 色狠狠av一区二区三区香蕉蜜桃| 亚洲第一天堂av| 成人免费网站在线看| 在线观看欧美日韩| 亚洲性69xxxbbb| 欧美视频专区一二在线观看| 日韩精品在线播放| 97久久国产精品| 精品日韩视频在线观看| 亚洲欧美制服中文字幕| 国内免费精品永久在线视频| 亚洲精品久久久久久久久| 国语自产在线不卡| 少妇av一区二区三区| 不卡中文字幕av| 欧美另类69精品久久久久9999| 国产成人精品久久二区二区91| 欧美电影免费播放| 国产激情久久久| 国产精品视频久久久| 日韩在线观看免费全集电视剧网站| 91成人福利在线| 久久夜色撩人精品| 91网站免费看| 亚洲人成在线播放| 国产精品视频久久| 5278欧美一区二区三区| 蜜臀久久99精品久久久无需会员| 久久久精品国产| 亚州精品天堂中文字幕| 欧美亚洲另类在线| 亚洲一区二区自拍| 国产成+人+综合+亚洲欧洲| 日韩精品中文字| 欧美一区二区三区图| 91精品久久久久久久| 欧美洲成人男女午夜视频| 欧美亚洲在线视频| 2020久久国产精品| 国产做受高潮69| 欧美激情视频三区| 国产欧美精品一区二区| 国产精品久久久久影院日本| 欧美日韩国产精品一区| 秋霞av国产精品一区| 久久久精品2019中文字幕神马| 丁香五六月婷婷久久激情| 国产精品久久久久久亚洲影视| 欧美大尺度电影在线观看| 亚洲福利在线看| 97碰在线观看| 一区二区在线免费视频| 国产成人在线一区| 久久久久在线观看| 国自产精品手机在线观看视频| 国产福利精品av综合导导航| 7777kkkk成人观看| 欧美xxxwww| 这里只有精品在线播放| 欧美极品少妇全裸体| 欧美色欧美亚洲高清在线视频| 日韩最新中文字幕电影免费看| 91美女高潮出水| 中文字幕欧美日韩精品| 成人欧美一区二区三区黑人| 日韩黄色在线免费观看| 国产精品视频内| 日韩欧美在线字幕| 国产精品久久婷婷六月丁香| 国产精品久久久久久超碰| 久久久99久久精品女同性| 国模叶桐国产精品一区| 国产一区玩具在线观看| 91av中文字幕| 午夜精品久久久久久久99热浪潮| 91久久久久久久久| 久久亚洲综合国产精品99麻豆精品福利| 久热精品视频在线观看一区| 美女扒开尿口让男人操亚洲视频网站| 日韩在线观看免费网站| 欧美日韩国产区| 丝袜美腿精品国产二区| 91亚洲精品一区| 美乳少妇欧美精品| 成人字幕网zmw| 国内精品久久久久久久久| 日韩电影中文 亚洲精品乱码| 国产精品免费视频久久久| 亚洲第一视频网| 国产精品高潮呻吟久久av野狼| xxx成人少妇69| 国自产精品手机在线观看视频| 精品久久久久久久久久| 久久久久久久久久婷婷| 欧美视频一二三| 韩剧1988在线观看免费完整版| 欧美大荫蒂xxx| 免费91麻豆精品国产自产在线观看| 国产综合在线视频| 国产精品99久久久久久久久久久久| 亚洲天天在线日亚洲洲精| 亚洲天堂av女优| 国产伦精品一区二区三区精品视频| 日韩久久免费视频| 伊人伊成久久人综合网小说| 久久精品一区中文字幕| 成人亚洲欧美一区二区三区| 亚洲自拍欧美色图| 国产亚洲免费的视频看| 成人xvideos免费视频| 国产日韩欧美中文在线播放| 国产精品美女网站| 亚洲欧美日韩精品久久| 欧美性猛交xxxx富婆弯腰| 亚洲成人精品视频| 久久人人97超碰精品888| 成人在线国产精品| 亚洲午夜女主播在线直播| 久久久av一区| 久久久在线视频| 国产精欧美一区二区三区| 亚洲精品一区二区网址| 91最新国产视频| 久久精品视频在线观看| 国产91精品久久久久| 久久天天躁狠狠躁夜夜躁| 97视频免费在线观看| 亚洲国产精品99久久| 精品国产福利视频| 亚洲综合第一页| 九色91av视频| 亚洲国产精品久久久久秋霞不卡| 亚洲成年人在线播放| 色999日韩欧美国产| 国产精品视频永久免费播放| 亚洲国产日韩精品在线| 欧美日韩xxxxx| 91久久精品美女| 日韩成人xxxx| 九九九热精品免费视频观看网站| 亚洲在线免费观看| 欧美高清视频在线| 91免费国产网站| 青青久久av北条麻妃黑人| 国产精品欧美一区二区三区奶水| 久久久久久中文| 7m第一福利500精品视频| 日韩视频欧美视频| 中文字幕精品在线| 高清欧美性猛交xxxx| 欧美最顶级的aⅴ艳星| 欧美性xxxxx极品| 91久久国产综合久久91精品网站| 国产精品视频一区二区三区四| 中文字幕精品在线|