C#,最小生成树(MST)博鲁夫卡(Boruvka)算法的源代码

news2024/9/28 23:36:00

 Otakar Boruvka

本文给出Boruvka算法的C#实现源代码。

Boruvka算法用于查找边加权图的最小生成树(MST),它早于Prim和Kruskal的算法,但仍然可以被认为是两者的关联。

一、Boruvka算法的历史

1926年,奥塔卡·博鲁夫卡(Otakar Boruvka)首次提出了一种求给定图的MST的方法。这在计算机出现之前就已经存在了,事实上,它被用来设计一个高效的配电系统。

Georges Sollin在1965年重新发现了它,并将其用于并行计算。

二、Boruvka算法的思路

该算法的核心思想是从一组树开始,每个顶点代表一棵孤立的树。然后,我们需要不断增加边,以减少孤立树的数量,直到我们有一个单一的连接树。
让我们通过一个示例图逐步了解这一点:

步骤0:创建一个图表;
步骤1:从一堆未连接的树开始(树的数量=顶点的数量);
步骤2:当存在未连接的树时,对于每个未连接的树:
(1)以较小的重量找到它的边缘
(2)添加此边以连接另一棵树

三、Boruvka算法的源代码

1、核心代码

using System;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
    /// <summary>
    /// 图的连接边信息
    /// </summary>
    public class EdgeInfo
    {
        /// <summary>
        /// 起始节点编码(按一般教材习惯,1起步)
        /// </summary>
        public int Start { get; set; } = 0;
        /// <summary>
        /// 终点编码(按一般教材习惯,也从1起步)
        /// </summary>
        public int End { get; set; } = 0;
        /// <summary>
        /// 边的权值
        /// </summary>
        public int Weight { get; set; } = 0;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="c"></param>
        public EdgeInfo(int a, int b, int c)
        {
            this.Start = a;
            this.End = b;
            this.Weight = c;
        }
    }

    /// <summary>
    /// MST-Boruvka算法
    /// </summary>
    public static class Boruvka_Minium_Spaning_Tree
    {
        private static int[] Parent { get; set; } = null;
        private static int[] Minium { get; set; } = null;

        /// <summary>
        /// 计算最小生成树(MST)的最小代价及树信息
        /// </summary>
        /// <param name="graph">图信息(边列表)</param>
        /// <param name="tree">返回树信息(边的列表)</param>
        /// <returns></returns>
        public static int Execute(EdgeInfo[] graph, out List<int> tree)
        {
            tree = new List<int>();

            // 计算最大节点编号
            int N = 0;
            for (int i = 0; i < graph.Length; i++)
            {
                if (graph[i].Start > N) N = graph[i].Start;
                if (graph[i].End > N) N = graph[i].End;
            }

            Parent = new int[N + 1];
            for (int i = 1; i <= N; i++)
            {
                Parent[i] = i;
            }
            Minium = new int[N + 1];

            int result = 0;
            int components = N;
            while (components > 1)
            {
                for (int i = 1; i <= N; i++)
                {
                    Minium[i] = -1;
                }

                for (int i = 0; i < graph.Length; i++)
                {
                    if (Root(graph[i].Start) == Root(graph[i].End))
                    {
                        continue;
                    }

                    int r_v = Root(graph[i].Start);
                    if (Minium[r_v] == -1 || graph[i].Weight < graph[Minium[r_v]].Weight)
                    {
                        Minium[r_v] = i;
                    }

                    int r_u = Root(graph[i].End);
                    if (Minium[r_u] == -1 || graph[i].Weight < graph[Minium[r_u]].Weight)
                    {
                        Minium[r_u] = i;
                    }
                }

                for (int i = 1; i <= N; i++)
                {
                    if (Minium[i] != -1)
                    {
                        if (Merge(graph[Minium[i]].Start, graph[Minium[i]].End))
                        {
                            result += graph[Minium[i]].Weight;
                            tree.Add(Minium[i]);
                            components--;
                        }
                    }
                }
            }

            return result;
        }

        private static int Root(int v)
        {
            if (Parent[v] == v)
            {
                return v;
            }
            return Parent[v] = Root(Parent[v]);
        }

        private static bool Merge(int v, int u)
        {
            v = Root(v);
            u = Root(u);
            if (v == u)
            {
                return false;
            }
            Parent[v] = u;
            return true;
        }
    }
}

2、测试与显示

