Matheus Schmitz
LinkedIn
Github Portfolio
# Imports
import sys
import os
import time
import random
from pyspark import SparkContext, SparkConf
from collections import defaultdict
from operator import add
from itertools import combinations
# Track the time taken
start_time = time.time()
import findspark
findspark.init()
sc = SparkContext.getOrCreate(SparkConf().setMaster("local[*]").set("spark.executor.memory", "4g").set("spark.driver.memory", "4g"))
sc.setLogLevel("ERROR")
# Define user inputs
filter_threshold = 7
input_file_path = "data/ub_sample_data.csv"
betweenness_output_file_path = "betweenness.csv"
community_output_file_path = "communities.csv"
# Read the CSV skipping its header, and reshape it as (user_a, user_b)
inputRDD = sc.textFile(input_file_path)
inputHeader = inputRDD.first()
inputRDD = inputRDD.filter(lambda row: row != inputHeader).map(lambda row: row.split(',')).groupByKey().map(lambda x: (x[0], set(x[1]))).collect()
# Convert users to nodes and create edges between those whose shared business cross the threshold
nodes = set()
edges = set()
for user_a in inputRDD:
for user_b in inputRDD:
# Ensure we don't compare an user against itself
if user_a[0] != user_b[0]:
# Then check if the intersection of rated businesses is above the threshold
if len(user_a[1].intersection(user_b[1])) >= filter_threshold:
# If so, add both users to the set of nodes
nodes.update([user_a[0], user_b[0]])
# And also add an edge between the users
edges.add(tuple((user_a[0], user_b[0])))
edges.add(tuple((user_b[0], user_a[0])))
# For each node, get a set of all other nodes it connects to (it has edges with)
adjacency_dict = {}
for (left_node, right_node) in edges:
if adjacency_dict.get(left_node) == None:
adjacency_dict[left_node] = set()
adjacency_dict[left_node].add(right_node)
def GN(root_node):
# Track the depth level on the tree
depth = 0
# Use dictionaries to construct a tree connecting nodes
tree, parent_to_child, child_to_parent, distances, node_scores, explored_nodes = {}, {}, defaultdict(set), {}, {}, set()
# Draw the beginning of the tree
while depth == 0:
# Update the tree with the nodes at this level
tree[depth] = root_node
# Update the list of used nodes to include the ones from this iteration
explored_nodes.add(root_node)
# Find the nodes at the next depth
next_depth_nodes = adjacency_dict[root_node] #adjacency_dict.value[root_node]
# Update the dict mapping the current node to its children (the yet unexplored nodes)
parent_to_child[root_node] = next_depth_nodes
# Update the dict mapping the current children to its parent node
[child_to_parent[child].add(parent) for parent, all_childs in parent_to_child.items() for child in all_childs]
# The distance from the root to all its direct children is 1
distances[root_node] = 1
# Move to the next depth
depth += 1
# Iteratively explore the tree's depth until all nodes have been explored
while len(next_depth_nodes) > 0:
# Update the tree with the nodes at this level
tree[depth] = next_depth_nodes
# Update the list of used nodes to include the ones from the new iteration
explored_nodes.update(next_depth_nodes)
# For all current nodes, get their children
iteration_nodes = set()
for node in next_depth_nodes:
# Find all nodes that share edges with the current node
connected_nodes = adjacency_dict[node]
# From those, keep the ones that have not yet been explored
child_nodes = connected_nodes - explored_nodes
# Update the dict mapping the current node to its children (the yet unexplored nodes)
parent_to_child[node] = child_nodes
# Update the dict mapping the current children to its parent node
[child_to_parent[child].add(parent) for parent, all_childs in parent_to_child.items() for child in all_childs]
# Get all parents of the current node
parent_nodes = child_to_parent[node]
# The denominator is the sum of the shortest distance of each parent to the root
if len(parent_nodes) > 0:
distances[node] = sum([distances[parent] for parent in parent_nodes])
else:
distances[node] = 1
# Go adding all newly discovered nodes to the list of nodes to be ran in the next iterations
iteration_nodes.update(connected_nodes)
# Get the nodes to be evaluated on the next depth level
next_depth_nodes = iteration_nodes - explored_nodes
# Move to the next depth
depth += 1
# Give all nodes (except the root) their starting score of 1.0
for node in nodes:
if node == root_node:
node_scores[node] = 0.0
else:
node_scores[node] = 1.0
# Calculate edge betweenness from the bottom up
while depth > 1:
# For each node in the current depth (starting from the deepest point)
for node in tree[depth-1]:
# Iterate over the node's parents
for parent in child_to_parent[node]:
# Calculate their betweennes
child_parent_betweennees = node_scores[node] * (distances[parent] / distances[node])
# Update the parent's score (which will matter when comparing it to its parents, aka the grandparents)
node_scores[parent] += child_parent_betweennees
# Output the betweenness of the two current nodes (child and parent)
yield (tuple(sorted((node, parent))), child_parent_betweennees)
# Iteratively go upper in depth until the root is reached
depth -= 1
# Apply the Girvan Newman algorithm and find communities
communities = sc.parallelize(nodes).map(lambda n: GN(n))
# From the communities, calculate betweennees of nodes (dividing by two to accout for the two-way road)
B_score = communities.flatMap(lambda child_parent_betweennees: [*child_parent_betweennees]).reduceByKey(add).map(lambda row: (row[0], row[1]/2)).sortBy(lambda row: (-row[1], row[0])).collect()
# View results
B_score
[(('cyuDrrG5eEK-TZI867MUPA', 'l-1cva9rA8_ugLrtSdKAqA'), 4234.0), (('1st2ltGKJ00ZcRsev-Ieew', 'DKolrsBSwMTpTJL22dqJRQ'), 3986.487301587302), (('1st2ltGKJ00ZcRsev-Ieew', 'HLY9oDcVBH9D25lU4X_V5Q'), 3857.0), (('1st2ltGKJ00ZcRsev-Ieew', 'Hv_q_ZnSIoZwdcoH0CyV2Q'), 3724.0), (('1st2ltGKJ00ZcRsev-Ieew', 'JM0GL6Dx4EuZ1mprLk5Gyg'), 3669.5126984126982), (('HLY9oDcVBH9D25lU4X_V5Q', 'l-1cva9rA8_ugLrtSdKAqA'), 3335.0), (('Hv_q_ZnSIoZwdcoH0CyV2Q', 'l-1cva9rA8_ugLrtSdKAqA'), 3289.0), (('0FVcoJko1kfZCrJRfssfIA', 'DKolrsBSwMTpTJL22dqJRQ'), 2216.61747130141), (('a48HhwcmjFLApZhiax41IA', 'o-t-i7nbT5N_cmkCXs5oDQ'), 1969.0), (('A-U-K9z9oraMH7eBZW1dOA', 'l-1cva9rA8_ugLrtSdKAqA'), 1898.0), (('cyuDrrG5eEK-TZI867MUPA', 'o-t-i7nbT5N_cmkCXs5oDQ'), 1862.0000000000005), (('39FT2Ui8KUXwmUt6hnwy-g', 'JM0GL6Dx4EuZ1mprLk5Gyg'), 1400.881419228444), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'KLB3wIYUwKDPMbijIE92vg'), 1308.1145213602306), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'e5kg9bLvlJz-MEUrGjIeVQ'), 1070.3719891219894), (('cyuDrrG5eEK-TZI867MUPA', 'pDNeS1nbkKS7mJmhRQJPig'), 780.0), (('A-U-K9z9oraMH7eBZW1dOA', 'pDNeS1nbkKS7mJmhRQJPig'), 764.75), (('DKolrsBSwMTpTJL22dqJRQ', 'JM0GL6Dx4EuZ1mprLk5Gyg'), 743.2490653250375), (('MtdSCXtmrSxj_uZOJ5ZycQ', 'ay4M5J28kBUf0odOQct0BA'), 644.5901335727829), (('0FVcoJko1kfZCrJRfssfIA', '39FT2Ui8KUXwmUt6hnwy-g'), 638.0675969927122), (('QvLg2kxqHHahxxOlHlEIZw', 'cyuDrrG5eEK-TZI867MUPA'), 624.5), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'fLnkI1uHtXEsjtF6KoBHbQ'), 612.6982794982796), (('A-U-K9z9oraMH7eBZW1dOA', 'QvLg2kxqHHahxxOlHlEIZw'), 612.25), (('DKolrsBSwMTpTJL22dqJRQ', 'bSUS0YcvS7UelmHvCzNWBA'), 608.622466306405), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'tekHDsd0fskYG3tqu4sHQw'), 582.0982794982797), (('39FT2Ui8KUXwmUt6hnwy-g', 'Uo5dPwoDpYBzOnmUnjxJ6A'), 561.0), (('DKolrsBSwMTpTJL22dqJRQ', '_VTEyUzzH92X3w-IpGaXVA'), 554.4504476817548), (('0FVcoJko1kfZCrJRfssfIA', 'KLB3wIYUwKDPMbijIE92vg'), 529.747269281208), (('KLB3wIYUwKDPMbijIE92vg', 'hilL60vuuh06sMxs6Ckkog'), 500.21428571428567), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'MtdSCXtmrSxj_uZOJ5ZycQ'), 467.1333333333333), (('0FVcoJko1kfZCrJRfssfIA', 'ay4M5J28kBUf0odOQct0BA'), 407.3201585415396), (('0FVcoJko1kfZCrJRfssfIA', 'LcCRMIDz1JgshpPGYfLDcA'), 390.6882006882007), (('39FT2Ui8KUXwmUt6hnwy-g', 'DKolrsBSwMTpTJL22dqJRQ'), 387.88373015873026), (('5DgFmyjW6hkBtXtTMKl4tA', 'JM0GL6Dx4EuZ1mprLk5Gyg'), 379.1039924876678), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'OoyQYSeYNyRVOmdO3tsxYA'), 377.4968363807751), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'hLVq7VSJBHZwqurwWoCmpg'), 376.0), (('0QREkWHGO8-Z_70qx1BIWw', 'LcCRMIDz1JgshpPGYfLDcA'), 372.0), (('7G8w2SnaC-qDVQ7_GqTxMg', 'JM0GL6Dx4EuZ1mprLk5Gyg'), 363.16666666666663), (('IuaAfrkirlfzY3f4PkgSmw', 'JM0GL6Dx4EuZ1mprLk5Gyg'), 344.4666666666667), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'm1IVpXClMox1VGw5hO2LhQ'), 340.00000000000006), (('0FVcoJko1kfZCrJRfssfIA', 'OoyQYSeYNyRVOmdO3tsxYA'), 330.57183638077504), (('DKolrsBSwMTpTJL22dqJRQ', 'bE7Yd0jI_P6g27MWEKKalA'), 326.59187098092275), (('0FVcoJko1kfZCrJRfssfIA', 'Ams0iLRd0AhZZectGKA8fw'), 280.0), (('0FVcoJko1kfZCrJRfssfIA', 'EiwxlbR8fb68lMgEXhcWKA'), 278.0), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'Zk95TMXDx0zMUhYq5u8pxw'), 265.0881860718614), (('4pc_EyanaC3ARh0MZZyouA', 'DKolrsBSwMTpTJL22dqJRQ'), 247.53829313960895), (('LcCRMIDz1JgshpPGYfLDcA', '_VTEyUzzH92X3w-IpGaXVA'), 245.80791430791433), (('MtdSCXtmrSxj_uZOJ5ZycQ', 'kwIhn1_cnQeUaLN0CuWWHw'), 243.0), (('KLB3wIYUwKDPMbijIE92vg', 'kwIhn1_cnQeUaLN0CuWWHw'), 238.07142857142858), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'dzJDCQ5vubQBJTfYTEmcbg'), 215.63333333333335), (('MtdSCXtmrSxj_uZOJ5ZycQ', 'e5kg9bLvlJz-MEUrGjIeVQ'), 203.17801087801087), (('0FMte0z-repSVWSJ_BaQTg', '0FVcoJko1kfZCrJRfssfIA'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', '7Vfy39A_totC-w70qZi0MA'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'BDjiEmXljD2ZHT61Iv9rrQ'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'IXD-jdycm7m34b_Nliy82g'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'JLv2Dmfj73-I0d9N41tz1A'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'KgJdBWS3ReP6TVhYWJRKmg'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'TjsBbWAfwxWEXPxaLNv5SQ'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'UAB1Zyg6Q0oEpXeYRf5K_g'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'XUEwSGOGARxW-3gPiGJKUg'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'bbK1mL-AyYCHZncDQ_4RgA'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'j8Dts8irvVBwEhEEae_-wA'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'ma6206bmu-a_Ja7Iv-yRCw'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'p9942XebvxZ9ubHm4SXmMQ'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'sO6iNKgv_ToVfof-aQWgXg'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'voXU5A3FfOcXZ2VNsJ0q4w'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'waN6iwcphiVEoCews4f4CA'), 189.0), (('0FVcoJko1kfZCrJRfssfIA', 'yCaDISH0R8e5U376zDWTpQ'), 189.0), (('0KhRPd66BZGHCtsb9mGh_g', 'dzJDCQ5vubQBJTfYTEmcbg'), 189.0), (('0QREkWHGO8-Z_70qx1BIWw', 'kKTcYPz47sCDH1_ylnE4ZQ'), 189.0), (('23o7tyUGlC6FCDVcyqLeFA', 'ay4M5J28kBUf0odOQct0BA'), 189.0), (('2k8OVAPxlXHsA5X6EIoQpQ', 'JM0GL6Dx4EuZ1mprLk5Gyg'), 189.0), (('2xVrxhQJUBmOyG4ML77XKw', 'MtdSCXtmrSxj_uZOJ5ZycQ'), 189.0), (('37HswRimgBEf7_US-c3CDA', 'e5kg9bLvlJz-MEUrGjIeVQ'), 189.0), (('39FT2Ui8KUXwmUt6hnwy-g', '79yaBDbLASfIdB-C2c8DzA'), 189.0), (('39FT2Ui8KUXwmUt6hnwy-g', 'ChshgCKJTdIDg17JKtFuJw'), 189.0), (('39FT2Ui8KUXwmUt6hnwy-g', 'PE8s8ACYABRNANI-T_WmzA'), 189.0), (('39FT2Ui8KUXwmUt6hnwy-g', 'sdLns7062kz3Ur_b8wgeYw'), 189.0), (('5DgFmyjW6hkBtXtTMKl4tA', 'nOTl4aPC4tKHK35T3bNauQ'), 189.0), (('750rhwO7D_Cul7_GtO9Jsg', 'fLnkI1uHtXEsjtF6KoBHbQ'), 189.0), (('7RCz4Ln_FaTvNrdwe251Dg', '9xM8upr_n9jchUDKxqSGHw'), 189.0), (('8oYMqhC5fhqAK_yxRjE7dQ', 'JM0GL6Dx4EuZ1mprLk5Gyg'), 189.0), (('903YwVSoAKyzudc8LH_HMA', 'm1IVpXClMox1VGw5hO2LhQ'), 189.0), (('DKolrsBSwMTpTJL22dqJRQ', 'hd343st7cOIUSfAd5r0U7A'), 189.0), (('DjcRgZ0cJbf6-W2TxvFlBA', 'fLnkI1uHtXEsjtF6KoBHbQ'), 189.0), (('DkLSyxogCcJXY5DbTZ-f2A', 'bSUS0YcvS7UelmHvCzNWBA'), 189.0), (('ELfzWgdf64VBLi5z1ECItw', 'ay4M5J28kBUf0odOQct0BA'), 189.0), (('EY8h9IJimXDNbPXVFpYF3A', 'hilL60vuuh06sMxs6Ckkog'), 189.0), (('H4EQn0rjFuGRgIm6c9NFLg', 'a48HhwcmjFLApZhiax41IA'), 189.0), (('H5Asta4LpiKmRhSjWaogIg', 'a48HhwcmjFLApZhiax41IA'), 189.0), (('HLY9oDcVBH9D25lU4X_V5Q', 'fOut10lknIp64tm3z6UTNg'), 189.0), (('IuaAfrkirlfzY3f4PkgSmw', 'Y0-lLNc2Y7gUGXPzSsMueQ'), 189.0), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'JRqMFKGxx6DnTGZrxwQZaA'), 189.0), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'NlNlyQynkyEU3l7TR3LXdg'), 189.0), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'TZ974xcbw2kqjYxAhDUYVg'), 189.0), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'UYcmGbelzRa0Q6JqzLoguw'), 189.0), (('KBoIRjxSW7OWczv8OS9Bew', 'l-1cva9rA8_ugLrtSdKAqA'), 189.0), (('KLB3wIYUwKDPMbijIE92vg', 'O9pMFJSPg80YVzpMfNikxw'), 189.0), (('KLB3wIYUwKDPMbijIE92vg', 'mnoe2vwouRADn97dTDkw4A'), 189.0), (('LgFDWZTLi1w9OGi5BtKORg', 'cyuDrrG5eEK-TZI867MUPA'), 189.0), (('LiNx18WUre9WFCEQlUhtKA', 'hilL60vuuh06sMxs6Ckkog'), 189.0), (('MtdSCXtmrSxj_uZOJ5ZycQ', 'SsOiVav4V5_NjTl21Lj92w'), 189.0), (('MwpK7PqQX7fgTFM2Pfy61w', 'fLnkI1uHtXEsjtF6KoBHbQ'), 189.0), (('ORJnGXXkS9tQBTNyPQJF9A', 'cyuDrrG5eEK-TZI867MUPA'), 189.0), (('PKEzKWv_FktMm2mGPjwd0Q', 'tekHDsd0fskYG3tqu4sHQw'), 189.0), (('T88y73qdOSutuvzLlhWtqQ', 'bSUS0YcvS7UelmHvCzNWBA'), 189.0), (('Tk_FWXueutKii3f9yJFsdw', 'bE7Yd0jI_P6g27MWEKKalA'), 189.0), (('VdoTNYWuoXo01umgannw8A', 'e5kg9bLvlJz-MEUrGjIeVQ'), 189.0), (('WaAOt_eG0_-yLpG3fI--3g', 'e5kg9bLvlJz-MEUrGjIeVQ'), 189.0), (('XEqQG61fetXhuEV9RPslIA', 'hLVq7VSJBHZwqurwWoCmpg'), 189.0), (('_VTEyUzzH92X3w-IpGaXVA', 'jPcrABeWgWlTPi-E0Op_aA'), 189.0), (('a48HhwcmjFLApZhiax41IA', 'e5sdXDOkCf0sIUAivXVluA'), 189.0), (('e5kg9bLvlJz-MEUrGjIeVQ', 'fcWM-oqjgS94yi1INhZa0g'), 189.0), (('jgoG_hHqnhZvQEoBK0-82w', 'kwIhn1_cnQeUaLN0CuWWHw'), 189.0), (('k24kSTpZHUdEd-QYXLy3fQ', 'pDNeS1nbkKS7mJmhRQJPig'), 189.0), (('kwIhn1_cnQeUaLN0CuWWHw', 'qd16czwFUVHICKF7A4qWsQ'), 189.0), (('tekHDsd0fskYG3tqu4sHQw', 'xrvyW1ruKS0uz9RtFewC0Q'), 189.0), (('9W73B44Iw8WslrTNB2CdCg', 'Uo5dPwoDpYBzOnmUnjxJ6A'), 188.0), (('UmTMCfPlhA6kJLAsLycSfg', 'Uo5dPwoDpYBzOnmUnjxJ6A'), 188.0), (('6YmRpoIuiq8I19Q8dHKTHw', 'a48HhwcmjFLApZhiax41IA'), 187.0), (('BDmxm7aeWFOLT35gSvkmig', 'a48HhwcmjFLApZhiax41IA'), 187.0), (('a48HhwcmjFLApZhiax41IA', 'angEr2YcXmCl20s8WQu32w'), 187.0), (('a48HhwcmjFLApZhiax41IA', 'frQs7y5qa-X1pvAM0sJe1w'), 187.0), (('0FVcoJko1kfZCrJRfssfIA', '97j2wkFU46OOgm6ErRAb7w'), 186.5), (('0FVcoJko1kfZCrJRfssfIA', 'SdXxLZQQnQNUEL1rGMOQ6w'), 186.5), (('2GUjO7NU88cPXpoffYCU8w', 'a48HhwcmjFLApZhiax41IA'), 186.5), (('6xi9tBoZ6r_v41u_XFsSnA', 'a48HhwcmjFLApZhiax41IA'), 186.5), (('4ZQq0ozRs-gXSz1z55iIDw', 'HLY9oDcVBH9D25lU4X_V5Q'), 186.33333333333331), (('HLY9oDcVBH9D25lU4X_V5Q', 'oegRUjhGbP62M18WyAL6pQ'), 186.0), (('KHjroLTG6Ah8LyItTyB2yw', 'LcCRMIDz1JgshpPGYfLDcA'), 186.0), (('LcCRMIDz1JgshpPGYfLDcA', 'tAcY4S3vIuNlAoRlCcz5VA'), 186.0), (('XrRLaAeV20MRwdSIGjj2SQ', 'a48HhwcmjFLApZhiax41IA'), 186.0), (('cIbbfJEGLB3B-c8Po4AL5g', 'e5kg9bLvlJz-MEUrGjIeVQ'), 185.83333333333334), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'NUtVG7jNPLJR2cxMXMH2-A'), 185.66666666666669), (('4ZQq0ozRs-gXSz1z55iIDw', 'Hv_q_ZnSIoZwdcoH0CyV2Q'), 184.33333333333331), (('Hv_q_ZnSIoZwdcoH0CyV2Q', 'oegRUjhGbP62M18WyAL6pQ'), 184.0), (('7G8w2SnaC-qDVQ7_GqTxMg', 'JqjAthJThuVYgTh4iWDZ2A'), 182.16666666666669), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'ajxohdcsKhRGFlEvHZDyTw'), 179.16666666666669), (('39FT2Ui8KUXwmUt6hnwy-g', 'dzJDCQ5vubQBJTfYTEmcbg'), 177.28072254542843), (('DKolrsBSwMTpTJL22dqJRQ', 'dTeSvET2SR5LDF_J07wJAQ'), 170.35557219199234), (('39FT2Ui8KUXwmUt6hnwy-g', 'bSUS0YcvS7UelmHvCzNWBA'), 170.33568723580242), (('5fQ9P6kbQM_E0dx8DL6JWA', 'JM0GL6Dx4EuZ1mprLk5Gyg'), 168.08594412123824), (('SX_SMrddkDU5dySbsZMu9A', 'cyuDrrG5eEK-TZI867MUPA'), 162.0), (('cyuDrrG5eEK-TZI867MUPA', 'jnn504CkjtfbYIwBquWmBw'), 160.75), (('YA-caxALI4C-eCiSM97new', 'cyuDrrG5eEK-TZI867MUPA'), 158.25), (('o-t-i7nbT5N_cmkCXs5oDQ', 'pDNeS1nbkKS7mJmhRQJPig'), 158.0), (('KLB3wIYUwKDPMbijIE92vg', 'bSUS0YcvS7UelmHvCzNWBA'), 157.18797857191728), (('39FT2Ui8KUXwmUt6hnwy-g', '_VTEyUzzH92X3w-IpGaXVA'), 155.81085475833834), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'jcriwcTidug0fK8sgAloHA'), 154.6745698745699), (('39FT2Ui8KUXwmUt6hnwy-g', 'ay4M5J28kBUf0odOQct0BA'), 152.83333333333331), (('A-U-K9z9oraMH7eBZW1dOA', 'jnn504CkjtfbYIwBquWmBw'), 152.0), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'ZA1OT-PIZwz2kdHDA6mShw'), 151.97456987456985), (('0FVcoJko1kfZCrJRfssfIA', 'e8uzNcSC5tQMD22GNAQEQA'), 148.21428571428567), (('SVC0CajvmYfH5uAq4JnGvg', 'l-1cva9rA8_ugLrtSdKAqA'), 146.0), (('ZZvfGGLnAkSBSUduV7KN-w', 'l-1cva9rA8_ugLrtSdKAqA'), 146.0), (('ay4M5J28kBUf0odOQct0BA', 'kwIhn1_cnQeUaLN0CuWWHw'), 138.4642857142857), (('MtdSCXtmrSxj_uZOJ5ZycQ', 'UwV6jBuTR1S9acT6bPTBPw'), 132.01666666666668), (('MtdSCXtmrSxj_uZOJ5ZycQ', 'fLnkI1uHtXEsjtF6KoBHbQ'), 131.3017205017205), (('ay4M5J28kBUf0odOQct0BA', 'bSUS0YcvS7UelmHvCzNWBA'), 130.3082079920891), (('39FT2Ui8KUXwmUt6hnwy-g', 'zBi_JWB5uUdVuz3JLoAxGQ'), 129.72368643069478), (('KLB3wIYUwKDPMbijIE92vg', '_VTEyUzzH92X3w-IpGaXVA'), 126.66509414640126), (('4pc_EyanaC3ARh0MZZyouA', 'LcCRMIDz1JgshpPGYfLDcA'), 125.13908868908867), (('MtdSCXtmrSxj_uZOJ5ZycQ', 'tekHDsd0fskYG3tqu4sHQw'), 124.60172050172048), (('0FVcoJko1kfZCrJRfssfIA', '7RCz4Ln_FaTvNrdwe251Dg'), 120.98095238095244), (('39FT2Ui8KUXwmUt6hnwy-g', 'R4l3ONHzGBakKKNo4TN9iQ'), 119.58333333333331), (('QvLg2kxqHHahxxOlHlEIZw', 'o-t-i7nbT5N_cmkCXs5oDQ'), 116.0), (('5DgFmyjW6hkBtXtTMKl4tA', '9S52XHEyrvOv4OZxU6pCLw'), 113.74514726147191), (('_VTEyUzzH92X3w-IpGaXVA', 'ay4M5J28kBUf0odOQct0BA'), 112.91386534643067), (('DKolrsBSwMTpTJL22dqJRQ', 'WoKCLSctS7G2547xKcED-Q'), 111.87023809523811), (('0FVcoJko1kfZCrJRfssfIA', 'XPAJ2KHkCwBA0vafF-2Zcg'), 110.95932539682539), (('0FVcoJko1kfZCrJRfssfIA', '2XYdguaaZ7dgi6fAlddujg'), 110.45932539682539), (('0FVcoJko1kfZCrJRfssfIA', '4PQhC-zTQ4ACEN0-r39JuQ'), 110.45932539682539), (('0FVcoJko1kfZCrJRfssfIA', 'CebjpVd3PsofCgotWp60pg'), 110.45932539682539), (('JM0GL6Dx4EuZ1mprLk5Gyg', 'mu4XvWvJOb3XpG1C_CHCWA'), 109.31666666666666), (('S1cjSFKcS5NVc3o1MkfpwA', 'pDNeS1nbkKS7mJmhRQJPig'), 108.5), (('mm9WYrFhiNqvHCyhQKw3Mg', 'pDNeS1nbkKS7mJmhRQJPig'), 108.5), (('39FT2Ui8KUXwmUt6hnwy-g', 'B0ENvYKQdNNr1Izd2r-BAA'), 106.84523809523809), (('KLB3wIYUwKDPMbijIE92vg', 'S9dDf0JqSMAvusp5f-9bGw'), 105.61363636363637), (('0FVcoJko1kfZCrJRfssfIA', 'bSUS0YcvS7UelmHvCzNWBA'), 105.21626984126982), (('DKolrsBSwMTpTJL22dqJRQ', 'tL2pS5UOmN6aAOi3Z-qFGg'), 103.91666666666669), (('0gZ8E5tBWTEtGEZDuTzhzw', 'cyuDrrG5eEK-TZI867MUPA'), 102.5), (('4ONcRRisDZkbV1cviA7nFw', 'cyuDrrG5eEK-TZI867MUPA'), 102.5), (('39FT2Ui8KUXwmUt6hnwy-g', 'KLB3wIYUwKDPMbijIE92vg'), 100.27857142857144), (('KLB3wIYUwKDPMbijIE92vg', 'zBi_JWB5uUdVuz3JLoAxGQ'), 99.45101008743025), (('LcCRMIDz1JgshpPGYfLDcA', 'zBi_JWB5uUdVuz3JLoAxGQ'), 99.34104784104784), (('5DgFmyjW6hkBtXtTMKl4tA', 'MtdSCXtmrSxj_uZOJ5ZycQ'), 99.14115477380408), (('39FT2Ui8KUXwmUt6hnwy-g', 'bHufZ2OTlC-OUxBDRXxViw'), 98.1), (('QUYbGl1DL-9faG150MQ7zA', 'pDNeS1nbkKS7mJmhRQJPig'), 96.5), (('0FVcoJko1kfZCrJRfssfIA', 'cm3_8c_NDhPcpwJQ96Aixw'), 96.42857142857143), (('EiwxlbR8fb68lMgEXhcWKA', 'JteQGisqOf_pklq7GA0Rww'), 96.0), (('DPtOaWemjBPvFiZJBi0m8A', 'tekHDsd0fskYG3tqu4sHQw'), 95.76666666666668), (('MrsRJa4SWLq8XLU1RtPdlw', 'e5kg9bLvlJz-MEUrGjIeVQ'), 95.4), (('HLY9oDcVBH9D25lU4X_V5Q', 'e0Jn0ZjqL-dWi7Brs0bbmg'), 95.0), (('0FVcoJko1kfZCrJRfssfIA', 'tRZAC_H5RHrjvyvtufcNXQ'), 94.76190476190474), (('HLY9oDcVBH9D25lU4X_V5Q', 'LaiylSIbrA3aPvOYtl-J4A'), 94.5), (('HLY9oDcVBH9D25lU4X_V5Q', 'ZEq0WtRJD9Bl_vYgCsbfOg'), 94.5), (('Ih85YhFRDzOnB09yS__94g', 'oegRUjhGbP62M18WyAL6pQ'), 94.5), (('Z9a1tDT8fVI75qXYwNhPpw', 'oegRUjhGbP62M18WyAL6pQ'), 94.5), (('DPtOaWemjBPvFiZJBi0m8A', 'e5kg9bLvlJz-MEUrGjIeVQ'), 94.4), (('Ams0iLRd0AhZZectGKA8fw', 'JteQGisqOf_pklq7GA0Rww'), 94.0), (('Hv_q_ZnSIoZwdcoH0CyV2Q', 'e0Jn0ZjqL-dWi7Brs0bbmg'), 94.0), (('MrsRJa4SWLq8XLU1RtPdlw', 'tekHDsd0fskYG3tqu4sHQw'), 93.6), (('4ZQq0ozRs-gXSz1z55iIDw', 'Ih85YhFRDzOnB09yS__94g'), 93.5), (('4ZQq0ozRs-gXSz1z55iIDw', 'Z9a1tDT8fVI75qXYwNhPpw'), 93.5), (('Hv_q_ZnSIoZwdcoH0CyV2Q', 'LaiylSIbrA3aPvOYtl-J4A'), 93.5), (('Hv_q_ZnSIoZwdcoH0CyV2Q', 'ZEq0WtRJD9Bl_vYgCsbfOg'), 93.5), (('HLY9oDcVBH9D25lU4X_V5Q', 'wXdrUQg4-VkSZH1FG4Byzw'), 93.33333333333333), (('0FVcoJko1kfZCrJRfssfIA', 'hqmnMdDS-Opjp3BfBJA8qA'), 92.54338118022329), (('QUYbGl1DL-9faG150MQ7zA', 'QvLg2kxqHHahxxOlHlEIZw'), 92.5), (('Hv_q_ZnSIoZwdcoH0CyV2Q', 'wXdrUQg4-VkSZH1FG4Byzw'), 92.33333333333333), (('9SWtEX1k9AjRg93BAzMCpg', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('BE4fE4R3TaVn8xy4sYYjbg', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('DgfsJqg_gozVgaeZ5vjllA', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('EI9ijI9Wh66LrVW-GmWkOg', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('FyQrUamokaPLDrBxGmzPnA', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('LKP0Yq9T7Ss6oiDZnVtQwQ', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('Nf_Jw_W_CwOz5WJ7ApSMxg', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('WXlxViTwXHPBvhioljN9PQ', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('ZXyGw3Z1DyhK1sfNtpcyYA', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('ae7zi8F0B6l_JCITh1mXDg', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('h-ajC_UHD0QAyAzySN6g2A', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('k58KNO8Rya-q8njKq8-uBQ', 'pDNeS1nbkKS7mJmhRQJPig'), 90.5), (('pDNeS1nbkKS7mJmhRQJPig', 'tcWnoX_IfuDmlDl6o6y3_g'), 90.5), (('1KQi8Ymatd4ySAd4fhSfaw', '39FT2Ui8KUXwmUt6hnwy-g'), 90.1), (('ay4M5J28kBUf0odOQct0BA', 'bE7Yd0jI_P6g27MWEKKalA'), 89.15049669722845), (('0gZ8E5tBWTEtGEZDuTzhzw', 'A-U-K9z9oraMH7eBZW1dOA'), 86.5), (('4ONcRRisDZkbV1cviA7nFw', 'A-U-K9z9oraMH7eBZW1dOA'), 86.5), (('9SWtEX1k9AjRg93BAzMCpg', 'QvLg2kxqHHahxxOlHlEIZw'), 86.5), (('BE4fE4R3TaVn8xy4sYYjbg', 'QvLg2kxqHHahxxOlHlEIZw'), 86.5), (('DgfsJqg_gozVgaeZ5vjllA', 'QvLg2kxqHHahxxOlHlEIZw'), 86.5), (('EI9ijI9Wh66LrVW-GmWkOg', 'QvLg2kxqHHahxxOlHlEIZw'), 86.5), (('FyQrUamokaPLDrBxGmzPnA', 'QvLg2kxqHHahxxOlHlEIZw'), 86.5), (('LKP0Yq9T7Ss6oiDZnVtQwQ', 'QvLg2kxqHHahxxOlHlEIZw'), 86.5), (('Nf_Jw_W_CwOz5WJ7ApSMxg', 'QvLg2kxqHHahxxOlHlEIZw'), 86.5), (('QvLg2kxqHHahxxOlHlEIZw', 'WXlxViTwXHPBvhioljN9PQ'), 86.5), (('QvLg2kxqHHahxxOlHlEIZw', 'ZXyGw3Z1DyhK1sfNtpcyYA'), 86.5), (('QvLg2kxqHHahxxOlHlEIZw', 'ae7zi8F0B6l_JCITh1mXDg'), 86.5), (('QvLg2kxqHHahxxOlHlEIZw', 'h-ajC_UHD0QAyAzySN6g2A'), 86.5), (('QvLg2kxqHHahxxOlHlEIZw', 'k58KNO8Rya-q8njKq8-uBQ'), 86.5), (('QvLg2kxqHHahxxOlHlEIZw', 'tcWnoX_IfuDmlDl6o6y3_g'), 86.5), (('S9dDf0JqSMAvusp5f-9bGw', '_VTEyUzzH92X3w-IpGaXVA'), 83.38636363636363), (('B7IvZ26ZUdL2jGbYsFVGxQ', 'cyuDrrG5eEK-TZI867MUPA'), 82.74999999999999), (('Gua5GdTlTWJpovtG7Hdtyg', 'cyuDrrG5eEK-TZI867MUPA'), 82.5), (('0FVcoJko1kfZCrJRfssfIA', 'B0ENvYKQdNNr1Izd2r-BAA'), 82.15476190476191), (('9S52XHEyrvOv4OZxU6pCLw', 'Zk95TMXDx0zMUhYq5u8pxw'), 82.0881860718614), (('0FVcoJko1kfZCrJRfssfIA', 'bJguBxPlnTW29tRTAF0nkQ'), 81.95027870680042), (('0FVcoJko1kfZCrJRfssfIA', '_VTEyUzzH92X3w-IpGaXVA'), 81.85400432900434), (('KLB3wIYUwKDPMbijIE92vg', 'y6jsaAXFstAJkf53R4_y4Q'), 81.69109135119572), (('39FT2Ui8KUXwmUt6hnwy-g', 'qtOCfMTrozmUSHWIcohc6Q'), 81.31666666666668), (('39FT2Ui8KUXwmUt6hnwy-g', 'mu4XvWvJOb3XpG1C_CHCWA'), 79.68333333333334), (('S1cjSFKcS5NVc3o1MkfpwA', 'jnn504CkjtfbYIwBquWmBw'), 79.5), (('jnn504CkjtfbYIwBquWmBw', 'mm9WYrFhiNqvHCyhQKw3Mg'), 79.5), (('2XYdguaaZ7dgi6fAlddujg', 'bSUS0YcvS7UelmHvCzNWBA'), 78.54067460317461), (('4PQhC-zTQ4ACEN0-r39JuQ', 'bSUS0YcvS7UelmHvCzNWBA'), 78.54067460317461), (('CebjpVd3PsofCgotWp60pg', 'bSUS0YcvS7UelmHvCzNWBA'), 78.54067460317461), (('XPAJ2KHkCwBA0vafF-2Zcg', '_VTEyUzzH92X3w-IpGaXVA'), 78.04067460317461), (('A-U-K9z9oraMH7eBZW1dOA', 'Gua5GdTlTWJpovtG7Hdtyg'), 76.25), (('A-U-K9z9oraMH7eBZW1dOA', 'B7IvZ26ZUdL2jGbYsFVGxQ'), 76.0), (('0FVcoJko1kfZCrJRfssfIA', 'bE7Yd0jI_P6g27MWEKKalA'), 72.51785714285714), (('0FVcoJko1kfZCrJRfssfIA', 'KtE55izPs1ubJn3ofF2IrA'), 71.67256077256076), (('7RCz4Ln_FaTvNrdwe251Dg', 'bSUS0YcvS7UelmHvCzNWBA'), 70.22698412698414), (('0FVcoJko1kfZCrJRfssfIA', '2quguRdKBzul3GpRi9e1mA'), 69.58401287727663), (('R4l3ONHzGBakKKNo4TN9iQ', 'bSUS0YcvS7UelmHvCzNWBA'), 69.41666666666666), (('bSUS0YcvS7UelmHvCzNWBA', 'tRZAC_H5RHrjvyvtufcNXQ'), 67.49999999999997), (('7RCz4Ln_FaTvNrdwe251Dg', '_VTEyUzzH92X3w-IpGaXVA'), 67.22698412698414), (('_VTEyUzzH92X3w-IpGaXVA', 'cm3_8c_NDhPcpwJQ96Aixw'), 66.16666666666666), (('0FVcoJko1kfZCrJRfssfIA', 'sBqCpEUn0qYdpSF4DbWlAQ'), 65.88401287727665), (('0FVcoJko1kfZCrJRfssfIA', '1KQi8Ymatd4ySAd4fhSfaw'), 62.949999999999996), (('ay4M5J28kBUf0odOQct0BA', 'zBi_JWB5uUdVuz3JLoAxGQ'), 60.893486163902125), (('bSUS0YcvS7UelmHvCzNWBA', 'hqmnMdDS-Opjp3BfBJA8qA'), 60.86084529505582), (('hilL60vuuh06sMxs6Ckkog', 'kwIhn1_cnQeUaLN0CuWWHw'), 60.785714285714285), (('0FVcoJko1kfZCrJRfssfIA', 'dW6bAWM1HbPdk_cGS_a2HA'), 57.35264297106404), (('UwV6jBuTR1S9acT6bPTBPw', 'e5kg9bLvlJz-MEUrGjIeVQ'), 56.983333333333334), (('LcCRMIDz1JgshpPGYfLDcA', 'y6jsaAXFstAJkf53R4_y4Q'), 55.254773004773), (('bJguBxPlnTW29tRTAF0nkQ', 'bSUS0YcvS7UelmHvCzNWBA'), 54.02486064659978), (('39FT2Ui8KUXwmUt6hnwy-g', 'dTeSvET2SR5LDF_J07wJAQ'), 53.51757032457871), (('_VTEyUzzH92X3w-IpGaXVA', 'bJguBxPlnTW29tRTAF0nkQ'), 53.02486064659978), (('0FVcoJko1kfZCrJRfssfIA', 'qtOCfMTrozmUSHWIcohc6Q'), 52.11666666666669), (('39FT2Ui8KUXwmUt6hnwy-g', '_Pn-EmWO-pFPFg81ZIEiDw'), 51.05595238095238), (('ay4M5J28kBUf0odOQct0BA', 'dTeSvET2SR5LDF_J07wJAQ'), 50.372607043022995), (('2quguRdKBzul3GpRi9e1mA', 'bSUS0YcvS7UelmHvCzNWBA'), 48.742724500883895), (('_VTEyUzzH92X3w-IpGaXVA', 'bHufZ2OTlC-OUxBDRXxViw'), 45.45000000000001), (('bHufZ2OTlC-OUxBDRXxViw', 'bSUS0YcvS7UelmHvCzNWBA'), 45.45), (('7RCz4Ln_FaTvNrdwe251Dg', 'dTeSvET2SR5LDF_J07wJAQ'), 45.2063492063492), (('KtE55izPs1ubJn3ofF2IrA', 'bSUS0YcvS7UelmHvCzNWBA'), 44.78784548784549), (('KtE55izPs1ubJn3ofF2IrA', '_VTEyUzzH92X3w-IpGaXVA'), 43.12117882117883), (('0FVcoJko1kfZCrJRfssfIA', 'tL2pS5UOmN6aAOi3Z-qFGg'), 42.840476190476195), (('ay4M5J28kBUf0odOQct0BA', 'y6jsaAXFstAJkf53R4_y4Q'), 42.62178797904605), (('2quguRdKBzul3GpRi9e1mA', '_VTEyUzzH92X3w-IpGaXVA'), 42.48716894532834), (('0FVcoJko1kfZCrJRfssfIA', '_Pn-EmWO-pFPFg81ZIEiDw'), 41.95357142857144), (('7RCz4Ln_FaTvNrdwe251Dg', 'bE7Yd0jI_P6g27MWEKKalA'), 41.11904761904762), (('e8uzNcSC5tQMD22GNAQEQA', 'zBi_JWB5uUdVuz3JLoAxGQ'), 40.785714285714285), (('0FVcoJko1kfZCrJRfssfIA', 'y6jsaAXFstAJkf53R4_y4Q'), 40.74523809523811), (('0FVcoJko1kfZCrJRfssfIA', '4pc_EyanaC3ARh0MZZyouA'), 40.700865800865806), (('MtdSCXtmrSxj_uZOJ5ZycQ', 'ZA1OT-PIZwz2kdHDA6mShw'), 39.02543012543013), (('bSUS0YcvS7UelmHvCzNWBA', 'sBqCpEUn0qYdpSF4DbWlAQ'), 38.653835611995014), (('_VTEyUzzH92X3w-IpGaXVA', 'sBqCpEUn0qYdpSF4DbWlAQ'), 37.82050227866169), (('1KQi8Ymatd4ySAd4fhSfaw', 'bSUS0YcvS7UelmHvCzNWBA'), 35.95), (('bE7Yd0jI_P6g27MWEKKalA', 'hqmnMdDS-Opjp3BfBJA8qA'), 35.59577352472089), (('KLB3wIYUwKDPMbijIE92vg', '_Pn-EmWO-pFPFg81ZIEiDw'), 35.45952380952382), (('0FVcoJko1kfZCrJRfssfIA', 'zBi_JWB5uUdVuz3JLoAxGQ'), 34.75515873015873), (('MtdSCXtmrSxj_uZOJ5ZycQ', 'jcriwcTidug0fK8sgAloHA'), 34.32543012543013), (('bSUS0YcvS7UelmHvCzNWBA', 'dW6bAWM1HbPdk_cGS_a2HA'), 32.51375598086124), (('0FVcoJko1kfZCrJRfssfIA', 'dTeSvET2SR5LDF_J07wJAQ'), 31.5547619047619), (('_VTEyUzzH92X3w-IpGaXVA', 'dW6bAWM1HbPdk_cGS_a2HA'), 31.307046024151283), (('WoKCLSctS7G2547xKcED-Q', '_VTEyUzzH92X3w-IpGaXVA'), 31.3047619047619), (('WoKCLSctS7G2547xKcED-Q', 'bSUS0YcvS7UelmHvCzNWBA'), 31.3047619047619), (('7RCz4Ln_FaTvNrdwe251Dg', 'zBi_JWB5uUdVuz3JLoAxGQ'), 31.239682539682537), (('SVC0CajvmYfH5uAq4JnGvg', 'cyuDrrG5eEK-TZI867MUPA'), 29.0), (('ZZvfGGLnAkSBSUduV7KN-w', 'cyuDrrG5eEK-TZI867MUPA'), 29.0), (('bSUS0YcvS7UelmHvCzNWBA', 'qtOCfMTrozmUSHWIcohc6Q'), 27.950000000000003), (('_VTEyUzzH92X3w-IpGaXVA', 'qtOCfMTrozmUSHWIcohc6Q'), 27.61666666666666), (('SX_SMrddkDU5dySbsZMu9A', 'pDNeS1nbkKS7mJmhRQJPig'), 27.0), (('tRZAC_H5RHrjvyvtufcNXQ', 'zBi_JWB5uUdVuz3JLoAxGQ'), 26.73809523809523), (('KtE55izPs1ubJn3ofF2IrA', 'bE7Yd0jI_P6g27MWEKKalA'), 26.685081585081583), (('cm3_8c_NDhPcpwJQ96Aixw', 'zBi_JWB5uUdVuz3JLoAxGQ'), 26.4047619047619), (('IuaAfrkirlfzY3f4PkgSmw', 'tekHDsd0fskYG3tqu4sHQw'), 25.533333333333335), (('dTeSvET2SR5LDF_J07wJAQ', 'sBqCpEUn0qYdpSF4DbWlAQ'), 24.79865834671338), (('e5kg9bLvlJz-MEUrGjIeVQ', 'tekHDsd0fskYG3tqu4sHQw'), 24.066666666666666), (('39FT2Ui8KUXwmUt6hnwy-g', 'OoyQYSeYNyRVOmdO3tsxYA'), 22.941666666666666), (('bSUS0YcvS7UelmHvCzNWBA', 'y6jsaAXFstAJkf53R4_y4Q'), 22.300793650793647), (('4pc_EyanaC3ARh0MZZyouA', 'bSUS0YcvS7UelmHvCzNWBA'), 22.256421356421356), (('bE7Yd0jI_P6g27MWEKKalA', 'sBqCpEUn0qYdpSF4DbWlAQ'), 21.842990885353316), (('_VTEyUzzH92X3w-IpGaXVA', 'bSUS0YcvS7UelmHvCzNWBA'), 21.38217893217893), (('e5kg9bLvlJz-MEUrGjIeVQ', 'm1IVpXClMox1VGw5hO2LhQ'), 21.000000000000004), (('5fQ9P6kbQM_E0dx8DL6JWA', 'dzJDCQ5vubQBJTfYTEmcbg'), 20.914055878761758), (('bSUS0YcvS7UelmHvCzNWBA', 'zBi_JWB5uUdVuz3JLoAxGQ'), 20.703571428571426), (('dTeSvET2SR5LDF_J07wJAQ', 'dW6bAWM1HbPdk_cGS_a2HA'), 20.624868990658463), (('bE7Yd0jI_P6g27MWEKKalA', 'zBi_JWB5uUdVuz3JLoAxGQ'), 20.338492063492062), (('bE7Yd0jI_P6g27MWEKKalA', 'bSUS0YcvS7UelmHvCzNWBA'), 20.19047619047619), (('bE7Yd0jI_P6g27MWEKKalA', 'dW6bAWM1HbPdk_cGS_a2HA'), 18.87169628616997), (('_Pn-EmWO-pFPFg81ZIEiDw', 'bSUS0YcvS7UelmHvCzNWBA'), 18.453571428571422), (('_VTEyUzzH92X3w-IpGaXVA', 'bE7Yd0jI_P6g27MWEKKalA'), 18.22380952380953), (('bSUS0YcvS7UelmHvCzNWBA', 'tL2pS5UOmN6aAOi3Z-qFGg'), 18.09047619047619), (('_Pn-EmWO-pFPFg81ZIEiDw', 'bE7Yd0jI_P6g27MWEKKalA'), 17.644047619047615), (('bE7Yd0jI_P6g27MWEKKalA', 'y6jsaAXFstAJkf53R4_y4Q'), 17.435714285714283), (('_VTEyUzzH92X3w-IpGaXVA', 'tL2pS5UOmN6aAOi3Z-qFGg'), 17.423809523809524), (('4pc_EyanaC3ARh0MZZyouA', 'zBi_JWB5uUdVuz3JLoAxGQ'), 17.264357864357862), (('_Pn-EmWO-pFPFg81ZIEiDw', '_VTEyUzzH92X3w-IpGaXVA'), 17.12023809523809), (('_Pn-EmWO-pFPFg81ZIEiDw', 'ay4M5J28kBUf0odOQct0BA'), 16.426190476190474), (('_VTEyUzzH92X3w-IpGaXVA', 'y6jsaAXFstAJkf53R4_y4Q'), 16.288528138528136), (('YA-caxALI4C-eCiSM97new', 'pDNeS1nbkKS7mJmhRQJPig'), 16.25), (('2quguRdKBzul3GpRi9e1mA', 'zBi_JWB5uUdVuz3JLoAxGQ'), 16.073658346713373), (('4pc_EyanaC3ARh0MZZyouA', 'dW6bAWM1HbPdk_cGS_a2HA'), 15.358367509683298), (('4pc_EyanaC3ARh0MZZyouA', 'y6jsaAXFstAJkf53R4_y4Q'), 15.029437229437228), (('m1IVpXClMox1VGw5hO2LhQ', 'tekHDsd0fskYG3tqu4sHQw'), 15.0), (('B7IvZ26ZUdL2jGbYsFVGxQ', 'pDNeS1nbkKS7mJmhRQJPig'), 14.75), (('dW6bAWM1HbPdk_cGS_a2HA', 'zBi_JWB5uUdVuz3JLoAxGQ'), 14.724868990658463), (('_VTEyUzzH92X3w-IpGaXVA', 'zBi_JWB5uUdVuz3JLoAxGQ'), 14.524639249639248), (('WoKCLSctS7G2547xKcED-Q', 'bE7Yd0jI_P6g27MWEKKalA'), 14.520238095238094), (('Gua5GdTlTWJpovtG7Hdtyg', 'pDNeS1nbkKS7mJmhRQJPig'), 14.5), (('dTeSvET2SR5LDF_J07wJAQ', 'y6jsaAXFstAJkf53R4_y4Q'), 14.316666666666663), (('jnn504CkjtfbYIwBquWmBw', 'pDNeS1nbkKS7mJmhRQJPig'), 13.75), (('QvLg2kxqHHahxxOlHlEIZw', 'jnn504CkjtfbYIwBquWmBw'), 13.250000000000002), (('A-U-K9z9oraMH7eBZW1dOA', 'SVC0CajvmYfH5uAq4JnGvg'), 13.0), (('A-U-K9z9oraMH7eBZW1dOA', 'ZZvfGGLnAkSBSUduV7KN-w'), 13.0), (('QvLg2kxqHHahxxOlHlEIZw', 'YA-caxALI4C-eCiSM97new'), 12.750000000000002), (('B7IvZ26ZUdL2jGbYsFVGxQ', 'QvLg2kxqHHahxxOlHlEIZw'), 12.250000000000002), (('Gua5GdTlTWJpovtG7Hdtyg', 'QvLg2kxqHHahxxOlHlEIZw'), 12.0), (('dTeSvET2SR5LDF_J07wJAQ', 'zBi_JWB5uUdVuz3JLoAxGQ'), 11.64206349206349), (('2quguRdKBzul3GpRi9e1mA', 'LcCRMIDz1JgshpPGYfLDcA'), 9.92222222222222), (('5DgFmyjW6hkBtXtTMKl4tA', 'ajxohdcsKhRGFlEvHZDyTw'), 9.166666666666666), (('bSUS0YcvS7UelmHvCzNWBA', 'dTeSvET2SR5LDF_J07wJAQ'), 9.054761904761904), (('2quguRdKBzul3GpRi9e1mA', 'y6jsaAXFstAJkf53R4_y4Q'), 9.03465755201998), (('9S52XHEyrvOv4OZxU6pCLw', 'JqjAthJThuVYgTh4iWDZ2A'), 8.833333333333332), (('IuaAfrkirlfzY3f4PkgSmw', 'ZA1OT-PIZwz2kdHDA6mShw'), 8.799999999999999), (('_VTEyUzzH92X3w-IpGaXVA', 'dTeSvET2SR5LDF_J07wJAQ'), 7.9714285714285715), (('A-U-K9z9oraMH7eBZW1dOA', 'cyuDrrG5eEK-TZI867MUPA'), 7.75), (('bE7Yd0jI_P6g27MWEKKalA', 'tL2pS5UOmN6aAOi3Z-qFGg'), 6.728571428571429), (('bE7Yd0jI_P6g27MWEKKalA', 'dTeSvET2SR5LDF_J07wJAQ'), 5.842857142857143), (('_Pn-EmWO-pFPFg81ZIEiDw', 'y6jsaAXFstAJkf53R4_y4Q'), 4.851190476190476), (('y6jsaAXFstAJkf53R4_y4Q', 'zBi_JWB5uUdVuz3JLoAxGQ'), 4.101190476190475), (('7G8w2SnaC-qDVQ7_GqTxMg', 'ajxohdcsKhRGFlEvHZDyTw'), 4.0), (('Cf0chERnfd06ltnN45xLNQ', 'CyrRjt_7iJ8_lSHeH1_TlA'), 4.0), (('Cf0chERnfd06ltnN45xLNQ', 'JhFK9D3LYl23Se3x4oPUxA'), 4.0), (('Cf0chERnfd06ltnN45xLNQ', 'ZW-XoteNlRuuK-19q1spmw'), 4.0), (('Cf0chERnfd06ltnN45xLNQ', 'lL-wNa0TKK6LXrlcVmjYrQ'), 4.0), (('_6Zg4ukwS0kst9UtkfVw3w', 'lJFBgSAccsMGwIjfD7LMeQ'), 4.0), (('QvLg2kxqHHahxxOlHlEIZw', 'pDNeS1nbkKS7mJmhRQJPig'), 3.5), (('2quguRdKBzul3GpRi9e1mA', 'KtE55izPs1ubJn3ofF2IrA'), 3.4), (('oegRUjhGbP62M18WyAL6pQ', 'wXdrUQg4-VkSZH1FG4Byzw'), 3.3333333333333335), (('NUtVG7jNPLJR2cxMXMH2-A', 'ajxohdcsKhRGFlEvHZDyTw'), 3.333333333333333), (('DPtOaWemjBPvFiZJBi0m8A', 'cIbbfJEGLB3B-c8Po4AL5g'), 3.166666666666666), (('CLbpPUqP6XpeAfoqScGaJQ', 'tX0r-C9BaHYEolRUfufTsQ'), 3.0), (('Gr-MqCunME2K_KmsAwjpTA', 'lJFBgSAccsMGwIjfD7LMeQ'), 3.0), (('QRsuZ_LqrRU65dTs5CL4Lw', '_6Zg4ukwS0kst9UtkfVw3w'), 3.0), (('drTMOo4p8nL0pnMNEyat2A', 'tX0r-C9BaHYEolRUfufTsQ'), 3.0), (('tX0r-C9BaHYEolRUfufTsQ', 'xhlcoVm3FOKcxZ0phkdO6Q'), 3.0), (('97j2wkFU46OOgm6ErRAb7w', 'EiwxlbR8fb68lMgEXhcWKA'), 2.5), (('EiwxlbR8fb68lMgEXhcWKA', 'SdXxLZQQnQNUEL1rGMOQ6w'), 2.5), (('Gua5GdTlTWJpovtG7Hdtyg', 'jnn504CkjtfbYIwBquWmBw'), 2.25), (('0QREkWHGO8-Z_70qx1BIWw', 'KHjroLTG6Ah8LyItTyB2yw'), 2.0), (('0QREkWHGO8-Z_70qx1BIWw', 'tAcY4S3vIuNlAoRlCcz5VA'), 2.0), (('98rLDXbloLXekGjieuQSlA', 'QYKexxaOJQlseGWmc6soRg'), 2.0), (('B7IvZ26ZUdL2jGbYsFVGxQ', 'jnn504CkjtfbYIwBquWmBw'), 2.0), (('BDmxm7aeWFOLT35gSvkmig', 'XrRLaAeV20MRwdSIGjj2SQ'), 2.0), (('HLY9oDcVBH9D25lU4X_V5Q', 'Hv_q_ZnSIoZwdcoH0CyV2Q'), 2.0), (('MJ0Wphhko2-LbJ0uZ5XyQA', 'QYKexxaOJQlseGWmc6soRg'), 2.0), (('Gua5GdTlTWJpovtG7Hdtyg', 'YA-caxALI4C-eCiSM97new'), 1.75), (('2GUjO7NU88cPXpoffYCU8w', 'XrRLaAeV20MRwdSIGjj2SQ'), 1.5), (('6xi9tBoZ6r_v41u_XFsSnA', 'XrRLaAeV20MRwdSIGjj2SQ'), 1.5), (('4ZQq0ozRs-gXSz1z55iIDw', 'oegRUjhGbP62M18WyAL6pQ'), 1.3333333333333333), (('B7IvZ26ZUdL2jGbYsFVGxQ', 'Gua5GdTlTWJpovtG7Hdtyg'), 1.25), (('23y0Nv9FFWn_3UWudpnFMA', 'eqWEgMH-DCP74i82BEAZzw'), 1.0), (('2GUjO7NU88cPXpoffYCU8w', '6xi9tBoZ6r_v41u_XFsSnA'), 1.0), (('3Vd_ATdvvuVVgn_YCpz8fw', 'jSbXY_rno4hYHQCFftsWXg'), 1.0), (('453V8MlGr8y61PpsDAFjKQ', 'gH0dJQhyKUOVCKQA6sqAnw'), 1.0), (('46HhzhpBfTdTSB5ceTx_Og', 'YVQFzWm0H72mLUh-8gzd5w'), 1.0), (('6YmRpoIuiq8I19Q8dHKTHw', 'angEr2YcXmCl20s8WQu32w'), 1.0), (('6YmRpoIuiq8I19Q8dHKTHw', 'frQs7y5qa-X1pvAM0sJe1w'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'BE4fE4R3TaVn8xy4sYYjbg'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'DgfsJqg_gozVgaeZ5vjllA'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'EI9ijI9Wh66LrVW-GmWkOg'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'FyQrUamokaPLDrBxGmzPnA'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'LKP0Yq9T7Ss6oiDZnVtQwQ'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'Nf_Jw_W_CwOz5WJ7ApSMxg'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'WXlxViTwXHPBvhioljN9PQ'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'ZXyGw3Z1DyhK1sfNtpcyYA'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'ae7zi8F0B6l_JCITh1mXDg'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'h-ajC_UHD0QAyAzySN6g2A'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('9SWtEX1k9AjRg93BAzMCpg', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('9W73B44Iw8WslrTNB2CdCg', 'UmTMCfPlhA6kJLAsLycSfg'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'DgfsJqg_gozVgaeZ5vjllA'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'EI9ijI9Wh66LrVW-GmWkOg'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'FyQrUamokaPLDrBxGmzPnA'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'LKP0Yq9T7Ss6oiDZnVtQwQ'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'Nf_Jw_W_CwOz5WJ7ApSMxg'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'WXlxViTwXHPBvhioljN9PQ'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'ZXyGw3Z1DyhK1sfNtpcyYA'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'ae7zi8F0B6l_JCITh1mXDg'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'h-ajC_UHD0QAyAzySN6g2A'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('BE4fE4R3TaVn8xy4sYYjbg', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('DgfsJqg_gozVgaeZ5vjllA', 'EI9ijI9Wh66LrVW-GmWkOg'), 1.0), (('DgfsJqg_gozVgaeZ5vjllA', 'FyQrUamokaPLDrBxGmzPnA'), 1.0), (('DgfsJqg_gozVgaeZ5vjllA', 'LKP0Yq9T7Ss6oiDZnVtQwQ'), 1.0), (('DgfsJqg_gozVgaeZ5vjllA', 'Nf_Jw_W_CwOz5WJ7ApSMxg'), 1.0), (('DgfsJqg_gozVgaeZ5vjllA', 'WXlxViTwXHPBvhioljN9PQ'), 1.0), (('DgfsJqg_gozVgaeZ5vjllA', 'ZXyGw3Z1DyhK1sfNtpcyYA'), 1.0), (('DgfsJqg_gozVgaeZ5vjllA', 'ae7zi8F0B6l_JCITh1mXDg'), 1.0), (('DgfsJqg_gozVgaeZ5vjllA', 'h-ajC_UHD0QAyAzySN6g2A'), 1.0), (('DgfsJqg_gozVgaeZ5vjllA', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('DgfsJqg_gozVgaeZ5vjllA', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('EI9ijI9Wh66LrVW-GmWkOg', 'FyQrUamokaPLDrBxGmzPnA'), 1.0), (('EI9ijI9Wh66LrVW-GmWkOg', 'LKP0Yq9T7Ss6oiDZnVtQwQ'), 1.0), (('EI9ijI9Wh66LrVW-GmWkOg', 'Nf_Jw_W_CwOz5WJ7ApSMxg'), 1.0), (('EI9ijI9Wh66LrVW-GmWkOg', 'WXlxViTwXHPBvhioljN9PQ'), 1.0), (('EI9ijI9Wh66LrVW-GmWkOg', 'ZXyGw3Z1DyhK1sfNtpcyYA'), 1.0), (('EI9ijI9Wh66LrVW-GmWkOg', 'ae7zi8F0B6l_JCITh1mXDg'), 1.0), (('EI9ijI9Wh66LrVW-GmWkOg', 'h-ajC_UHD0QAyAzySN6g2A'), 1.0), (('EI9ijI9Wh66LrVW-GmWkOg', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('EI9ijI9Wh66LrVW-GmWkOg', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('F47atsRPw-KHmRVk5exBFw', 'JeOHA8tW7gr-FDYOcPJoeA'), 1.0), (('FyQrUamokaPLDrBxGmzPnA', 'LKP0Yq9T7Ss6oiDZnVtQwQ'), 1.0), (('FyQrUamokaPLDrBxGmzPnA', 'Nf_Jw_W_CwOz5WJ7ApSMxg'), 1.0), (('FyQrUamokaPLDrBxGmzPnA', 'WXlxViTwXHPBvhioljN9PQ'), 1.0), (('FyQrUamokaPLDrBxGmzPnA', 'ZXyGw3Z1DyhK1sfNtpcyYA'), 1.0), (('FyQrUamokaPLDrBxGmzPnA', 'ae7zi8F0B6l_JCITh1mXDg'), 1.0), (('FyQrUamokaPLDrBxGmzPnA', 'h-ajC_UHD0QAyAzySN6g2A'), 1.0), (('FyQrUamokaPLDrBxGmzPnA', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('FyQrUamokaPLDrBxGmzPnA', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('Ih85YhFRDzOnB09yS__94g', 'Z9a1tDT8fVI75qXYwNhPpw'), 1.0), (('KHjroLTG6Ah8LyItTyB2yw', 'tAcY4S3vIuNlAoRlCcz5VA'), 1.0), (('LKP0Yq9T7Ss6oiDZnVtQwQ', 'Nf_Jw_W_CwOz5WJ7ApSMxg'), 1.0), (('LKP0Yq9T7Ss6oiDZnVtQwQ', 'WXlxViTwXHPBvhioljN9PQ'), 1.0), (('LKP0Yq9T7Ss6oiDZnVtQwQ', 'ZXyGw3Z1DyhK1sfNtpcyYA'), 1.0), (('LKP0Yq9T7Ss6oiDZnVtQwQ', 'ae7zi8F0B6l_JCITh1mXDg'), 1.0), (('LKP0Yq9T7Ss6oiDZnVtQwQ', 'h-ajC_UHD0QAyAzySN6g2A'), 1.0), (('LKP0Yq9T7Ss6oiDZnVtQwQ', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('LKP0Yq9T7Ss6oiDZnVtQwQ', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('LaiylSIbrA3aPvOYtl-J4A', 'ZEq0WtRJD9Bl_vYgCsbfOg'), 1.0), (('Nf_Jw_W_CwOz5WJ7ApSMxg', 'WXlxViTwXHPBvhioljN9PQ'), 1.0), (('Nf_Jw_W_CwOz5WJ7ApSMxg', 'ZXyGw3Z1DyhK1sfNtpcyYA'), 1.0), (('Nf_Jw_W_CwOz5WJ7ApSMxg', 'ae7zi8F0B6l_JCITh1mXDg'), 1.0), (('Nf_Jw_W_CwOz5WJ7ApSMxg', 'h-ajC_UHD0QAyAzySN6g2A'), 1.0), (('Nf_Jw_W_CwOz5WJ7ApSMxg', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('Nf_Jw_W_CwOz5WJ7ApSMxg', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('S1cjSFKcS5NVc3o1MkfpwA', 'mm9WYrFhiNqvHCyhQKw3Mg'), 1.0), (('SVC0CajvmYfH5uAq4JnGvg', 'ZZvfGGLnAkSBSUduV7KN-w'), 1.0), (('Si3aMsOVGSVlsc54iuiPwA', 'd5WLqmTMvmL7-RmUDVKqqQ'), 1.0), (('WXlxViTwXHPBvhioljN9PQ', 'ZXyGw3Z1DyhK1sfNtpcyYA'), 1.0), (('WXlxViTwXHPBvhioljN9PQ', 'ae7zi8F0B6l_JCITh1mXDg'), 1.0), (('WXlxViTwXHPBvhioljN9PQ', 'h-ajC_UHD0QAyAzySN6g2A'), 1.0), (('WXlxViTwXHPBvhioljN9PQ', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('WXlxViTwXHPBvhioljN9PQ', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('ZXyGw3Z1DyhK1sfNtpcyYA', 'ae7zi8F0B6l_JCITh1mXDg'), 1.0), (('ZXyGw3Z1DyhK1sfNtpcyYA', 'h-ajC_UHD0QAyAzySN6g2A'), 1.0), (('ZXyGw3Z1DyhK1sfNtpcyYA', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('ZXyGw3Z1DyhK1sfNtpcyYA', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('_m1ot2zZetDgjerAD2Sidg', 'vENR70IrUsDNTDebbuxyQA'), 1.0), (('ae7zi8F0B6l_JCITh1mXDg', 'h-ajC_UHD0QAyAzySN6g2A'), 1.0), (('ae7zi8F0B6l_JCITh1mXDg', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('ae7zi8F0B6l_JCITh1mXDg', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('angEr2YcXmCl20s8WQu32w', 'frQs7y5qa-X1pvAM0sJe1w'), 1.0), (('gUu0uaiU7UEUVIgCdnqPVQ', 'jJDUCuPwVqwjbth3s92whA'), 1.0), (('h-ajC_UHD0QAyAzySN6g2A', 'k58KNO8Rya-q8njKq8-uBQ'), 1.0), (('h-ajC_UHD0QAyAzySN6g2A', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0), (('k58KNO8Rya-q8njKq8-uBQ', 'tcWnoX_IfuDmlDl6o6y3_g'), 1.0)]
# Save the pairs and thei betweenness to a txt
with open(betweenness_output_file_path, 'w') as f_out:
for node_pair, betweenness in B_score:
f_out.write(str(node_pair) + ',' + str(round(betweenness, 5)) + '\n')
# Calculate the degree matrix
DM = {left_node: len(right_node) for left_node, right_node in adjacency_dict.items()}
# Calculate the adjacency matrix
AM = {(left_node, right_node): 1 if (left_node, right_node) in edges else 0 for left_node in nodes for right_node in nodes}
# Calculate m (number of edges in the original graph)
m = len(edges) / 2
# Track the number of edges remaning
remaning_edges = m
Use Modularity to Define the Best Community Split
def compute_communities(adjacency_dict, nodes):
# Objects to store data over iterations
communities = []
remaning_nodes = nodes.copy()
# Generate nodes until there are no more "remaining_nodes"
while len(remaning_nodes) > 0:
# Pick one node at random as seed and generate communities
curr_community = compute_community(random.sample(remaning_nodes, 1)[0], adjacency_dict)
# Then update the objects storing the status of the nodes and communities
communities.append(curr_community)
remaning_nodes.difference_update(curr_community)
return communities
def compute_community(root_node, adjacency_dict):
community = set()
#community = {root_node}
# Find all nodes that share edges with the current node
connected_nodes = adjacency_dict[root_node]
# Recursively explore all connected nodes
while len(connected_nodes) > 0:
# Update the list of used nodes to include the ones from the new iteration
community.update(connected_nodes)
# For all current nodes, get their children
iteration_nodes = set()
for node in connected_nodes:
# Get the next set of nodes to explore
connected_nodes_next = adjacency_dict[node]
iteration_nodes.update(connected_nodes_next)
# Find the next set of yet unseen connected nodes
connected_nodes = iteration_nodes - community
# Handle unconnected nodes
if len(community) == 0:
community = {root_node}
return community
# Track the modularity
Q = float('-inf')
# Iteratively remove edges and track the changes in modularity
while remaning_edges > 0:
# Apply the Girvan Newman algorithm and find communities in the ever-shrinking adjacency dict
new_graph = sc.parallelize(nodes).map(lambda n: GN(n))
# Recompute betweenness to be used in this iteration
B_score = new_graph.flatMap(lambda child_parent_betweennees: [*child_parent_betweennees]).reduceByKey(add).map(lambda row: (row[0], row[1]/2)).sortBy(lambda row: (-row[1], row[0])).collect()
# Take highest "yet unremoved" betweenness
curr_betweenness = B_score[0][1]
# Then remove all pairs whose betweenness matches "curr_betweenness"
for (left_node, right_node), betweenness in B_score:
if betweenness >= curr_betweenness:
adjacency_dict[left_node].remove(right_node)
adjacency_dict[right_node].remove(left_node)
remaning_edges -= 1
# Recompute communities taking into consideration the removed links
iter_communities = compute_communities(adjacency_dict, nodes)
# Recompute the modularity score Q
iter_Q = sum([AM[(left_node, right_node)] - DM[left_node] * DM[right_node] / (2 * m) for comm in iter_communities for left_node in comm for right_node in comm]) / (2 * m)
# If the modularity score improved, store the current Q and communities as the best thus far
if iter_Q > Q:
communities = iter_communities
Q = iter_Q
print(f'Remaining Edges: {int(remaning_edges)}')
print(f'Best Modularity: {Q}')
print()
# Once all edged have been explores, take the sort the best communities found (necessary for proper outputting)
output_communities = sc.parallelize(communities).map(lambda community: sorted(community)).sortBy(lambda community: (len(community), community)).collect()
# Save the communities to a txt
with open(community_output_file_path, "w") as f_out:
for community in output_communities:
f_out.write(str(community).replace("[", "").replace("]", "") + "\n")
# View results
output_communities
[['23y0Nv9FFWn_3UWudpnFMA', 'eqWEgMH-DCP74i82BEAZzw'], ['3Vd_ATdvvuVVgn_YCpz8fw', 'jSbXY_rno4hYHQCFftsWXg'], ['453V8MlGr8y61PpsDAFjKQ', 'gH0dJQhyKUOVCKQA6sqAnw'], ['46HhzhpBfTdTSB5ceTx_Og', 'YVQFzWm0H72mLUh-8gzd5w'], ['F47atsRPw-KHmRVk5exBFw', 'JeOHA8tW7gr-FDYOcPJoeA'], ['Si3aMsOVGSVlsc54iuiPwA', 'd5WLqmTMvmL7-RmUDVKqqQ'], ['_m1ot2zZetDgjerAD2Sidg', 'vENR70IrUsDNTDebbuxyQA'], ['gUu0uaiU7UEUVIgCdnqPVQ', 'jJDUCuPwVqwjbth3s92whA'], ['98rLDXbloLXekGjieuQSlA', 'MJ0Wphhko2-LbJ0uZ5XyQA', 'QYKexxaOJQlseGWmc6soRg'], ['9W73B44Iw8WslrTNB2CdCg', 'UmTMCfPlhA6kJLAsLycSfg', 'Uo5dPwoDpYBzOnmUnjxJ6A'], ['CLbpPUqP6XpeAfoqScGaJQ', 'drTMOo4p8nL0pnMNEyat2A', 'tX0r-C9BaHYEolRUfufTsQ', 'xhlcoVm3FOKcxZ0phkdO6Q'], ['Gr-MqCunME2K_KmsAwjpTA', 'QRsuZ_LqrRU65dTs5CL4Lw', '_6Zg4ukwS0kst9UtkfVw3w', 'lJFBgSAccsMGwIjfD7LMeQ'], ['Cf0chERnfd06ltnN45xLNQ', 'CyrRjt_7iJ8_lSHeH1_TlA', 'JhFK9D3LYl23Se3x4oPUxA', 'ZW-XoteNlRuuK-19q1spmw', 'lL-wNa0TKK6LXrlcVmjYrQ'], ['EY8h9IJimXDNbPXVFpYF3A', 'LiNx18WUre9WFCEQlUhtKA', 'hilL60vuuh06sMxs6Ckkog', 'jgoG_hHqnhZvQEoBK0-82w', 'kwIhn1_cnQeUaLN0CuWWHw', 'qd16czwFUVHICKF7A4qWsQ'], ['2GUjO7NU88cPXpoffYCU8w', '6YmRpoIuiq8I19Q8dHKTHw', '6xi9tBoZ6r_v41u_XFsSnA', 'BDmxm7aeWFOLT35gSvkmig', 'H4EQn0rjFuGRgIm6c9NFLg', 'H5Asta4LpiKmRhSjWaogIg', 'XrRLaAeV20MRwdSIGjj2SQ', 'a48HhwcmjFLApZhiax41IA', 'angEr2YcXmCl20s8WQu32w', 'e5sdXDOkCf0sIUAivXVluA', 'frQs7y5qa-X1pvAM0sJe1w'], ['1st2ltGKJ00ZcRsev-Ieew', '4ZQq0ozRs-gXSz1z55iIDw', 'HLY9oDcVBH9D25lU4X_V5Q', 'Hv_q_ZnSIoZwdcoH0CyV2Q', 'Ih85YhFRDzOnB09yS__94g', 'KBoIRjxSW7OWczv8OS9Bew', 'LaiylSIbrA3aPvOYtl-J4A', 'Z9a1tDT8fVI75qXYwNhPpw', 'ZEq0WtRJD9Bl_vYgCsbfOg', 'e0Jn0ZjqL-dWi7Brs0bbmg', 'fOut10lknIp64tm3z6UTNg', 'l-1cva9rA8_ugLrtSdKAqA', 'oegRUjhGbP62M18WyAL6pQ', 'wXdrUQg4-VkSZH1FG4Byzw'], ['0gZ8E5tBWTEtGEZDuTzhzw', '4ONcRRisDZkbV1cviA7nFw', '9SWtEX1k9AjRg93BAzMCpg', 'A-U-K9z9oraMH7eBZW1dOA', 'B7IvZ26ZUdL2jGbYsFVGxQ', 'BE4fE4R3TaVn8xy4sYYjbg', 'DgfsJqg_gozVgaeZ5vjllA', 'EI9ijI9Wh66LrVW-GmWkOg', 'FyQrUamokaPLDrBxGmzPnA', 'Gua5GdTlTWJpovtG7Hdtyg', 'LKP0Yq9T7Ss6oiDZnVtQwQ', 'LgFDWZTLi1w9OGi5BtKORg', 'Nf_Jw_W_CwOz5WJ7ApSMxg', 'ORJnGXXkS9tQBTNyPQJF9A', 'QUYbGl1DL-9faG150MQ7zA', 'QvLg2kxqHHahxxOlHlEIZw', 'S1cjSFKcS5NVc3o1MkfpwA', 'SVC0CajvmYfH5uAq4JnGvg', 'SX_SMrddkDU5dySbsZMu9A', 'WXlxViTwXHPBvhioljN9PQ', 'YA-caxALI4C-eCiSM97new', 'ZXyGw3Z1DyhK1sfNtpcyYA', 'ZZvfGGLnAkSBSUduV7KN-w', 'ae7zi8F0B6l_JCITh1mXDg', 'cyuDrrG5eEK-TZI867MUPA', 'h-ajC_UHD0QAyAzySN6g2A', 'jnn504CkjtfbYIwBquWmBw', 'k24kSTpZHUdEd-QYXLy3fQ', 'k58KNO8Rya-q8njKq8-uBQ', 'mm9WYrFhiNqvHCyhQKw3Mg', 'o-t-i7nbT5N_cmkCXs5oDQ', 'pDNeS1nbkKS7mJmhRQJPig', 'tcWnoX_IfuDmlDl6o6y3_g'], ['0KhRPd66BZGHCtsb9mGh_g', '2k8OVAPxlXHsA5X6EIoQpQ', '2xVrxhQJUBmOyG4ML77XKw', '37HswRimgBEf7_US-c3CDA', '5DgFmyjW6hkBtXtTMKl4tA', '5fQ9P6kbQM_E0dx8DL6JWA', '750rhwO7D_Cul7_GtO9Jsg', '7G8w2SnaC-qDVQ7_GqTxMg', '8oYMqhC5fhqAK_yxRjE7dQ', '903YwVSoAKyzudc8LH_HMA', '9S52XHEyrvOv4OZxU6pCLw', 'DPtOaWemjBPvFiZJBi0m8A', 'DjcRgZ0cJbf6-W2TxvFlBA', 'IuaAfrkirlfzY3f4PkgSmw', 'JM0GL6Dx4EuZ1mprLk5Gyg', 'JRqMFKGxx6DnTGZrxwQZaA', 'JqjAthJThuVYgTh4iWDZ2A', 'MrsRJa4SWLq8XLU1RtPdlw', 'MtdSCXtmrSxj_uZOJ5ZycQ', 'MwpK7PqQX7fgTFM2Pfy61w', 'NUtVG7jNPLJR2cxMXMH2-A', 'NlNlyQynkyEU3l7TR3LXdg', 'PKEzKWv_FktMm2mGPjwd0Q', 'SsOiVav4V5_NjTl21Lj92w', 'TZ974xcbw2kqjYxAhDUYVg', 'UYcmGbelzRa0Q6JqzLoguw', 'UwV6jBuTR1S9acT6bPTBPw', 'VdoTNYWuoXo01umgannw8A', 'WaAOt_eG0_-yLpG3fI--3g', 'XEqQG61fetXhuEV9RPslIA', 'Y0-lLNc2Y7gUGXPzSsMueQ', 'ZA1OT-PIZwz2kdHDA6mShw', 'Zk95TMXDx0zMUhYq5u8pxw', 'ajxohdcsKhRGFlEvHZDyTw', 'cIbbfJEGLB3B-c8Po4AL5g', 'dzJDCQ5vubQBJTfYTEmcbg', 'e5kg9bLvlJz-MEUrGjIeVQ', 'fLnkI1uHtXEsjtF6KoBHbQ', 'fcWM-oqjgS94yi1INhZa0g', 'hLVq7VSJBHZwqurwWoCmpg', 'jcriwcTidug0fK8sgAloHA', 'm1IVpXClMox1VGw5hO2LhQ', 'mu4XvWvJOb3XpG1C_CHCWA', 'nOTl4aPC4tKHK35T3bNauQ', 'tekHDsd0fskYG3tqu4sHQw', 'xrvyW1ruKS0uz9RtFewC0Q'], ['0FMte0z-repSVWSJ_BaQTg', '0FVcoJko1kfZCrJRfssfIA', '0QREkWHGO8-Z_70qx1BIWw', '1KQi8Ymatd4ySAd4fhSfaw', '23o7tyUGlC6FCDVcyqLeFA', '2XYdguaaZ7dgi6fAlddujg', '2quguRdKBzul3GpRi9e1mA', '39FT2Ui8KUXwmUt6hnwy-g', '4PQhC-zTQ4ACEN0-r39JuQ', '4pc_EyanaC3ARh0MZZyouA', '79yaBDbLASfIdB-C2c8DzA', '7RCz4Ln_FaTvNrdwe251Dg', '7Vfy39A_totC-w70qZi0MA', '97j2wkFU46OOgm6ErRAb7w', '9xM8upr_n9jchUDKxqSGHw', 'Ams0iLRd0AhZZectGKA8fw', 'B0ENvYKQdNNr1Izd2r-BAA', 'BDjiEmXljD2ZHT61Iv9rrQ', 'CebjpVd3PsofCgotWp60pg', 'ChshgCKJTdIDg17JKtFuJw', 'DKolrsBSwMTpTJL22dqJRQ', 'DkLSyxogCcJXY5DbTZ-f2A', 'ELfzWgdf64VBLi5z1ECItw', 'EiwxlbR8fb68lMgEXhcWKA', 'IXD-jdycm7m34b_Nliy82g', 'JLv2Dmfj73-I0d9N41tz1A', 'JteQGisqOf_pklq7GA0Rww', 'KHjroLTG6Ah8LyItTyB2yw', 'KLB3wIYUwKDPMbijIE92vg', 'KgJdBWS3ReP6TVhYWJRKmg', 'KtE55izPs1ubJn3ofF2IrA', 'LcCRMIDz1JgshpPGYfLDcA', 'O9pMFJSPg80YVzpMfNikxw', 'OoyQYSeYNyRVOmdO3tsxYA', 'PE8s8ACYABRNANI-T_WmzA', 'R4l3ONHzGBakKKNo4TN9iQ', 'S9dDf0JqSMAvusp5f-9bGw', 'SdXxLZQQnQNUEL1rGMOQ6w', 'T88y73qdOSutuvzLlhWtqQ', 'TjsBbWAfwxWEXPxaLNv5SQ', 'Tk_FWXueutKii3f9yJFsdw', 'UAB1Zyg6Q0oEpXeYRf5K_g', 'WoKCLSctS7G2547xKcED-Q', 'XPAJ2KHkCwBA0vafF-2Zcg', 'XUEwSGOGARxW-3gPiGJKUg', '_Pn-EmWO-pFPFg81ZIEiDw', '_VTEyUzzH92X3w-IpGaXVA', 'ay4M5J28kBUf0odOQct0BA', 'bE7Yd0jI_P6g27MWEKKalA', 'bHufZ2OTlC-OUxBDRXxViw', 'bJguBxPlnTW29tRTAF0nkQ', 'bSUS0YcvS7UelmHvCzNWBA', 'bbK1mL-AyYCHZncDQ_4RgA', 'cm3_8c_NDhPcpwJQ96Aixw', 'dTeSvET2SR5LDF_J07wJAQ', 'dW6bAWM1HbPdk_cGS_a2HA', 'e8uzNcSC5tQMD22GNAQEQA', 'hd343st7cOIUSfAd5r0U7A', 'hqmnMdDS-Opjp3BfBJA8qA', 'j8Dts8irvVBwEhEEae_-wA', 'jPcrABeWgWlTPi-E0Op_aA', 'kKTcYPz47sCDH1_ylnE4ZQ', 'ma6206bmu-a_Ja7Iv-yRCw', 'mnoe2vwouRADn97dTDkw4A', 'p9942XebvxZ9ubHm4SXmMQ', 'qtOCfMTrozmUSHWIcohc6Q', 'sBqCpEUn0qYdpSF4DbWlAQ', 'sO6iNKgv_ToVfof-aQWgXg', 'sdLns7062kz3Ur_b8wgeYw', 'tAcY4S3vIuNlAoRlCcz5VA', 'tL2pS5UOmN6aAOi3Z-qFGg', 'tRZAC_H5RHrjvyvtufcNXQ', 'voXU5A3FfOcXZ2VNsJ0q4w', 'waN6iwcphiVEoCews4f4CA', 'y6jsaAXFstAJkf53R4_y4Q', 'yCaDISH0R8e5U376zDWTpQ', 'zBi_JWB5uUdVuz3JLoAxGQ']]
# Close spark context
sc.stop()
# Measure the total time taken and report it
time_elapsed = time.time() - start_time
print(f'Duration: {time_elapsed:.0f} seconds')
Duration: 3206 seconds
Matheus Schmitz
LinkedIn
Github Portfolio