Seats Allocation under Various Electoral Systems

Seats Allocation under Various Electoral Systems preview image

1 collaborator

Default-person Jaehyun Song (Author)

Tags

electoral system  

Tagged by Jaehyun Song about 2 years ago

politics 

Tagged by Jaehyun Song about 2 years ago

voting behavior 

Tagged by Jaehyun Song about 2 years ago

Visible to everyone | Changeable by everyone
Model was written in NetLogo 6.0 • Viewed 242 times • Downloaded 10 times • Run 0 times
Download the 'Seats Allocation under Various Electoral Systems' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Info tab cannot be displayed because of an encoding error

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;; ===================================
;; 日本選挙学会2017年度大会@香川大学
;;
;; 制度変化とその帰結のシミュレーション
;;  ー異なる投票方法の下での議席配分
;;
;; シミュレーション・ソースコード
;;
;; 報告者: 品田裕・Song Jaehyun
;; 作成者: Song Jaehyun
;; 作成日: 2017-01-06
;;
;; 修正履歴
;;  20170107 選挙サイクルの導入
;;           プロット機能の追加
;;  20170108 選好をベータ分布へ変更
;;           投票確率関数の修正
;; ===================================

;;全域変数の宣言
globals [election_cycle ENC]

;;エージェントの定義
breed [voters voter]         ;;有権者エージェント
breed [candidates candidate] ;;候補者エージェント
breed [v_counters v_counter] ;;得票数カウンター    (今後、パッチ化する)
breed [r_counters r_counter] ;;当選率カウンター    (今後、パッチ化する)
breed [w_counters w_counter] ;;当選回数カウンター   (今後、パッチ化する)
breed [l_counters l_counter] ;;連続敗北回数カウンター (今後、パッチ化する)

;;有権者の属性
voters-own [id        ;; ID
            ideology] ;; イデオロギー (Beta(vAlpha, vBeta)の分布から生成)

;;候補者の属性
candidates-own [run_election ;;立候補時期
                ideology     ;;イデオロギー (Uniform(0, 1)の分布から生成)
                votes        ;;現在の得票数
                votes2 .     ;;現在の得票数^2
                rate         ;;当選率
                nWin         ;;累積当選回数
                prevLose     ;;前回の選挙での敗北有無
                nLose        ;;連続敗北回数
                plotColor]   ;;Line Color in Plot

;;カウンターの属性 (今後、パッチ化する)
v_counters-own [votes] ;;得票数
r_counters-own [rate]  ;;得票数j順位
w_counters-own [nWin]  ;;当選回数
l_counters-own [nLose] ;;連続敗北回数

to setup
  if (magnitude > nCandidates) [
    error "Error! District Magnitude (magnitude) must be smaller than number of candidates (nCandidates)!"
  ]
  if (nBallot > nCandidates) [
    error "Error! If number of ballots (nBallot) is bigger than number of candidates (nCandidates), elections are endless!"
  ]

  clear-all            ;;全て初期化
  random-seed seed     ;;Set seed
  set election_cycle 1 ;;選挙回数の初期化
  set ENC 0

  create_candidates   ;;候補者の生成
  create_voters       ;;有権者の生成
  create-v_counter    ;;得票数カウンターの生成
  show-v_counter      ;;得票数カウンターの表示
  create-r_counter    ;;当選率カウンターの生成
  show-r_counter      ;;当選率カウンターの表示
  create-w_counter    ;;当選回数カウンターの生成
  show-w_counter      ;;当選回数カウンターの表示
  create-l_counter    ;;連続敗北回数カウンターの生成
  show-l_counter      ;;連続敗北回数カウンターの表示
  reset-ticks         ;;時間(tick)の初期化
end 

to go
  cast-votes                 ;;投票行動
  highlight-top-candidates   ;;当選可能ライン候補者の得票数をハイライト
  highlight-top-candidates2  ;;当選回数上位の候補者の当選回数をハイライト
  highlight-top-candidates4  ;;連続敗北回数が1以上の候補者をハイライト
end -cycle                  ;;全員投票済みの場合、1回分の選挙終了
  if (election_cycle > Last-election) [ stop ]