List<EdgeInfo> g = new List<EdgeInfo>();
g.Add(new EdgeInfo(1, 2, 6));
g.Add(new EdgeInfo(1, 3, 1));
g.Add(new EdgeInfo(1, 4, 4));
g.Add(new EdgeInfo(1, 5, 4));
g.Add(new EdgeInfo(2, 4, 2));
g.Add(new EdgeInfo(2, 5, 2));
g.Add(new EdgeInfo(3, 4, 8));

int weight = Boruvka_Minium_Spaning_Tree.Execute(g.ToArray(), out List<int> path);
StringBuilder sb = new StringBuilder();
sb.AppendLine("The minium weight is: " + weight + "<br>");
sb.AppendLine("The minium tree is : <br>");
foreach (int idx in path)
{
	sb.AppendLine("("+g[idx].Start + " --- " + g[idx].End + ") weight = " + g[idx].Weight + "<br>");
}
webBrowser1.DocumentText = sb.ToString();

更多算法源代码将陆续发布,建议关注。

——————————————————————————————————————————

POWER BY TRUFFER.CN

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1409795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Flink-1.17-教程】-【四】Flink DataStream API(1)源算子(Source)

【Flink-1.17-教程】-【四】Flink DataStream API&#xff08;1&#xff09;源算子&#xff08;Source&#xff09; 1&#xff09;执行环境&#xff08;Execution Environment&#xff09;1.1.创建执行环境1.2.执行模式&#xff08;Execution Mode&#xff09;1.3.触发程序执行…

米贸搜|Meta广告中级水准:Facebook自动完成四项广告设置,改善投放成效!

广告投放中的机器学习预算自动分配版位自动分配受众自动分配创意灵活调整 一、广告投放中的机器学习 机器学习现已成为数字营销的基础&#xff0c;能够帮助我们面向想要触达的受众投放与之相关的广告。随着我们对如何使用机器学习的了解加深&#xff0c;我们对“如何创建广告…

眼镜清洗机是智商说吗?适合清洗眼镜的超声波清洗机推荐

随着现代生活步伐的加快&#xff0c;对于家居清洁的需求也日益增长。在这个背景下&#xff0c;超声波清洗机成为了现代家庭清洁的好帮手。有的朋友会认识超声波清洗机洗眼镜是智商税&#xff01;其实只要是用过超声波清洗机都知道这不是智商税&#xff0c;眼镜店老板每天用来清…

程序员如何保持身心健康

程序员要保持身心健康&#xff0c;可以注意以下几个方面&#xff1a; 饮食健康&#xff1a;保持均衡的饮食&#xff0c;多吃蔬菜水果&#xff0c;减少油腻和高热量食物的摄入。同时&#xff0c;适当饮水&#xff0c;避免因长时间坐着工作而导致的脱水。尽量不要吃街边摊、大排…

postgresql12表膨胀解决(不锁表)

查看所有数据库占用磁盘空间 SELECTpg_database.datname AS "数据库名称",pg_size_pretty(pg_database_size(pg_database.datname)) AS "磁盘占用空间" FROMpg_database;发现有个数据库占用空间过大 查询库中所有表占用空间 SELECTtable_name,pg_size_…

Chatgpt的崛起之路

Chatgpt的崛起之路 背景与发展历程背景发展历程 技术原理第一阶段&#xff1a;训练监督策略模型第二阶段&#xff1a;训练奖励模型第三阶段&#xff1a;采用强化学习来增强模型的能力。 国内使用情况及应用的领域面临的数据安全挑战与建议ChatGPT获取数据产生的问题数据泄露问题…

【学网攻】 第(8)节 -- 端口安全

文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交换机配置聚合端口【学网攻】 第(4)节 -- 交换机划分Vlan【学网攻】 第(5)节 -- Cisco VTP的使用​​​​​​【学网攻】 第(6)节 -- 三层交换机实现VLAN间路由【学网攻…

docker 部署springboot项目

新建Dockerfile ## AdoptOpenJDK 停止发布 OpenJDK 二进制&#xff0c;而 Eclipse Temurin 是它的延伸&#xff0c;提供更好的稳定性 ## 感谢复旦核博士的建议&#xff01;灰子哥&#xff0c;牛皮&#xff01; FROM eclipse-temurin:8-jre## 将后端项目的 Jar 文件&#xff0c…

念念不忘智能编程,必有回响CodeArts Snap

