예제 #1
0
def test_ranked_bury():

    v = spatial.Voters(seed=0)
    v.add(voter_pref)
    c = spatial.Candidates(v)
    c.add(candidate_pref)

    strategy = {
        'tactics': 'bury',
        'subset': '',
        'ratio': 1,
        'underdog': None,
        'frontrunnertype': 'eliminate'
    }

    s2 = spatial.Strategies(v).add(**strategy)
    e2 = spatial.Election(voters=v, candidates=c, strategies=s2)
    e2.run('ranked_pairs')

    right = [[1, 2, 0], [1, 2, 0], [1, 2, 0], [1, 2, 0], [1, 2, 0], [1, 2, 0],
             [1, 2, 0], [0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 0, 1], [0, 0, 1],
             [0, 0, 1], [0, 0, 1], [0, 0, 1]]
    right = votesim.votemethods.tools.rcv_reorder(right)
    ballots = e2.result.ballots
    ballots = votesim.votemethods.tools.rcv_reorder(ballots)
    assert np.all(right == ballots)
    return
예제 #2
0
def test_ranked_deep_bury():
    """Test ranked burial tactic. 
    
    Burial strategies
    --------------------------
    * For #0 voters, their ballots are unchanged as their least favorite is 
      already buried.
    * For #1 voters, they decide to bury #2.
    * For #2 voters, they decide to bury #1. 
    
    Outcomes
    --------
    Burial strategies backfires with #1 and #2 voters, allowing #0 to win. 
    """
    v = spatial.Voters(seed=0)
    v.add(voter_pref)
    c = spatial.Candidates(v)
    c.add(candidate_pref)

    # run honest election
    e1 = spatial.Election(voters=v, candidates=c)
    result1 = e1.run('ranked_pairs')

    # Make sure condorcet winner was found
    assert 1 in e1.result.winners

    #run strategic election
    strategy = {
        'tactics': 'deep_bury',
        'ratio': 1,
        'underdog': None,
        'subset': '',
        'frontrunnertype': 'eliminate'
    }
    s2 = spatial.Strategies(v).add(**strategy)
    e2 = spatial.Election(voters=v, candidates=c, strategies=s2)
    e2.run('ranked_pairs', result=result1)

    # Make sure the correct front runners were
    tballots = e2.ballotgen.tacticalballots
    tgroup = list(tballots.root._tactical_groups.values())[0]
    front_runners = tgroup.front_runners
    assert 1 in front_runners
    assert 2 in front_runners

    # Check that #0 is the winner
    assert 0 in e2.result.winners

    ballots = e2.result.ballots
    ballots = votesim.votemethods.tools.rcv_reorder(ballots)

    # Check the new tactical rankings
    right = [[1, 2, 0], [1, 2, 0], [1, 2, 0], [1, 2, 0], [1, 2, 0], [1, 2, 0],
             [1, 2, 0], [3, 1, 0], [3, 1, 0], [3, 1, 0], [3, 0, 1], [3, 0, 1],
             [3, 0, 1], [3, 0, 1], [3, 0, 1]]
    right = votesim.votemethods.tools.rcv_reorder(right)

    assert np.all(right == ballots)
    return
