日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > php >内容正文

php

php fuzzy,模糊C均值聚类算法(Fuzzy C-means)

發(fā)布時(shí)間:2025/3/11 php 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php fuzzy,模糊C均值聚类算法(Fuzzy C-means) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

模糊c均值聚類與k均值聚類區(qū)別

k均值聚類

k均值聚類的實(shí)現(xiàn)中,把每個樣本劃分到單一的類別中,亦即是每個樣本只能屬于一種類別,不能屬于多種類別。這樣的劃分,稱為硬劃分。

模糊c均值均類

為了解決硬劃分所帶來的問題,因此有了稱為軟劃分的聚類算法,這一類算法中,每個樣本不再只能屬于一種類別,而是對于每個樣本,都有對應(yīng)的隸屬度數(shù)組,數(shù)組里的每一個元素代表該樣本屬于某種類別的程度。而該樣本的隸屬度數(shù)組中的總值等于1。

其目標(biāo)方程以及優(yōu)化的推導(dǎo)過程可以參照下述鏈接,個人認(rèn)為推導(dǎo)過程十分詳細(xì)。

模糊c均值聚類推導(dǎo)

實(shí)現(xiàn)步驟:

根據(jù)相關(guān)的推導(dǎo)結(jié)果,具體實(shí)現(xiàn)步驟如下:

初始化數(shù)據(jù)集

初始化隸屬度數(shù)組

根據(jù)隸屬度數(shù)組更新聚類中心

根據(jù)聚類中心更新隸屬度數(shù)組

是否達(dá)到結(jié)束條件,沒有達(dá)到則重復(fù)2-4步驟。

實(shí)現(xiàn)

各個相關(guān)函數(shù)都有注釋。

#include

#include

#include

#include

typedef struct{

double x;

double y;

} Position;

//隨機(jī)生成二維數(shù)據(jù)點(diǎn)

//len:節(jié)點(diǎn)數(shù)量

//range:節(jié)點(diǎn)x、y值的范圍

Position *randomPosition(int len, int range){

srand((unsigned)time(NULL));

Position *allPos = (Position *)malloc(len * sizeof(Position));

short a = 1; //人為差異量

for (int i = 0; i < len; ++i)

{

if (a)

{

allPos[i].x = (double)rand() / 2147483647 * range;

allPos[i].y = (double)rand() / 2147483647 * range;

a = 0;

}

else if (!a)

{

allPos[i].x = (double)rand() / 2147483647 * range+50;

allPos[i].y = (double)rand() / 2147483647 * range+50;

a = 1;

}

}

return allPos;

}

//fcm初始化:隸屬度矩陣

//posNum:節(jié)點(diǎn)數(shù)量

//clusterNum:聚類中心數(shù)量

