Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. function win_prob(nVacancies, p, listSize, nVoters, nSimulations)
  2. v = 0.5*(flipud(eye(length(p),1)) - sqrt(p))
  3. Q = eye(length(v)) - (2/(v'*v)[1,1]) .* (v*v')
  4. M = diagm(sqrt(p./nVoters)) * Q[:,1:(end-1)]
  5.  
  6. # Generate random columns of vote shares;
  7. # each column represents a multinomial experiment.
  8. f = M * randn((length(p)-1, nSimulations))
  9. for (j = 1:nSimulations)
  10. f[:,j] += p
  11. end
  12. # Normalize vote shares by 1/(number of vacancies)
  13. f .*= nVacancies
  14.  
  15. # C[i,L] = total number of seats won by candidate i
  16. # of candidate list L throughout all experiments
  17. C = zeros(max(listSize), length(listSize))
  18.  
  19. # Count C[i,j]
  20. for (j = 1:nSimulations)
  21. # no. of seats won by each list by meeting Hare quota
  22. won = max(min(listSize, ifloor(f[:,j])), 0)
  23.  
  24. # remaining (normalized) vote shares
  25. r = f[:,j] - won
  26.  
  27. # final no. of seats won by a candidate list
  28. won += (r .>= sort(r)[nVacancies - sum(won)])
  29.  
  30. # add 1 to the no. of seats won by each elected candidate
  31. for L=1:length(listSize)
  32. C[1:won[L], L] += 1
  33. end
  34. end
  35.  
  36. # Probability of winning a seat for each candidate
  37. C = C./float(nSimulations)
  38.  
  39. # Sort those probabilities
  40. result = [(0,0,0.0)]; pop(result)
  41. for j in 1:size(C,2)
  42. for i in 1:listSize[j]
  43. push(result, (j, i, C[i,j]))
  44. end
  45. end
  46. sort!((x,y)->x[3]>y[3], result)
  47. end
  48.  
  49. # The main program
  50. begin
  51. t0 = time()
  52. nVacancies = 9
  53. # NOW News' rolling survey, Sep 2-6, NT West
  54. p = [.04 .07 .05 .07 .01 .02 .16 .09 .03 .03 .08 .04 .01 .08 .1 .12]'
  55. # HKUPOP's rolling survey, Aug 1 - Sep 7, NT West
  56. #p = [4.6 6.8 4.6 7.9 0 2.3 15.7 9.5 2.5 2.7 7 4.8 1.6 8.4 9.8 11.8]'*0.01
  57. listSize = [6 5 5 4 1 1 2 4 1 1 2 7 7 3 2 4]' # no. of candidates in each list
  58. nVoters = 503
  59. nSimulations = 1000000
  60. result = win_prob(nVacancies, p, listSize, nVoters, nSimulations)
  61. for i=1:length(result)
  62. println(result[i])
  63. end
  64. println(time()-t0)
  65. end