克鲁斯卡尔算法(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/

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

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

posted on 2012-12-18 14:22  前端小屁孩  阅读(3423)  评论(0编辑  收藏  举报