kmean算法java版

package com.anyec.math.base;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

public class Kmean {
/***
*
* @param npoints
*            中心点
* @param data
*            输入样本
* @return
*/
public static Map<Point, List<Point>> getPointsGroup(List<Point> npoints,
List<Point> data) {
Map<Point, List<Point>> kdata = new HashMap<Point, List<Point>>();
for (Point jp : npoints) {
kdata.put(jp, new ArrayList<Point>());
}
for (Point ip : data) {
Point spoint = null;
double lastdistance = 0;
double currdistance = 0;
for (Point jp : npoints) {
currdistance = getDistince(jp, ip);
if (spoint == null || lastdistance > currdistance) {
lastdistance = currdistance;
spoint = jp;
}
}
kdata.get(spoint).add(ip);
}
return kdata;
}

/******
* 依据分类,获取新的中心点
*
* @param mpoints
*            分类键对
* @return
*/
public static List<Point> getCenterPoints(Map<Point, List<Point>> mpoints) {
List<Point> npoints = new ArrayList<Point>();
Set<Point> key = mpoints.keySet();
for (Point p : key) {
List<Point> lpoints = mpoints.get(p);
double sumx = 0, sumy = 0;
for (Point lpoint : lpoints) {
sumx += lpoint.getX();
sumy += lpoint.getY();
}
Point newcenterPoint = new Point();
newcenterPoint.setX(sumx / lpoints.size());
newcenterPoint.setY(sumy / lpoints.size());
npoints.add(newcenterPoint);
}
return npoints;
}

public static List<Point> initData(int n) {
List<Point> list = new ArrayList<Point>();
java.util.Random rd = new Random(3000);
for (int i = 0; i < n; i++) {
Point p = new Point();
p.setX(rd.nextDouble() * 1000);
p.setY(rd.nextDouble() * 1000);
list.add(p);
}
return list;
}

public static void printPair(Map<Point, List<Point>> cpoints) {

Set<Point> key = cpoints.keySet();
for (Point p : key) {
System.out.print(p + "  :{");
List<Point> list = cpoints.get(p);
for (Point lp : list) {
System.out.print(lp + ",");
}
System.out.println("}");
}

}

public static void printResult(List<Map<Point, List<Point>>> cpoints) {
int i = 0;
for (Map<Point, List<Point>> mp : cpoints) {
System.out.println("第" + i + "计算分类信息");
Set<Point> key = mp.keySet();
for (Point p : key) {
System.out.print(p + "  :{");
List<Point> list = mp.get(p);
for (Point lp : list) {
System.out.print(lp + ",");
}
System.out.println("}");
}
i++;
}

}

public static double getDistince(Point p1, Point p2) {
return Math.sqrt((p1.getX() - p2.getX()) * (p1.getX() - p2.getX())
+ (p1.getY() - p2.getY()) * (p1.getY() - p2.getY()));
}

public static double sumDistince(Point p1, List<Point> ps) {
double sum = 0;
for (Point p : ps) {
sum = sum + getDistince(p1, p);
}
return sum;
}

/**
* @param args
*/
public static void main(String[] args) {
List<Point> data = initData(5000);
List<Point> kpoint = initData(5);
List<List<Point>> kpoints = new ArrayList<List<Point>>();
List<Map<Point, List<Point>>> cpoints = new ArrayList<Map<Point, List<Point>>>();
double lastDistince = 0;
double currDistince = 0;
long count = 1;
double minDistince = Long.MAX_VALUE;
while (true) {
// System.out.println("正在进行" + count + "次迭代");
Map<Point, List<Point>> pair = getPointsGroup(kpoint, data);
printPair(pair);
// cpoints.add(pair);
Set<Point> key = pair.keySet();
lastDistince = currDistince;
currDistince = 0;
for (Point p : key) {
currDistince += sumDistince(p, pair.get(p));
}
if (currDistince < minDistince)
minDistince = currDistince;
// System.out.println(lastDistince + "  " + currDistince + " " +
// minDistince + " " + count);
count++;
if (lastDistince <= currDistince
&& (currDistince < 0.001 || Math.abs(lastDistince
- currDistince)
/ lastDistince < 0.0001))
break;
else
kpoint = getCenterPoints(pair);

}
// printResult(cpoints);
}

}


---------------------------------------
package com.anyec.math.base;

import java.io.Serializable;
import java.util.List;

public class Point implements Serializable,Comparable<Point> {
private double x;
private double y;

public double getX() {
return x;
}

public void setX(double x) {
this.x = x;
}

public double getY() {
return y;
}

public void setY(double y) {
this.y = y;
}

@Override
public String toString() {
return "(" + x + ", " + y + ")";
}

@Override
public int compareTo(Point o) {
if(this.getX()>o.getX()){
return 1;
}else if(this.getX()==o.getX()){
if(this.getY()>o.getY()){
return 1;
}else if(this.getY()==o.getY()){
return 0;
}else{
return -1;
}
}else{
return -1;
}

}





}

猜你喜欢

转载自qqggcc.iteye.com/blog/2007525