def test_plurality_chain():
    """Test re-using honest election data to initialize 
    strategic runs."""
    
    pref = [-1]*7 + [-0.5]*2 + [0.5]*3 + [1]*5
    pref = np.array(pref)[:, None]
    v = spatial.Voters(seed=0)
    v.add(pref)
    
    # Generate candidate preferences    
    cpref = [-1, -.5, .5, 1]
    cpref = np.array(cpref)[:, None]
    c = spatial.Candidates(v)
    c.add(cpref)

    # Run honest
    e1 = spatial.Election(voters=v, candidates=c)
    e1.run('plurality',)
    tally1 = e1.result.runner.output['tally']
    result1 = e1.result
    assert np.all(tally1 == np.array([7, 2, 3, 5]))
    
    # Run tactical
    strategy = {'tactics' : 'bullet_preferred',
                 'ratio' : 1,
                 'underdog' : None,
                 'subset' : ''
                 }
    s1 = spatial.Strategies(v).add(**strategy)
    e1.set_models(strategies=s1)
    e1.run('plurality', result=result1)
    tally2 = e1.result.runner.output['tally']
    assert np.all(tally2 == np.array([9, 0, 0, 8]))
    
    # Run one sided
    strategy = {'tactics' : 'bullet_preferred',
                 'ratio' : 1,
                 'underdog' : None,
                 'subset' : 'underdog'}
    s1 = spatial.Strategies(v).add(**strategy)
    e1.set_models(strategies=s1)
    e1.run('plurality', result=result1)
    tally3 = e1.result.runner.output['tally']
    assert np.all(tally3 == np.array([7, 2, 0, 8]))
    
    return locals()
def test_plurality_bullet_preferred():
    """Test plurality bullet voting strategy.
    
    Scenario attributes:
     - 3 candidate race with 3 concentrated, coincident voter groups
     
     >>> Candidates               #0   #1   #2
     >>> Preference locations =  [-1,  0.5,  1]
     >>> Number of voters =      [ 7,    3,  5]
     
     - If voters are honest, plurality candidate #0 should win with 7 votes 
     - If voters are strategic and consider only the top two candidates, 
       Candidate #1 supporters also lean towards #2 - therefore 
       candidate #2 should win with 3 + 5 = 8 votes.
       
    """
    pref = [-1]*7 + [0.5]*3 + [1]*5
    pref = np.array(pref)[:, None]
    v = spatial.Voters(seed=0)
    v.add(pref)
    
    cpref = [-1, .5, 1]
    cpref = np.array(cpref)[:, None]
    c = spatial.Candidates(v)
    c.add(cpref)
    
    #####################################################################
    # Run honest election    
    
    e1 = spatial.Election(voters=v, candidates=c)
    e1.run('plurality')
    tally1 = e1.result.runner.output['tally']
    result1 = e1.result
    #####################################################################
    # Run strategic election
  
    strategy1 = {'tactics' : 'bullet_preferred',
                 'ratio' : 1,
                 'subset' : 'underdog',
                 'underdog' : None,}
    s = spatial.Strategies(v)
    s.add(**strategy1)
    
    
    e1.set_models(strategies=s)
    e1.run('plurality', result=result1)
    tally2 = e1.result.runner.output['tally']
    result2 = e1.result
    # Check honest vote tally
    assert np.all(tally1 == np.array([7, 3, 5]))
    # Check strategic vote tally
    assert np.all(tally2 == np.array([7, 0, 8]))
    # Check honest winner
    assert 0 in result1.winners
    # Check strategic winner
    assert 2 in result2.winners
    return
def test_plurality_ratio():
    """Test adjusted the ratio of tactical to honest voters"""
    
    v = spatial.Voters(seed=0)
    v.add_random(100)
    c = spatial.Candidates(voters=v, seed=1)
    c.add_random(5)
    
    e1 = spatial.Election(voters=v, candidates=c)
    result1 = e1.run('plurality')
    tally1 = e1.result.runner.output['tally']
    print('---------------------------------------')
    for tacti_num in [0, 10, 25, 50, 75, 100]:
        ratio = tacti_num / 100.
        strategy =  {'tactics' : 'bullet_preferred', 
                     'ratio' : ratio,
                     'underdog' : None,
                     'subset' : ''}
        s1 = spatial.Strategies(v).add(**strategy)
        e1.set_models(strategies=s1)
        
        e1.run('plurality', result=result1)
        tally2 = e1.result.runner.output['tally']
        print('vote tally =', tally2)
        bgen = e1.ballotgen
        tactical_ballots = bgen.tacticalballots
        num_tactical_voters = len(tactical_ballots.group_index['tactical-0'])
        
        # check that tactical voters number is correct
        assert num_tactical_voters == tacti_num
        
        # check that total voters in group index is correct. 
        group_index = tactical_ballots.group_index
        count1 = len(group_index['honest-0'])
        count2 = len(group_index['tactical-0'])
        assert count1 + count2 == 100
        count3 = len(group_index['topdog-0'])
        count4 = len(group_index['underdog-0'])
        assert count3 + count4 == count2
    return
