dbscan算法 java_java实现 聚类算法之MST算法

本文详细介绍了平均链接聚类算法后,重点探讨了最小生成树(MST)算法,如何通过实例演示在城市间网络布局中的最短路径选择。通过实例代码展示了如何使用MST解决多城市间网络铺设成本优化问题,包括创建City和Edge类,计算距离矩阵,以及MST核心计算过程。
摘要由CSDN通过智能技术生成

在介绍最小生成树算法(MST)之前,简单说一下平均链接算法(average-link)的实现过程,平均链接聚类算法和单链接类似,多了计算聚类之间距离矩阵的步骤

实现步骤如下:

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 data;

private double[][] ds;

public MST(List data){

this.data=data;

}

public List 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 edges=new ArrayList();

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

if(isMst[i]==true){

for(int j=0;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 citys = new ArrayList();

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

}

}

03175213_ZrKs.jpg

By 阿飞哥 转载请说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值