end 

;;有権者生成プロシージャ

to create_voters
  let counter 1 ;;臨時カウンターの初期化

  loop [
    if counter > nVoter [ stop ]            ;;臨時カウンターが有権者数より小さい限り、反復

    let temp_ideology rngBeta vAlpha vBeta  ;;Beta(vAlpha, vBeta)からイデオロギーの生成

    ;;有権者を票数だけ生成
    create-voters nBallot [
      set shape "square"                  ;;形は四角形
      set color [255 0 0 15]              ;;色は半透明な白
      ifelse ((random-float 1) >= 0.5) [  ;;移動方向(左右)をランダムに割当
        set heading 90
      ]
      [ set heading 270 ]
      setxy (random 50) 5                 ;;初期位置の指定 (横 = ランダム, 縦 = 3)

      set id counter                      ;;固有IDの割当
      set ideology temp_ideology          ;;イデオロギーの割当

    ]

    set counter counter + 1               ;;カウンター++
  ]
end 

to create_candidates
  let counter 1 ;;臨時カウンターの初期化

  loop[
    if counter > nCandidates [ stop ] ;;臨時カウンターが候補者数より小さい限り、反復

    create-candidates 1 [
      set shape "person"                   ;;形は人間
      set color red - 2                    ;;色はちょっと暗い赤
      set heading 180                      ;;全員南向き
      set run_election election_cycle      ;;最初に立候補した選挙は現在のelection_cycle
      ;;X座標は均等に並ぶように。Y座標は4
      setxy (((50 / nCandidates) / 2) + ((counter - 1) * (50 / nCandidates)) - 0.5) 4
      set ideology (rngBeta cAlpha cBeta)  ;;イデオロギーはBeta(cAlpha, cBeta)からランダムに生成
      set votes 0                          ;;得票数の初期化
      set votes2 0                         ;;得票数^2の初期化
      set rate 0                           ;;当選率の初期化
      set nWin 0                           ;;当選回数の初期化
      set nLose 0                          ;;連続敗北回数の初期化
      set prevLose 0                       ;;前回選挙敗北有無の初期化
      set plotColor random 145

      set label precision ideology 2       ;;ラベルはイデオロギーで
    ]

    set counter counter + 1                ;;カウンターを増やす
  ]
end 

;;得票数カウンターの生成

to create-v_counter
  let counter 1                            ;;臨時カウンターの初期化

  loop[                                    ;;候補者の数だけ繰り返し
    if counter > nCandidates [ stop ]

    create-v_counters 1 [                  ;;得票数カウンターの生成
      set shape "wolf"                     ;;どうせ透明だから形はどうでもいい
      set color [0 0 0 0]                  ;;色は透明
      ;;X座標は候補者と同じ、Y座標は候補者の座標 - 1
      setxy (((50 / nCandidates) / 2) + ((counter - 1) * (50 / nCandidates)) - 0.5) 3
      set votes 0                          ;;得票数の初期化
    ]

    set counter counter + 1                ;;臨時カウンター++
  ]
end 

to show-v_counter
  ask v_counters [
    set label votes
  ]
end 

to create-r_counter
  let counter 1

  loop[
    if counter > nCandidates [ stop ]

    create-r_counters 1 [
      set shape "wolf"
      set color [0 0 0 0]
      setxy (((50 / nCandidates) / 2) + ((counter - 1) * (50 / nCandidates)) - 0.5) 2
      set rate 0
    ]

    set counter counter + 1
  ]
end 

to show-r_counter
  ask r_counters [
    set label round rate
  ]
end 

to create-w_counter
  let counter 1

  loop[
    if counter > nCandidates [ stop ]

    create-w_counters 1 [
      set shape "wolf"
      set color [0 0 0 0]
      setxy (((50 / nCandidates) / 2) + ((counter - 1) * (50 / nCandidates)) - 0.5) 1
      set nWin 0
    ]

    set counter counter + 1
  ]
end 

to show-w_counter
  ask w_counters [
    set label nWin
  ]
end 

