聚类算法基本实现[Java]

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() {
  }
}

    原文作者:聚类算法
    原文地址: https://blog.csdn.net/L_xiaodao/article/details/551762
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