import java.util.*;
/**
* 需求:在较大的范围内有很多个点,取出n个点,这n个点要“随机”的均匀分布,不能太集中。
* 聚类运算基本实现:假设有n个二维点(x,y),把这n个点分割成m*m个格子.如m=4,即16个格子.取出10个点,这些点在格子范围内,每个格子只取一次.
* @author paulliu
* 以下是我第一个版本,之所以拿出来“献丑”,主要是和大家讨论并且让不了解的朋友能有基本认识
* ,避免犯我同样“错误”。
*
*/
public class CluArray {
private static double minX;
private static double minY;
private static ArrayList resultVec;
public CluArray() {
}
/**
* 聚类运算
* @param arrayList ArrayList
*/
public static ArrayList clusterArray(ArrayList listarray) {
ArrayList result = new ArrayList(); //返回结果list
resultVec = new ArrayList(); //保存了分类后坐标点序列
ArrayList xypoint = new ArrayList(); //初始化坐标点
for (int i = 0; i < listarray.size(); i++) {
String string = listarray.get(i).toString(); //格式[name,layerid,uid,fid,cx,cy]
String[] pointxy = string.split(“,”);
String id = pointxy[2];//uniqueid
String x = pointxy[4];
String y = pointxy[5];
//保存坐标点
Point point = new Point();
double id0 = Double.parseDouble(id);
point.setId(id0);
double x0 = Double.parseDouble(x);
point.setX(x0);
double y0 = Double.parseDouble(y);
point.setY(y0);
xypoint.add(point);
}
cluster3(xypoint); //调用聚类方法
if (xypoint != null) {
xypoint = null;
}
for (int i = 0; i < resultVec.size(); i++) {
for (int j = 0; j < listarray.size(); j++) {
String string = listarray.get(j).toString(); //格式[name,layerid,uid,fid,cx,cy]
String[] pointxy = string.split(“,”);
double id1 = Double.parseDouble(pointxy[2]);
double id2 = ( (Point) resultVec.get(i)).getId();
if (id1 == id2) {
result.add(string);
}
}
}
return result;
}
private static void cluster3(ArrayList xy) {
//提取坐标x,y入数组.
Point poin = (Point) xy.get(0);
double minx=poin.getX();
double miny=poin.getY();
double maxx=poin.getX();
double maxy=poin.getY();
for(int i=1;i<xy.size();i++){
Point point = (Point) xy.get(i);
double vule_x=point.getX();
double vule_y=point.getY();
if(vule_x<minx) minx=vule_x;
if(vule_y<miny) miny=vule_y;
if(vule_x>maxx) maxx=vule_x;
if(vule_y>maxy) maxy=vule_y;
}
double chax = maxx – minX;
double chay = maxy – minY;
int weidu=4;
double xDist = 0.0;
double yDist = 0.0;
xDist = chax / weidu; //单格长度,分格n*n,默认4
yDist = chay / weidu;
int k=4; //纬度,默认为4,
int numSize=10;//需要的点个数
//—初始化格子—//
ArrayList gridsList = new ArrayList();
for (int n = 0; n < k; n++) {
int m = 0;
for (int i = 0; i < k; i++) {
//对角线上左下角点
double x1 = n * xDist;
double y1 = (m++) * yDist;
//对角线上右上角点
double x2 = (n + 1) * xDist;
double y2 = m * yDist;
Grid grid = new Grid();
Point point1 = new Point(); //对角线上左下角点
point1.setX(x1);
point1.setY(y1);
Point point2 = new Point(); //对角线上右上角点
point2.setX(x2);
point2.setY(y2);
grid.setPoint1(point1);
grid.setPoint2(point2);
grid.setMark(true); //初始化标记为可以插入
gridsList.add(grid); //添加对象
}
}
//—插入判断操作—//
for (int i = 0; i < xy.size(); i++) {
for (int j = 0; j < gridsList.size(); j++) {
Grid grid = (Grid) gridsList.get(j); //格子对象
if (grid.isMark()) { //true可以插入
double x1 = grid.getPoint1().getX();
double y1 = grid.getPoint1().getY();
double x2 = grid.getPoint2().getX();
double y2 = grid.getPoint2().getY();
//double x = xy[i][0] – minX; //相对坐标轴
//double y = xy[i][1] – minY;
Point point0 = (Point) xy.get(i);
double x = point0.getX() – minX; //相对坐标轴
double y = point0.getY() – minY;
double id = point0.getId();
if (x1 <= x && x <= x2 && y1 <= y && y <= y2) {
//比较相对坐标,在格子范围内记录下来
if (resultVec.size() == numSize) {
break; //默认取得10个就够
}
Point point = new Point();
point.setX(x + minX); //封装坐标
point.setY(y + minY); //封装坐标
point.setId(id);
resultVec.add(point);
grid.setMark(false); //格子插入后,设置为false
}
}
} //for end!
} //for end!
int resulLeng = resultVec.size();
if (resulLeng < numSize) {
for (int i = 0; i < resulLeng; i++) {
for (int j = 0; j < xy.size(); j++) {
double id1 = ( (Point) resultVec.get(i)).getId();
double id2 = ( (Point) xy.get(j)).getId();
if (id1 == id2) {
{
xy.remove(j);
}
}
} //for end!
} //for end!
cluster3(xy); //没有取够10个点,进行递归
}
}
public static void main(String[] ffff) {
ArrayList rrr = new ArrayList();
//坐标,[x,y]
String coordString =”1000001801158,20862325.4799593,4368782.9668355,1000001801097,20862326.0739075,4368766.23325946,1000001798837,20862493.4270821,4368863.70408938,1000001798857,20862495.1759298,4368863.68408511,1000001796173,20862325.5707014,4368770.22411233,1000001796220,20862325.4964578,4368771.55439661,1000001795905,20862424.2403578,4368865.30443138,1000001795924,20862428.4309929,4368865.39445062,1000001793998,20862558.5469106,4368865.89455749,1000001794043,20862562.5395628,4368876.38679973,1000001793731,20862556.4598424,4368865.35444207,1000001793788,20862327.9959901,4368395.41401387,1000001790668,20862333.2012868,4368651.79880435,1000001790649,20862324.770521,4368642.45680793,1000001790331,20862318.6990498,4368857.83283467,1000001790354,20862322.8154413,4368861.78367898,1000001790404,20862325.7191884,4368629.14396292,1000001790419,20862322.4194758,4368755.07087402,1000001789307,20862053.9383588,4368872.05587419,1000001789344,20862219.7076714,4368880.31763976,1000001786890,20862574.4597747,4368857.88284536,1000001785952,20862571.4075405,4368857.80282826,1000001785361,20862573.2058839,4368865.76452971,1000001785382,20862572.859414,4368865.76452971,1000001785276,20862538.3856665,4368865.18440573,1000001785294,20862535.1436989,4368865.09438649,1000001785194,20862564.0986771,4368872.37594259,1000001785213,20862563.9666886,4368855.32229816,1000001783579,20862224.5664982,4368901.44215416,1000001783595,20862227.3465061,4368861.31357852,1000001781616,20862323.772358,4368749.51968771,1000001781665,20862327.492784,4368657.2799757,1000001781488,20862224.2942719,4368875.51661376,1000001781511,20862459.8195091,4368860.67344172,1000001781532,20862328.284715,4368609.61979052,1000001781551,20862332.7640749,4368736.13682773,1000001781355,20862296.1785112,4368784.11708131,1000001781403,20862323.4258882,4368785.31733781,1000001781454,20862333.9354728,4368729.92550035,1000001781258,20862325.0592459,4368794.59932141,1000001781307,20862323.5826245,4368785.31733781,1000001780865,20862325.0592459,4368794.59932141,1000001780041,20862552.7889121,4368866.39466437,1000001780069,20862558.2004408,4368866.23463017,1000001780093,20862548.7962598,4368869.85540394,1000001780099,20862547.4516269,4368864.99436512,1000001778990,20862560.7082223,4368863.77410434,1000001779014,20862546.5772031,4368863.66408083″;
String[] coordarray = coordString.split(“,”);
for (int i = 0; i < coordarray.length; i = i + 3) {
String uid=coordarray[i];
String x = coordarray[i+1];
String y = coordarray[i + 2];
//格式模仿一实际例子,与算法本身无关
String one = uid + “NAME” + “,” + uid + “otherid” + “,” + uid + “,” + uid +
“ffid” + “,” + x + “,” + y;
rrr.add(one);
}
long time1 = System.currentTimeMillis();
ArrayList result = clusterArray(rrr);
System.out.println(“Cluster计算时间::” + (System.currentTimeMillis() – time1));
System.out.println(rrr.size());
System.out.println(result.size());
for (int m = 0; m < result.size(); m++) {
String thr = result.get(m).toString();
System.out.println(thr);
}
}
//class end!
}
/****************************************************/
public class Grid {
private Point point1;
private Point point2;
private boolean mark;
public void setPoint1(Point point1) {
this.point1 = point1;
}
public void setPoint2(Point point2) {
this.point2 = point2;
}
public void setMark(boolean mark) {
this.mark = mark;
}
public Point getPoint1() {
return point1;
}
public Point getPoint2() {
return point2;
}
public boolean isMark() {
return mark;
}
public Grid() {
}
}
/*******************************************/
public class Point {
private double x;
private double y;
private double id;
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
public void setId(double id) {
this.id = id;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getId() {
return id;
}
public Point() {
}
}