克鲁斯卡尔算法

简介: 克鲁斯卡尔算法

公众号merlinsea


  • 问题介绍
  • 已知一个无向带权图,现在希望求出保证这个无向带权图连通性同时是的所有遍的权重之和最小的连通子图。
  • 最小生成树问题介绍
  • 现在有一个无向带权图,请求出这个图的最小生成树。
  • 最小指的是基于原图得到的树的边的权值之和是最小的。
  • 树指的是保证图中所有节点连通的无回路的图。


640.png


  • 算法难点: 如何才能快速判断是否存在回路呢?
  • 并查集的介绍
  • 树是保证所有节点连通且没有回路的极大连通子图,在树中的任意两个节点之间多加入一条边,那么就会产生回路。
  • 并查集就是把这些节点看成一个树,并且采用树的双亲存储,如果我们加入一条新的边,边的两个端点节点都在同一棵树中,那么这两个节点之间加入边就会产生回路。


640.png640.png


  • 克鲁斯卡尔代码实现


public class Main {
    public static void main(String[] args) {
        // {0,1,5}表示j节点0,1之间有一条权重为5的边
        int[][] edges = new int[][]{{0,1,5},{0,2,1},{0,3,2},{1,2,3},{2,3,6},{1,4,4},{2,4,2},{3,4,3}};
        int n = 5;
        Arrays.sort(edges, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                //升序排列,返回正数就发生交换
                return o1[2]-o2[2];
            }
        });
        for(int[] edge : edges){
            System.out.println("["+ edge[0]+" "+ edge[1] + " " + edge[2] +"]");
        }
        System.out.println();
        //树的双亲存储
        int[] tree = new int[n];
        for(int i=0;i<n;i++){
            tree[i] = i;
        }
        List<int[]> result = new LinkedList<>();
        int i = 0;
        // cnt 代表我们选取的边的个数
        int cnt  = 0;
        while(cnt<n-1){
            int a = edges[i][0];
            int b = edges[i][1];
            int aPar = findPar(tree,a);
            int bPar = findPar(tree,b);
            if(aPar != bPar){
                //说明a,b不属于同一棵树 ,因此加入<a,b>边不会产生回路
                result.add(edges[i]);
                //链接 bPar 和 aPar
                tree[aPar] = bPar;
                //选取的边+1
                cnt++;
            }
            i++;
        }
        for(int j=0;j<result.size();j++){
            int[] edge = result.get(j);
            System.out.println("["+ edge[0]+" "+ edge[1] + " " + edge[2] +"]");
        }
    }
    /**
     * 查找双亲节点
     */
    public static int findPar(int[] tree,int k){
        if(tree[k]==k){
            return k;
        }
        tree[k] = findPar(tree,tree[k]);
        return tree[k];
    }
}


  • 算法性能分析
  • 从上面的代码中可以发现,克鲁斯卡尔算法的时间开销主要是sort()排序上,在之前的排序算法中,我们知道排序的最快时间复杂度是O(nlogn),而我们排序其实是对所有的边进行排序的,所以对于边越少的图,越适用于通过克鲁斯卡尔算法生成最小生成树。

  • 最小生成树问题的应用场景
  • 比如村村通路问题:假设有若干个村庄,现在政府需要为这些村子进行修路,现在已经知道了每个村庄相互之间的距离,并且修路的费用成本和路之间的距离成正比关系,问如何修路才能保证个村庄可以相互连通的基础上尽可能让市政的投入的费用最小?


640.png

相关文章
|
4月前
|
机器学习/深度学习 算法 数据挖掘
算法金 | 欧氏距离算法、余弦相似度、汉明、曼哈顿、切比雪夫、闵可夫斯基、雅卡尔指数、半正矢、Sørensen-Dice
**摘要:** 了解9种距离和相似度算法:欧氏距离、余弦相似度、汉明距离、曼哈顿距离、切比雪夫距离、闵可夫斯基距离、雅卡尔指数、半正矢距离和Sørensen-Dice系数。这些算法在机器学习、文本分析、图像处理和生物学等领域各有应用。例如,欧氏距离用于KNN和K-Means,余弦相似度用于文本相似性,汉明距离在错误检测中,曼哈顿距离在数据挖掘,切比雪夫距离在棋盘游戏,闵可夫斯基距离通过调整参数适应不同场景,雅卡尔指数和Sørensen-Dice系数用于集合相似度。每种算法有其优缺点,如欧氏距离对异常值敏感,余弦相似度忽略数值大小,汉明距离仅适用于等长数据。
124 2
算法金 | 欧氏距离算法、余弦相似度、汉明、曼哈顿、切比雪夫、闵可夫斯基、雅卡尔指数、半正矢、Sørensen-Dice
|
监控 算法
转:克鲁斯卡尔算法在文档管理软件中应用使其更加高效
克鲁斯卡尔算法是一种用于解决最小生成树问题的贪心算法。在文档管理软件中,可以将网络节点之间的连接关系抽象为一张图,然后使用克鲁斯卡尔算法来寻找最小生成树,即最小的连接所有节点的路径。
87 0
|
存储 算法 数据可视化
转:电子文档管理系统中应用克鲁斯卡尔算法有什么作用
克鲁斯卡尔算法是一种求解最小生成树问题的算法,其在电子文档管理系统中可以用于优化文档的管理和存储。
66 0
|
存储 算法 数据可视化
转:克鲁斯卡尔算法在电子文档管理系统中的应用
克鲁斯卡尔算法能够找到连接所有节点的最小生成树,从而找到最优解。在电子文档管理系统中,这意味着可以通过算法找到最佳的文档组织方式,提高文档检索的效率和精度。
311 0
|
算法 C++
蓝桥杯(聪明的猴子)克鲁斯卡尔算法最小生成树
蓝桥杯(聪明的猴子)克鲁斯卡尔算法最小生成树
106 0
|
监控 算法
转:克鲁斯卡尔算法在电脑监控软件中的应用
在电脑监控软件中,使用克鲁斯卡尔算法可以帮助管理员更好地了解整个网络的拓扑结构,找出网络中潜在的问题和风险点。
319 0
|
算法
Kruskal算法(克鲁斯卡尔)最小生成树
Kruskal算法(克鲁斯卡尔)最小生成树
143 0
|
24天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
9天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。
|
10天前
|
算法 调度
基于遗传模拟退火混合优化算法的车间作业最优调度matlab仿真,输出甘特图
车间作业调度问题(JSSP)通过遗传算法(GA)和模拟退火算法(SA)优化多个作业在并行工作中心上的加工顺序和时间,以最小化总完成时间和机器闲置时间。MATLAB2022a版本运行测试,展示了有效性和可行性。核心程序采用作业列表表示法,结合遗传操作和模拟退火过程,提高算法性能。