예제 #6
0
def test_ranked_deep_bury_onesided():
    """Test one sided burial strategy.
    
    For one-sided, only the under-dog voters vote tactically. 
    
    * Honest Condorcet winner is Candidate #1. 
    * Runner up is Candidate #2. 
    * Therefore only #2 voters vote strategically in this scenario. 
    

    Outcomes
    -------
    It seems like burial backfires again in this scenario. 

    """
    v = spatial.Voters(seed=0)
    v.add(voter_pref)
    c = spatial.Candidates(v)
    c.add(candidate_pref)

    strategy = {
        'tactics': 'deep_bury',
        'subset': 'underdog',
        'ratio': 1,
        'underdog': None,
        'frontrunnertype': 'eliminate'
    }

    s2 = spatial.Strategies(v).add(**strategy)
    e2 = spatial.Election(voters=v, candidates=c, strategies=s2)
    e2.run('ranked_pairs')

    right = [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3],
             [1, 2, 3], [3, 1, 2], [3, 1, 2], [3, 1, 2], [3, 0, 1], [3, 0, 1],
             [3, 0, 1], [3, 0, 1], [3, 0, 1]]
    right = votesim.votemethods.tools.rcv_reorder(right)
    ballots = e2.result.ballots
    ballots = votesim.votemethods.tools.rcv_reorder(ballots)
    assert np.all(right == ballots)
    return
def test_plurality_onesided():
    """Test plurality one sided voting strategy. 
    
    - #0 would win if #1 voters are strategic. 
    - #3 will win if #1 are honest and #2 voters use one-sided strategy.
    
     >>> Candidates               #0   #1    #2  #3
     >>> Preference locations =  [-1, -0.5,  0.5,  1]
     >>> Number of voters =      [ 7,    2,    3,  5]
     
     
    """
    # Generate voter preferences
    pref = [-1]*7 + [-0.5]*2 + [0.5]*3 + [1]*5
    pref = np.array(pref)[:, None]
    v = spatial.Voters(seed=0)
    v.add(pref)
    
    # Generate candidate preferences    
    cpref = [-1, -.5, .5, 1]
    cpref = np.array(cpref)[:, None]
    c = spatial.Candidates(v)
    c.add(cpref)
    
    #####################################################################
    # Run honest election
    e1 = spatial.Election(voters=v, candidates=c)
    e1.run('plurality')
    tally1 = e1.result.runner.output['tally']
    result1 = e1.result
    
    assert np.all(tally1 == np.array([7, 2, 3, 5]))
    assert 0 in e1.result.winners
    
    #####################################################################
    # Run one-sided tactical election
    
    strategy1 = {'tactics' : 'bullet_preferred', 
                 'ratio' : 1,
                 'subset' : 'underdog',
                 'underdog' : None,}
    strat1 = spatial.Strategies(v).add(**strategy1)
    
    
    e2 = spatial.Election(voters=v, candidates=c, strategies=strat1)
    result2 = e2.run('plurality', result=result1)
    tally2 = result2.runner.output['tally']    
    assert np.all(tally2 == np.array([7, 2, 0, 8]))
    assert 3 in result2.winners
    
    # Test metric comparison system.
    tc = TacticCompare(e_strat=result2.stats,
                       e_honest=result1.stats,
                       )
    # e2.electionStats.add_output(tc)
    stats2 = result2.stats
    stats1 = result1.stats
    print('---------------------------------------')
    print('one-sided regret change =', tc.regret)    
    print('')
    print('one-sided VSE change = ', tc.regret_efficiency_candidate)
    print('')
    print('VSE tactical  = ', stats2.winner.regret_efficiency_candidate)
    print('VSE honest  = ', stats1.winner.regret_efficiency_candidate)
    
    #####################################################################
    # Run full tactical election
    
    strategy1 = {'tactics' : 'bullet_preferred',
                 'ratio' : 1,
                 'underdog' : None,
                 'subset' : ''}
    strat1 = spatial.Strategies(v).add(**strategy1)
    
    e3 = spatial.Election(voters=v, candidates=c, strategies=strat1)
    result3 = e3.run('plurality', result=result1)
    tally3 = result3.runner.output['tally']    
    assert np.all(tally3 == np.array([9, 0, 0, 8]))
    assert 0 in result3.winners
    
    # Test metric comparison system.
    tc = TacticCompare(e_strat=result3.stats,
                       e_honest=result1.stats,
                       )
    print('')
    print('two-sided regret change =', tc.regret)    
    print('two-sided VSE change = ', tc.regret_efficiency_candidate)
    
    docs = result3.output_docs

    # Try to append new output to election results
    e3.append_stat(tc)
    df = e3.dataframe()

    # pdb.set_trace()
    return df
