def test_ell_p_norm_calculating(self): self.assertEqual( ell_p_norm([1], 1), Decimal(1) ) self.assertAlmostEquals( ell_p_norm([1], 2), Decimal(1) ) self.assertAlmostEquals( ell_p_norm([1, 2, 3], 2), Decimal(sqrt(1 + 4 + 9)) ) self.assertAlmostEquals( ell_p_norm([1, 2, 3], 10000), Decimal(3) )
def calculate_committee_score_from_prefetched(self, committee): temp_score = 0 for voter in self.voters: voter_preferences = [] for candidate in committee: voter_preferences.append( self.preferences[voter.pk][candidate.pk] ) voter_preferences = [self.candidates_number - x for x in voter_preferences] temp_score += voter.repeats * ell_p_norm(voter_preferences, self.p_parameter) if temp_score > self.biggest: self.biggest = temp_score return temp_score
def calculate_committee_score_from_prefetched(self, committee): temp_score = 0 for voter in self.voters: voter_preferences = [] for candidate in committee: voter_preferences.append( self.preferences[voter.pk][candidate.pk]) voter_preferences = [ self.candidates_number - x for x in voter_preferences ] temp_score += voter.repeats * ell_p_norm(voter_preferences, self.p_parameter) if temp_score > self.biggest: self.biggest = temp_score return temp_score
def calculate_committee_score(self, committee, p, candidates_number): """ Calculate committee score multiplied by vote repeats :param candidates_number: number of candidates in election :type candidates_number: int :type committee: list of ecs.elections.models.Candidate :type p: int :rtype: Decimal :return: committee score """ # create pos_v sequence, but order actually # does not matter in our election system: voter_preferences = self.preferences.filter(candidate__in=committee).values_list('preference', flat=True) voter_preferences = [candidates_number - x for x in voter_preferences] return self.repeats * ell_p_norm(voter_preferences, p)
def update_voters_satisfaction(self, leading_candidate, voters, current_voters_satisfaction, candidates_number, p): """ :param leading_candidate: Candidate :param voters: QuerySet :param current_voters_satisfaction: dict{Voter: int} :param candidates_number: int :param p: int :return: """ for v in voters: x = candidates_number - self.preferences[v.pk][ leading_candidate.pk] values = [current_voters_satisfaction[v.pk], x] current_voters_satisfaction[v.pk] = ell_p_norm(values, p)
def calculate_committee_score(self, committee, p, candidates_number): """ Calculate committee score multiplied by vote repeats :param candidates_number: number of candidates in election :type candidates_number: int :type committee: list of ecs.elections.models.Candidate :type p: int :rtype: Decimal :return: committee score """ # create pos_v sequence, but order actually # does not matter in our election system: voter_preferences = self.preferences.filter( candidate__in=committee).values_list('preference', flat=True) voter_preferences = [candidates_number - x for x in voter_preferences] return self.repeats * ell_p_norm(voter_preferences, p)
def run(self): self.fetch_preferences() voters = list(self.election.voters.all()) candidates_still_fighting = list(self.election.candidates.all()) winning_committee = [] current_voters_satisfaction = {} for v in voters: current_voters_satisfaction[v.pk] = 0 for i in range(self.election.committee_size): if settings.PRINT_PROGRESS: print i + 1, "out of", self.election.committee_size, "to be chosen" satisfaction_with_leading_candidate = 0 leading_candidate = None for c in candidates_still_fighting: satisfaction_with_given_candidate = 0 for v in voters: x = self.candidates_number - self.preferences[v.pk][c.pk] satisfaction_of_given_voter = current_voters_satisfaction[ v.pk] values = [satisfaction_of_given_voter, x] satisfaction_of_given_voter_with_given_candidate = ell_p_norm( values, self.p_parameter) satisfaction_with_given_candidate += v.repeats * satisfaction_of_given_voter_with_given_candidate if satisfaction_with_given_candidate > satisfaction_with_leading_candidate: leading_candidate = c satisfaction_with_leading_candidate = satisfaction_with_given_candidate self.update_voters_satisfaction(leading_candidate, voters, current_voters_satisfaction, self.candidates_number, self.p_parameter) winning_committee.append(leading_candidate) candidates_still_fighting.remove(leading_candidate) return tuple(winning_committee)
def test_ell_p_norm_calculating(self): self.assertEqual(ell_p_norm([1], 1), Decimal(1)) self.assertAlmostEquals(ell_p_norm([1], 2), Decimal(1)) self.assertAlmostEquals(ell_p_norm([1, 2, 3], 2), Decimal(sqrt(1 + 4 + 9))) self.assertAlmostEquals(ell_p_norm([1, 2, 3], 10000), Decimal(3))