开发者的碎碎念 之前在【我与ModelArts的故事】的文章里&#xff0c;分享过我学习新技术的经历&#xff0c;主要有&#xff1a; 自主学习&#xff0c;比如自学Python&#xff1b;借助华为云的产品边用边学。 在围着"编程学习"这座城池&#xff0c;外围来来回回转了…

springboot126疫情下图书馆管理系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的疫情下图书馆管理系统 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章…

帕金森既然不是癌症,但又为什么令患者非常的痛苦呢?

帕金森病是一种慢性、进行性的神经系统退行性疾病&#xff0c;主要影响到大脑中负责协调和控制运动的神经元。帕金森病的主要症状包括肢体僵硬、震颤、运动迟缓以及平衡障碍等&#xff0c;给患者的生活和工作带来了很大的困扰和痛苦。 帕金森病的肢体僵硬和运动迟缓是最常见的…

IMX6:pthread_cond_t条件变量测试

简介 pthread_cond_t是一个条件变量的数据类型&#xff0c;用于线程间的同步和通信。它通常与互斥锁&#xff08;pthread_mutex_t&#xff09;一起使用&#xff0c;以实现线程的等待和唤醒操作。 以下是两个与pthread_cond_t相关的函数的介绍&#xff1a; pthread_cond_init&a…

10个免费高质量视频素材网站,无版权,可商用。

推荐10个高清无水印视频素材网站&#xff0c;免费下载&#xff0c;无版权可商用&#xff0c;建议收藏起来&#xff01; 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx 菜鸟图库虽然是个设计素材网站&#xff0c;但除了设计类素材之外还有很多视频、音频、办公类…

22款奔驰GLS450升级香氛负离子车载香薰功能

奔驰原厂香氛系统激活原车自带系统&#xff0c;将香气加藏储物盒中&#xff0c;通过系统调节与出风口相结合&#xff0c;再将香味传达至整个车厢&#xff0c;达到净化车厢空气的效果&#xff0c;让整个车厢更加绿色健康&#xff0c;清新淡雅。星骏汇小许Xjh15863 产品功能&…

django从入门到实践(学习笔记一)

django3学习笔记一 django开发1.创建项目和app2.设计表结构3.在MySQL中生成表4.静态文件管理5.部门管理5.1部门列表6.模板的继承 django开发 主题&#xff1a;员工管理系统 1.创建项目和app 创建app并注册 python manage.py startapp app01注册 2.设计表结构 3.在MySQL中生…

用这个烟感监测技术!同事下巴都惊掉了!

在当今社会&#xff0c;火灾作为一种极具破坏性的灾害&#xff0c;对人们的生命和财产安全构成着严峻的威胁。 为了更好地预防和管理火灾风险&#xff0c;烟感监控系统成为一项不可或缺的技术创新。为各行各业提供了全方位、高效的火灾预警和防范手段。 客户案例 商业办公楼 …

专门为机器学习开发的jpy语言

这本来是一个为工科教学专门开发的附属品&#xff0c;并不是说Python或Java有多不好&#xff0c;根本上它就是一个Java工程教材&#xff0c;但又要结合人工智能。因此&#xff0c;出现了这样一个包容性的怪胎&#xff0c;可以用python一样的语法与Java一起编写。 没流行起来的一…

共享WiFi项目加盟需要怎么操作?

共享WiFi项目作为当前热门的创业选择&#xff0c;越来越多的人选择加入这个行业。如果你也对共享WiFi项目感兴趣&#xff0c;并希望通过加盟方式来开展自己的创业计划&#xff0c;那么接下来&#xff0c;我们将为你详细介绍加盟共享WiFi项目的操作方法&#xff0c;助你成功开启…

【AI绘画】Stable Diffusion使用入门教程!!!!

手把手教你入门绘图超强的AI绘画&#xff0c;用户只需要输入一段图片的文字描述&#xff0c;即可生成精美的绘画。给大家带来了全新保姆级教程资料包 &#xff08;文末可获取&#xff09; 首先提几个好玩的名词&#xff1a; 炼丹&#xff1a;训练AI学习图片生成模型 咒语&…

tee漏洞学习-翻译-1:从任何上下文中获取 TrustZone 内核中的任意代码执行

原文&#xff1a;http://bits-please.blogspot.com/2015/03/getting-arbitrary-code-execution-in.html 目标是什么&#xff1f; 这将是一系列博客文章&#xff0c;详细介绍我发现的一系列漏洞&#xff0c;这些漏洞将使我们能够将任何用户的权限提升到所有用户的最高权限 - 在…