Example #1
0
    def tau_strategic(self, strategy):
        """Tau-vector associated to a strategy (fully strategic voting).

        Parameters
        ----------
        strategy : StrategyThreshold
            A strategy that specifies at least all the rankings that are present in the profile. If some voters
            have a utility for their second candidate that is equal to the utility threshold of the strategy, then the
            ratio of optimistic voters must be specified.

        Returns
        -------
        TauVector
            Tau-vector associated to this profile and strategy `strategy`.
        """
        assert self.voting_rule == strategy.voting_rule
        t = self.d_ballot_share_weak_voters_strategic(strategy)
        for ranking, threshold in strategy.d_ranking_threshold.items():
            if self.d_ranking_share[ranking] == 0:
                continue
            t[ballot_low_u(ranking, self.voting_rule)] += self.have_ranking_with_utility_below_u(ranking, u=threshold)
            t[ballot_high_u(ranking, self.voting_rule)] += self.have_ranking_with_utility_above_u(ranking, u=threshold)
            share_limit_voters = self.have_ranking_with_utility_u(ranking, u=threshold)
            if share_limit_voters != 0:
                ratio_optimistic = strategy.d_ranking_ratio_optimistic[ranking]
                t[ballot_low_u(ranking, self.voting_rule)] += self.ce.multiply_with_absorbing_zero(
                    share_limit_voters, ratio_optimistic)
                t[ballot_high_u(ranking, self.voting_rule)] += self.ce.multiply_with_absorbing_zero(
                    share_limit_voters, 1 - ratio_optimistic)
        return TauVector(t, voting_rule=self.voting_rule, symbolic=self.symbolic)
 def possible_ballots(ranking):
     try:
         return [self.d_ranking_fixed_strategy[ranking]]
     except KeyError:
         pass
     if self.profile is not None and self.profile.d_ranking_share[
             ranking] == 0:
         return ['']
     return [
         ballot_low_u(ranking, self.voting_rule),
         ballot_high_u(ranking, self.voting_rule)
     ]
 def ballot(self):
     """str : This can be a valid ballot or ``'utility-dependent'``.
     """
     if isnan(self.utility_threshold):
         raise AssertionError('Unable to compute utility threshold'
                              )  # pragma: no cover - Should never happen
     elif self.ce.look_equal(self.utility_threshold, 1):
         return ballot_low_u(self.ranking, self.voting_rule)
     elif self.ce.look_equal(self.utility_threshold, 0, abs_tol=1E-9):
         return ballot_high_u(self.ranking, self.voting_rule)
     else:
         assert 0 <= self.utility_threshold <= 1
         return UTILITY_DEPENDENT
Example #4
0
 def possible_ballots(ranking):
     try:
         return [self.d_ranking_fixed_strategy[ranking]]
     except KeyError:
         pass
     if self.profile is not None:
         share_ranking_1 = self.profile.d_type_share[ranking[0] + '_' +
                                                     ranking[1:]]
         share_ranking_12 = self.profile.d_type_share[ranking[0:2] +
                                                      '_' + ranking[2]]
         strategy_1 = ballot_low_u(ranking, self.voting_rule)
         strategy_12 = ballot_high_u(ranking, self.voting_rule)
         if share_ranking_1 > 0 and share_ranking_12 > 0:
             return [strategy_1, strategy_12, UTILITY_DEPENDENT]
         elif share_ranking_1 > 0 or share_ranking_12 > 0:
             return [strategy_1, strategy_12]
         else:
             return ['']
     else:
         return [
             ballot_low_u(ranking, self.voting_rule),
             ballot_high_u(ranking, self.voting_rule), UTILITY_DEPENDENT
         ]
Example #5
0
    def tau_strategic(self, strategy):
        """Tau-vector associated to a strategy.

        Parameters
        ----------
        strategy : StrategyTwelve
            A strategy that specifies at least all the rankings that are present in the profile.

        Returns
        -------
        TauVector
            Tau-vector associated to this profile and strategy `strategy`.

        Examples
        --------
            >>> from fractions import Fraction
            >>> profile = ProfileTwelve({'ab_c': Fraction(1, 10), 'b_ac': Fraction(6, 10),
            ...                          'c_ab': Fraction(2, 10), 'ca_b': Fraction(1, 10)})
            >>> strategy = StrategyTwelve({'abc': 'ab', 'bac': 'b', 'cab': 'utility-dependent'})
            >>> tau_strategic = profile.tau_strategic(strategy)
            >>> print(tau_strategic)
            <ab: 1/10, ac: 1/10, b: 3/5, c: 1/5> ==> b
        """
        assert self.voting_rule == strategy.voting_rule
        t = self.d_ballot_share_weak_voters_strategic(strategy)
        for ranking, ballot in strategy.d_ranking_ballot.items():
            if self.d_ranking_share[ranking] == 0:
                continue
            # For a ranking abc, ballot can be real ballots (e.g. 'a', 'ab'), '' or 'utility-dependent'.
            if ballot == UTILITY_DEPENDENT:
                t[ballot_low_u(ranking, self.voting_rule
                               )] += self.have_ranking_with_utility_below_u(
                                   ranking, u=.5)
                t[ballot_high_u(ranking, self.voting_rule
                                )] += self.have_ranking_with_utility_above_u(
                                    ranking, u=.5)
            else:
                t[ballot] += self.d_ranking_share[ranking]
        return TauVector(t,
                         voting_rule=self.voting_rule,
                         symbolic=self.symbolic)
Example #6
0
    def random_tau_undominated(self):
        """Random tau based on undominated ballots.

        This is used, for example, in :meth:`~poisson_approval.ProfileCardinal.iterated_voting`.

        Returns
        -------
        TauVector
            A random tau-vector. Independently for each ranking, a proportion uniformly drawn in [0, 1] of voters
            use one undominated ballot, and the rest use the other undominated ballot. For example, in Approval voting,
            voters with ranking `abc` are randomly split between ballots `a` and `ab`.
        """
        d = {ballot: 0 for ballot in BALLOTS_WITHOUT_INVERSIONS}
        for ranking, share in self.d_ranking_share.items():
            r = random.random()
            d[ballot_low_u(ranking, self.voting_rule)] += r * share
            d[ballot_high_u(ranking, self.voting_rule)] += (1 - r) * share
        for weak_order, share in self.d_weak_order_share.items():
            if is_lover(weak_order):
                if self.voting_rule in {APPROVAL, PLURALITY}:
                    d[weak_order[0]] += share
                elif self.voting_rule == ANTI_PLURALITY:
                    r = random.random()
                    d[sort_ballot(weak_order[0] + weak_order[2])] += r * share
                    d[sort_ballot(weak_order[0] + weak_order[4])] += (1 - r) * share
                else:
                    raise NotImplementedError
            else:  # is_hater(weak_order)
                if self.voting_rule == PLURALITY:
                    r = random.random()
                    d[weak_order[0]] += r * share
                    d[weak_order[2]] += (1 - r) * share
                elif self.voting_rule in {APPROVAL, ANTI_PLURALITY}:
                    d[sort_ballot(weak_order[0] + weak_order[2])] += share
                else:
                    raise NotImplementedError
        return TauVector(d, voting_rule=self.voting_rule, symbolic=self.symbolic)