to create-l_counter
  let counter 1

  loop[
    if counter > nCandidates [ stop ]

    create-l_counters 1 [
      set shape "wolf"
      set color [0 0 0 0]
      setxy (((50 / nCandidates) / 2) + ((counter - 1) * (50 / nCandidates)) - 0.5) 0
      set nLose 0
    ]

    set counter counter + 1
  ]
end 

to show-l_counter
  ask l_counters [
    set label nLose
  ]
end 

;;移動方法
;;forward 1のみなら別にプロシージャにする必要はないが、
;;今後、より複雑な移動をする時のためにプロシージャ化しておく

to normal_move
  forward 1
end 

;;選挙一回分終了

to end-cycle
  ;;全ての有権者が投票済み (透明)なら
  if (count voters with [color != [0 0 0 0]] = 0) [

    show_winner                               ;;当選者の表示
    set ENC (calc-ENC)
    tick

    ask candidates [                          ;;全ての高著者のの
      set votes 0                               ;;得票数を0に戻す
      set votes2 0                              ;;得票数^2を0に戻す

      let temp_rate ((nWin / (election_cycle - run_election + 1)) * 100)

      set rate temp_rate

      ask v_counters-at 0 -1 [
        set votes 0
      ]
      ask r_counters-at 0 -2 [
        set rate temp_rate
        set label round rate
      ]

    ]

    retire-candidate

    set election_cycle election_cycle + 1     ;;election_cycleを1増やす

    ask voters [                              ;;全ての有権者の
      set color [255 0 0 15]                    ;;色を元に戻す (= 復活させる)
      setxy (random 50) 5                       ;;位置の初期化
    ]

  ]
end 

;;当選者の表示

to show_winner
  ask max-n-of magnitude candidates [ votes ] [
    set nWin nWin + 1
    set prevLose 0
    set nLose 0

    ask w_counters-at 0 -3 [
      set nWin nWin + 1
      set label nWin
    ]
    ask l_counters-at 0 -4 [
      set nLose 0
      set label nLose
    ]
  ]

  ask min-n-of (nCandidates - magnitude) candidates [ votes ] [
    set prevLose PrevLose + 1
  ]

  ask candidates with [prevLose > 0] [
    set nLose nLose + 1
    ask l_counters-at 0 -4 [
      set nLose nLose + 1
      set label nLose
    ]
  ]
end 

;;retire-timingで指定した回数だけ連続敗北した候補者は引退
;;引退と同時に、そのパッチに新人候補者を生成
;;新人候補者のイデオロギーは同様にUniform(0, 1)

to retire-candidate

  ;;連続敗北回数がretire-timing以上なら...
  ask candidates with [ nLose >= retire-timing ] [

    ;;新しい候補者を孵化(?!)させる
    hatch-candidates 1 [
      set shape "person"                  ;;形は同様に「人間」
      set color red - 2                   ;;色は暗い赤
      set run_election election_cycle + 1 ;;立候補時期の記録
      set ideology (rngBeta cAlpha cBeta) ;;イデオロギーの割当
      set votes 0                         ;;得票数
      set votes2 0                        ;;得票数^2
      set rate 0                          ;;Rate
      set nWin 0                          ;;累積当選回数
      set nLose 0                         ;;連続敗北回数
      set prevLose 0                      ;;前回選挙での敗北有無
      set plotColor random 145

      set label precision ideology 2      ;;ラベルにイデオロギーを表示
    ]

    ;;当選回数カウンターの初期化
    ask v_counters-at 0 -1 [
      set votes 0
      set label votes
    ]
    ask r_counters-at 0 -2 [
      set label round rate
    ]
    ask w_counters-at 0 -3 [
      set nWin 0
      set label nWin
    ]
    ask l_counters-at 0 -4 [
      set nLose 0
      set label nLose
    ]

  die ;;政治家は落ちたらただの人間...ではなく死体
]
end 

;; 投票行動プロシージャ

