zoukankan      html  css  js  c++  java
  • kruskal算法JAVA实现

    克鲁斯卡尔算法(Kruskal's algorithm)是两个经典的最小生成树算法的较为简单理解的一个。这里面充分体现了贪心算法的精髓。算法如下:

    假设T中的边和顶点均涂成红色,其余边为白色。开始时G中的边均为白色。

      1)将所有顶点涂成红色;

      2)在白色边中,挑选一条权最小的边,使其与红色边不形成圈,将该白色边涂红;

      3)重复2)直到有n-1条红色边,这n-1条红色边便构成最小生成树T的边集合。

      注意到在算法执行过程中,红色顶点和红色边会形成一个或多个连通分支,它们都是G的子树。一条边与红色边形成圈当且仅当这条边的两个端点属于同一个子树。因此判定一条边是否与红色边形成圈,只需判断这条边的两端点是否属于同一个子树。

      上述判断可以如此实现:给每个子树一个不同的编号,对每一个顶点引入一个标记t,表示这个顶点所在的子树编号。当加入一条红色边,就会使该边两端点所在的两个子树连接起来,成为一个子树,从而两个子树中的顶点标记要改变成一样。综上,可将Kruskal算法细化使其更容易计算机实现。

    我的实现结果如下:(200个节点)

    java部分代码如下:

        public static void kruskal(Graph g) {
            //    每个顶点加编号
            int[] parent = new int[g.MAX_VERTEX ];
            for (int i = 0; i < g.MAX_VERTEX; i++) {
                parent[i] = i;
            }
    //        找到n-1条边,既满足条件
            while (result.size() < (g.MAX_VERTEX-1) ) {
                // 取最小边
                double min = MOUSTMAX;
                int jtemp=0;
                int i = 0;
                
                for(int k=0;k<g.MAX_VERTEX;k++){
                    for (int j = 0; j < g.MAX_VERTEX; j++) {
    //                    System.out.println("-------------"+k+"--"+j + "parent[" + k + "]--"+parent[k]+"parent[" + j+"]" +parent[j] + "--"+g.L1_Matrix[k][j] + "min" + min);
                        if ((parent[k] != parent[j] ) && g.L1_Matrix[k][j] < min) {
                            min = g.L1_Matrix[k][j];
                            jtemp = j;
                            i=k;
                        }
                    }
                }
                int jj = parent[i];
                int kk = parent[jtemp];
                proc.add("------选中结点 "+i+" 与结点 "+jtemp + " ,路径长度:" + g.L1_Matrix[i][jtemp]);
                //判断该边的两个端点是否在同一个子树中:
                //   不在:将该边加入结果集
                //     在:继续循环
                if (kk != jj) {
                    int tempi = parent[i];
                    //将新找到的边的顶点与以前的顶点标志值设为一样,注意要把以前的顶点相连的顶点都要同步改变值
                    for(int j = 0; j<parent.length;j++){
                        if(parent[j] == tempi )
                            parent[j] = parent[jtemp];
                    }
                    //取出已经加入的边
                    boolean temp = true;
                    for(Vertex[] v:result){
                        if(v[0] == g.vertexList[i] && v[1] ==g.vertexList[jtemp]){
                            temp = false;
                        }
                        if(v[1] == g.vertexList[i] && v[0] ==g.vertexList[jtemp]){
                            temp = false;
                        }
                    }
                    if(temp){
                        result.add(new Vertex[] { g.vertexList[i],g.vertexList[jtemp] } );
                    }
                    //将已找到的边,权值设为最大
                    g.L1_Matrix[i][jtemp] = MOUSTMAX;
                    
                }
                
            }
        }

     ---------------------------------------------------------

     参见:http://home.ustc.edu.cn/~chh1990/win/

    -------------------------------------------------------------------

    补肾的食物有哪些吃什么补肾专家建议初冬宜补肾

  • 相关阅读:
    无名信号量在多线程间的同步
    ftok函数例子
    strerror和perror函数详解
    lockf函数的使用
    背包问题-2动态规划【正解】
    递归思想即背包问题
    生产者消费者问题(基于线程和无名信号量)
    eclipse 安装python后pydev不出现
    Eclipse+pydev解决中文显示和注释问题的方法大全
    MyEclipse10配置PyDev进行Python开发
  • 原文地址:https://www.cnblogs.com/chero/p/2823223.html
Copyright © 2011-2022 走看看