packagekmeans;
importjava.util.*;
publicclassKmeans{
publicArrayListallGenerals=null;
publicinttotalNumber=0;//得到所有的武将数目
publicintK=0;//假设K=10
publicKmeans(){
allGenerals=newDomParser().prepare();
totalNumber=allGenerals.size();
K=3;
}
//第一次随机选取聚类中心
publicSetfirstRandom(){
Setcenter=newHashSet();//聚类中心的点的id,采用set保证不会有重复id
Randomran=newRandom();
introll=ran.nextInt(totalNumber);
while(center.size()
roll=ran.nextInt(totalNumber);
center.add(roll);
}
returncenter;
}
//根据聚类中心初始化聚类信息
publicArrayListinit(Setcenter){
ArrayListcluster=newArrayList();//聚类的数组
Iteratorit=center.iterator();
while(it.hasNext()){
Clusterc=newCluster();//代表一个聚类
c.setCenter(it.next());
cluster.add(c);
}
returncluster;
}
/**
*计算各个武将到各个聚类中心的距离,重新聚类
*
*@paramcluster
*聚类数组,用来聚类的,根据最近原则把武将聚类
*@paramcenter
*中心点id,用于计算各个武将到中心点的距离returncluster聚类后的所有聚类组成的数组
*/
publicArrayListjuLei(Setcenter,
ArrayListcluster){
ArrayListdistence=newArrayList();//存放距离信息,表示每个点到各个中心点的距离组成的数组
Generalsource=null;
Generaldest=null;
intid=0;//目的节点id
intid2=0;//源节点id
Object[]p=center.toArray();//p为聚类中心点id数组
booleanflag=false;
//分别计算各个点到各个中心点的距离,并将距离最小的加入到各个聚类中,进行聚类
for(inti=0;i
//每个点计算完,并聚类到距离最小的聚类中就清空距离数组
distence.clear();
//计算到j个类中心点的距离,便利各个中心点
for(intj=0;j
//如果该点不在中心点内则计算距离
if(!(center.contains(i))){
flag=true;
//计算距离
source=allGenerals.get(i);//某个点
dest=allGenerals.get((Integer)p[j]);//各个中心点
//计算距离并存入数组
distence.add(newDistance((Integer)p[j],i,Tool.juli(
source,dest)));
}else{
flag=false;
}
}
//说明计算完某个武将到类中心的距离,开始比较
if(flag==true){
//排序比较一个点到各个中心的距离的大小,找到距离最小的武将的目的id,和源id,
//目的id即类中心点id,这个就归到这个中心点所在聚类中
doublemin=distence.get(0).getDist();//默认第一个distance距离是最小的
//从1开始遍历distance数组
intminid=0;
for(intk=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(intn=0;n
//如果和中心点的id相同则setError
if(cluster.get(n).getCenter()==id){
cluster.get(n).addGeneral(allGenerals.get(id2));//将与该聚类中心距离最小的武将加入该聚类
break;
}
}
}
}
returncluster;
}
//产生新的聚类中心点数组
publicSetupdateCenter(){
Setcenter=newHashSet();
for(inti=0;i
center.add(i);
}
returncenter;
}
//更新聚类中心,求平均值
publicArrayListupdateCluster(ArrayListcluster){
ArrayListresult=newArrayList();
//重新产生的新的聚类中心组成的数组
//k个聚类进行更新聚类中心
for(intj=0;j
ArrayListps=cluster.get(j).getOfCluster();//该聚类的所有武将
//组成的数组
ps.add(allGenerals.get(cluster.get(j).getCenter()));//同时将该类中心对应的武将加入该武将数组
intsize=ps.size();//该聚类的长度大小
//计算和,然后在计算平均值
intsumrender=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(intk1=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();
}
//产生新的聚类,然后加入到聚类数组中
ClusternewCluster=newCluster();
newCluster.setCenter(j);
//计算平均值并构造新的武将对象
newCluster.addGeneral(newGeneral(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);
}
returnresult;
}
/**
*计算各个武将到各个更新后的聚类中心的距离,重新聚类
*@paramupdate更新后的聚类中心
*@paramcluster要存储的聚类中心
*/
publicArrayListupdateJuLei(ArrayListupdate,
ArrayListcluster){
ArrayListdistence=newArrayList();//存放距离信息,表示每个点到各个中心点的距离组成的数组
Generalsource=null;
Generaldest=null;
intid=0;//目的节点id
intid2=0;//源节点id
//Object[]p=center.toArray();//p为聚类中心点id数组
booleanflag=false;
//分别计算各个点到各个中心点的距离,并将距离最小的加入到各个聚类中,进行聚类
for(inti=0;i
//每个点计算完,并聚类到距离最小的聚类中就清空距离数组
distence.clear();
//计算到j个类中心点的距离,便利各个中心点
//for(intj=0;j
for(intj=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(newDistance((Integer)p[j],i,Tool.juli(
distence.add(newDistance(update.get(j).getCenter(),i,Tool.juli(
source,dest)));
/*}else{
flag=false;
}*/
}
//说明计算完某个武将到类中心的距离,开始比较
if(flag==true){
//排序比较一个点到各个中心的距离的大小,找到距离最小的武将的目的id,和源id,
//目的id即类中心点id,这个就归到这个中心点所在聚类中
doublemin=distence.get(0).getDist();//默认第一个distance距离是最小的
//从1开始遍历distance数组
intmid=0;
for(intk=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(intn=0;n
//如果和中心点的id相同则setError
if(cluster.get(n).getCenter()==id){
cluster.get(n).addGeneral(allGenerals.get(id2));//将与该聚类中心距离最小的武将加入该聚类
}
}
}
}
returncluster;
}
//不断循环聚类直到各个聚类没有重新分配
publicArrayListgetResult(){
ArrayListresult=newArrayList();
ArrayListtemp=newArrayList();
booleanflag=false;
//得到随机中心点然后进行聚类
Setcenter=firstRandom();
result=juLei(center,init(center));
print(result);
do{
//重新聚类
ArrayListup=updateCluster(result);//新的聚类中心
ArrayListcluster=init(updateCenter());//得到更新后的中心点对应的聚类数组
temp=updateJuLei(up,cluster);
//print(temp);
flag=isEquals(temp,result);
result=temp;
}while(!flag);
returnresult;
}
publicbooleanisEquals(ArrayListtemp,ArrayListresult){
booleanflag=false;
if(temp.size()!=result.size()){
returnflag;
}
for(Clustertem:temp){
for(Clusterres:result){
if(tem.getCenter()==res.getCenter()){
flag=true;
}
}
//如果找了一轮没找到则说明两个聚类
if(flag==false){
returnfalse;
}else{//如果找了一轮找到了,那么接着找
flag=false;
}
}
//如果代码能进行到这边,说明是true
flag=true;
returnflag;
}
//输出所有的聚类
publicvoidprint(ArrayListcs){
System.out.println("***************************************");
for(inti=0;i
Clusterc=cs.get(i);
System.out.println("-----------------------------------------------------");
System.out.println("center:"+allGenerals.get(c.getCenter()));
ArrayListp=c.getOfCluster();
for(intj=0;j
System.out.println("general:"+p.get(j)+"\n");
}
}
}
}
如果觉得《java聚类分析实例_K-means算法的java实现 聚类分析681个三国武将》对你有帮助,请点赞、收藏,并留下你的观点哦!