Source code for thema.multiverse.universe.starGraph
# File: multiverse/universe/starGraph.py# Last Update: 05/15/24# Updated by: JWimportnetworkxasnx
[docs]classstarGraph:""" A graph wrapper to guide you through the stars! Parameters ---------- graph : nx.Graph The graph object representing the star graph. Attributes ---------- graph : nx.Graph The graph object representing the star graph. Methods ------- is_EdgeLess() Check if the graph is edgeless. components() Get a list of connected components in the graph. get_MST(k=0, components=None) Calculate a customizable Minimum Spanning Tree of the weighted graph. get_shortest_path(nodeID_1, nodeID_2) Calculate the shortest path between two nodes in the graph using Dijkstra's algorithm. """def__init__(self,graph):""" Initialize the starGraph class. Parameters ---------- graph : nx.Graph The graph object representing the star graph. """self.graph=graph@propertydefis_EdgeLess(self):""" Check if the graph is edgeless. Returns ------- bool True if the graph is edgeless, False otherwise. """returnlen(self.graph.edges)==0@propertydefcomponents(self):""" Get a list of connected components in the graph. Returns ------- dict A dictionary where the keys are component indices and the values are subgraphs representing the connected components. """returndict([(i,self.graph.subgraph(c).copy())fori,cinenumerate(nx.connected_components(self.graph))])
[docs]defget_MST(self,k=0,components=None):""" Calculate a customizable Minimum Spanning Tree of the weighted graph. Default is to return a minimum spanning tree for each connected component. If a `k` value is supplied that is greater than the number of connected components, then a minimum spanning forest of k trees will be returned (in the case that k is less than the number of connected components, then the default MST is returned). In the case that only certain components should be considered for further edge removal, then they may be specified in `components` and the `k` value should be supplied as a list. Parameters ---------- k : int or list, optional The number of trees in the minimum spanning forest. Note that k is ignored if it is less than the number of connected components. Default is 0. components : int or list, optional The connected components that are to be split. Default is None. Returns ------- nx.Graph The minimum spanning tree or forest of the weighted graph. """# Calculate simple MSTmst=nx.minimum_spanning_tree(self.graph,weight="weight")# Handle no components caseifcomponentsisNone:ifk<=nx.number_connected_components(self.graph):returnmstelse:k=k-nx.number_connected_components(self.graph)# Sort edges by weightsorted_edges=sorted(mst.edges(data=True),key=lambdax:x[2]["weight"])foredgeinsorted_edges[-k:]:mst.remove_edge(edge[0],edge[1])returnmst# Handle component specificelse:# Cast ints to listiftype(components)==int:components=[components]iftype(k)==int:k=[k]# List k must be same length as component listassertlen(k)==len(components),"Length of k must be equal to length of components"mst=nx.Graph()foriinrange(len(self._components)):cc_mst=nx.minimum_spanning_tree(self._components[i],weight="weight")# Component is to be split into specified number of groupsifiincomponents:j=components.index(i)cc_sorted_edges=sorted(cc_mst.edges(data=True),key=lambdax:x[2]["weight"])# Check number of edges is greater than k valueassertk[j]<len(cc_sorted_edges),f"k value for component {i} was greater than number of edges in component. "# k value should split component if it is givenassertk[j]>1,"Please supply k values greater than 1. "# Remove k-1 edges to result in k componentsforedgeincc_sorted_edges[-k[j]+1:]:cc_mst.remove_edge(edge[0],edge[1])# Combine component MSTsmst=nx.union(cc_mst,mst)returnmst
[docs]defget_shortest_path(self,nodeID_1,nodeID_2):""" Calculate the shortest path between two nodes in the graph using Dijkstra's algorithm. Parameters ---------- nodeID_1 : int or str The identifier of the source node. nodeID_2 : int or str The identifier of the target node. Returns ------- tuple A tuple containing: - A list representing the nodes in the shortest path from nodeID_1 to nodeID_2. - The length of the shortest path, considering edge weights. If no path exists between the nodes, returns (None, infinity). """try:# Calculate shortest path using Dijkstra's algorithmshortest_path=nx.shortest_path(self.graph,source=nodeID_1,target=nodeID_2,weight="weight")# Calculate the length of the shortest pathpath_length=sum(self.graph[shortest_path[i]][shortest_path[i+1]]["weight"]foriinrange(len(shortest_path)-1))returnshortest_path,path_lengthexceptnx.NetworkXNoPath:returnNone,float("inf")# No path exists, return None and infinity length