예제 #8
0
def tactical_model_v2(
    name: str,
    methods: list,
    seed=0,
    numvoters=51,
    cnum=5,
    cstd=1.5,
    ndim=1,
    tol=None,
    ratio=1.0,
) -> spatial.Election:
    """Tactical Election model that test every single candidate as an underdog,
    and tests topdog resistance using bullet voting. 
    """

    e = spatial.Election(None, None, seed=seed, name=name)

    # Construct base strategy
    strategy_base = {}
    strategy_base['ratio'] = ratio
    strategy_base['subset'] = 'underdog'

    # Create underdog strategy
    strategy2 = strategy_base.copy()

    # Create topdog strategy
    strategy3 = strategy_base.copy()
    strategy3['tactics'] = ['bullet_preferred']
    strategy3['subset'] = 'topdog'

    # Generate voters
    v = spatial.Voters(seed=seed, tol=tol, base='linear')
    v.add_random(numvoters, ndim=ndim)

    # Generate candidates
    c = spatial.Candidates(v, seed=seed)
    c.add_random(cnum, sdev=cstd)
    e.set_models(voters=v, candidates=c)

    # Construct election identification
    eid = (
        seed,
        numvoters,
        cnum,
        ndim,
    )

    for method in methods:

        # Set empty (honest) strategy
        e.set_models(strategies=spatial.StrategiesEmpty())
        e.user_data(eid=eid, strategy='honest')
        result1 = e.run(etype=method)
        winner = result1.winners[0]
        stats_honest = result1.stats

        underdog_list = list(range(cnum))
        underdog_list.remove(winner)

        # test each underdog
        for underdog in underdog_list:
            strategy2['underdog'] = underdog
            strategy3['underdog'] = underdog

            # test each tactic
            tactics = get_tactics(method)
            for tactic in tactics:
                strategy2['tactics'] = tactic

                # Run one-sided strategy
                s = spatial.Strategies(v).add(**strategy2)
                e.set_models(strategies=s)
                e.user_data(eid=eid, strategy='one-sided')
                result2 = e.run(etype=method, result=result1)

                # Create tactical comparison output, add to output
                tactic_compare = TacticCompare(e_strat=result2.stats,
                                               e_honest=stats_honest)
                e.append_stat(tactic_compare)

                # Run two-sided strategy with top-dog bullet vote.
                s.add(**strategy3)
                e.set_models(strategies=s)
                e.user_data(eid=eid, strategy='two-sided')
                result3 = e.run(etype=method, result=result1)

                # Create tactical comparison output, add to output
                tactic_compare = TacticCompare(e_strat=result3.stats,
                                               e_honest=stats_honest)
                e.append_stat(tactic_compare)

    return e
