
項目結構本文展示了一個珠寶供應鏈物流規劃的Python實現采用領域驅動設計(DDD)架構包含Prim和Kruskal兩種最小生成樹算法。系統主要包含領域模型LogisticsNode(實體)、LogisticsEdge(值對象)、LogisticsMST(聚合根)核心算法PrimAlgorithm(稠密圖)、KruskalAlgorithm(稀疏圖)應用服務層協調領域對象和算法示例演示了從緬甸礦區到各地門店的最低成本運輸路線規劃系統特點嚴格遵循DDD分層架構算法服務封裝在領域層支持鄰接矩陣(Prim)和邊列表(Kruskal)兩種輸入輸出格式化路線詳情和總成本適用于珠寶等貴重物品的高效物流網絡規劃。# encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:14 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : AggregateRoot.py class AggregateRoot: 聚合根父類DDD聚合根頂層抽象 def __init__(self): self._domain_events [] def get_domain_events(self): :return: return self._domain_events.copy() def clear_domain_events(self): :return: self._domain_events.clear() # encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:36 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : Entity.py class Entity: 實體父類擁有唯一業務ID def __init__(self, node_id: int): self._id node_id property def id(self) - int: return self._id def __eq__(self, other): if not isinstance(other, Entity): return False return self.id other.id # encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:36 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : ValueObject.py class ValueObject: 值對象父類不可變基于屬性判等 def __eq__(self, other): if not isinstance(other, ValueObject): return False return self.__dict__ other.__dict__ def __hash__(self): return hash(tuple(sorted(self.__dict__.items()))) # encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:38 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : DomainException.py class DomainException(Exception): 領域統一業務異常 def __init__(self, message: str): self.message message super().__init__(self.message) # encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:38 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : UnionFind.py class UnionFind: 并查集基礎設施Kruskal算法專用路徑壓縮普通合并 def __init__(self, size: int): self.parent list(range(size)) def find(self, x: int) - int: 查找根節點路徑壓縮 :param x: :return: if self.parent[x] ! x: self.parent[x] self.find(self.parent[x]) return self.parent[x] def union(self, x: int, y: int) - bool: 合并兩個集合 :return: True合并成功無環False同集合成環 root_x self.find(x) root_y self.find(y) if root_x root_y: return False self.parent[root_y] root_x return True # encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:40 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : LogisticsNode.py from PrimKruskal.Common.Entity import Entity class LogisticsNode(Entity): 物流網點【實體】 代表珠寶供應鏈節點礦區、加工廠、倉庫、線下門店 def __init__(self, node_id: int, node_name: str, node_category: str): super().__init__(node_id) self._node_name node_name self._node_category node_category property def node_name(self) - str: return self._node_name property def node_category(self) - str: return self._node_category def __repr__(self): return fNode id{self.id}, name{self.node_name}, type{self.node_category} # encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:41 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : LogisticsEdge.py from PrimKruskal.Common.ValueObject import ValueObject class LogisticsEdge(ValueObject): 物流運輸線路【值對象】 兩個網點之間運輸鏈路權重運輸綜合成本押運、損耗、路費、保險 不可變排序、判等基于起點、終點、成本 def __init__(self, start_id: int, end_id: int, cost: float): self.start_id start_id self.end_id end_id self.cost cost def __repr__(self): return fEdge {self.start_id}-{self.end_id}, cost{self.cost} # encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:41 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : LogisticsMST.py from PrimKruskal.Common.AggregateRoot import AggregateRoot from PrimKruskal.Domain.Model.LogisticsEdge import LogisticsEdge from PrimKruskal.Domain.Model.LogisticsNode import LogisticsNode from typing import List class LogisticsMST(AggregateRoot): 最小生成樹【聚合根】 聚合包含全部網點、MST選中線路、總成本 封裝領域結果統一對外輸出結構化數據 def __init__(self): super().__init__() self.all_nodes: List[LogisticsNode] [] self.mst_edges: List[LogisticsEdge] [] self.total_cost: float 0.0 def set_nodes(self, nodes: List[LogisticsNode]): self.all_nodes nodes def set_mst_result(self, edges: List[LogisticsEdge], total_cost: float): self.mst_edges edges self.total_cost total_cost def get_edge_detail(self) - List[tuple]: 格式化線路詳情用于打印展示 node_map {node.id: node.node_name for node in self.all_nodes} detail_list [] for edge in self.mst_edges: s_name node_map[edge.start_id] e_name node_map[edge.end_id] detail_list.append((s_name, e_name, edge.cost)) return detail_list # encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:42 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : PrimAlgorithm.py from PrimKruskal.Common.DomainException import DomainException from PrimKruskal.Domain.Model.LogisticsEdge import LogisticsEdge from PrimKruskal.Domain.Model.LogisticsNode import LogisticsNode from typing import List class PrimAlgorithm: 領域算法服務Prim最小生成樹 適用場景珠寶密集網點加工廠、門店扎堆稠密圖 入參鄰接矩陣、節點集合出參MST線路列表、總成本 staticmethod def calculate(adj_matrix: List[List[float]], nodes: List[LogisticsNode]) - (List[LogisticsEdge], float): node_count len(nodes) if node_count 0: raise DomainException(網點集合不能為空無法生成物流路網) INF float(inf) in_mst [False] * node_count min_dist [INF] * node_count pre_node [-1] * node_count min_dist[0] 0 total_cost 0.0 mst_edge_list [] for _ in range(node_count): # 選取距離生成樹最近節點 select_idx -1 min_val INF for i in range(node_count): if not in_mst[i] and min_dist[i] min_val: min_val min_dist[i] select_idx i if select_idx -1: raise DomainException(當前網點圖不連通無法構建完整物流最小生成樹) in_mst[select_idx] True total_cost min_val # 記錄前驅邊 pre_idx pre_node[select_idx] if pre_idx ! -1: edge LogisticsEdge(pre_idx, select_idx, adj_matrix[pre_idx][select_idx]) mst_edge_list.append(edge) # 松弛更新鄰接點距離 for j in range(node_count): weight adj_matrix[select_idx][j] if not in_mst[j] and weight 0 and weight min_dist[j]: min_dist[j] weight pre_node[j] select_idx return mst_edge_list, total_cost # encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:43 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : KruskalAlgorithm.py from PrimKruskal.Common.UnionFind import UnionFind from PrimKruskal.Common.DomainException import DomainException from PrimKruskal.Domain.Model.LogisticsEdge import LogisticsEdge from PrimKruskal.Domain.Model.LogisticsNode import LogisticsNode from typing import List class KruskalAlgorithm: 領域算法服務Kruskal最小生成樹 適用場景珠寶跨城分散門店、礦區稀疏圖節點多直達線路少 staticmethod def calculate(edge_list: List[LogisticsEdge], nodes: List[LogisticsNode]) - (List[LogisticsEdge], float): node_count len(nodes) if node_count 0: raise DomainException(網點集合不能為空無法生成物流路網) # 邊按成本升序排序 sorted_edges sorted(edge_list, keylambda e: e.cost) uf UnionFind(node_count) mst_edge_list [] total_cost 0.0 for edge in sorted_edges: if uf.union(edge.start_id, edge.end_id): mst_edge_list.append(edge) total_cost edge.cost if len(mst_edge_list) node_count - 1: break if len(mst_edge_list) ! node_count - 1: raise DomainException(當前網點圖不連通無法構建完整物流最小生成樹) return mst_edge_list, total_cost # encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:44 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : LogisticsRouteService.py from PrimKruskal.Domain.Algorithm.PrimAlgorithm import PrimAlgorithm from PrimKruskal.Domain.Algorithm.KruskalAlgorithm import KruskalAlgorithm from PrimKruskal.Domain.Model.LogisticsMST import LogisticsMST from PrimKruskal.Domain.Model.LogisticsNode import LogisticsNode from PrimKruskal.Domain.Model.LogisticsEdge import LogisticsEdge from typing import List class LogisticsRouteApplicationService: 應用服務珠寶物流路線規劃應用用例 職責組裝領域數據、調用領域算法、組裝聚合根、對外提供統一業務接口 不寫業務邏輯只做協調編排 staticmethod def build_mst_by_prim(adj_matrix: List[List[float]], nodes: List[LogisticsNode]) - LogisticsMST: 使用Prim算法生成物流最小生成樹 edges, cost PrimAlgorithm.calculate(adj_matrix, nodes) mst LogisticsMST() mst.set_nodes(nodes) mst.set_mst_result(edges, cost) return mst staticmethod def build_mst_by_kruskal(edge_list: List[LogisticsEdge], nodes: List[LogisticsNode]) - LogisticsMST: 使用Kruskal算法生成物流最小生成樹 edges, cost KruskalAlgorithm.calculate(edge_list, nodes) mst LogisticsMST() mst.set_nodes(nodes) mst.set_mst_result(edges, cost) return mst調用# encoding: utf-8 # 版權所有 2026 ?涂聚文有限公司? ? # 許可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述 Prim Algorithms and Kruskal Algorithms # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2024.3.6 python 3.11 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/8/7 22:44 # User : geovindu # Product : PyCharm # Project : PyAlgorithms # File : PrimKruskalBll.py from PrimKruskal.Application.LogisticsRouteService import LogisticsRouteApplicationService from PrimKruskal.Domain.Model.LogisticsNode import LogisticsNode from PrimKruskal.Domain.Model.LogisticsEdge import LogisticsEdge class PrimKruskalBll(object): def demo(self): :return: # 1. 構建珠寶供應鏈網點實體 node_list [ LogisticsNode(0, 緬甸翡翠礦區A, 原料礦區), LogisticsNode(1, 云南分揀加工廠, 加工中心), LogisticsNode(2, 深圳總倉儲中心, 倉儲中心), LogisticsNode(3, 廣州旗艦門店, 線下門店), LogisticsNode(4, 上海門店, 線下門店), LogisticsNode(5, 北京門店, 線下門店), ] # 2. Prim使用鄰接矩陣 單位千元0代表無直達線路 adj_matrix [ [0, 12, 28, 0, 0, 0], [12, 0, 8, 15, 0, 0], [28, 8, 0, 6, 18, 22], [0, 15, 6, 0, 25, 0], [0, 0, 18, 25, 0, 14], [0, 0, 22, 0, 14, 0] ] # 3. Kruskal使用原始邊列表 raw_edges [ LogisticsEdge(0, 1, 12), LogisticsEdge(0, 2, 28), LogisticsEdge(1, 2, 8), LogisticsEdge(1, 3, 15), LogisticsEdge(2, 3, 6), LogisticsEdge(2, 4, 18), LogisticsEdge(2, 5, 22), LogisticsEdge(3, 4, 25), LogisticsEdge(4, 5, 14), ] # 4. 應用服務調用 print( Prim算法-稠密網點物流規劃 ) prim_mst LogisticsRouteApplicationService.build_mst_by_prim(adj_matrix, node_list) prim_detail prim_mst.get_edge_detail() for start, end, cost in prim_detail: print(f{start} -- {end} 運輸成本{cost}千元) print(f全網最低總成本{prim_mst.total_cost} 千元\n) print( Kruskal算法-稀疏跨城網點規劃 ) krus_mst LogisticsRouteApplicationService.build_mst_by_kruskal(raw_edges, node_list) krus_detail krus_mst.get_edge_detail() for start, end, cost in krus_detail: print(f{start} -- {end} 運輸成本{cost}千元) print(f全網最低總成本{krus_mst.total_cost} 千元)輸出