java聚类分析实例_K-means算法的java实现,聚类分析681个三国武将
package?kmeans;
import?java.util.*;
public?class?Kmeans?{
public?ArrayList?allGenerals?=?null;
public?int?totalNumber?=?0;//?得到所有的武將數目
public?int?K?=?0;//?假設K=10
public?Kmeans()?{
allGenerals?=?new?DomParser().prepare();
totalNumber?=?allGenerals.size();
K?=?3;
}
//?第一次隨機選取聚類中心
public?Set?firstRandom()?{
Set?center?=?new?HashSet();//?聚類中心的點的id,采用set保證不會有重復id
Random?ran?=?new?Random();
int?roll?=?ran.nextInt(totalNumber);
while?(center.size()?
roll?=?ran.nextInt(totalNumber);
center.add(roll);
}
return?center;
}
//?根據聚類中心初始化聚類信息
public?ArrayList?init(Set?center)?{
ArrayList?cluster?=?new?ArrayList();//?聚類?的數組
Iterator?it?=?center.iterator();
while?(it.hasNext())?{
Cluster?c?=?new?Cluster();//?代表一個聚類
c.setCenter(it.next());
cluster.add(c);
}
return?cluster;
}
/**
*?計算各個武將到各個聚類中心的距離,重新聚類
*
*?@param?cluster
*????????????聚類數組,用來聚類的,根據最近原則把武將聚類
*?@param?center
*????????????中心點id,用于計算各個武將到中心點的距離?return?cluster?聚類后的所有聚類組成的數組
*/
public?ArrayList?juLei(Set?center,
ArrayList?cluster)?{
ArrayList?distence?=?new?ArrayList();//?存放距離信息,表示每個點到各個中心點的距離組成的數組
General?source?=?null;
General?dest?=?null;
int?id?=?0;//?目的節點id
int?id2?=?0;//?源節點id
Object[]?p?=?center.toArray();//?p?為聚類中心點id數組
boolean?flag?=?false;
//?分別計算各個點到各個中心點的距離,并將距離最小的加入到各個聚類中,進行聚類
for?(int?i?=?0;?i?
//?每個點計算完,并聚類到距離最小的聚類中就清空距離數組
distence.clear();
//?計算到j個類中心點的距離,便利各個中心點
for?(int?j?=?0;?j?
//?如果該點不在中心點內?則計算距離
if?(!(center.contains(i)))?{
flag?=?true;
//?計算距離
source?=?allGenerals.get(i);//?某個點
dest?=?allGenerals.get((Integer)?p[j]);//?各個?中心點
//?計算距離并存入數組
distence.add(new?Distance((Integer)?p[j],?i,?Tool.juli(
source,?dest)));
}?else?{
flag?=?false;
}
}
//?說明計算完某個武將到類中心的距離,開始比較
if?(flag?==?true)?{
//?排序比較一個點到各個中心的距離的大小,找到距離最小的武將的?目的id,和源id,
//?目的id即類中心點id,這個就歸到這個中心點所在聚類中
double?min?=?distence.get(0).getDist();//?默認第一個distance距離是最小的
//?從1開始遍歷distance數組
int?minid?=?0;
for?(int?k?=?1;?k?
if?(min?>?distence.get(k).getDist())?{
min?=?distence.get(k).getDist();
id?=?distence.get(k).getDest();//?目的,即類中心點
id2?=?distence.get(k).getSource();//?某個武將
minid?=?k;
}?else?{
id?=?distence.get(minid).getDest();
id2?=?distence.get(minid).getSource();
}
}
//?遍歷cluster聚類數組,找到類中心點id與最小距離目的武將id相同的聚類
for?(int?n?=?0;?n?
//?如果和中心點的id相同?則setError
if?(cluster.get(n).getCenter()?==?id)?{
cluster.get(n).addGeneral(allGenerals.get(id2));//?將與該聚類中心距離最小的武將加入該聚類
break;
}
}
}
}
return?cluster;
}
//?產生新的聚類中心點數組
public?Set?updateCenter()?{
Set?center?=?new?HashSet();
for?(int?i?=?0;?i?
center.add(i);
}
return?center;
}
//?更新聚類中心,?求平均值
public?ArrayList?updateCluster(ArrayList?cluster)?{
ArrayList?result?=?new?ArrayList();
//?重新產生的新的聚類中心組成的數組
//?k個聚類進行更新聚類中心
for?(int?j?=?0;?j?
ArrayList?ps?=?cluster.get(j).getOfCluster();//?該聚類的所有?武將
//?組成的數組
ps.add(allGenerals.get(cluster.get(j).getCenter()));//?同時將該類中心對應的武將加入該武將數組
int?size?=?ps.size();//?該聚類的長度大小
//?計算和,然后在計算平均值
int?sumrender?=?0,?sumtongshai?=?0,?sumwuli?=?0,?sumzhili?=?0,?sumjibin?=?0,?sumnubin?=?0,?sumqibin?=?0,?sumpolic?=?0,?sumqiangbin?=?0,?sumbinqi?=?0,?sumtongwu?=?0,?sumtongzhi?=?0,?sumtongwuzhi?=?0,?sumtongwuzhizheng?=?0,?sumsalary?=?0;
for?(int?k1?=?0;?k1?
sumrender?+=?ps.get(k1).getRender();
sumtongshai?+=?ps.get(k1).getRender();
sumwuli?+=?ps.get(k1).getWuli();
sumzhili?+=?ps.get(k1).getZhili();
sumjibin?+=?ps.get(k1).getJibin();
sumnubin?+=?ps.get(k1).getNubin();
sumqibin?+=?ps.get(k1).getQibin();
sumpolic?+=?ps.get(k1).getPolic();
sumqiangbin?+=?ps.get(k1).getQiangbin();
sumbinqi?+=?ps.get(k1).getBinqi();
sumtongwu?+=?ps.get(k1).getTongwu();
sumtongzhi?+=?ps.get(k1).getTongzhi();
sumtongwuzhi?+=?ps.get(k1).getTongwuzhi();
sumtongwuzhizheng?+=?ps.get(k1).getTongwuzhizheng();
sumsalary?+=?ps.get(k1).getSalary();
}
//?產生新的聚類,然后加入到聚類數組中
Cluster?newCluster?=?new?Cluster();
newCluster.setCenter(j);
//?計算平均值并構造新的武將對象
newCluster.addGeneral(new?General(sumrender?/?size,?sumtongshai
/?size,?sumwuli?/?size,?sumzhili?/?size,?sumjibin?/?size,
sumnubin?/?size,?sumqibin?/?size,?sumpolic?=?0,
sumqiangbin?=?0,?sumbinqi?/?size,?sumtongwu?/?size,
sumtongzhi?/?size,?sumtongwuzhi?/?size,?sumtongwuzhizheng
/?size,?sumsalary?/?size));
result.add(newCluster);
}
return?result;
}
/**
*?計算各個武將到各個更新后的聚類中心的距離,重新聚類
*?@param?update?更新后的聚類中心
*?@param?cluster?要存儲的聚類中心
*/
public?ArrayList?updateJuLei(ArrayList?update,
ArrayList?cluster)?{
ArrayList?distence?=?new?ArrayList();//?存放距離信息,表示每個點到各個中心點的距離組成的數組
General?source?=?null;
General?dest?=?null;
int?id?=?0;//?目的節點id
int?id2?=?0;//?源節點id
//Object[]?p?=?center.toArray();//?p?為聚類中心點id數組
boolean?flag?=?false;
//?分別計算各個點到各個中心點的距離,并將距離最小的加入到各個聚類中,進行聚類
for?(int?i?=?0;?i?
//?每個點計算完,并聚類到距離最小的聚類中就清空距離數組
distence.clear();
//?計算到j個類中心點的距離,便利各個中心點
//for?(int?j?=?0;?j?
for?(int?j?=?0;?j?
//?如果該點不在中心點內?則計算距離
//if?(!(center.contains(i)))?{
flag?=?true;
//?計算距離
source?=?allGenerals.get(i);//?某個點
//?dest?=?allGenerals.get((Integer)?p[j]);//?各個?中心點
dest?=?update.get(j).getOfCluster().get(0);//?各個?中心點
//?計算距離并存入數組
//distence.add(new?Distance((Integer)?p[j],?i,?Tool.juli(
distence.add(new?Distance(update.get(j).getCenter(),?i,?Tool.juli(
source,?dest)));
/*}?else?{
flag?=?false;
}*/
}
//?說明計算完某個武將到類中心的距離,開始比較
if?(flag?==?true)?{
//?排序比較一個點到各個中心的距離的大小,找到距離最小的武將的?目的id,和源id,
//?目的id即類中心點id,這個就歸到這個中心點所在聚類中
double?min?=?distence.get(0).getDist();//?默認第一個distance距離是最小的
//?從1開始遍歷distance數組
int?mid?=?0;
for?(int?k?=?1;?k?
if?(min?>?distence.get(k).getDist())?{
min?=?distence.get(k).getDist();
id?=?distence.get(k).getDest();//?目的,即類中心點
id2?=?distence.get(k).getSource();//?某個武將
mid?=?k;
}?else?{
id?=?distence.get(mid).getDest();
id2?=?distence.get(mid).getSource();
}
}
//?遍歷cluster聚類數組,找到類中心點id與最小距離目的武將id相同的聚類
for?(int?n?=?0;?n?
//?如果和中心點的id相同?則setError
if?(cluster.get(n).getCenter()?==?id)?{
cluster.get(n).addGeneral(allGenerals.get(id2));//?將與該聚類中心距離最小的武將加入該聚類
}
}
}
}
return?cluster;
}
//?不斷循環聚類直到各個聚類沒有重新分配
public?ArrayList?getResult()?{
ArrayList?result?=?new?ArrayList();
ArrayList?temp?=?new?ArrayList();
boolean?flag?=?false;
//?得到隨機中心點然后進行聚類
Set?center?=?firstRandom();
result?=?juLei(center,?init(center));
print(result);
do?{
//?重新聚類
ArrayList?up?=?updateCluster(result);//新的聚類中心
ArrayList?cluster?=?init(updateCenter());?//?得到更新后的中心點對應的聚類數組
temp?=?updateJuLei(up,?cluster);
//print(temp);
flag?=?isEquals(temp,?result);
result?=?temp;
}?while?(!flag);
return?result;
}
public?boolean?isEquals(ArrayList?temp,?ArrayList?result){
boolean?flag?=?false;
if(temp.size()?!=?result.size()){
return?flag;
}
for(Cluster?tem?:?temp){
for(Cluster?res?:?result){
if(tem.getCenter()?==?res.getCenter()){
flag?=?true;
}
}
//?如果找了一輪沒找到?則說明兩個聚類
if(flag?==?false){
return?false;
}else{//?如果找了一輪找到了,那么接著找
flag?=?false;
}
}
//如果代碼能進行到這邊,說明是true
flag?=?true;
return?flag;
}
//輸出所有的聚類
public?void?print(ArrayList?cs)?{
System.out.println("***************************************");
for?(int?i?=?0;?i?
Cluster?c?=?cs.get(i);
System.out.println("-----------------------------------------------------");
System.out.println("center:?"?+?allGenerals.get(c.getCenter()));
ArrayList?p?=?c.getOfCluster();
for?(int?j?=?0;?j?
System.out.println("general:"+p.get(j)+"\n");
}
}
}
}
總結
以上是生活随笔為你收集整理的java聚类分析实例_K-means算法的java实现,聚类分析681个三国武将的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 如何更换系统字体
- 下一篇: [动态系统的建模与分析]15_伯德图,b