一维数组kmeans聚类c语言,一维数组的 K-Means 聚类算法理解
剛看了這個算法,理解如下,放在這里,備忘,如有錯誤的地方,請指出,謝謝
需要做聚類的數組我們稱之為【源數組】
需要一個分組個數K變量來標記需要分多少個組,這個數組我們稱之為【聚類中心數組】及
一個緩存臨時聚類中心的數組,我們稱之為【緩存聚類中心數組】
然后初始化一個K長度的數組,值隨機(盡量分布在原數組的更大的區間以便計算),用于和源數組進行比對計算。
下面是計算的部分:
死循環遍歷對源數據進行分組。
分組內遍歷原數組的每個元素與聚類中心的每個元素的距離(差值的絕對值),將最小距離的聚類中心數組下標緩存的臨時變量臨時變量數組A中(長度=原數組),
創建二維數組,我們稱之為【分組數組】 [聚類中心數組長度][源數組中分類的值],
遍歷臨時變量數組A,使用A的小標拿到原數組對應的值,賦值給分組數組。
具體公式如:
分組數組[A[i]].add(原數組[i]);
返回分組數組
對分組后的數組計算中間值存入緩存聚類中心數組,比較緩存劇烈數組和聚類數組,是否位置一樣,值一樣,如果一樣跳出死循環,分類結束,
否則將臨時劇烈中心數組賦值給聚類中心數組進行下次循環
別笑!語文從來沒及格過,表達能力就這樣了。。。。。。。。不明白我說的啥,那么就看代碼吧。
下面是c#代碼,如果需要java代碼,請看http://www.oschina.net/code/snippet_42411_2527
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceK_MeansTest
{classProgram
{static void Main(string[] args)
{double[] p = { 1, 2, 3, 5, 6, 7, 9, 10, 11,20,21,22,23,27,40,41,42,43,61,62,63, 100, 150, 200, 1000};int k = 5;double[][] g;
g=cluster(p, k);for (int i = 0; i < g.Length; i++)
{for (int j = 0; j < g[i].Length; j++)
{
Console.WriteLine(g[i][j]);
}
Console.WriteLine("----------------------");
}
Console.ReadKey();
}/** 聚類函數主體。
* 針對一維 double 數組。指定聚類數目 k。
* 將數據聚成 k 類。*/
public static double[][] cluster(double[] p, intk)
{//存放聚類舊的聚類中心
double[] c = new double[k];//存放新計算的聚類中心
double[] nc = new double[k];//存放放回結果
double[][] g;//初始化聚類中心//經典方法是隨機選取 k 個//本例中采用前 k 個作為聚類中心//聚類中心的選取不影響最終結果
for (int i = 0; i < k; i++)
c[i]=p[i];//循環聚類,更新聚類中心//到聚類中心不變為止
while (true)
{//根據聚類中心將元素分類
g =group(p, c);//計算分類后的聚類中心
for (int i = 0; i < g.Length; i++)
{
nc[i]=center(g[i]);
}//如果聚類中心不同
if (!equal(nc, c))
{//為下一次聚類準備
c =nc;
nc= new double[k];
}else //聚類結束
break;
}//返回聚類結果
returng;
}/** 聚類中心函數
* 簡單的一維聚類返回其算數平均值
* 可擴展*/
public static double center(double[] p)
{return sum(p) /p.Length;
}/** 給定 double 型數組 p 和聚類中心 c。
* 根據 c 將 p 中元素聚類。返回二維數組。
* 存放各組元素。*/
public static double[][] group(double[] p, double[] c)
{//中間變量,用來分組標記
int[] gi = new int[p.Length];//考察每一個元素 pi 同聚類中心 cj 的距離//pi 與 cj 的距離最小則歸為 j 類
for (int i = 0; i < p.Length; i++)
{//存放距離
double[] d = new double[c.Length];//計算到每個聚類中心的距離
for (int j = 0; j < c.Length; j++)
{
d[j]=distance(p[i], c[j]);
}//找出最小距離
int ci =min(d);//標記屬于哪一組
gi[i] =ci;
}//存放分組結果
double[][] g = new double[c.Length][];//遍歷每個聚類中心,分組
for (int i = 0; i < c.Length; i++)
{//中間變量,記錄聚類后每一組的大小
int s = 0;//計算每一組的長度
for (int j = 0; j < gi.Length; j++)if (gi[j] ==i)
s++;//存儲每一組的成員
g[i] = new double[s];
s= 0;//根據分組標記將各元素歸位
for (int j = 0; j < gi.Length; j++)if (gi[j] ==i)
{
g[i][s]=p[j];
s++;
}
}//返回分組結果
returng;
}/** 計算兩個點之間的距離, 這里采用最簡單得一維歐氏距離, 可擴展。*/
public static double distance(double x, doubley)
{return Math.Abs(x -y);
}/** 返回給定 double 數組各元素之和。*/
public static double sum(double[] p)
{double sum = 0.0;for (int i = 0; i < p.Length; i++)
sum+=p[i];returnsum;
}/** 給定 double 類型數組,返回最小值得下標。*/
public static int min(double[] p)
{int i = 0;double m = p[0];for (int j = 1; j < p.Length; j++)
{if (p[j]
{
i=j;
m=p[j];
}
}returni;
}/** 判斷兩個 double 數組是否相等。 長度一樣且對應位置值相同返回真。*/
public static bool equal(double[] a, double[] b)
{if (a.Length !=b.Length)return false;else{for (int i = 0; i < a.Length; i++)
{if (a[i] !=b[i])return false;
}
}return true;
}
}
}
結果如下
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的一维数组kmeans聚类c语言,一维数组的 K-Means 聚类算法理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c#+mysql图片存数据库_C#图片存
- 下一篇: ora00936缺失表达式怎么解决_初学