to cast-votes

  ;;まだ投票していない有権者のみ
  ask voters with [color != [0 0 0 0]] [

    let didIvoted count voters-here with [ id = [id] of myself ]

    ;;自分より下のパッチに候補者がいたら
    ifelse any? candidates-at 0 -1 [
      ifelse (didIvoted = 1) [

        ;;投票確率計算のために必要な変数
        let voter_ideology ideology                                      ;;1. 有権者のイデオロギー
        let cand_ideology [ideology] of one-of candidates-on neighbors4  ;;2. 候補者のイデオロギー
        let cand_nWin [nWin] of one-of candidates-on neighbors4          ;;3. 候補者の当選回数
        let cand_prev [prevLose] of one-of candidates-on neighbors4      ;;4. 候補者の当選回数
        let cand_rate [rate] of one-of candidates-on neighbors4          ;;5. 候補者の当選Rate

        let vote_prob 0                                                  ;;投票確率の宣言・初期化

        set vote_prob (calc-voteProb cand_ideology voter_ideology cand_nWin cand_prev cand_rate)

        let vote_prob2 random-float 1

        if vote_prob2 >= vote_prob [
          normal_move
        ]

        if vote_prob2 < vote_prob [
          set color [ 0 0 0 0 ] ;;投票した有権者を透明にする

          ask candidates-at 0 -1 [
            set votes votes + 1
            set votes2 ((votes / (nVoter * nBallot)) * (votes / (nVoter * nBallot)))
          ]

          ask v_counters-at 0 -2 [
            set votes votes + 1
            set label votes
          ]
        ]

      ]

      [ normal_move ]
    ]
    [ normal_move ]
  ]
end 

;;現在、上位M名候補者の得票数と当選回数をハイライト

to highlight-top-candidates
  ask max-n-of magnitude candidates [ votes ] [
    set color red + 2
    ask v_counters-at 0 -1 [
      set label-color yellow
    ]
  ]
  ask min-n-of (nCandidates - magnitude) candidates [ votes ] [
    set color red - 2
    ask v_counters-at 0 -1 [
      set label-color white
    ]
  ]
end 

to highlight-top-candidates2
  ask max-n-of magnitude candidates [ rate ] [
    ask r_counters-at 0 -2 [set label-color yellow]
  ]

  ask min-n-of (nCandidates - magnitude) candidates [ rate ] [
    ask r_counters-at 0 -2 [set label-color white]
  ]
end 

to highlight-top-candidates4
  ask candidates [
    ask l_counters-at 0 -4 [
      ifelse (nLose >= 1) [
        set label-color yellow
      ]
      [
        set label-color white
      ]
    ]

  ]
end 

;;投票確率の計算

to-report calc-voteProb [candId voterId cand_nWin cand_prev cand_rate]
  let temp_nWin 1
  let temp_incum 0

  if ((incumbency_advantage?) and (cand_nWin >= 1) and (cand_prev = 0)) [
    set temp_incum incumbency_discount
  ]
  if nWin_advantage? [
    ;set temp_nWin (1 + (nWin_advantage_discount * (cand_rate * 0.01)))
    set temp_nWin (1 + (nWin_advantage_discount * (cand_nWin / (election_cycle))))
  ]

  if (utility-function = "Simple") [
    report (1 - (abs(candID - voterID)) * temp_nWin + temp_incum)
  ]
  if (utility-function = "Logistic") [
    report (1 / (1 + exp(-(uBeta0 - uBeta1 * (abs(candID - voterID)))))) * temp_nWin + temp_incum
  ]
end 

;;ベータ分布から乱数生成レポーター
;;Beta(alpha, beta)からの乱数生成は
;;Gamma(alpha, 1) / (Gamma(alpha, 1) + Gamma(beta, 1))
;;でもできる。

to-report rngBeta [alpha beta]
  let temp1 random-gamma alpha 1
  let temp2 random-gamma beta 1
  report (temp1 / (temp1 + temp2))
end 

to-report calc-ENC
  report (1 / sum([votes2] of candidates))
end 

There are 2 versions of this model.

Uploaded by When Description Download
Jaehyun Song about 2 years ago Minor change Download this version
Jaehyun Song about 2 years ago Initial upload Download this version

Attached files

File Type Description Last updated
Seats Allocation under Various Electoral Systems.png preview Preview for 'Seats Allocation under Various Electoral Systems' about 2 years ago, by Jaehyun Song Download

This model does not have any ancestors.

This model does not have any descendants.