예제 #9
0
def tactical_model(
    name: str,
    methods: list,
    seed=0,
    numvoters=100,
    cnum=3,
    ndim=1,
    tol=None,
    ratio=1.0,
) -> spatial.Election:
    """Tactical Election model where voters use naive underdog prediction.  """

    e = spatial.Election(None, None, seed=seed, name=name)

    # Construct base strategy
    strategy_base = {}
    strategy_base['ratio'] = ratio
    strategy_base['underdog'] = None

    # Generate voters
    v = spatial.Voters(seed=seed, tol=tol, base='linear')
    v.add_random(numvoters, ndim=ndim)

    # Generate candidates
    c = spatial.Candidates(v, seed=seed)
    c.add_random(cnum, sdev=2.0)

    e.set_models(voters=v, candidates=c)

    # Construct election identification
    eid = (
        seed,
        numvoters,
        cnum,
        ndim,
    )

    # Loop through election methods
    for method in methods:
        # Retrieve topdog strategy.
        strategy_topdog = get_topdog_strategy1(method)
        strategy_topdog['ratio'] = ratio
        strategy_topdog['subset'] = 'topdog'
        strategy_topdog['underdog'] = None

        # First run the honest election
        e.user_data(
            eid=eid,
            num_voters=numvoters,
            num_candidates=cnum,
            num_dimensions=ndim,
            strat_id=-1,
            onesided=False,
        )
        # Set empty (honest) strategy
        e.set_models(strategies=spatial.StrategiesEmpty())
        result1 = e.run(etype=method)
        stats_honest = result1.stats
        # honest_ballots = e.ballotgen.honest_ballots
        # stats_honest = e.electionStats.copy()

        # Initialize strategy elections
        strategies = get_strategies1(method)

        for s in strategies:
            s.update(strategy_base)

        # Iterate through available strategies
        for ii, strategy in enumerate(strategies):

            # Run one-sided strategy
            strategy['subset'] = 'underdog'
            s = spatial.Strategies(v).add(**strategy)
            e.set_models(strategies=s)
            e.user_data(eid=eid,
                        num_voters=numvoters,
                        num_candidates=cnum,
                        num_dimensions=ndim,
                        strat_id=ii,
                        onesided=True)
            result2 = e.run(etype=method, result=result1)
            # Create tactical comparison output, add to output
            tactic_compare = TacticCompare(e_strat=result2.stats,
                                           e_honest=stats_honest)
            e.append_stat(tactic_compare)

            # Run defensive topdog strategy

            s = s.add(**strategy_topdog)
            e.set_models(strategies=s)
            e.user_data(
                eid=eid,
                num_voters=numvoters,
                num_candidates=cnum,
                num_dimensions=ndim,
                strat_id=ii,
                onesided=False,
            )
            result3 = e.run(etype=method, result=result1)
            tactic_compare = TacticCompare(e_strat=result3.stats,
                                           e_honest=stats_honest)
            e.append_stat(tactic_compare)

    return e
