In [19]:
import random
class Matcher(object):
def __init__(self, users, user_history):
self.users = users
self.user_history = user_history
def random_matcher(self):
"""Randomly assign pairs of users.
Returns a tuple:
- a list of lists, representing user-pairings
- a list of unpaired users."""
user_options = set(self.users)
matches = []
while len(user_options) >= 2:
new_pair = random.sample(user_options, 2)
matches.append(new_pair)
user_options = user_options - set(new_pair)
# print(matches)
# print('Remainder: {}'.format(list(user_options)))
return matches, list(user_options)
def find_repeat_pairs(self, matches):
"""Finds pairs that have been previously matched.
Returns a list of lists (representing user-pairings) that have already been matched"""
rematched = []
for match in matches:
if match[0] in self.user_history[match[1]]:
rematched.append(match)
return rematched
def matching_algorithm(self, num_iters=100):
# Initialize score
current_score = len(self.users)
score = current_score
# Initialize matches
matches = []
unmatched = []
i = 0
for i in range(num_iters):
# print('\nIteration: {}'.format(i))
current_matches, current_unmatched = self.random_matcher()
current_score = len(current_unmatched) + 2 * len(self.find_repeat_pairs(current_matches))
# print('Current score: {}'.format(current_score))
# print('Current matched: {}'.format(current_matches))
# print('Current unmatched: {}'.format(current_unmatched))
if current_score < score:
# print('Beat previous iteration! Updating score...')
matches = current_matches
unmatched = current_unmatched
score = current_score
if score <= 1:
break
# Update history
for match in matches:
self.user_history[match[0]].add(match[1])
self.user_history[match[1]].add(match[0])
print('# of iterations: {}'.format(i+1))
return matches, unmatched, score
In [14]:
num_users = 30
users = list(range(num_users))
user_history = {
u: set([]) for u in users
}
matcher = Matcher(users, user_history)
In [15]:
matches, unmatched, score = matcher.matching_algorithm()
print('\n\nRESULTS')
print('Score: {}'.format(score))
print('Matches: {}'.format(matches))
print('Unmatched users: {}'.format(unmatched))
In [26]:
num_users = 30
users = list(range(num_users))
user_history = {
u: set([]) for u in users
}
matcher2 = Matcher(users, user_history)
num_days = 29
for i in range(num_days):
print('\nDay: {}'.format(i))
matches, unmatched, score = matcher2.matching_algorithm(num_iters=1000000)
# print('\n\nRESULTS')
print('Score: {}'.format(score))
# print('Matches: {}'.format(matches))
# print('Unmatched users: {}'.format(unmatched))
In [ ]: