Files
boundary-aware-centrality/src/centrality.py

81 lines
2.4 KiB
Python

import math
import numpy as np
from src import plot
def convex_hull(G):
# gift wrapping algorithm
pos = G.vp["pos"]
x = []
y = []
for v in G.vertices():
# print(pos[v])
ver = pos[v]
x.append(ver[0])
y.append(ver[1])
min_x = min(x)
min_y = min(y)
max_x = max(x)
max_y = max(y)
pos = np.stack((np.array(x), np.array(y)), axis=-1)
convex_hull = []
hull_point = np.array([min_x,pos[np.argmin(x)][1]])
convex_hull.append(hull_point)
endpoint = None
i = 0
while not plot.Vector.eql(endpoint, convex_hull[0]):
endpoint = pos[0]
for point in pos:
if plot.Vector.eql(endpoint, hull_point) or plot.Vector.cross_z(plot.Vector.vec(convex_hull[i], endpoint), plot.Vector.vec(convex_hull[i], point)) < 0:
endpoint = point
i += 1
hull_point = endpoint
convex_hull.append(hull_point)
return convex_hull
def correct(G, centrality, m_opt, c0_opt, b_opt):
"""
Correct a given centrality through the calculated model.
@param pos [Array-2d] Positions of points (i.e. `g.vp["pos"].get_2d_array()`)
@param centrality [VertexPropertyMap] Result of a centrality calculation of `graph-tool` on graph G
@param m_opt [Float] Model m value (slope of linear function)
@param c0_opt [Float] Model c0 value (offset of linear function)
@param b_opt [Float] Model b value (intersection point)
@return [VertexPropertyMap] Corrected centrality values based on @param centrality
"""
corrected_metric = centrality
pos = G.vp["pos"]
x = []
y = []
for v in G.vertices():
# print(pos[v])
ver = pos[v]
x.append(ver[0])
y.append(ver[1])
keys = iter(centrality.a)
hull = convex_hull(G)
points = np.stack((np.array(x), np.array(y)), axis=-1)
for point in pos:
min_distance = math.inf
key = next(keys)
for edge in hull:
vector = plot.Vector.vec(point, edge)
distance = plot.Vector.vec_len(vector)
if distance < min_distance:
min_distance = distance
if min_distance <= b_opt:
# requires correction
value = centrality[key]
delta = (m_opt * b_opt) - (m_opt * min_distance)
corrected_metric[key] = value + delta
else:
# unaffected by boundary
corrected_metric[key] = centrality[key]
return corrected_metric