예제 #10
0
    def __init__(self,
                 name: str,
                 method: str,
                 voters: spatial.Voters,
                 candidates: spatial.Candidates,
                 ratio=1.0,
                 frontrunnernum=2,
                 user_args: dict = None,
                 record: spatial.ResultRecord = None,
                 get_all_defense=False):
        """Tactical Election model """

        if record is None:
            record = spatial.ResultRecord()

        # Construct base one-sided strategy
        strategy1 = {}
        strategy1['ratio'] = ratio
        strategy1['frontrunnernum'] = frontrunnernum
        strategy1['subset'] = 'underdog'

        # Construct base two-sided strategy
        strategy2 = {}
        strategy2['ratio'] = ratio
        strategy2['frontrunnernum'] = frontrunnernum
        strategy2['subset'] = 'topdog'

        #-------------------------------------------------------------------
        # STEP1: HONEST LECTION SIMULATION
        # Run honest election
        e = spatial.Election(voters=voters,
                             candidates=candidates,
                             strategies=None,
                             save_records=False,
                             seed=0,
                             name=name)
        e.user_data(user_args)

        result1 = e.run(etype=method)
        record.append(result1)
        cnum = len(candidates.data.pref)
        tactics = get_tactics(method)
        self.vse_honest = result1.stats.winner.regret_efficiency_candidate

        #-------------------------------------------------------------------
        # STEP 2: ONE SIDED ELECTION SIMULATIONS
        # Perform tactics on every candidate, see which one produces benefit
        # to the candidate's supporters.
        logger.info('Running one-sided simulations')
        dvse_topdogs = []
        dvse_underdogs = []
        effective_list = []
        vse_list1 = []
        underdogs = []
        for underdog in range(cnum):
            strategy1['underdog'] = underdog

            for tactic in tactics:
                strategy1['tactics'] = tactic
                strategies = spatial.Strategies(e.voters).add(strategy1, 0)
                e.set_models(strategies=strategies)
                result2 = e.run(etype=method, result=result1)
                winner = result2.winners[0]

                # Get underdog change in VSE (positive means the group benefited)
                compare = TacticCompare(e_strat=result2.stats,
                                        e_honest=result1.stats)
                dvse_u = compare.regret_efficiency_candidate['underdog-0']
                dvse_t = compare.regret_efficiency_candidate['topdog-0']

                # record VSE
                vse = result2.stats.winner.regret_efficiency_candidate
                vse_list1.append(vse)

                logger.debug('underdog #%s', underdog)
                logger.debug('strategy = %s', tactic)
                logger.debug(compare.voter_nums)
                logger.debug('underdog VSE change = %.2f', dvse_u)
                logger.debug('topdog VSE change = %.2f', dvse_t)
                try:
                    dvse_u = float(dvse_u)
                    dvse_t = float(dvse_t)
                except TypeError:
                    raise ValueError(
                        'Something went wrong with VSE calculation.')

                # record tactic if it succeeds.
                if dvse_u > 0 and winner == underdog:
                    dvse_underdogs.append(dvse_u)
                    dvse_topdogs.append(dvse_t)
                    effective_list.append(tactic)
                    underdogs.append(underdog)

                    record.append(result2)
                    record.append_stat(compare)

        #-------------------------------------------------------------------
        # STEP 3: TWO SIDED ELECTION SIMULATIONS
        # If a one-sided tactic succeeds, see if a defensive counter exists.
        logger.info('Running two-sided simulations')
        vse_twosided_list = []
        for ii in range(len(effective_list)):

            dvse_topdog = dvse_topdogs[ii]
            strategy1['tactics'] = effective_list[ii]
            strategy1['underdog'] = underdogs[ii]

            vse_list2 = []
            for tactic2 in tactics:
                strategy2['tactics'] = tactic2
                strategy2['underdog'] = underdogs[ii]
                strategies = spatial.Strategies(e.voters)
                strategies.add(strategy1, 0)
                strategies.add(strategy2, 0)

                e.set_models(strategies=strategies)
                result3 = e.run(etype=method, result=result1)

                # Get change in VSE (positive means the group benefited)
                compare = TacticCompare(e_strat=result3.stats,
                                        e_honest=result1.stats)
                dvse_u = compare.regret_efficiency_candidate['underdog-0']
                dvse_t = compare.regret_efficiency_candidate['topdog-0']
                vse = result3.stats.winner.regret_efficiency_candidate
                vse_list2.append(vse)

                logger.debug('tactic = %s', tactic2)
                logger.debug('underdog VSE change = %.2f', dvse_u)
                logger.debug('topdog VSE change = %.2f', dvse_t)

                try:
                    dvse_u = float(dvse_u)
                    dvse_t = float(dvse_t)
                except TypeError:
                    raise ValueError(
                        'Something went wrong with VSE calculation.')

                if dvse_t > dvse_topdog:
                    record.append(result3)
                    record.append_stat(compare)

                    # If a defensive tactic is found to completely counter
                    # offense, break.
                    # if (dvse_u == 0) and (get_all_defense == False):
                    #     break

            vse_twosided = np.max(vse_list2)
            vse_twosided_list.append(vse_twosided)

        self.record = record
        self.dvse_underdogs = dvse_underdogs
        self.dvse_topdogs = dvse_topdogs
        self.vse_onesided = np.min(vse_list1)
        self.viable_underdogs = len(np.unique(underdogs))

        try:
            self.vse_twosided = np.min(vse_twosided_list)
        except ValueError:
            # If no values found that means underdog strategies were ineffective
            # and therefore two-sided runs were not performed.
            self.vse_twosided = self.vse_honest
        self.df = record.dataframe()
        return
