zoukankan      html  css  js  c++  java
  • Java实现聚类算法k-means

     

    java简单实现聚类算法

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

    ////////////////////

    改好了。。。。。。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 }
  • 相关阅读:
    防止表单重复提交
    tp5中的配置机制
    PHP remove,empty和detach区别
    jquery data方法
    webstrom使用记录
    input checkbox问题和li里面包含checkbox
    【转】HTML中A标签与click事件的前世今生
    jquery toggle方法
    webstore+nodejs
    web storm使用和配置
  • 原文地址:https://www.cnblogs.com/8335IT/p/5635965.html
Copyright © 2011-2022 走看看