聚类算法之MST算法 java实现版本 博客分类: java综合web算法 算法averagelinkmst最短距离
程序员文章站
2024-03-22 12:51:04
...
在介绍最小生成树算法(MST)之前,简单说一下平均链接算法(average-link)的实现过程,平均链接聚类算法和单链接类似,多了计算聚类之间距离矩阵的步骤
实现步骤如下:
MST算法比较有意思点,不仅用于聚类,还可以解决最短铺路成本这类问题。
我们假设一个场景:现在想在多个城市之间铺网络,怎样才是最短距离?每个城市当作一个数据点,每个点间的距离称为一个边,最短距离实际上就是求得每个点都能连成边,但是又不会回路的情况。
实现过程如下:
1,首先建立城市类和边类,如下
2,MST核心类,Edge类表示一个边的两点和距离,
找最短距离的边的过程是:不断的纳入最短边,并且再根据这些已知的最短边的两端寻找最短边(md 这句话我也感觉绕口 但应该是最通俗的了)
第一步肯定是算出临近距离矩阵
3,测试一下
By 阿飞哥 转载请说明
腾讯微博:http://t.qq.com/duyunfeiRoom
新浪微博:http://weibo.com/u/1766094735
实现步骤如下:
- 1,将元素各成一组,把这些组放入容器H
- 2,循环元素距离数组,根据两层下标得到将要比较的两个元素A,B
- 3,在H中分别查找含有A,B的组AH,BH。假如AH不等于BH(也就是A,B不同组), AH和BH的距离累加A,B的距离。
- 4,得到组间距离数组后,循环比较组间距离与阀值,小于阀值,则此两组合并成一组,合并之前把H中的两个作为比较的原始组删除。
MST算法比较有意思点,不仅用于聚类,还可以解决最短铺路成本这类问题。
我们假设一个场景:现在想在多个城市之间铺网络,怎样才是最短距离?每个城市当作一个数据点,每个点间的距离称为一个边,最短距离实际上就是求得每个点都能连成边,但是又不会回路的情况。
实现过程如下:
1,首先建立城市类和边类,如下
/** * 城市 * * @author duyf * */ class City { private String name; // 经度 private double x; // 纬度 private double y; public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean equals(Object obj) { if (obj == null) { return false; } if (this == obj) { return true; } City other = (City) obj; if (this.getX() == other.getX() && this.getY() == other.getY()) { return true; } return false; } } /** * 边距 包含两端数据点(城市)的索引 * @author duyf * */ class Edge { private int i; private int j; private double w; Edge(int i, int j, double w) { this.i = i; this.j = j; this.w = w; } public int getI() { return i; } public int getJ() { return j; } public double getW() { return w; } }
2,MST核心类,Edge类表示一个边的两点和距离,
找最短距离的边的过程是:不断的纳入最短边,并且再根据这些已知的最短边的两端寻找最短边(md 这句话我也感觉绕口 但应该是最通俗的了)
public class MST { private List<City> data; private double[][] ds; public MST(List<City> data){ this.data=data; } public List<Edge> compute(){ // 距离矩阵 ds = new double[data.size()][data.size()]; for (int i = 0; i < data.size(); i++) { City city1 = data.get(i); for (int j = i + 1; j < data.size(); j++) { City city2 = data.get(j); ds[i][j] = getDistance(city1, city2); // 矩阵 对称性 ds[j][i] = ds[i][j]; } ds[i][i] = 0.0; } boolean[] isMst=new boolean[data.size()]; isMst[0]=true; Edge edge=null; List<Edge> edges=new ArrayList<Edge>(); while((edge=findMinEdge(isMst))!=null){ edges.add(edge); //标记为已知MST数据点 isMst[edge.getJ()]=true; } return edges; } //找出 和 已知的MST数据点 最小距离的点 private Edge findMinEdge(boolean[] isMst){ //初始化无限大 double minds = Double.POSITIVE_INFINITY; int minI=-1; int minJ=-1; Edge edge=null; for(int i=0;i<ds.length;i++){ if(isMst[i]==true){ for(int j=0;j<ds.length;j++){ if(isMst[j]==false){ if(minds>ds[i][j]){ minds=ds[i][j]; minI=i; minJ=j; } } } } } if(minI>-1){ edge=new Edge(minI,minJ,minds); } return edge; } // 计算空间距离 private double getDistance(City city1, City city2) { double distance=Math.pow(city1.getX()-city2.getX(),2)+Math.pow(city1.getY()-city2.getY(),2); return Math.sqrt(distance); } }
第一步肯定是算出临近距离矩阵
3,测试一下
public static void main(String[] args) { List<City> citys = new ArrayList<City>(); City city0 = new City(); city0.setName("北 京"); city0.setX(116.28); city0.setY(39.54); citys.add(city0); City city1 = new City(); city1.setName("上 海"); city1.setX(121.29); city1.setY(31.14); citys.add(city1); City city2 = new City(); city2.setName("天 津"); city2.setX(117.11); city2.setY(39.09); citys.add(city2); City city3 = new City(); city3.setName("重 庆"); city3.setX(106.32); city3.setY(29.32); citys.add(city3); City city4 = new City(); city4.setName("哈尔滨"); city4.setX(126.41); city4.setY(45.45); citys.add(city4); City city5 = new City(); city5.setName("长 春"); city5.setX(125.19); city5.setY(43.52); citys.add(city5); City city6 = new City(); city6.setName("南 京"); city6.setX(118.50); city6.setY(32.02); citys.add(city6); City city7 = new City(); city7.setName("武 汉"); city7.setX(114.21); city7.setY(30.37); citys.add(city7); City city8 = new City(); city8.setName("台 北"); city8.setX(121.31); city8.setY(25.03); citys.add(city8); City city9 = new City(); city9.setName("香 港"); city9.setX(114.10); city9.setY(22.18); citys.add(city9); MST mst=new MST(citys); List<Edge> edges=mst.compute(); System.out.println("------------------线路最佳方案如下------------------"); for(Edge edge:edges){ City from=citys.get(edge.getI()); City to=citys.get(edge.getJ()); double length=edge.getW(); System.out.println(edge.getI()+"========>"+edge.getJ()); System.out.println(from.getName()+"到"+to.getName()+",全长"+length); } }
By 阿飞哥 转载请说明
腾讯微博:http://t.qq.com/duyunfeiRoom
新浪微博:http://weibo.com/u/1766094735