double **init(int posNum, int clusterNum){

double **u = (double **)malloc(sizeof(double *) * clusterNum);

for (int i = 0; i

{

u[i] = (double *)malloc(sizeof(double) * posNum);

}

srand((unsigned)time(NULL));

double sum;

//初始化u:sigmaU[i]=1

for (int i = 0; i < posNum; ++i)

{

sum=1;

for (int x = 0; x < clusterNum - 1; ++x)

{

u[x][i] = ((double)rand() / 2147483647) * sum;

sum -= u[x][i];

printf("u[%d][%d]:%f ",x,i,u[x][i]);

}

u[clusterNum-1][i]=sum;

printf("u[%d][%d]:%f\n",clusterNum-1,i,u[clusterNum-1][i]);

}

return u;

}

//輸出所有數(shù)據(jù)點(diǎn)

//allPos:節(jié)點(diǎn)數(shù)組

//len:節(jié)點(diǎn)數(shù)量

void outputPos(Position *allPos, int len){

for (int i = 0; i < len; ++i)

printf("position %d:(%f,%f)\n", i, allPos[i].x, allPos[i].y);

return;

}

//所有隸屬于聚類中心i的點(diǎn)的隸屬程度和

//u:隸屬度矩陣

//posNum:節(jié)點(diǎn)數(shù)量

//i:第i個聚類中心

//m:隸屬度因子

double sumUi(double** u,int posNum,int i,int m){

double res=0;

for(int x=0;x

res+=pow(u[i][x],m);

return res;

}

//所有隸屬于聚類中心i的點(diǎn)的x坐標(biāo)的和

//u:隸屬度矩陣

//allPos:節(jié)點(diǎn)數(shù)組

//posNum:節(jié)點(diǎn)數(shù)量

//i:第i個聚類中心

//m:隸屬度因子

double sumXi(double** u,Position* allPos,int posNum,int i,int m){

double res=0;

for(int x=0;x

res+=allPos[x].x*pow(u[i][x],m);

return res;

}

//所有隸屬于聚類中心i的點(diǎn)的y坐標(biāo)的和

//u:隸屬度矩陣

//posNum:節(jié)點(diǎn)數(shù)量

//i:第i個聚類中心

//m:隸屬度因子

double sumYi(double** u,Position* allPos,int posNum,int i,int m){

double res=0;

for(int x=0;x

res+=allPos[x].y*pow(u[i][x],m);

return res;

}

//第j個節(jié)點(diǎn)到所有聚類中心距離總和

//pos:第j個節(jié)點(diǎn)

//cluster:聚類中心數(shù)組

//clusterNum:聚類中心數(shù)量

//m:隸屬度因子

double sumDis(Position pos,Position* cluster,int clusterNum,int m){

double res=0;

for(int i=0;i

res+=(double)1/pow(pow(pos.x-cluster[i].x,2)+pow(pos.y-cluster[i].y,2),(double)1/(m-1));

return res;

}

//更新聚類中心

//allPos:節(jié)點(diǎn)數(shù)組

//cluster:聚類中心數(shù)組

//u:隸屬度矩陣

//posNum:節(jié)點(diǎn)數(shù)量

//clusterNum:聚類中心數(shù)量

//m:隸屬度因子

void updateCluster(Position* allPos,Position* cluster,double** u,int posNum,int clusterNum,int m){

for(int i=0;i

cluster[i].x=sumXi(u,allPos,posNum,i,m)/sumUi(u,posNum,i,m);

cluster[i].y=sumYi(u,allPos,posNum,i,m)/sumUi(u,posNum,i,m);

}

}

//更新隸屬度矩陣

//allPos:節(jié)點(diǎn)數(shù)組

//cluster:聚類中心數(shù)組

//u:隸屬度矩陣

//posNum:節(jié)點(diǎn)數(shù)量

//clusterNum:聚類中心數(shù)量

//m:隸屬度因子

void updateU(Position* allPos,Position* cluster,double** u,int posNum,int clusterNum,int m){

double disXI;

for(int i=0;i

for(int x=0;x

disXI=pow(pow(allPos[x].x-cluster[i].x,2)+pow(allPos[x].y-cluster[i].y,2),(double)1/(m-1));

u[i][x]=(double)1/(disXI*sumDis(allPos[x],cluster,clusterNum,m));

}

}

//輸出目標(biāo)函數(shù)

//allPos:節(jié)點(diǎn)數(shù)組

//cluster:聚類中心數(shù)組

//u:隸屬度矩陣

//posNum:節(jié)點(diǎn)數(shù)量

//clusterNum:聚類中心數(shù)量

//m:隸屬度因子

void outpuCost_fun(Position* allPos,Position* cluster,double** u,int posNum,int clusterNum,int m){

double res=0;

for(int i=0;i

for(int x=0;x

res+=(pow(u[i][x],m)*(pow(allPos[x].x-cluster[i].x,2)+pow(allPos[x].y-cluster[i].y,2)));

printf("costFun:%f\n",res);

}

//..略,同上

void outputU(double** u,int posNum,int clusterNum){

for(int i=0;i

for(int x=0;x

printf("u[%d][%d]:%f ",x,i,u[x][i]);

printf("\n");

}

}

void fuzzy_Cmeans(int posNum,int clusterNum, int m, int iterTime,int range)

{

Position* allPos=randomPosition(posNum,range);

Position* cluster=(Position*)malloc(sizeof(Position)*clusterNum);

double** u=init(posNum,clusterNum);

for (int i = 0; i < iterTime; ++i)

{

updateCluster(allPos,cluster,u,posNum,clusterNum,m);

updateU(allPos,cluster,u,posNum,clusterNum,m);

outpuCost_fun(allPos,cluster,u,posNum,clusterNum,m);

//outputU(u,posNum,clusterNum);

}

}

int main(){

fuzzy_Cmeans(100,10,3,500,500);

return 0;

}

結(jié)果

可以看到,其目標(biāo)函數(shù)的值是逐漸減少的,最后達(dá)到穩(wěn)定的狀態(tài)。

總結(jié)

以上是生活随笔為你收集整理的php fuzzy,模糊C均值聚类算法(Fuzzy C-means)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。