Advertisement
Guest User

JonathanM

a guest
Apr 3rd, 2014
128
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #oneVoteTwoVoteRedVoteBlueVote
  2. #a very, very rough MMP election simulator
  3. # David Hood
  4. # Jonathan Marshall
  5.  
  6. # useful things to do:
  7. # 1. Simulate electorates given some assumptions
  8.  
  9. party <- c("Nat", "Lab", "Green", "NZF", "Cons", "Maori", "ACT", "United", "Mana", "Other")
  10. side <- c("n", "l", "l", "w", "n", "n", "n", "n", "l", "o")
  11.  
  12. # likely electorates
  13. electorates <- c(1, 1, 0, 0, 0, 1, 1, 1, 0, 0);
  14.  
  15. simulate_election <- function() {
  16.   # we want to estimate the vector P of probabilities within a bayesian framework
  17.   # based on one (or more) polls, and then generate the posterior distribution for
  18.   # P and use this to forward-simulate for potential outcomes
  19.  
  20.   # Given P, the poll is multinomial(size, P)
  21.   # Thus, if we put a dirichlet prior on P, the posterior is also dirichlet
  22.   # with parameter P + poll_results
  23.  
  24.   poll <- c(.47, .31, .11, .07, .023, 0.007, 0.003, 0.001, 0.000, 0.004)
  25.   num_people <- round(poll * 767) # the best we can do as we don't know the weighting
  26.   prior <- rep(1, length(num_people))
  27.  
  28.   # number of votes in the simulated election
  29.   total_votes <- 2000000
  30.  
  31.   prop <- rdirichlet(1, num_people + prior)
  32.   return(round(total_votes * prop))
  33. }
  34.  
  35. allocate_seats <- function(votes, electorates) {
  36.  
  37.   # uses Sainte Laguë to allocate seats in an election, assuming
  38.   # that each party gets at least electorates
  39.   total_seats <- 125
  40.  
  41.   # now determine seats, given 125 available...
  42.  
  43.   # exclude parties that don't make the threshold
  44.   prop <- votes / sum(votes);
  45.   exclude <- prop < 0.05 & !electorates
  46.   prop[exclude] <- 0;
  47.   # renormalize to 1
  48.   prop <- prop / sum(prop)
  49.  
  50.   # figure out total number of votes via Sainte Laguë
  51.   divisors <- seq(1, by=2, length.out=total_seats)
  52.  
  53.   r <- rep(1:length(votes), length(divisors))
  54.   d <- expand.grid(votes, divisors)
  55.   o <- order(-round(d[,1] / d[,2]))
  56.  
  57.   seats <- rep(0, length(votes))
  58.   t <- tabulate(r[o[1:total_seats]])
  59.   seats[1:length(t)] <- t
  60.   return(pmax(seats, electorates))
  61. }
  62.  
  63. decide_winner <- function(seats) {
  64.   # now decide party allegiance, assuming NZF is king-maker
  65.   nseats <- sum(seats[side == "n"])
  66.   lseats <- sum(seats[side == "l"])
  67.   wseats <- sum(seats[side == "w"])
  68.  
  69.   if (nseats > (lseats + wseats))  {
  70.     victory <- "national_led"
  71.   } else if (lseats > (nseats + wseats))  {
  72.     victory <- "labour_led"
  73.   }  else if ((lseats == nseats) & (wseats == 0)){
  74.     victory <- "hung"
  75.   } else { victory <- "nzf_decides"}
  76.   return(victory)
  77. }
  78.  
  79. elect <- function(support) {
  80.   votes <- simulate_election()
  81.   seats <- allocate_seats(votes, electorates)
  82.   return(decide_winner(seats))
  83. }
  84.  
  85. many_elections <- 1000
  86. outcomes <- rep("", many_elections)
  87. for (i in 1:many_elections)
  88.   outcomes[i] <- elect()
  89. print("Results for many elections")
  90. print(prop.table(table(outcomes)))
Advertisement
RAW Paste Data Copied
Advertisement