精华内容
下载资源
问答
  • K-means聚类算法是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象...
  • 网上很多python的聚类算法有很多,找的Java的,里面是个jar,直接调用就好了
  • 聚类算法 java实现

    2021-02-12 10:17:54
    import java.util.ArrayList;import org.algorithm.Kmeans;public class KmeansTest {publicstatic void main(String[] args){//初始化一个Kmean对象,将k置为10Kmeans k=new Kmeans(10);ArrayList dataSet=n...

    package org.test;

    import java.util.ArrayList;

    import org.algorithm.Kmeans;

    public class KmeansTest {

    public static void main(String[] args)

    {

    //初始化一个Kmean对象,将k置为10

    Kmeans k=new Kmeans(10);

    ArrayList dataSet=new ArrayList();

    dataSet.add(new float[]{1,2});

    dataSet.add(new float[]{3,3});

    dataSet.add(new float[]{3,4});

    dataSet.add(new float[]{5,6});

    dataSet.add(new float[]{8,9});

    dataSet.add(new float[]{4,5});

    dataSet.add(new float[]{6,4});

    dataSet.add(new float[]{3,9});

    dataSet.add(new float[]{5,9});

    dataSet.add(new float[]{4,2});

    dataSet.add(new float[]{1,9});

    dataSet.add(new float[]{7,8});

    //设置原始数据集

    k.setDataSet(dataSet);

    //执行算法

    k.execute();

    //得到聚类结果

    ArrayList> cluster=k.getCluster();

    //查看结果

    for(int i=0;i

    {

    k.printDataArray(cluster.get(i), "cluster["+i+"]");

    }

    }

    }

    package org.algorithm;

    import java.util.ArrayList;

    import java.util.Random;

    public class Kmeans {

    private int k;// 分成多少簇

    private int m;// 迭代次数

    private int dataSetLength;// 数据集元素个数,即数据集的长度

    private ArrayList dataSet;// 数据集链表

    private ArrayList center;// 中心链表

    private ArrayList> cluster; // 簇

    private ArrayList jc;// 误差平方和,k越接近dataSetLength,误差越小

    private Random random;

    public void setDataSet(ArrayList dataSet) {

    this.dataSet = dataSet;

    }

    public ArrayList> getCluster() {

    return cluster;

    }

    public Kmeans(int k) {

    if (k <= 0) {

    k = 1;

    }

    this.k = k;

    }

    private void init() {

    m = 0;

    random = new Random();

    if (dataSet == null || dataSet.size() == 0) {

    initDataSet();

    }

    dataSetLength = dataSet.size();

    if (k > dataSetLength) {

    k = dataSetLength;

    }

    center = initCenters();

    cluster = initCluster();

    jc = new ArrayList();

    }

    private void initDataSet() {

    dataSet = new ArrayList();

    // 其中{6,3}是一样的,所以长度为15的数据集分成14簇和15簇的误差都为0

    float[][] dataSetArray = new float[][] { { 8, 2 }, { 3, 4 }, {

    2, 5 },

    { 4, 2 }, { 7, 3 }, { 6, 2 }, { 4, 7 }, { 6, 3 }, { 5, 3 },

    { 6, 3 }, { 6, 9 }, { 1, 6 }, { 3, 9 }, { 4, 1 }, { 8, 6 }

    };

    for (int i = 0; i < dataSetArray.length; i++) {

    dataSet.add(dataSetArray[i]);

    }

    }

    private ArrayList initCenters() {

    ArrayList center = new ArrayList();

    int[] randoms = new int[k];

    boolean flag;

    int temp = random.nextInt(dataSetLength);

    randoms[0] = temp;

    for (int i = 1; i < k; i++) {

    flag = true;

    while (flag) {

    temp = random.nextInt(dataSetLength);

    int j = 0;

    // 不清楚for循环导致j无法加1

    // for(j=0;j

    // {

    // if(temp==randoms[j]);

    // {

    // break;

    // }

    // }

    while (j < i) {

    if (temp == randoms[j]) {

    break;

    }

    j++;

    }

    if (j == i) {

    flag = false;

    }

    }

    randoms[i] = temp;

    }

    // 测试随机数生成情况

    // for(int i=0;i

    // {

    // System.out.println("test1:randoms["+i+"]="+randoms[i]);

    // }

    // System.out.println();

    for (int i = 0; i < k; i++) {

    center.add(dataSet.get(randoms[i]));// 生成初始化中心链表

    }

    return center;

    }

    private ArrayList> initCluster() {

    ArrayList> cluster = new ArrayList>();

    for (int i = 0; i < k; i++) {

    cluster.add(new ArrayList());

    }

    return cluster;

    }

    private float distance(float[] element, float[] center) {

    float distance = 0.0f;

    float x = element[0] - center[0];

    float y = element[1] - center[1];

    float z = x * x + y * y;

    distance = (float) Math.sqrt(z);

    return distance;

    }

    private int minDistance(float[] distance) {

    float minDistance = distance[0];

    int minLocation = 0;

    for (int i = 1; i < distance.length; i++) {

    if (distance[i] < minDistance) {

    minDistance = distance[i];

    minLocation = i;

    } else if (distance[i] == minDistance) // 如果相等,随机返回一个位置

    {

    if (random.nextInt(10) < 5) {

    minLocation = i;

    }

    }

    }

    return minLocation;

    }

    private void clusterSet() {

    float[] distance = new float[k];

    for (int i = 0; i < dataSetLength; i++) {

    for (int j = 0; j < k; j++) {

    distance[j] = distance(dataSet.get(i), center.get(j));

    //

    System.out.println("test2:"+"dataSet["+i+"],center["+j+"],distance="+distance[j]);

    }

    int minLocation = minDistance(distance);

    //

    System.out.println("test3:"+"dataSet["+i+"],minLocation="+minLocation);

    // System.out.println();

    cluster.get(minLocation).add(dataSet.get(i));//

    核心,将当前元素放到最小距离中心相关的簇中

    }

    }

    private float errorSquare(float[] element, float[] center) {

    float x = element[0] - center[0];

    float y = element[1] - center[1];

    float errSquare = x * x + y * y;

    return errSquare;

    }

    private void countRule() {

    float jcF = 0;

    for (int i = 0; i < cluster.size(); i++) {

    for (int j = 0; j < cluster.get(i).size(); j++) {

    jcF += errorSquare(cluster.get(i).get(j), center.get(i));

    }

    }

    jc.add(jcF);

    }

    private void setNewCenter() {

    for (int i = 0; i < k; i++) {

    int n = cluster.get(i).size();

    if (n != 0) {

    float[] newCenter = { 0, 0 };

    for (int j = 0; j < n; j++) {

    newCenter[0] += cluster.get(i).get(j)[0];

    newCenter[1] += cluster.get(i).get(j)[1];

    }

    // 设置一个平均值

    newCenter[0] = newCenter[0] / n;

    newCenter[1] = newCenter[1] / n;

    center.set(i, newCenter);

    }

    }

    }

    public void printDataArray(ArrayList dataArray,

    String dataArrayName) {

    for (int i = 0; i < dataArray.size(); i++) {

    System.out.println("print:" + dataArrayName + "[" + i +

    "]={"

    + dataArray.get(i)[0] + "," + dataArray.get(i)[1] + "}");

    }

    System.out.println("===================================");

    }

    private void kmeans() {

    init();

    // printDataArray(dataSet,"initDataSet");

    // printDataArray(center,"initCenter");

    // 循环分组,直到误差不变为止

    while (true) {

    clusterSet();

    // for(int i=0;i

    // {

    // printDataArray(cluster.get(i),"cluster["+i+"]");

    // }

    countRule();

    // System.out.println("count:"+"jc["+m+"]="+jc.get(m));

    // System.out.println();

    // 误差不变了,分组完成

    if (m != 0) {

    if (jc.get(m) - jc.get(m - 1) == 0) {

    break;

    }

    }

    setNewCenter();

    // printDataArray(center,"newCenter");

    m++;

    cluster.clear();

    cluster = initCluster();

    }

    // System.out.println("note:the times of

    repeat:m="+m);//输出迭代次数

    }

    public void execute() {

    long startTime = System.currentTimeMillis();

    System.out.println("kmeans begins");

    kmeans();

    long endTime = System.currentTimeMillis();

    System.out.println("kmeans running time=" + (endTime -

    startTime)

    + "ms");

    System.out.println("kmeans ends");

    System.out.println();

    }

    }

    package org.algorithm;

    import java.util.ArrayList;

    import java.util.Random;

    public class Kmeans {

    private int k;// 分成多少簇

    private int m;// 迭代次数

    private int dataSetLength;// 数据集元素个数,即数据集的长度

    private ArrayList dataSet;// 数据集链表

    private ArrayList center;// 中心链表

    private ArrayList> cluster; // 簇

    private ArrayList jc;// 误差平方和,k越接近dataSetLength,误差越小

    private Random random;

    public void setDataSet(ArrayList dataSet) {

    this.dataSet = dataSet;

    }

    public ArrayList> getCluster() {

    return cluster;

    }

    public Kmeans(int k) {

    if (k <= 0) {

    k = 1;

    }

    this.k = k;

    }

    private void init() {

    m = 0;

    random = new Random();

    if (dataSet == null || dataSet.size() == 0) {

    initDataSet();

    }

    dataSetLength = dataSet.size();

    if (k > dataSetLength) {

    k = dataSetLength;

    }

    center = initCenters();

    cluster = initCluster();

    jc = new ArrayList();

    }

    private void initDataSet() {

    dataSet = new ArrayList();

    // 其中{6,3}是一样的,所以长度为15的数据集分成14簇和15簇的误差都为0

    float[][] dataSetArray = new float[][] { { 8, 2 }, { 3, 4 }, { 2, 5

    },

    { 4, 2 }, { 7, 3 }, { 6, 2 }, { 4, 7 }, { 6, 3 }, { 5, 3 },

    { 6, 3 }, { 6, 9 }, { 1, 6 }, { 3, 9 }, { 4, 1 }, { 8, 6 } };

    for (int i = 0; i < dataSetArray.length; i++) {

    dataSet.add(dataSetArray[i]);

    }

    }

    private ArrayList initCenters() {

    ArrayList center = new ArrayList();

    int[] randoms = new int[k];

    boolean flag;

    int temp = random.nextInt(dataSetLength);

    randoms[0] = temp;

    for (int i = 1; i < k; i++) {

    flag = true;

    while (flag) {

    temp = random.nextInt(dataSetLength);

    int j = 0;

    // 不清楚for循环导致j无法加1

    // for(j=0;j

    // {

    // if(temp==randoms[j]);

    // {

    // break;

    // }

    // }

    while (j < i) {

    if (temp == randoms[j]) {

    break;

    }

    j++;

    }

    if (j == i) {

    flag = false;

    }

    }

    randoms[i] = temp;

    }

    // 测试随机数生成情况

    // for(int i=0;i

    // {

    // System.out.println("test1:randoms["+i+"]="+randoms[i]);

    // }

    // System.out.println();

    for (int i = 0; i < k; i++) {

    center.add(dataSet.get(randoms[i]));// 生成初始化中心链表

    }

    return center;

    }

    private ArrayList> initCluster() {

    ArrayList> cluster = new ArrayList>();

    for (int i = 0; i < k; i++) {

    cluster.add(new ArrayList());

    }

    return cluster;

    }

    private float distance(float[] element, float[] center) {

    float distance = 0.0f;

    float x = element[0] - center[0];

    float y = element[1] - center[1];

    float z = x * x + y * y;

    distance = (float) Math.sqrt(z);

    return distance;

    }

    private int minDistance(float[] distance) {

    float minDistance = distance[0];

    int minLocation = 0;

    for (int i = 1; i < distance.length; i++) {

    if (distance[i] < minDistance) {

    minDistance = distance[i];

    minLocation = i;

    } else if (distance[i] == minDistance) // 如果相等,随机返回一个位置

    {

    if (random.nextInt(10) < 5) {

    minLocation = i;

    }

    }

    }

    return minLocation;

    }

    private void clusterSet() {

    float[] distance = new float[k];

    for (int i = 0; i < dataSetLength; i++) {

    for (int j = 0; j < k; j++) {

    distance[j] = distance(dataSet.get(i), center.get(j));

    //

    System.out.println("test2:"+"dataSet["+i+"],center["+j+"],distance="+distance[j]);

    }

    int minLocation = minDistance(distance);

    //

    System.out.println("test3:"+"dataSet["+i+"],minLocation="+minLocation);

    // System.out.println();

    cluster.get(minLocation).add(dataSet.get(i));//

    核心,将当前元素放到最小距离中心相关的簇中

    }

    }

    private float errorSquare(float[] element, float[] center) {

    float x = element[0] - center[0];

    float y = element[1] - center[1];

    float errSquare = x * x + y * y;

    return errSquare;

    }

    private void countRule() {

    float jcF = 0;

    for (int i = 0; i < cluster.size(); i++) {

    for (int j = 0; j < cluster.get(i).size(); j++) {

    jcF += errorSquare(cluster.get(i).get(j), center.get(i));

    }

    }

    jc.add(jcF);

    }

    private void setNewCenter() {

    for (int i = 0; i < k; i++) {

    int n = cluster.get(i).size();

    if (n != 0) {

    float[] newCenter = { 0, 0 };

    for (int j = 0; j < n; j++) {

    newCenter[0] += cluster.get(i).get(j)[0];

    newCenter[1] += cluster.get(i).get(j)[1];

    }

    // 设置一个平均值

    newCenter[0] = newCenter[0] / n;

    newCenter[1] = newCenter[1] / n;

    center.set(i, newCenter);

    }

    }

    }

    public void printDataArray(ArrayList dataArray,

    String dataArrayName) {

    for (int i = 0; i < dataArray.size(); i++) {

    System.out.println("print:" + dataArrayName + "[" + i + "]={"

    + dataArray.get(i)[0] + "," + dataArray.get(i)[1] + "}");

    }

    System.out.println("===================================");

    }

    private void kmeans() {

    init();

    // printDataArray(dataSet,"initDataSet");

    // printDataArray(center,"initCenter");

    // 循环分组,直到误差不变为止

    while (true) {

    clusterSet();

    // for(int i=0;i

    // {

    // printDataArray(cluster.get(i),"cluster["+i+"]");

    // }

    countRule();

    // System.out.println("count:"+"jc["+m+"]="+jc.get(m));

    // System.out.println();

    // 误差不变了,分组完成

    if (m != 0) {

    if (jc.get(m) - jc.get(m - 1) == 0) {

    break;

    }

    }

    setNewCenter();

    // printDataArray(center,"newCenter");

    m++;

    cluster.clear();

    cluster = initCluster();

    }

    // System.out.println("note:the times of repeat:m="+m);//输出迭代次数

    }

    public void execute() {

    long startTime = System.currentTimeMillis();

    System.out.println("kmeans begins");

    kmeans();

    long endTime = System.currentTimeMillis();

    System.out.println("kmeans running time=" + (endTime -

    startTime)

    + "ms");

    System.out.println("kmeans ends");

    System.out.println();

    }

    }

    测试:

    1.聚类分析

    聚类分析是数据挖掘中的一种分析方法,它把一个没有类别标记的样本集按照一种准则划分成若干个相似的子集类,使相似的样本尽可能归为一类,不相似的划分到不同的类别中。聚类通过比较数据的相似性和差异性发现数据的内在特征和分布规律,从而获得对数据更深刻的认识。聚类分析以相似性为基础,在一个聚类中的模式之间比不在同一聚类中的模式之间具有更多的相似性。

    聚类分析的算法可以分为划分法、层次法、基于密度的方法、基于网格的方法、基于模型的方法。

    基于划分的聚类主要有k-平均及其变种,速度快易于实现还适用于文本图像等多种数据的聚类分析。

    k-means算法

    k-means 算法接受输入量 k ;然后将n个数据对象划分为

    k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。

    k-means 算法的工作过程说明如下:

    首先从n个数据对象任意选择 k

    个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;

    然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。

    一般都采用均方差作为标准测度函数.

    k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。

    KMeans算法的基本思想是初始随机给定K个簇中心,按照最邻近原则把待分类样本点分到各个簇。然后按平均法重新计算各个簇的质心,从而确定新的簇心。一直迭代,直到簇心的移动距离小于某个给定的值。

    a4c26d1e5885305701be709a3d33442f.png

    a4c26d1e5885305701be709a3d33442f.png

    展开全文
  • java简单实现聚类算法 但是有一个小问题,,,,我其实每次迭代之后(就是达不到我的收敛标准之前,聚类中心的误差达不到指定小的时候),虽然重新算了聚类中心,但是其实我的那些点并没有变,可是这个程序不知道咋...

    2016-07

    java简单实现聚类算法

    但是有一个小问题,,,,我其实每次迭代之后(就是达不到我的收敛标准之前,聚类中心的误差达不到指定小的时候),虽然重新算了聚类中心,但是其实我的那些点并没有变,可是这个程序不知道咋回事每次都把我原先随机指定的聚类中心给变成了我算的聚类中心,怎么用,按照指示来就行了,不用读文件(源码全都是可以运行的,反正在我这个几几上是木有错误,才往上贴的,有的不足之处还望批评指正)输出的结果有一堆小数的那是新聚类中心和老的的误差值,在没有达到指定小的时候,是不会停的。

    2016-11

    重新看看。。终于改好了。。。。。。Java对象直接赋值属于浅拷贝

    修改后为创建一个对象,值来源于随机点,但是跟随机点已经没有任何关系了。。。。。

    A a=b;浅拷贝

    ..............................

    A a=new A();

    a.x=b.x;

    a.y=b.y;

     a并没有引用b

    、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

    题目如下:、

     初始,有问题版本:

      1 import java.sql.Array;
      2 import java.util.ArrayList;
      3 import java.util.Random;
      4 import java.util.Scanner;
      5 
      6 class point {
      7     public float x = 0;
      8     public float y = 0;
      9     public int flage = -1;
     10 
     11     public float getX() {
     12         return x;
     13     }
     14 
     15     public void setX(float x) {
     16         this.x = x;
     17     }
     18 
     19     public float getY() {
     20         return y;
     21     }
     22 
     23     public void setY(float y) {
     24         this.y = y;
     25     }
     26 }
     27 
     28 public class Kcluster {
     29 
     30     point[] ypo;// 点集
     31     point[] pacore = null;// old聚类中心
     32     point[] pacoren = null;// new聚类中心
     33 
     34     // 初试聚类中心,点集
     35     public void productpoint() {
     36         Scanner cina = new Scanner(System.in);
     37         System.out.print("请输入聚类中点的个数(随机产生):");
     38         int num = cina.nextInt();
     39 
     40         ypo = new point[num];
     41         // 随机产生点
     42         for (int i = 0; i < num; i++) {
     43 
     44             float x = (int) (new Random().nextInt(10));
     45             float y = (int) (new Random().nextInt(10));
     46 
     47             ypo[i] = new point();// 对象创建
     48             ypo[i].setX(x);
     49             ypo[i].setY(y);
     50 
     51         }
     52 
     53         // 初始化聚类中心位置
     54         System.out.print("请输入初始化聚类中心个数(随机产生):");
     55         int core = cina.nextInt();
     56         this.pacore = new point[core];// 存放聚类中心
     57         this.pacoren = new point[core];
     58 
     59         Random rand = new Random();
     60         int temp[] = new int[core];
     61         temp[0] = rand.nextInt(num);
     62         pacore[0] = new point();
     63         pacore[0] = ypo[temp[0]];
     64         // 避免产生重复的中心
     65         for (int i = 1; i < core; i++) {
     66             int flage = 0;
     67             int thistemp = rand.nextInt(num);
     68             for (int j = 0; j < i; j++) {
     69                 if (temp[j] == thistemp) {
     70                     flage = 1;// 有重复
     71                     break;
     72 
     73                 }
     74             }
     75             if (flage == 1) {
     76                 i--;
     77             } else {
     78                 pacore[i] = new point();
     79                 pacore[i] = ypo[thistemp];
     80                 pacore[i].flage = 0;// 0表示聚类中心
     81             }
     82 
     83         }
     84         System.out.println("初始聚类中心:");
     85         for (int i = 0; i < pacore.length; i++) {
     86             System.out.println(pacore[i].x + " " + pacore[i].y);
     87         }
     88 
     89     }
     90 
     91     // ///找出每个点属于哪个聚类中心
     92     public void searchbelong()// 找出每个点属于哪个聚类中心
     93     {
     94 
     95         for (int i = 0; i < ypo.length; i++) {
     96             double dist = 999;
     97             int lable = -1;
     98             for (int j = 0; j < pacore.length; j++) {
     99 
    100                 double distance = distpoint(ypo[i], pacore[j]);
    101                 if (distance < dist) {
    102                     dist = distance;
    103                     lable = j;
    104                     // po[i].flage = j + 1;// 1,2,3......
    105 
    106                 }
    107             }
    108             ypo[i].flage = lable + 1;
    109 
    110         }
    111 
    112     }
    113 
    114     // 更新聚类中心
    115     public void calaverage() {
    116 
    117         for (int i = 0; i < pacore.length; i++) {
    118             System.out.println("以<" + pacore[i].x + "," + pacore[i].y
    119                     + ">为中心的点:");
    120             int numc = 0;
    121             point newcore = new point();
    122             for (int j = 0; j < ypo.length; j++) {
    123 
    124                 if (ypo[j].flage == (i + 1)) {
    125                     numc += 1;
    126                     newcore.x += ypo[j].x;
    127                     newcore.y += ypo[j].y;
    128                     System.out.println(ypo[j].x + "," + ypo[j].y);
    129                 }
    130             }
    131             // 新的聚类中心
    132             pacoren[i] = new point();
    133             pacoren[i].x = newcore.x / numc;
    134             pacoren[i].y = newcore.y / numc;
    135             pacoren[i].flage = 0;
    136             System.out.println("新的聚类中心:" + pacoren[i].x + "," + pacoren[i].y);
    137 
    138         }
    139     }
    140 
    141     public double distpoint(point px, point py) {
    142 
    143         return Math.sqrt(Math.pow((px.x - py.x), 2)
    144                 + Math.pow((px.y - py.y), 2));
    145 
    146     }
    147 
    148     public void change_oldtonew(point[] old, point[] news) {
    149         for (int i = 0; i < old.length; i++) {
    150             old[i].x = news[i].x;
    151             old[i].y = news[i].y;
    152             old[i].flage = 0;// 表示为聚类中心的标志。
    153         }
    154     }
    155 
    156     public void movecore() {
    157         // this.productpoint();//初始化,样本集,聚类中心,
    158         this.searchbelong();
    159         this.calaverage();//
    160         double movedistance = 0;
    161         int biao = -1;//标志,聚类中心点的移动是否符合最小距离
    162         for (int i = 0; i < pacore.length; i++) {
    163             movedistance = distpoint(pacore[i], pacoren[i]);
    164             System.out.println("distcore:" + movedistance);//聚类中心的移动距离
    165             if (movedistance < 0.01) {
    166                 biao = 0;
    167 
    168             } else {
    169                 
    170                 biao=1;
    171                 break;
    172 
    173             }
    174         }
    175         if (biao == 0) {
    176             System.out.print("迭代完毕!!!!!");
    177         } else {
    178             change_oldtonew(pacore, pacoren);
    179             movecore();
    180         }
    181 
    182     }
    183 
    184     public static void main(String[] args) {
    185         // TODO Auto-generated method stub
    186 
    187         Kcluster kmean = new Kcluster();
    188         kmean.productpoint();
    189         kmean.movecore();
    190     }
    191 
    192 }

     修稿版:在初始化聚类中心那里。。。。。。。。。。。。嘤嘤嘤

      1 import java.sql.Array;
      2 import java.util.ArrayList;
      3 import java.util.Random;
      4 import java.util.Scanner;
      5 
      6 class point {
      7     public float x = 0;
      8     public float y = 0;
      9     public int flage = -1;
     10 
     11     public float getX() {
     12         return x;
     13     }
     14 
     15     public void setX(float x) {
     16         this.x = x;
     17     }
     18 
     19     public float getY() {
     20         return y;
     21     }
     22 
     23     public void setY(float y) {
     24         this.y = y;
     25     }
     26 }
     27 
     28 public class Kcluster {
     29 
     30     point[] ypo;// 点集
     31     point[] pacore = null;// old聚类中心
     32     point[] pacoren = null;// new聚类中心
     33 
     34     // 初试聚类中心,点集
     35     public void productpoint() {
     36         Scanner cina = new Scanner(System.in);
     37         System.out.print("请输入聚类中点的个数(随机产生):");
     38         int num = cina.nextInt();
     39 
     40         ypo = new point[num];
     41         // 随机产生点
     42         for (int i = 0; i < num; i++) {
     43 
     44             float x = (int) (new Random().nextInt(10));
     45             float y = (int) (new Random().nextInt(10));
     46 
     47             ypo[i] = new point();// 对象创建
     48             ypo[i].setX(x);
     49             ypo[i].setY(y);
     50 
     51         }
     52 
     53         // 初始化聚类中心位置
     54         System.out.print("请输入初始化聚类中心个数(随机产生):");
     55         int core = cina.nextInt();
     56         this.pacore = new point[core];// 存放聚类中心
     57         this.pacoren = new point[core];
     58 
     59         Random rand = new Random();
     60         int temp[] = new int[core];
     61         temp[0] = rand.nextInt(num);
     62         pacore[0] = new point();
     63         pacore[0].x = ypo[temp[0]].x;
     64         pacore[0].y = ypo[temp[0]].y;
     65         pacore[0].flage=0 ;
     66         // 避免产生重复的中心
     67         for (int i = 1; i < core; i++) {
     68             int flage = 0;
     69             int thistemp = rand.nextInt(num);
     70             for (int j = 0; j < i; j++) {
     71                 if (temp[j] == thistemp) {
     72                     flage = 1;// 有重复
     73                     break;
     74 
     75                 }
     76             }
     77             if (flage == 1) {
     78                 i--;
     79             } else {
     80                 pacore[i] = new point();
     81                 pacore[i].x= ypo[thistemp].x;
     82                 pacore[i].y = ypo[thistemp].y;
     83                 pacore[i].flage = 0;// 0表示聚类中心
     84             }
     85 
     86         }
     87         System.out.println("初始聚类中心:");
     88         for (int i = 0; i < pacore.length; i++) {
     89             System.out.println(pacore[i].x + " " + pacore[i].y);
     90         }
     91 
     92     }
     93 
     94     // ///找出每个点属于哪个聚类中心
     95     public void searchbelong()// 找出每个点属于哪个聚类中心
     96     {
     97 
     98         for (int i = 0; i < ypo.length; i++) {
     99             double dist = 999;
    100             int lable = -1;
    101             for (int j = 0; j < pacore.length; j++) {
    102 
    103                 double distance = distpoint(ypo[i], pacore[j]);
    104                 if (distance < dist) {
    105                     dist = distance;
    106                     lable = j;
    107                     // po[i].flage = j + 1;// 1,2,3......
    108 
    109                 }
    110             }
    111             ypo[i].flage = lable + 1;
    112 
    113         }
    114 
    115     }
    116 
    117     // 更新聚类中心
    118     public void calaverage() {
    119 
    120         for (int i = 0; i < pacore.length; i++) {
    121             System.out.println("以<" + pacore[i].x + "," + pacore[i].y
    122                     + ">为中心的点:");
    123             int numc = 0;
    124             point newcore = new point();
    125             for (int j = 0; j < ypo.length; j++) {
    126 
    127                 if (ypo[j].flage == (i + 1)) {
    128                     System.out.println(ypo[j].x + "," + ypo[j].y);
    129                     numc += 1;
    130                     newcore.x += ypo[j].x;
    131                     newcore.y += ypo[j].y;
    132                     
    133                 }
    134             }
    135             // 新的聚类中心
    136             pacoren[i] = new point();
    137             pacoren[i].x = newcore.x / numc;
    138             pacoren[i].y = newcore.y / numc;
    139             pacoren[i].flage = 0;
    140             System.out.println("新的聚类中心:" + pacoren[i].x + "," + pacoren[i].y);
    141 
    142         }
    143     }
    144 
    145     public double distpoint(point px, point py) {
    146 
    147         return Math.sqrt(Math.pow((px.x - py.x), 2)
    148                 + Math.pow((px.y - py.y), 2));
    149 
    150     }
    151 
    152     public void change_oldtonew(point[] old, point[] news) {
    153         for (int i = 0; i < old.length; i++) {
    154             old[i].x = news[i].x;
    155             old[i].y = news[i].y;
    156             old[i].flage = 0;// 表示为聚类中心的标志。
    157         }
    158     }
    159 
    160     public void movecore() {
    161         // this.productpoint();//初始化,样本集,聚类中心,
    162         this.searchbelong();
    163         this.calaverage();//
    164         double movedistance = 0;
    165         int biao = -1;//标志,聚类中心点的移动是否符合最小距离
    166         for (int i = 0; i < pacore.length; i++) {
    167             movedistance = distpoint(pacore[i], pacoren[i]);
    168             System.out.println("distcore:" + movedistance);//聚类中心的移动距离
    169             if (movedistance < 0.01) {
    170                 biao = 0;
    171 
    172             } else {
    173                 
    174                 biao=1;//需要继续迭代,
    175                 break;
    176 
    177             }
    178         }
    179         if (biao == 0) {
    180             System.out.print("迭代完毕!!!!!");
    181         } else {
    182             change_oldtonew(pacore, pacoren);
    183             movecore();
    184         }
    185 
    186     }
    187 
    188     public static void main(String[] args) {
    189         // TODO Auto-generated method stub
    190 
    191         Kcluster kmean = new Kcluster();
    192         kmean.productpoint();
    193         kmean.movecore();
    194     }
    195 
    196 }

     

    转载于:https://www.cnblogs.com/8335IT/p/5635965.html

    展开全文
  • 主要介绍了详解Java实现的k-means聚类算法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 对指定数据集进行聚类分析,选择适当的聚类算法,编写程序实现,提交程序和结果报告。 数据集: Iris Data Set(见附件一) ,根据花的属性进行聚类。 数据包括四个属性:sepal length花萼长度,sepal width花萼宽度...
  • 然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。k个...

    一,k-means算法介绍:

    k-means算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。 k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。

    k-means算法的工作过程说明如下:首先从n个数据对象任意选择 k 个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。一般都采用均方差作为标准测度函数。k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。

    二,k-means算法基本步骤:

    (1) 从 n个数据对象任意选择 k 个对象作为初始聚类中心;

    (2) 根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;并根据最小距离重新对相应对象进行划分;

    (3) 重新计算每个(有变化)聚类的均值(中心对象);

    (4) 计算标准测度函数,当满足一定条件,如函数收敛时,则算法终止;如果条件不满足则回到步骤(2),不断重复直到标准测度函数开始收敛为止。(一般都采用均方差作为标准测度函数。)

    三,k-means算法的java实现:

    一共有七个类,General.java代表武将对象, Distance.java距离类计算各个武将到中心武将之间的距离, Cluster.java聚类对象包含一个中心武将和该聚类中所有武将, Kmeans.java核心的聚类算法类, Tool.java工具类用于转换武将的星级为数字等操作, TestKmeans.java测试类即入口文件, DomParser.java用于读取xml中的681个武将。

    具体思路:先从general.xml文件中读取681个武将,然后随机选取初始类中心,计算各个武将到中心武将的距离,根据最小的距离进行聚类,然后重新根据平均值新的聚类的类中心,重新计算各个武将到新的中心武将的距离,直到更新后的聚类与原来的聚类包含的武将不再改变,即收敛时结束。

    具体代码如下:

    1,General.java

    
     
    packagekmeans;

    publicclassGeneral {

    privateString name;// 姓名

    privateintrender;// 星级

    privateinttongshai;// 统帅

    privateintwuli;// 武力

    privateintzhili;// 智力

    privateintpolic;// 政治

    privateintqiangbin;// 枪兵

    privateintjibin;// 戟兵

    privateintnubin;// 弩兵

    privateintqibin;// 骑兵

    privateintbinqi;// 兵器

    privateinttongwu;// 统武

    privateinttongzhi;// 统智

    privateinttongwuzhi;// 统武智

    privateinttongwuzhizheng;// 统武智政

    privateintsalary;// 50级工资

    publicGeneral(intrender, String name,inttongshai,intwuli,intzhili,

    intpolic,intqiangbin,intjibin,intnubin,intqibin,

    intbinqi,inttongwu,inttongzhi,inttongwuzhi,

    inttongwuzhizheng,intsalary) {

    super();

    this.name = name;

    this.render = render;

    this.tongshai = tongshai;

    this.wuli = wuli;

    this.zhili = zhili;

    this.polic = polic;

    this.qiangbin = qiangbin;

    this.jibin = jibin;

    this.nubin = nubin;

    this.qibin = qibin;

    this.binqi = binqi;

    this.tongwu = tongwu;

    this.tongzhi = tongzhi;

    this.tongwuzhi = tongwuzhi;

    this.tongwuzhizheng = tongwuzhizheng;

    this.salary = salary;

    }

    publicGeneral(intrender,inttongshai,intwuli,intzhili,intpolic,

    intqiangbin,intjibin,intnubin,intqibin,intbinqi,

    inttongwu,inttongzhi,inttongwuzhi,inttongwuzhizheng,

    intsalary) {

    super();

    this.name ="聚类中心";

    this.render = render;

    this.tongshai = tongshai;

    this.wuli = wuli;

    this.zhili = zhili;

    this.polic = polic;

    this.qiangbin = qiangbin;

    this.jibin = jibin;

    this.nubin = nubin;

    this.qibin = qibin;

    this.binqi = binqi;

    this.tongwu = tongwu;

    this.tongzhi = tongzhi;

    this.tongwuzhi = tongwuzhi;

    this.tongwuzhizheng = tongwuzhizheng;

    this.salary = salary;

    }

    publicGeneral() {

    }

    @Override

    publicString toString() {

    return"武将 [name="+ name +", render="+ Tool.dxingji(render)

    +", tongshai="+ tongshai +", wuli="+ wuli +", zhili="

    + zhili +", polic="+ polic +", qiangbin="

    + Tool.dchange(qiangbin) +", jibin="+ Tool.dchange(jibin)

    +", nubin="+ Tool.dchange(nubin) +", qibin="

    + Tool.dchange(qibin) +", binqi="+ Tool.dchange(binqi)

    +", tongwu="+ tongwu +", tongzhi="+ tongzhi

    +", tongwuzhi="+ tongwuzhi +", tongwuzhizheng="

    + tongwuzhizheng +", salary="+ salary +"]";

    }

    publicString getName() {

    returnname;

    }

    publicvoidsetName(String name) {

    this.name = name;

    }

    publicintgetRender() {

    returnrender;

    }

    publicvoidsetRender(intrender) {

    this.render = render;

    }

    publicintgetTongshai() {

    returntongshai;

    }

    publicvoidsetTongshai(inttongshai) {

    this.tongshai = tongshai;

    }

    publicintgetWuli() {

    returnwuli;

    }

    publicvoidsetWuli(intwuli) {

    this.wuli = wuli;

    }

    publicintgetZhili() {

    returnzhili;

    }

    publicvoidsetZhili(intzhili) {

    this.zhili = zhili;

    }

    publicintgetPolic() {

    returnpolic;

    }

    publicvoidsetPolic(intpolic) {

    this.polic = polic;

    }

    publicintgetQiangbin() {

    returnqiangbin;

    }

    publicvoidsetQiangbin(intqiangbin) {

    this.qiangbin = qiangbin;

    }

    publicintgetJibin() {

    returnjibin;

    }

    publicvoidsetJibin(intjibin) {

    this.jibin = jibin;

    }

    publicintgetNubin() {

    returnnubin;

    }

    publicvoidsetNubin(intnubin) {

    this.nubin = nubin;

    }

    publicintgetQibin() {

    returnqibin;

    }

    publicvoidsetQibin(intqibin) {

    this.qibin = qibin;

    }

    publicintgetBinqi() {

    returnbinqi;

    }

    publicvoidsetBinqi(intbinqi) {

    this.binqi = binqi;

    }

    publicintgetTongwu() {

    returntongwu;

    }

    publicvoidsetTongwu(inttongwu) {

    this.tongwu = tongwu;

    }

    publicintgetTongzhi() {

    returntongzhi;

    }

    publicvoidsetTongzhi(inttongzhi) {

    this.tongzhi = tongzhi;

    }

    publicintgetTongwuzhi() {

    returntongwuzhi;

    }

    publicvoidsetTongwuzhi(inttongwuzhi) {

    this.tongwuzhi = tongwuzhi;

    }

    publicintgetTongwuzhizheng() {

    returntongwuzhizheng;

    }

    publicvoidsetTongwuzhizheng(inttongwuzhizheng) {

    this.tongwuzhizheng = tongwuzhizheng;

    }

    publicintgetSalary() {

    returnsalary;

    }

    publicvoidsetSalary(intsalary) {

    this.salary = salary;

    }

    }

    2,Distance.java

    packagekmeans;

    /**

    * 这个类用于计算距离的。。

    *

    */

    publicclassDistance {

    intdest;// 目的

    intsource;// 源

    doubledist;// 欧式距离

    publicintgetDest() {

    returndest;

    }

    publicvoidsetDest(intdest) {

    this.dest = dest;

    }

    publicintgetSource() {

    returnsource;

    }

    publicvoidsetSource(intsource) {

    this.source = source;

    }

    publicdoublegetDist() {

    returndist;

    }

    publicvoidsetDist(doubledist) {

    this.dist = dist;

    }

    /**

    * 计算源和目的的距离

    * @param dest 目的武将

    * @param source 源武将

    * @param dist 两者间的距离

    */

    publicDistance(intdest,intsource,doubledist) {

    this.dest = dest;

    this.source = source;

    this.dist = dist;

    }

    publicDistance() {

    }

    }

    3,Cluster.java

    packagekmeans;

    importjava.util.ArrayList;

    publicclassCluster {

    privateintcenter;// 聚类中心武将的id

    privateArrayList ofCluster =newArrayList();// 属于这个聚类的武将的集合

    publicintgetCenter() {

    returncenter;

    }

    publicvoidsetCenter(intcenter) {

    this.center = center;

    }

    publicArrayList getOfCluster() {

    returnofCluster;

    }

    publicvoidsetOfCluster(ArrayList ofCluster) {

    this.ofCluster = ofCluster;

    }

    publicvoidaddGeneral(General general) {

    if(!(this.ofCluster.contains(general)))

    this.ofCluster.add(general);

    }

    }

    4,Kmeans.java

    
     

    packagekmeans;

    importjava.util.*;

    publicclassKmeans {

    publicArrayList allGenerals =null;

    publicinttotalNumber =0;// 得到所有的武将数目

    publicintK =0;// 假设K=10

    publicKmeans() {

    allGenerals =newDomParser().prepare();

    totalNumber = allGenerals.size();

    K =3;

    }

    // 第一次随机选取聚类中心

    publicSet firstRandom() {

    Set center =newHashSet();// 聚类中心的点的id,采用set保证不会有重复id

    Random ran =newRandom();

    introll = ran.nextInt(totalNumber);

    while(center.size() 

    roll = ran.nextInt(totalNumber);

    center.add(roll);

    }

    returncenter;

    }

    // 根据聚类中心初始化聚类信息

    publicArrayList init(Set center) {

    ArrayList cluster =newArrayList();// 聚类 的数组

    Iterator it = center.iterator();

    while(it.hasNext()) {

    Cluster c =newCluster();// 代表一个聚类

    c.setCenter(it.next());

    cluster.add(c);

    }

    returncluster;

    }

    /**

    * 计算各个武将到各个聚类中心的距离,重新聚类

    *

    * @param cluster

    *            聚类数组,用来聚类的,根据最近原则把武将聚类

    * @param center

    *            中心点id,用于计算各个武将到中心点的距离 return cluster 聚类后的所有聚类组成的数组

    */

    publicArrayList juLei(Set center,

    ArrayList cluster) {

    ArrayList distence =newArrayList();// 存放距离信息,表示每个点到各个中心点的距离组成的数组

    General source =null;

    General dest =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;

    }

    // 产生新的聚类中心点数组

    publicSet updateCenter() {

    Set center =newHashSet();

    for(inti =0; i 

    center.add(i);

    }

    returncenter;

    }

    // 更新聚类中心, 求平均值

    publicArrayList updateCluster(ArrayList cluster) {

    ArrayList result =newArrayList();

    // 重新产生的新的聚类中心组成的数组

    // k个聚类进行更新聚类中心

    for(intj =0; j 

    ArrayList ps = 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();

    }

    // 产生新的聚类,然后加入到聚类数组中

    Cluster newCluster =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;

    }

    /**

    * 计算各个武将到各个更新后的聚类中心的距离,重新聚类

    * @param update 更新后的聚类中心

    * @param cluster 要存储的聚类中心

    */

    publicArrayList updateJuLei(ArrayList update,

    ArrayList cluster) {

    ArrayList distence =newArrayList();// 存放距离信息,表示每个点到各个中心点的距离组成的数组

    General source =null;

    General dest =null;

    intid =0;// 目的节点id

    intid2 =0;// 源节点id

    //Object[] p = center.toArray();// p 为聚类中心点id数组

    booleanflag =false;

    // 分别计算各个点到各个中心点的距离,并将距离最小的加入到各个聚类中,进行聚类

    for(inti =0; i 

    // 每个点计算完,并聚类到距离最小的聚类中就清空距离数组

    distence.clear();

    // 计算到j个类中心点的距离,便利各个中心点

    //for (int j = 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(new Distance((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;

    }

    // 不断循环聚类直到各个聚类没有重新分配

    publicArrayList getResult() {

    ArrayList result =newArrayList();

    ArrayList temp =newArrayList();

    booleanflag =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);

    returnresult;

    }

    publicbooleanisEquals(ArrayList temp, ArrayList result){

    booleanflag =false;

    if(temp.size() != result.size()){

    returnflag;

    }

    for(Cluster tem : temp){

    for(Cluster res : result){

    if(tem.getCenter() == res.getCenter()){

    flag =true;

    }

    }

    // 如果找了一轮没找到 则说明两个聚类

    if(flag ==false){

    returnfalse;

    }else{// 如果找了一轮找到了,那么接着找

    flag =false;

    }

    }

    //如果代码能进行到这边,说明是true

    flag =true;

    returnflag;

    }

    //输出所有的聚类

    publicvoidprint(ArrayList cs) {

    System.out.println("***************************************");

    for(inti =0; i 

    Cluster c = cs.get(i);

    System.out.println("-----------------------------------------------------");

    System.out.println("center: "+ allGenerals.get(c.getCenter()));

    ArrayList p = c.getOfCluster();

    for(intj =0; j 

    System.out.println("general:"+p.get(j)+"\n");

    }

    }

    }

    }

    5,Tool.java

    packagekmeans;

    publicclassTool {

    //将各种武器的精通程度转为数字

    publicstaticintchange(String str) {

    intresult = str.equals("精") ?4: (str.equals("神") ?3: (str

    .equals("通") ?2:1));

    returnresult;

    }

    //将星级转为数字

    publicstaticintxingji(String str) {

    intresult = str.equals("★★★★★") ?5: (str.equals("★★★★") ?4: (str

    .equals("★★★") ?3: (str.equals("★★") ?2:1)));

    returnresult;

    }

    //反转 将各种武器的数字转为精通程度

    publicstaticString dchange(intstr) {

    String result = str==4?"精": (str==3?"神": (str==2?"通":"疏"));

    returnresult;

    }

    //反转 将数字转为星级

    publicstaticString dxingji(intstr) {

    String result = str==5?"★★★★★": (str==4?"★★★★": (str==3?"★★★": (str ==2?"★★":"★")));

    returnresult;

    }

    //计算欧式距离 传入两个将军对象。。

    publicstaticdoublejuli(General g1, General g2) {

    doubleresult = (Double) Math.sqrt(StrictMath.pow(g1.getRender() - g2.getRender(),2)

    + StrictMath.pow(g1.getTongshai() - g2.getTongshai(),2)

    + StrictMath.pow(g1.getWuli() - g2.getWuli(),2)

    + StrictMath.pow(g1.getZhili() - g2.getZhili(),2)

    + StrictMath.pow(g1.getPolic() - g2.getPolic(),2)

    + StrictMath.pow(g1.getQiangbin() - g2.getQiangbin(),2)

    + StrictMath.pow(g1.getQibin() - g2.getQibin(),2)

    + StrictMath.pow(g1.getJibin() - g2.getJibin(),2)

    + StrictMath.pow(g1.getNubin() - g2.getNubin(),2)

    + StrictMath.pow(g1.getBinqi() - g2.getBinqi(),2)

    + StrictMath.pow(g1.getTongwu() - g2.getTongwu(),2)

    + StrictMath.pow(g1.getTongzhi() - g2.getTongzhi(),2)

    + StrictMath.pow(g1.getTongwuzhizheng() - g2.getTongwuzhizheng(),2)

    + StrictMath.pow(g1.getTongwuzhi() - g2.getTongwuzhi(),2)

    + StrictMath.pow(g1.getSalary() - g2.getSalary(),2)

    );

    returnresult;

    }

    }

    6,DomParser.java

    packagekmeans;

    importjavax.xml.parsers.*;

    importjava.io.*;

    importjava.util.ArrayList;

    importorg.w3c.dom.*;

    importorg.xml.sax.SAXException;

    publicclassDomParser {

    privateArrayList generals =newArrayList();

    publicArrayList prepare(){

    // get dom解析器工厂

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

    factory.setIgnoringElementContentWhitespace(true);

    // get dom 解析器

    DocumentBuilder builder =null;

    try{

    builder = factory.newDocumentBuilder();

    }catch(ParserConfigurationException e) {

    e.printStackTrace();

    }

    // 解析文档

    Document doc =null;

    try{

    doc = builder.parse(newFile("general.xml"));

    }catch(SAXException e) {

    e.printStackTrace();

    }catch(IOException e) {

    e.printStackTrace();

    }

    // 取得根节点

    Element generalList = doc.getDocumentElement();

    // 得到所有row节点

    NodeList nodeList = generalList.getElementsByTagName("Row");

    // 便利所有row节点

    for(inti =1; i 

    System.out.println("------------the "+ i

    +" element--------------");

    Node row = nodeList.item(i);

    // 取得所有Data数据

    NodeList attList = row.getChildNodes();

    // 取得数据中的各个部分, 并加入ArrayList中

    generals.add(newGeneral(Tool.xingji(attList.item(1)

    .getTextContent()), attList.item(3).getTextContent(),

    Integer.parseInt(attList.item(5).getTextContent()),

    Integer.parseInt(attList.item(7).getTextContent()),

    Integer.parseInt(attList.item(9).getTextContent()),

    Integer.parseInt(attList.item(11).getTextContent()),

    Tool.change(attList.item(13).getTextContent()),

    Tool.change(attList.item(15).getTextContent()),

    Tool.change(attList.item(17).getTextContent()),

    Tool.change(attList.item(19).getTextContent()),

    Tool.change(attList.item(21).getTextContent()),

    Integer.parseInt(attList.item(23).getTextContent()),

    Integer.parseInt(attList.item(25).getTextContent()),

    Integer.parseInt(attList.item(27).getTextContent()),

    Integer.parseInt(attList.item(29).getTextContent()),

    Integer.parseInt(attList.item(31).getTextContent())));

    System.out.println(" 星级:"

    + Tool.xingji(attList.item(1).getTextContent()) +" 姓名:"

    + attList.item(3).getTextContent() +" 统率:"

    + attList.item(5).getTextContent() +" 武力:"

    + attList.item(7).getTextContent() +" 智力:"

    + attList.item(9).getTextContent() +" 政治:"

    + attList.item(11).getTextContent() +"枪兵:"

    + Tool.change(attList.item(13).getTextContent()) +" 戟兵:"

    + Tool.change(attList.item(15).getTextContent()) +" 弩兵:"

    + Tool.change(attList.item(17).getTextContent()) +" 骑兵:"

    + Tool.change(attList.item(19).getTextContent()) +" 兵器:"

    + Tool.change(attList.item(21).getTextContent()) +" 统武:"

    + attList.item(23).getTextContent() +" 统智:"

    + attList.item(25).getTextContent() +" 统武智:"

    + attList.item(27).getTextContent() +" 统武智政:"

    + attList.item(29).getTextContent() +" 50级工资:"

    + attList.item(31).getTextContent() +" ");

    /*

    * for (int j = 0; j 

    * System.out.println(attList.item(j).getTextContent()); }

    */

    }

    returngenerals;

    }

    }

    7,TestKmeans.java

    packagekmeans;

    publicclassTestKmeans {

    publicstaticvoidmain(String[] args) {

    Kmeans_eold kmeans =newKmeans_eold();

    kmeans.print(kmeans.getResult());

    }

    }

    附部分general.xml:

    xmlns:o="urn:schemas-microsoft-com:office:office"

    xmlns:x="urn:schemas-microsoft-com:office:excel"

    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"

    xmlns:html="http://www.w3.org/TR/REC-html40">

    2006-09-13T11:21:51Z

    2012-04-26T13:39:57Z

    14.00

    5850

    11070

    0

    90

    False

    False

    x:FullRows="1"ss:DefaultColumnWidth="54"ss:DefaultRowHeight="13.5">

    星级

    姓名

    统率

    武力

    智力

    政治

    枪兵

    戟兵

    弩兵

    骑兵

    兵器

    统武

    统智

    统武智

    统武智政

    50级工资

    ★★★★★

    吕布

    87

    100

    26

    13

    161

    194

    257

    350

    19250

    ★★★★★

    张飞

    85

    98

    30

    22

    168

    193

    264

    350

    19250

    ★★★★★

    関羽

    95

    97

    75

    62

    165

    191

    260

    347

    19085

    ★★★★★

    马超

    88

    97

    44

    26

    168

    187

    259

    353

    19415

    ★★★★★

    赵雲

    91

    96

    76

    65

    192

    170

    267

    329

    18095

    ★★★★★

    许褚

    65

    96

    36

    20

    161

    101

    197

    217

    11935

    ★★★★★

    典韦

    56

    95

    35

    29

    151

    91

    186

    215

    11825

    ★★★★★

    甘宁

    86

    94

    76

    18

    181

    183

    270

    351

    19305

    ★★★★★

    庞德

    80

    94

    70

    44

    174

    150

    244

    288

    15840

    ★★★★★

    文醜

    78

    94

    25

    25

    172

    103

    197

    222

    12210

    ★★★★★

    黄忠

    86

    93

    60

    52

    185

    171

    263

    321

    17655

    ★★★★★

    太史慈

    82

    93

    66

    58

    175

    148

    241

    299

    16445

    ★★★★★

    颜良

    79

    93

    42

    32

    172

    121

    214

    246

    13530

    ★★★★★

    张辽

    93

    92

    78

    58

    183

    167

    257

    330

    18150

    ★★★★★

    孙策

    92

    92

    69

    70

    130

    192

    230

    325

    17875

    ★★★★★

    魏延

    81

    92

    69

    49

    173

    150

    242

    291

    16005

    ★★★★★

    华雄

    81

    92

    56

    40

    173

    137

    229

    269

    14795

    最终运行结果截图如下:

    读取到得武将数据如图,

    ff166406114cdddaf6a46e5d2bf1d7f6.png

    运行后的部分截图:

    30f76e1e02cfd0982f89622b59c8cfc0.png

    【编辑推荐】

    【责任编辑:小林 TEL:(010)68476606】

    点赞 0

    展开全文
  • 基于演化依赖的Java软件聚类实现技术研究
  • java实现的KMeans聚类算法

    热门讨论 2013-01-24 20:00:13
    java实现kmeans算法,可以处理任意维度的向量。并将聚类结果写入文本。
  • 主要介绍了K均值聚类算法的Java实现代码示例,具有一定借鉴价值,需要的朋友可以参考下。
  • 多维k-means聚类算法java简单实现,导入运行KmeansTest.java可看到结果 多维k-means聚类算法java简单实现,导入运行KmeansTest.java可看到结果
  • java 算法的实现说明 1) 假设给点一组 c 点资料 X = {x1, ..., xc} ,每一点都有 d 维;给定一个群聚的数目 k, 求其 最好的聚类结果。 2 ) BasicKMeans.java 主类 int coordCount = 250;// 原始的资料个树 int ...

    从网上找到了很多定义,这里选取比较典型的几个;

    K-Mean

    分群法是一种分割式分群方法,其主要目标是要在大量高纬的资料点中找出

    具有代表性的资料点;这些资料点可以称为群中心,代表点;然后再根据这些

    群中心,进行后续的处理,这些处理可以包含

    1

    )资料压缩:以少数的资料点来代表大量的资料,达到资料压缩的功能;

    2

    )资料分类:以少数代表点来代表特点类别的资料,可以降低资料量及计算量;

    分割式分群法的目的是希望盡量減小每個群聚中,每一點與群中心的距離平方差(square error)。

    假設我們現在有一組包含c個群聚的資料,其中第k個群聚可以用集合Gk來表示,假設Gk包含nk筆

    資料{x1, x2, …, xnk),此群聚中心為yk,則該群聚的平方差ek可以定義為:

    ek =

    S

    i

    |xi-yk|2

    ,其中xi是屬於第k群的資料點。

    而這c個群聚的總和平方差E便是每個群聚的平方差總和:

    E =

    S

    k=1~c

    ek

    我們分群的方法,就變成是一個最佳化的問題,換句話說,我們要如何選取c個群聚以及相關的群中心,

    使得E的值為最小。

    2

    .处理流程

    (

    1

    )

    c

    个数据对象任意选择

    k

    个对象作为初始聚类中心;

    (

    2

    )

    循环(

    3

    )到(

    4

    )直到每个聚类不再发生变化为止;

    (

    3

    )

    根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;并根据最小距离重新对相应对象进行划分;

    (

    4

    )

    重新计算每个(有变化)聚类的均值(中心对象)

    3. java

    算法的实现说明

    1)

    假设给点一组

    c

    点资料

    X = {x1, ..., xc}

    ,每一点都有

    d

    维;给定一个群聚的数目

    k,

    求其

    最好的聚类结果。

    2

    )

    BasicKMeans.java

    主类

    int coordCount = 250;//

    原始的资料个树

    int dimensions = 100;//

    每个资料的纬度数目

    double[][] coordinates = new double[coordCount][dimensions];

    这里假设

    c

    点资料为

    coordinates

    对象,其中

    c

    coordCount,d

    dimensions

    相应值。

    int mk = 30; //

    想要群聚的数目

    根据群聚数目定义

    mk

    个群聚类对象

    mProtoClusters = new ProtoCluster[mK];//

    ProtoCluster

    类说明

    //

    首先随机选取

    mk

    个原始资料点作为群聚类

    mProtoClusters[i]= new ProtoCluster (coordinates[j] );//i

    依此为

    0

    mk

    的值;

    j

    0

    coordCount

    的值

    定义一个变量用于记录和跟踪每个资料点属于哪个群聚类

    mClusterAssignments = new int[coordCount];

    mClusterAssignments[j]=i;//

    表示第

    j

    个资料点对象属于第

    i

    个群聚类

    //

    开始循环

    //

    依次调用计算每个群聚类的均值

    mProtoClusters[i].updateCenter(mCoordinates);//

    计算第

    i

    个聚类对象的均值

    //

    依次计算每个资料点到中心点的距离,然后根据最小值划分到相应的群集类中;

    采用距离平方差来表示资料点到中心点的距离;

    //定义一个变量,来表示资料点到中心点的距离

    mDistanceCache = new double[coordCount][mk];

    //其中mDistanceCache[i][j]表示第i个资料点到第j个群聚对象中心点的距离;

    //距离算法描述():

    a)依次取出每个资料点对象double[] coord = coordinates[i];

    b)再依次取出每个群聚类中的中心点对象double[] center = mProtoClusters[j].mCenter;

    c)计算coord对象与center对象之间的距离

    double distance(double[] coord, double[] center) {

    int len = coord.length;

    double sumSquared = 0.0;

    for (int i=0; i

    double v = coord[i] - center[i];

    sumSquared += v*v; //平方差

    }

    return Math.sqrt(sumSquared);

    }

    d)循环执行上面的流程,把结果记录在mDistanceCache[i][j]中;

    //比较出最小距离,然后根据最小距离重新对相应对象进行划分

    依次比较每个资料点的 最短中心距离,

    int nearestCluster(int ndx) {

    int nearest = -1;

    double min = Double.MAX_VALUE;

    for (int c = 0; c < mK; c++) {

    double d = mDistanceCache[ndx][c];

    if (d < min) {

    min = d;

    nearest = c;

    }

    }

    return nearest;

    }

    该方法返回该资料点对应的最短中心距离的群聚类的索引值;

    比较每个 nearestCluster[coordCount] 的值和mClusterAssignments[coordCount]

    的值是否相等,如果全相等表示所有的点已经是最佳距离了,直接返回;

    否则需要重新调整资料点和群聚类的关系,调整完毕后再重新开始循环;

    调整时需要更新下列数据:

    a)更新mProtoClusters[i]中的mCurrentMembership集合;

    b)更新mClusterAssignments[i]中对应的值;

    然后重行开始循环

    3

    )

    ProtoCluster.java

    是一个包含代表点的群聚类,该类有两个最主要的属性"代表点"和"群中心";

    int[] mCurrentMembership;//

    用于表示每个群聚包含的数据资料点集合

    double[] mCenter;//

    用于表示每个聚类对象的均值,也就是中心对象

    void updateCenter(double[][] coordinates) {

    //

    该方法计算

    聚类对象的均值

    ;

    //

    根据

    mCurrentMembership

    取得原始资料点对象

    coord

    ,该对象是

    coordinates

    的一个子集;然后取出该子集的均值;

    取均值的算法很简单,可以把

    coordinates

    想象成一个

    m*n

    的距阵

    ,

    每个均值就是每个纵向列的取和平均值

    ,

    该值保

    存在

    mCenter

    for (int i=0; i< mCurrentMembership.length; i++) {

    double[] coord = coordinates[mCurrentMembership[i]];

    for (int j=0; j

    mCenter[j] += coord[j];//

    得到每个纵向列的和;

    }

    f

    or (int i=0; i

    mCenter[i] /= mCurrentSize; //

    对每个纵向列取平均值

    }

    }

    展开全文
  • 基于演化依赖的Java软件聚类实现技术研究.pdf
  • DBSCAN聚类算法java实现

    2018-04-28 16:34:52
    java版的DBSCAN聚类算法实现,是典型的算法思路实现,遍历未访问的所有点,如果是核心点,就新建一个簇,然后遍历其邻域内的所有点集A,不断扩展,如果簇内的点时核心点,就将其邻域所有点纳入点集A,并从点集移除已...
  • java聚类算法

    2014-11-05 19:38:03
    java编程语言实现最大最小距离聚类算法,例子使用的是一系列二维坐标。
  • 这个是ap算法,java实现的,写好了就直接上传了整个实验的所有东西,请大家纠正错误。
  • java文本聚类程序代码文件,实现文本聚类功能,分词
  • 层次聚类算法的java实现

    热门讨论 2010-03-17 18:50:36
    层次聚类算法的java实现,采用了java控制台输出,同时也建立了txt文档输出。
  • JAVA实现K-means聚类

    万次阅读 多人点赞 2016-04-19 15:12:04
    K-means算法是比较经典的聚类算法,算法的基本思想是选取K个点(随机)作为中心进行聚类,然后对聚类的结果计算该类的质心,通过迭代的方法不断更新质心,直到质心不变或稍微移动为止,则最后的聚类结果就是最后的...
  • kmeans聚类java实现附测试数据及结果

    热门讨论 2011-12-01 19:11:06
    kmeans聚类java实现附测试数据及结果
  • Java实现Kmeans聚类算法

    千次阅读 2019-05-22 14:44:54
    本文用K_means算法实现鸢尾花的识别 鸢尾花卉数据集,是一类多重变量分析的数据集。 每个数据包含4个属性。 可通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica...
  • Kmeans文本聚类java实现

    热门讨论 2015-02-17 10:20:03
    java实现的文本聚类使用了kmeans算法
  • 一个聚类算法的Java实现

    千次阅读 2018-05-23 14:27:47
    import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * KNN算法工具类 * Created by Mistletoe on 2018/05/11 17:13 **/ public class KNNUtils { ...
  • /*** K均值聚类算法*/public classKmeans {private int numOfCluster;//分成多少簇private int timeOfIteration;//迭代次数private int dataSetLength;//数据集元素个数,即数据集的长度private ...
  • java实现的kmeans聚类算法, 对某张表的某个字段进行kmeans聚类算法,并写到新创建的表中
  • 基于KMeans聚类的协同过滤推荐算法可运用于基于用户和基于项目的协同过滤推荐算法中,作为降低数据稀疏度和提高推荐准确率的方法之一,一个协同过滤推荐过程可实现多次KMeans聚类。 一、基于KMeans聚类的协同过滤...
  • 1.项目背景 在做交通路线分析的时候,客户需要找出车辆的行车规律,我们将车辆每天的行车路线当做一个数据样本,总共有365天或是更多,从这些数据中通过聚类来获得行车路线规律统计分析。我首先想到是K-means算法,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,220
精华内容 6,488
关键字:

java聚类实现

java 订阅