예제 #11
0
def tactical_model(
    name: str,
    method: str,
    seed=0,
    numvoters=51,
    cnum=5,
    ndim=1,
    tol=None,
    ratio=1.0,
    frontrunnernum=2,
) -> spatial.Election:
    """Tactical Election model """

    e = spatial.Election(None, None, seed=seed, name=name)

    # Construct base strategy
    strategy_base = {}
    strategy_base['ratio'] = ratio
    strategy_base['frontrunnernum'] = frontrunnernum
    strategy_base['frontrunnertype'] = 'eliminate'
    # strategy_base['tactics'] = ('bury', 'compromise')
    strategy_base['tactics'] = ('minmax_preferred')
    strategy_base['subset'] = 'underdog'

    strategy2 = strategy_base.copy()

    # Generate voters
    v = spatial.Voters(seed=seed, tol=tol, base='linear')
    v.add_random(numvoters, ndim=ndim)

    # Generate candidates
    c = spatial.Candidates(v, seed=seed)
    c.add_random(cnum, sdev=1.0)
    e.set_models(voters=v, candidates=c)

    # Set empty (honest) strategy
    e.set_models(strategies=())
    result1 = e.run(etype=method)
    winner = result1.winners[0]
    stats_honest = result1.stats

    underdog_list = list(range(cnum))
    underdog_list.remove(winner)

    try:
        print('honest tally')
        print(result1.runner.output['tally'])
        print('')
    except KeyError:
        pass
    # test each underdog

    for underdog in underdog_list:
        # Run one-sided strategy
        strategy2['underdog'] = underdog
        s = spatial.Strategies(v).add(strategy2, 0)
        e.set_models(strategies=s)

        result2 = e.run(etype=method, result=result1)

        # Create tactical comparison output, add to output
        tactic_compare = TacticCompare(e_strat=result2.stats,
                                       e_honest=stats_honest)
        e.append_stat(tactic_compare)
        series = e.dataseries()
        out1 = series[statnames[0]]
        out2 = series[statnames[1]]
        print('Setting underdog = %s' % underdog)
        print('Topdog VSE = %.2f' % out1)
        print('Underdog VSE = %.2f' % out2)
        print('winner=%s' % result2.winners[0])
        try:
            print('tally=', result2.runner.output['tally'])
        except KeyError:
            pass
        # print(result2.ballots)
        print('')

    # Calculate underdog using tally
    s0 = spatial.Strategies(v).add(strategy_base, 0)
    e.set_models(voters=v, candidates=c, strategies=s0)
    e.run(etype=method)
    frunners = e.ballotgen.tacticalballots.root.get_group_frontrunners(s0.data)
    print('calculated front runners (tally) = ', frunners)

    #Calculate underdog using eliminate
    strategy_base['frontrunnertype'] = 'eliminate'
    s0 = spatial.Strategies(v).add(strategy_base, 0)
    e.set_models(voters=v, candidates=c, strategies=s0)
    e.run(etype=method)
    frunners = e.ballotgen.tacticalballots.root.get_group_frontrunners(s0.data)
    print('calculated front runners (eliminate) = ', frunners)
    return e
