Last active
November 12, 2016 00:25
-
-
Save duhaime/b6638b40e897ea78fc51878b319cff93 to your computer and use it in GitHub Desktop.
Recursively find friends of friends
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import itertools | |
| from collections import defaultdict | |
| d = { | |
| 1: ["a", "b"], | |
| 2: ["b", "c"], | |
| 3: ["c", "d"] | |
| } | |
| def find_friend_of_friends(d): | |
| """Read in a dictionary with cluster keys and cluster | |
| member values, and return a dictionary in which | |
| all friends of friends have been clustered in the | |
| dictionary values""" | |
| # first create the inverse of the input d, such that | |
| # the values of d are keys in the new dictionary and | |
| # the values of the new dictionary are the clusters to which | |
| # the points belong | |
| # store the clusters to which a point belongs in a list | |
| value_to_clusters = defaultdict(list) | |
| for cluster in d.iterkeys(): | |
| for value in d[cluster]: | |
| value_to_clusters[value].append(cluster) | |
| # now for each point, find that point's friends, where | |
| # a friend is defined by the fact that two points belong | |
| # to the same cluster | |
| friends = defaultdict(list) | |
| for value in value_to_clusters.iterkeys(): | |
| linked_friends = [] | |
| for cluster in value_to_clusters[value]: | |
| for friend in d[cluster]: | |
| linked_friends.append(friend) | |
| for linked_friend in linked_friends: | |
| friends[cluster].append(linked_friend) | |
| # remove duplicate entries from each value in the friends dict | |
| for cluster in friends.iterkeys(): | |
| friends[cluster] = list(set(friends[cluster])) | |
| # remove any clusters whose values are subsets of other clusters | |
| clusters = friends.keys() | |
| for cluster_pair in itertools.combinations(clusters, 2): | |
| cluster_a_values = set(friends[cluster_pair[0]]) | |
| cluster_b_values = set(friends[cluster_pair[1]]) | |
| if cluster_a_values.issubset(cluster_b_values): | |
| friends.pop(cluster_pair[0], 0) | |
| elif cluster_b_values.issubset(cluster_a_values): | |
| friends.pop(cluster_pair[1], 0) | |
| # if the resulting dictionary is identical to the input | |
| # then we're done, else recurse | |
| if friends == d: | |
| print friends | |
| return friends | |
| else: | |
| return find_friend_of_friends(friends) | |
| if __name__ == "__main__": | |
| find_friend_of_friends(d) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment