聚类算法之单链接算法java实现

 聚类算法中基于链接的算法大致有三种:单链接算法(single link),平均链接算法(average link),最小生成数算法(minimum spanning tree)。现在实现单链接算法,其他算法以后再续吧。 
       单链接算法的过程是 首先生成各个元素的距离矩阵,根据距离和阀值的比对来控制生成的聚类个数,阀值越大,生成的聚类越少,直到同属一类。 
       下面例子实现了根据经纬度来实现城市的聚类。 
  
   
Java代码   收藏代码
  1.     package singlelink;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashSet;  
  5. import java.util.List;  
  6. import java.util.Set;  
  7.   
  8. public class SingleLinkTest {  
  9.   
  10.     public static void main(String[] args) {  
  11.   
  12.         List<City> citys = new ArrayList<City>();  
  13.           
  14.         City city0 = new City();  
  15.         city0.setName("北 京");  
  16.         city0.setX(116.28);  
  17.         city0.setY(39.54);  
  18.         citys.add(city0);  
  19.           
  20.           
  21.         City city1 = new City();  
  22.         city1.setName("上 海");  
  23.         city1.setX(121.29);  
  24.         city1.setY(31.14);  
  25.         citys.add(city1);  
  26.           
  27.         City city2 = new City();  
  28.         city2.setName("天 津");  
  29.         city2.setX(117.11);  
  30.         city2.setY(39.09);  
  31.         citys.add(city2);  
  32.           
  33.         City city3 = new City();  
  34.         city3.setName("重 庆");  
  35.         city3.setX(106.32);  
  36.         city3.setY(29.32);  
  37.         citys.add(city3);  
  38.           
  39.           
  40.         City city4 = new City();  
  41.         city4.setName("哈尔滨");  
  42.         city4.setX(126.41);  
  43.         city4.setY(45.45);  
  44.         citys.add(city4);  
  45.           
  46.           
  47.         City city5 = new City();  
  48.         city5.setName("长 春");  
  49.         city5.setX(125.19);  
  50.         city5.setY(43.52);  
  51.         citys.add(city5);  
  52.           
  53.           
  54.         City city6 = new City();  
  55.         city6.setName("南 京");  
  56.         city6.setX(118.50);  
  57.         city6.setY(32.02);  
  58.         citys.add(city6);  
  59.           
  60.         City city7 = new City();  
  61.         city7.setName("武 汉");  
  62.         city7.setX(114.21);  
  63.         city7.setY(30.37);  
  64.         citys.add(city7);  
  65.           
  66.           
  67.         City city8 = new City();  
  68.         city8.setName("台 北");  
  69.         city8.setX(121.31);  
  70.         city8.setY(25.03);  
  71.         citys.add(city8);  
  72.           
  73.         City city9 = new City();  
  74.         city9.setName("香 港");  
  75.         city9.setX(114.10);  
  76.         city9.setY(22.18);  
  77.         citys.add(city9);  
  78.           
  79.         SingleLink sing = new SingleLink(citys);  
  80.         List<Set<City>> list = sing.compute();  
  81.         for (Set<City> list0 : list) {  
  82.             System.out.println("=============");  
  83.             for (City city : list0) {  
  84.                 System.out.println(city.getName() + " : (" + city.getX()+","+city.getY()+")");  
  85.             }  
  86.         }  
  87.     }  
  88.   
  89. }  
  90.   
  91. /** 
  92.  * 聚类之 单链接算法 
  93.  *  
  94.  * @author duyf 
  95.  *  
  96.  */  
  97. class SingleLink {  
  98.   
  99.     private List<City> data;  
  100.   
  101.     // 默认阀值  
  102.     private double distanceX = 8;  
  103.   
  104.     public SingleLink(List<City> list) {  
  105.         data = list;  
  106.     }  
  107.   
  108.     public List<Set<City>> compute() {  
  109.         List<Set<City>> list = new ArrayList<Set<City>>();  
  110.   
  111.         // 距离矩阵  
  112.         double[][] ds = new double[data.size()][data.size()];  
  113.   
  114.         for (int i = 0; i < data.size(); i++) {  
  115.             City city1 = data.get(i);  
  116.             for (int j = i + 1; j < data.size(); j++) {  
  117.                 City city2 = data.get(j);  
  118.                 ds[i][j] = getDistance(city1, city2);  
  119.                 // 矩阵 对称性  
  120.                 ds[j][i] = ds[i][j];  
  121.             }  
  122.             ds[i][i] = 0.0;  
  123.         }  
  124.   
  125.         for (int i = 0; i < ds.length; i++) {  
  126.             for (int j = 0; j < ds.length; j++) {  
  127.                 System.out.print((int) ds[i][j] + ",");  
  128.             }  
  129.             System.out.println();  
  130.         }  
  131.           
  132.         boolean[] hasUsed = new boolean[ds.length];  
  133.         for (int i = 0; i < ds.length; i++) {  
  134.             Set<City> setDs = new HashSet<City>();  
  135.             if (hasUsed[i]) {  
  136.                 continue;  
  137.             }  
  138.             for (int j = i; j < ds.length; j++) {  
  139.                 if (ds[i][j] <= distanceX && hasUsed[j]==false) {  
  140.                     setDs.add(data.get(j));  
  141.                     hasUsed[j] = true;  
  142.                 }  
  143.             }  
  144.             if (setDs.size() > 0) {  
  145.                 list.add(setDs);  
  146.             }  
  147.   
  148.         }  
  149.         return list;  
  150.     }  
  151.   
  152.     // 计算空间距离  
  153.     private double getDistance(City city1, City city2) {  
  154.          double  distance=Math.pow(city1.getX()-city2.getX(),2)+Math.pow(city1.getY()-city2.getY(),2);  
  155.          return Math.sqrt(distance);  
  156.            
  157.     }  
  158.   
  159. }  
  160.   
  161. /** 
  162.  * 城市 
  163.  *  
  164.  * @author duyf 
  165.  *  
  166.  */  
  167. class City {  
  168.   
  169.     private String name;  
  170.     // 经度  
  171.     private double x;  
  172.   
  173.     // 纬度  
  174.     private double y;  
  175.   
  176.     public double getX() {  
  177.         return x;  
  178.     }  
  179.   
  180.     public void setX(double x) {  
  181.         this.x = x;  
  182.     }  
  183.   
  184.     public double getY() {  
  185.         return y;  
  186.     }  
  187.   
  188.     public void setY(double y) {  
  189.         this.y = y;  
  190.     }  
  191.   
  192.     public String getName() {  
  193.         return name;  
  194.     }  
  195.   
  196.     public void setName(String name) {  
  197.         this.name = name;  
  198.     }  
  199.   
  200.     public boolean equals(Object obj) {  
  201.         if (obj == null) {  
  202.             return false;  
  203.         }  
  204.         if (this == obj) {  
  205.             return true;  
  206.         }  
  207.         City other = (City) obj;  
  208.         if (this.getX() == other.getX() && this.getY() == other.getY()) {  
  209.             return true;  
  210.         }  
  211.         return false;  
  212.     }  
  213. }  
  214.    
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值