예제 #12
0
def test_metrics_compare():
    """Test plurality bullet voting strategy.
    
    Scenario attributes:
     - 3 candidate race with 3 concentrated, coincident voter groups
     
     >>> Candidates               #0   #1   #2
     >>> Preference locations =  [-1,  0.5,  1]
     >>> Number of voters =      [ 7,    3,  5]
     
     - If voters are honest, plurality candidate #0 should win with 7 votes 
     - If voters are strategic and consider only the top two candidates, 
       Candidate #1 supporters also lean towards #2 - therefore 
       candidate #2 should win with 3 + 5 = 8 votes.
       
    """
    pref = [-1] * 7 + [0.5] * 3 + [1] * 5
    pref = np.array(pref)[:, None]
    v = spatial.Voters(seed=0)
    v.add(pref)

    cpref = [-1, .5, 1]
    cpref = np.array(cpref)[:, None]
    c = spatial.Candidates(v)
    c.add(cpref)

    #####################################################################
    # Run honest election

    e1 = spatial.Election(voters=v, candidates=c)
    e1.run('plurality')
    result1 = e1.result
    estat1 = result1.stats
    #####################################################################
    # Run strategic election

    strategy1 = {
        'tactics': 'bullet_preferred',
        'subset': '',
        'ratio': 1,
        'underdog': None
    }
    s = spatial.Strategies(v)
    s.add(**strategy1)

    e1.set_models(strategies=s)
    e1.run('plurality', result=result1)
    result2 = e1.result
    estat2 = result2.stats

    #####################################################################
    # Run the assestions

    tc = votesim.metrics.TacticCompare(estat2, estat1)
    t = e1.ballotgen.tacticalballots
    topdog_num = len(t.group_index['topdog-0'])
    underdog_num = len(t.group_index['underdog-0'])

    regret1 = estat1.winner.regret
    regret2 = estat2.winner.regret
    regret_change = tc.regret

    # Make sure regret change adds up for tactical and honest voters
    assert regret2 - regret1 == regret_change['tactical-0']

    # Make sure group regrets add up for the total reget, honest.
    regret_honest = tc._group_honest.regret
    regret1a = ((regret_honest['topdog-0'] * topdog_num +
                 regret_honest['underdog-0'] * underdog_num) /
                (topdog_num + underdog_num))
    assert regret1a == regret1

    # Make sure group regrets add up for the total reget, tactical.
    regret_strate = tc._group_strate.regret
    regret2a = ((regret_strate['topdog-0'] * topdog_num +
                 regret_strate['underdog-0'] * underdog_num) /
                (topdog_num + underdog_num))
    assert regret2a == regret2

    return e1, estat2, estat1
예제 #13
0
 tally = result1.runner.output['tally']
 print('ballots = ')
 print(result1.runner.ballots)
 print('honest tally = ', tally)
 print('candidate net regrets = ', result1.stats.candidates.regrets)
 assert np.all(tally == [65, 59, 28])
 
 print('---- ONE-SIDED ELECTION --------------------------------')
 strat1 = {'tactics' : ('minmax_preferred'),
           'frontrunnertype' : 'tally',
           'subset' : 'underdog',
           'ratio' : 1,
           'underdog' : None,
           'groupnum' : 0,
           }
 s1 = spatial.Strategies(v).add(**strat1)
 e1.set_models(strategies=s1)
 result2 = e1.run(etype)
 tally = result2.runner.output['tally']
 
 print('ballots = ')
 print(result2.runner.ballots)
 print('one-sided tactical tally = ', result2.runner.output['tally'])
 assert np.all(tally == [45, 64, 25])
 
 
 
 print('---- TWO-SIDED ELECTION --------------------------------')
 strat2 = {'tactics' : ('minmax_preferred'),
           'frontrunnertype' : 'tally',
           'subset' : 'topdog',