def getEssentialEmployees(self): # Use the "Hopcroft-Karp bipartite matching algorithm" to get the max cardinality maxMatching, pred, unlayered = bipartite_match.bipartiteMatch(self.__employeesGraph) # With the max cardinality, we can calculate the min vertex cover using the Konig # theorem in polynomial time return self.__minVertexCover(set(maxMatching.items()))
def resolve(self): bipartiteByCat = {} catLovers = [] dogLover = {} dogHater = {} count = 0 for vote in votes: vote = "%s %d" % (vote, count) count += 1 if vote[0] == 'D': voteParts = vote.split() if voteParts[0] in dogLover: dogLover[voteParts[0]].add(vote) else: dogLover[voteParts[0]] = set([vote]) if voteParts[1] in dogHater: dogHater[voteParts[1]].add(vote) else: dogHater[voteParts[1]] = set([vote]) else: catLovers.append(vote) for catVote in catLovers: catVoteParts = catVote.split() bipartiteByCat[catVote] = dogLover.get( catVoteParts[1], set()) | dogHater.get(catVoteParts[0], set()) maxMatching, pred, unlayered = bipartiteMatch(bipartiteByCat) return len(votes) - len(maxMatching)
def resolve(self): # This graph will contain all the conflictive relations between voters bipartite_by_cat = {} cat_lovers = [] # Dog lovers groupped by the dog who they loves by_dog_love = {} # Dog lovers groupped by the cat who they hate by_dog_hate = {} # This counter will be used to avoid problems with duplicate votes on the # sets and the key of the dict who conforms the graph count = 0 for vote in self.__votes_list: vote = "%s %d" % (vote, count) count += 1 if vote[0] == 'D': vote_parts = vote.split() if vote_parts[0] in by_dog_love: by_dog_love[vote_parts[0]].add(vote) else: by_dog_love[vote_parts[0]] = set([vote]) if vote_parts[1] in by_dog_hate: by_dog_hate[vote_parts[1]].add(vote) else: by_dog_hate[vote_parts[1]] = set([vote]) else: cat_lovers.append(vote) # Create the bipartite graph using a dictionary, the key will be the vote of the cat lover, and the # values a set with all the votes who have problems with the vote of the cat lover at the key for cat_vote in cat_lovers: cat_vote_parts = cat_vote.split() bipartite_by_cat[cat_vote] = by_dog_love.get( cat_vote_parts[1], set()) | by_dog_hate.get( cat_vote_parts[0], set()) # Use the Hopcroft-Karp algorith in order to determinate the max cardinality, then we will know the # min number of conflictive votters that we have max_matching, pred, unlayered = bipartiteMatch(bipartite_by_cat) if self.__debug: print "Votes: %s" % (bipartite_by_cat) print "Max matching %s" % (max_matching) print "Dog love: %s" % (by_dog_love) print "Dog hate: %s" % (by_dog_hate) # The max number of happy voters are the number of total voters minus the number of conflictive pairs (we can remove # one of the members of each pair) return len(self.__votes_list) - len(max_matching)
def resolve(self): # This graph will contain all the conflictive relations between voters bipartite_by_cat = {} cat_lovers = [] # Dog lovers groupped by the dog who they loves by_dog_love = {} # Dog lovers groupped by the cat who they hate by_dog_hate = {} # This counter will be used to avoid problems with duplicate votes on the # sets and the key of the dict who conforms the graph count = 0 for vote in self.__votes_list: vote = "%s %d" % (vote, count) count += 1 if vote[0] == 'D': vote_parts = vote.split() if vote_parts[0] in by_dog_love: by_dog_love[vote_parts[0]].add(vote) else: by_dog_love[vote_parts[0]] = set([vote]) if vote_parts[1] in by_dog_hate: by_dog_hate[vote_parts[1]].add(vote) else: by_dog_hate[vote_parts[1]] = set([vote]) else: cat_lovers.append(vote) # Create the bipartite graph using a dictionary, the key will be the vote of the cat lover, and the # values a set with all the votes who have problems with the vote of the cat lover at the key for cat_vote in cat_lovers: cat_vote_parts = cat_vote.split() bipartite_by_cat[cat_vote] = by_dog_love.get(cat_vote_parts[1], set()) | by_dog_hate.get(cat_vote_parts[0], set()) # Use the Hopcroft-Karp algorith in order to determinate the max cardinality, then we will know the # min number of conflictive votters that we have max_matching, pred, unlayered = bipartiteMatch(bipartite_by_cat) if self.__debug: print "Votes: %s" % (bipartite_by_cat) print "Max matching %s" % (max_matching) print "Dog love: %s" % (by_dog_love) print "Dog hate: %s" % (by_dog_hate) # The max number of happy voters are the number of total voters minus the number of conflictive pairs (we can remove # one of the members of each pair) return len(self.__votes_list) - len(max_matching)
dogLoversDownvote[v2].add(vote) else: dogLoversDownvote[v2] = set([vote]) # Else cat lover... else: catLovers.append(vote) k += 1 # Populate the bipartite graph with problematic edges, eg conflicting votes # (DogLovers downvotes vs CatLover upvote UNION DogLovers upvotes vs CatLover downvote) for vote in catLovers: upvote, downvote, _ = vote.split() bipartite[vote] = dogLoversUpvote.get(downvote, set()).union( dogLoversDownvote.get(upvote, set())) # Let's use Hopcroft-Karp algorithm to compute the maximum cardinality of the bipartite graph # we created : minimum number of conflicting voters maxMatching = bipartiteMatch(bipartite)[0] if debug: print("Votes: {}".format(bipartite)) print("Max matching {}".format(maxMatching)) print("Dog love: {}".format(dogLoversUpvote)) print("Dog hate: {}".format(dogLoversDownvote)) i += 1 # Final result print(str(v - len(maxMatching)))
if v2 in dogLoversDownvote: dogLoversDownvote[v2].add(vote) else: dogLoversDownvote[v2] = set([vote]) # Else cat lover... else: catLovers.append(vote) k += 1 # Populate the bipartite graph with problematic edges, eg conflicting votes # (DogLovers downvotes vs CatLover upvote UNION DogLovers upvotes vs CatLover downvote) for vote in catLovers: upvote, downvote, _ = vote.split() bipartite[vote] = dogLoversUpvote.get(downvote, set()).union(dogLoversDownvote.get(upvote, set())) # Let's use Hopcroft-Karp algorithm to compute the maximum cardinality of the bipartite graph # we created : minimum number of conflicting voters maxMatching = bipartiteMatch(bipartite)[0] if debug: print ("Votes: {}".format(bipartite)) print ("Max matching {}".format(maxMatching)) print ("Dog love: {}".format(dogLoversUpvote)) print ("Dog hate: {}".format(dogLoversDownvote)) i += 1 # Final result print(str(v - len(maxMatching)))