Skip to content

Commit 41fd4fc

Browse files
committed
Merge branch 'master' of github.com:HGX-Team/hypergraphx
2 parents 9284969 + 132cfac commit 41fd4fc

File tree

4 files changed

+171
-10
lines changed

4 files changed

+171
-10
lines changed

hypergraphx/core/directed_hypergraph.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,28 @@ def get_sizes(self):
696696
"""
697697
return [len(edge[0]) + len(edge[1]) for edge in self._edge_list.keys()]
698698

699+
def max_size(self):
700+
"""
701+
Returns the maximum size of the hypergraph.
702+
703+
Returns
704+
-------
705+
int
706+
Maximum size of the hypergraph.
707+
"""
708+
return max(self.get_sizes())
709+
710+
def max_order(self):
711+
"""
712+
Returns the maximum order of the hypergraph.
713+
714+
Returns
715+
-------
716+
int
717+
Maximum order of the hypergraph.
718+
"""
719+
return self.max_size() - 1
720+
699721
def distribution_sizes(self):
700722
"""
701723
Returns the distribution of sizes of the hyperedges in the hypergraph.
@@ -876,6 +898,10 @@ def is_isolated(self, node, size=None, order=None):
876898

877899
return is_isolated(self, node, size=size, order=order)
878900

901+
def to_line_graph(self, distance="intersection",s:int = 1, weighted=False):
902+
from hypergraphx.representations.projections import directed_line_graph
903+
return directed_line_graph(self, distance, s, weighted)
904+
879905
#Metadata
880906
def set_hypergraph_metadata(self, metadata):
881907
self._hypergraph_metadata = metadata

hypergraphx/core/hypergraph.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,10 @@ def adjacency_factor(self,t:int = 0):
978978
from hypergraphx.linalg import adjacency_factor
979979
return adjacency_factor(self, t)
980980

981+
def to_line_graph(self, distance="intersection",s:int = 1, weighted=False):
982+
from hypergraphx.representations.projections import line_graph
983+
return line_graph(self, distance, s, weighted)
984+
981985
#Metadata
982986
def set_hypergraph_metadata(self, metadata):
983987
self._hypergraph_metadata = metadata

hypergraphx/measures/s_centralities.py

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,64 @@ def s_closeness(H: Hypergraph, s=1):
3636
c = nx.closeness_centrality(lg)
3737
return {id_to_edge[k]: v for k, v in c.items()}
3838

39+
def s_betweenness_averaged(H: TemporalHypergraph, s=1):
40+
"""
41+
Computes the betweenness centrality for each edge in the temporal hypergraph.
42+
The function calculates the betweenness centrality during each time of the temporal hypergraph and then
43+
the result is the average betweenness centrality in each time.
44+
Parameters
45+
----------
46+
H : TemporalHypergraph
47+
The temporal hypergraph to compute the betweenness centrality for.
48+
s : int, optional
49+
Returns
50+
-------
51+
dict.
52+
The betweenness centrality for each edge in the temporal hypergraph.
53+
The keys are the edges and the values are the betweenness centrality.
54+
"""
55+
subhypergraphs = H.subhypergraph()
56+
T = len(subhypergraphs)
57+
res = dict()
58+
for hypergraph in subhypergraphs.values():
59+
lg, id_to_edge = line_graph(hypergraph, s=s)
60+
b = nx.betweenness_centrality(lg)
61+
for k, v in b.items():
62+
k = id_to_edge[k]
63+
if k not in res.keys():
64+
res[k] = 0
65+
res[k] += v
66+
return {k: v/T for k, v in res.items()}
67+
68+
def s_closeness_averaged(H: TemporalHypergraph, s=1):
69+
"""
70+
Computes the closeness centrality for each edge in the temporal hypergraph.
71+
The function calculates the closeness centrality during each time of the temporal hypergraph and then
72+
the result is the average closeness centrality in each time.
73+
Parameters
74+
----------
75+
H : TemporalHypergraph
76+
The temporal hypergraph to compute the closeness centrality for.
77+
s : int, optional
78+
Returns
79+
-------
80+
dict.
81+
The closeness centrality for each edge in the hypergraph.
82+
The keys are the edges and the values are the closeness centrality.
83+
"""
84+
subhypergraphs = H.subhypergraph()
85+
T = len(subhypergraphs)
86+
res = dict()
87+
for hypergraph in subhypergraphs.values():
88+
lg, id_to_edge = line_graph(hypergraph, s=s)
89+
b = nx.closeness_centrality(lg)
90+
for k, v in b.items():
91+
k = id_to_edge[k]
92+
if k not in res.keys():
93+
res[k] = 0
94+
res[k] += v
95+
return {k: v/T for k, v in res.items()}
96+
3997
def s_betweenness_nodes(H: Hypergraph|DirectedHypergraph):
4098
"""
4199
Computes the betweenness centrality for each node in the hypergraph.
@@ -94,10 +152,12 @@ def s_betweenness_nodes_averaged(H: TemporalHypergraph):
94152
lg, id_to_edge = bipartite_projection(hypergraph)
95153
b = nx.betweenness_centrality(lg)
96154
for k, v in b.items():
97-
if k not in res.keys():
98-
res[k] = 0
99-
res[k] += v
100-
return {id_to_edge[k]: v/T for k, v in res.items() if "E" not in k}
155+
if "E" not in k:
156+
k = id_to_edge[k]
157+
if k not in res.keys():
158+
res[k] = 0
159+
res[k] += v
160+
return {k: v/T for k, v in res.items() if "E" not in k}
101161

102162
def s_closenness_nodes_averaged(H: TemporalHypergraph):
103163
"""
@@ -121,7 +181,9 @@ def s_closenness_nodes_averaged(H: TemporalHypergraph):
121181
lg, id_to_edge = bipartite_projection(hypergraph)
122182
b = nx.closeness_centrality(lg)
123183
for k, v in b.items():
124-
if k not in res.keys():
125-
res[k] = 0
126-
res[k] += v
127-
return {id_to_edge[k]: v/T for k, v in res.items() if "E" not in k}
184+
if "E" not in k:
185+
k = id_to_edge[k]
186+
if k not in res.keys():
187+
res[k] = 0
188+
res[k] += v
189+
return {k: v/T for k, v in res.items() if "E" not in k}

hypergraphx/representations/projections.py

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import networkx as nx
2-
3-
from hypergraphx import Hypergraph
2+
from hypergraphx import Hypergraph, DirectedHypergraph
43
from hypergraphx.measures.edge_similarity import intersection, jaccard_similarity
54

65

@@ -176,3 +175,73 @@ def _distance(a, b):
176175
)
177176
vis[k] = True
178177
return g, id_to_edge
178+
179+
def directed_line_graph(h: DirectedHypergraph, distance="intersection", s=1, weighted=False):
180+
"""
181+
Returns a line graph of the directed hypergraph.
182+
183+
Parameters
184+
----------
185+
h : DirectedHypergraph
186+
The directed hypergraph to be projected.
187+
distance : str
188+
The distance function to be used. Can be 'intersection' or 'jaccard'.
189+
s : float
190+
The threshold for the distance function.
191+
weighted : bool
192+
Whether the line graph should be weighted or not.
193+
194+
Returns
195+
-------
196+
networkx.Graph
197+
The line graph of the hypergraph.
198+
199+
Notes
200+
-----
201+
Computing the line graph can be very expensive for large hypergraphs.
202+
203+
Example
204+
-------
205+
>>> import networkx as nx
206+
>>> import hypergraphx as hgx
207+
>>> from hypergraphx.representations.projections import line_graph
208+
>>>
209+
>>> h = hgx.Hypergraph()
210+
>>> h.add_nodes([1, 2, 3, 4, 5])
211+
>>> h.add_edges([(1, 2), (1, 2, 3), (3, 4, 5)])
212+
>>> g, idx = line_graph(h)
213+
>>> g.edges()
214+
EdgeView([(0, 1), (1, 2)])
215+
"""
216+
217+
def _distance(a, b):
218+
if distance == "intersection":
219+
return intersection(a, b)
220+
if distance == "jaccard":
221+
return jaccard_similarity(a, b)
222+
223+
edges = h.get_edges()
224+
edge_to_id = {}
225+
id_to_edge = {}
226+
cont = 0
227+
for e in edges:
228+
edge_to_id[e] = cont
229+
id_to_edge[cont] = e
230+
cont += 1
231+
232+
g = nx.DiGraph()
233+
g.add_nodes_from([i for i in range(len(h))])
234+
235+
for edge1 in h.get_edges():
236+
for edge2 in h.get_edges():
237+
if edge1 != edge2:
238+
source = set(edge1[1])
239+
target = set(edge2[0])
240+
w = _distance(source, target)
241+
if w >= s:
242+
if weighted:
243+
g.add_edge(edge_to_id[edge1],edge_to_id[edge2], weight=w)
244+
else:
245+
g.add_edge( edge_to_id[edge1],edge_to_id[edge2] )
246+
247+
return g, id_to_edge

0 commit comments

Comments
 (0)