CSharp: Prim Algorithms and Kruskal Algorithms

发布时间:2026/8/8 22:44:07
CSharp: Prim Algorithms and Kruskal Algorithms 项目结构文中代码展示了Prim和Kruskal算法在物流网络规划中的应用。通过C#实现了以下核心功能领域模型包含物流网点实体(LogisticsNode)、运输线路值对象(LogisticsEdge)和最小生成树聚合根(LogisticsMST)算法实现Prim算法基于邻接矩阵适合稠密图场景Kruskal算法基于边集合使用并查集(UnionFind)检测环路适合稀疏图场景应用层服务LogisticsRouteAppService协调算法调用示例演示了珠宝供应链网络矿区、加工厂、门店等的最低成本运输路线规划输出结果将显示两种算法计算出的最优运输路线及对应的总成本。代码采用DDD设计包含实体、值对象、聚合根等模式适用于复杂业务场景的图算法实现。/* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : AggregateRoot.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Common { /// summary /// DDD 聚合根顶层基类 /// /summary public abstract class AggregateRoot { private readonly Listobject _domainEvents new Listobject(); public Listobject GetDomainEvents() { return new Listobject(_domainEvents); } public void ClearDomainEvents() { _domainEvents.Clear(); } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : Entity.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Common { /// summary /// DDD 实体基类拥有唯一Id标识 /// /summary public abstract class Entity { private readonly int _id; protected Entity(int id) { _id id; } public int Id _id; public override bool Equals(object obj) { return obj is Entity entity Id entity.Id; } public override int GetHashCode() { return Id; } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : IValueObject.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Common { /// summary /// DDD 值对象不可变基于属性判等 /// /summary public interface IValueObject { bool Equals(IValueObject other); } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : DomainException.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Common { /// summary /// 全局领域业务异常 /// /summary public class DomainException : Exception { public DomainException(string message) : base($【领域异常】{message}) { } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : UnionFind.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Common { /// summary /// 并查集Kruskal算法依赖路径压缩 /// /summary public class UnionFind { private readonly int[] _parent; public UnionFind(int size) { _parent new int[size]; for (int i 0; i size; i) { _parent[i] i; } } /// summary /// 查找根节点路径压缩 /// /summary public int Find(int x) { if (_parent[x] ! x) { _parent[x] Find(_parent[x]); } return _parent[x]; } /// summary /// 合并集合 /// 返回true无环合并成功false同集合成环 /// /summary public bool Union(int x, int y) { int rootX Find(x); int rootY Find(y); if (rootX rootY) return false; _parent[rootY] rootX; return true; } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : LogisticsNode.cs */ using CSharpAlgorithms.PrimKruskal.Common; using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Domain.Model { /// summary /// 物流网点【实体】 /// 珠宝供应链节点矿区、加工厂、仓库、线下门店 /// /summary public class LogisticsNode : Entity { /// summary网点名称/summary public string NodeName { get; } /// summary网点分类原料矿区/加工中心/仓储中心/线下门店/summary public string NodeCategory { get; } public LogisticsNode(int id, string nodeName, string nodeCategory) : base(id) { NodeName nodeName; NodeCategory nodeCategory; } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : LogisticsEdge.cs */ using CSharpAlgorithms.PrimKruskal.Common; using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Domain.Model { /// summary /// 物流运输线路【值对象】 /// 权重综合运输成本路费、押运、保险、货品损耗单位千元 /// /summary public class LogisticsEdge : IValueObject { public int StartId { get; } public int EndId { get; } public double Cost { get; } public LogisticsEdge(int startId, int endId, double cost) { StartId startId; EndId endId; Cost cost; } public bool Equals(IValueObject other) { if (!(other is LogisticsEdge edge)) return false; return StartId edge.StartId EndId edge.EndId Cost edge.Cost; } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : LogisticsMST.cs */ using CSharpAlgorithms.PrimKruskal.Common; using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Domain.Model { /// summary /// 最小生成树【聚合根】 /// 聚合所有网点、MST选中线路、全网总成本 /// /summary public class LogisticsMST : AggregateRoot { public ListLogisticsNode AllNodes { get; set; } new ListLogisticsNode(); public ListLogisticsEdge MstEdges { get; set; } new ListLogisticsEdge(); public double TotalCost { get; set; } public void SetNodes(ListLogisticsNode nodes) { AllNodes nodes; } public void SetResult(ListLogisticsEdge edges, double totalCost) { MstEdges edges; TotalCost totalCost; } /// summary /// 格式化线路详情用于控制台打印输出 /// /summary public ListTuplestring, string, double GetDetailList() { Dictionaryint, string nameMap new Dictionaryint, string(); foreach (var node in AllNodes) { nameMap[node.Id] node.NodeName; } ListTuplestring, string, double list new ListTuplestring, string, double(); foreach (var edge in MstEdges) { list.Add(Tuple.Create(nameMap[edge.StartId], nameMap[edge.EndId], edge.Cost)); } return list; } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : PrimAlgorithm.cs */ using CSharpAlgorithms.PrimKruskal.Common; using CSharpAlgorithms.PrimKruskal.Domain.Model; using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Domain.Algorithm { /// summary /// Prim最小生成树 领域算法服务 /// 适用场景门店、加工厂密集稠密图 /// /summary public static class PrimAlgorithm { public static TupleListLogisticsEdge, double Calculate(double[][] adjMatrix, ListLogisticsNode nodes) { int nodeCount nodes.Count; if (nodeCount 0) throw new DomainException(网点集合不能为空无法生成物流路网); double INF double.MaxValue; bool[] inMst new bool[nodeCount]; double[] minDist new double[nodeCount]; int[] preNode new int[nodeCount]; for (int i 0; i nodeCount; i) { minDist[i] INF; preNode[i] -1; } minDist[0] 0; double totalCost 0; ListLogisticsEdge mstEdges new ListLogisticsEdge(); for (int round 0; round nodeCount; round) { // 选取距离MST最近节点 int selectIdx -1; double minVal INF; for (int i 0; i nodeCount; i) { if (!inMst[i] minDist[i] minVal) { minVal minDist[i]; selectIdx i; } } if (selectIdx -1) throw new DomainException(网点图不连通无法构建完整物流最小生成树); inMst[selectIdx] true; totalCost minVal; // 记录边 int preIdx preNode[selectIdx]; if (preIdx ! -1) { mstEdges.Add(new LogisticsEdge(preIdx, selectIdx, adjMatrix[preIdx][selectIdx])); } // 松弛更新邻接点距离 for (int j 0; j nodeCount; j) { double weight adjMatrix[selectIdx][j]; if (!inMst[j] weight 0 weight minDist[j]) { minDist[j] weight; preNode[j] selectIdx; } } } return Tuple.Create(mstEdges, totalCost); } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : KruskalAlgorithm.cs */ using CSharpAlgorithms.PrimKruskal.Common; using CSharpAlgorithms.PrimKruskal.Domain.Model; using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Domain.Algorithm { /// summary /// Kruskal最小生成树 领域算法服务 /// 适用场景跨城分散网点稀疏图 /// /summary public static class KruskalAlgorithm { public static TupleListLogisticsEdge, double Calculate(ListLogisticsEdge edgeList, ListLogisticsNode nodes) { int nodeCount nodes.Count; if (nodeCount 0) throw new DomainException(网点集合不能为空无法生成物流路网); // 边按成本升序排序 var sortedEdges edgeList.OrderBy(e e.Cost).ToList(); UnionFind uf new UnionFind(nodeCount); ListLogisticsEdge mstEdges new ListLogisticsEdge(); double totalCost 0; foreach (var edge in sortedEdges) { if (uf.Union(edge.StartId, edge.EndId)) { mstEdges.Add(edge); totalCost edge.Cost; if (mstEdges.Count nodeCount - 1) break; } } if (mstEdges.Count ! nodeCount - 1) throw new DomainException(网点图不连通无法构建完整物流最小生成树); return Tuple.Create(mstEdges, totalCost); } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : LogisticsRouteAppService.cs */ using CSharpAlgorithms.PrimKruskal.Domain.Algorithm; using CSharpAlgorithms.PrimKruskal.Domain.Model; using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.PrimKruskal.Application { /// summary /// 物流路线应用服务只做编排调度不写核心算法 /// /summary public class LogisticsRouteAppService { /// summary /// Prim生成最小生成树 /// /summary public LogisticsMST BuildByPrim(double[][] adjMatrix, ListLogisticsNode nodes) { var res PrimAlgorithm.Calculate(adjMatrix, nodes); LogisticsMST mst new LogisticsMST(); mst.SetNodes(nodes); mst.SetResult(res.Item1, res.Item2); return mst; } /// summary /// Kruskal生成最小生成树 /// /summary public LogisticsMST BuildByKruskal(ListLogisticsEdge edges, ListLogisticsNode nodes) { var res KruskalAlgorithm.Calculate(edges, nodes); LogisticsMST mst new LogisticsMST(); mst.SetNodes(nodes); mst.SetResult(res.Item1, res.Item2); return mst; } } }调用/* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Prim Algorithms and Kruskal Algorithms 普里姆算法和克鲁斯卡尔算法 # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/08/01 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : PrimKruskalBll.cs */ using System; using System.Collections.Generic; using System.Text; using CSharpAlgorithms.PrimKruskal.Application; using CSharpAlgorithms.PrimKruskal.Domain.Model; namespace CSharpAlgorithms.Bll { /// summary /// /// /summary public class PrimKruskalBll { public void Demo() { // 1、初始化珠宝供应链网点 ListLogisticsNode nodeList new ListLogisticsNode() { new LogisticsNode(0,缅甸翡翠矿区A,原料矿区), new LogisticsNode(1,云南分拣加工厂,加工中心), new LogisticsNode(2,深圳总仓储中心,仓储中心), new LogisticsNode(3,广州旗舰门店,线下门店), new LogisticsNode(4,上海门店,线下门店), new LogisticsNode(5,北京门店,线下门店) }; // 2、Prim邻接矩阵0代表无直达路线 double[][] adjMatrix new double[][] { new double[]{0,12,28,0,0,0}, new double[]{12,0,8,15,0,0}, new double[]{28,8,0,6,18,22}, new double[]{0,15,6,0,25,0}, new double[]{0,0,18,25,0,14}, new double[]{0,0,22,0,14,0} }; // 3、Kruskal原始边集合 ListLogisticsEdge edgeList new ListLogisticsEdge() { new LogisticsEdge(0,1,12), new LogisticsEdge(0,2,28), new LogisticsEdge(1,2,8), new LogisticsEdge(1,3,15), new LogisticsEdge(2,3,6), new LogisticsEdge(2,4,18), new LogisticsEdge(2,5,22), new LogisticsEdge(3,4,25), new LogisticsEdge(4,5,14) }; LogisticsRouteAppService appService new LogisticsRouteAppService(); // Prim计算输出 Console.WriteLine( Prim算法-稠密网点物流规划 ); LogisticsMST primMst appService.BuildByPrim(adjMatrix, nodeList); foreach (var item in primMst.GetDetailList()) { Console.WriteLine(${item.Item1} -- {item.Item2} 运输成本{item.Item3:0}千元); } Console.WriteLine($全网最低总成本{primMst.TotalCost:0} 千元\n); // Kruskal计算输出 Console.WriteLine( Kruskal算法-稀疏跨城网点规划 ); LogisticsMST krusMst appService.BuildByKruskal(edgeList, nodeList); foreach (var item in krusMst.GetDetailList()) { Console.WriteLine(${item.Item1} -- {item.Item2} 运输成本{item.Item3:0}千元); } Console.WriteLine($全网最低总成本{krusMst.TotalCost:0} 千元); Console.ReadKey(); } } }输出