class Vote::Condorcet::Schulze::SchulzeBasic
Attributes
beat_couples[R]
candidates[R]
play_matrix[R]
potential_winners[R]
ranking[R]
result_matrix[R]
ties[R]
vote_count[R]
vote_matrix[R]
winners_array[R]
Public Class Methods
do(vote_matrix, candidate_count = nil)
click to toggle source
All-in-One class method to get a calculated SchulzeBasic
object
# File lib/vote/condorcet/schulze/basic.rb, line 14 def self.do(vote_matrix, candidate_count = nil) instance = new instance.load vote_matrix, candidate_count instance.run instance end
new()
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 8 def initialize @beat_couples = [] @ties = [] end
Public Instance Methods
load(vote_matrix, candidate_count = nil)
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 21 def load(vote_matrix, candidate_count = nil) input = if vote_matrix.is_a?(Vote::Condorcet::Schulze::Input) vote_matrix else Vote::Condorcet::Schulze::Input.new(vote_matrix, candidate_count) end @vote_matrix = input.matrix @candidate_count = input.candidates @candidates = (0..@candidate_count - 1).to_a @vote_count = input.voters self end
run()
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 34 def run play result calculate_winners rank calculate_beat_couples calculate_potential_winners end
Private Instance Methods
build_play_matrix()
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 51 def build_play_matrix ::Matrix.scalar(@candidate_count, 0).extend(Vote::Matrix) end
calculate_beat_couples()
click to toggle source
calculates @beat_couples and @ties in roder to display results afterward
# File lib/vote/condorcet/schulze/basic.rb, line 109 def calculate_beat_couples return if @calculated_beat_couples ranking.each_with_index do |_val, idx| ranking.each_with_index do |_val2, idx2| next if idx == idx2 next @beat_couples << [idx, idx2] if play_matrix[idx, idx2] > play_matrix[idx2, idx] calculate_ties(idx, idx2) end end @calculated_beat_couples = true end
calculate_potential_winners()
click to toggle source
you should call calculate_winners
first
# File lib/vote/condorcet/schulze/basic.rb, line 104 def calculate_potential_winners @potential_winners ||= winners_array.map.with_index { |val, idx| idx if val > 0 }.compact end
calculate_ties(idx, idx2)
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 122 def calculate_ties(idx, idx2) return unless in_tie?(idx, idx2) return if @ties.any? { |tie| ([idx, idx2] - tie).empty? } found_tie = tie_by_idx(idx) return found_tie << idx2 if found_tie found_tie = tie_by_idx(idx2) return found_tie << idx if found_tie @ties << [idx, idx2] end
calculate_winners()
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 88 def calculate_winners @winners_array = Array.new(@candidate_count, 0) @winners_array.each_with_index do |_el, idx| row = @play_matrix.row(idx) column = @play_matrix.column(idx) if row.each_with_index.all? { |r, index| r >= column[index] } @winners_array[idx] = 1 end end end
find_matches_with_wins()
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 55 def find_matches_with_wins @candidate_count.times do |i| @candidate_count.times do |j| next if i == j if @vote_matrix[i, j] > @vote_matrix[j, i] @play_matrix[i, j] = @vote_matrix[i, j] else @play_matrix[i, j] = 0 end end end end
find_strongest_paths()
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 68 def find_strongest_paths @candidate_count.times do |i| @candidate_count.times do |j| next if i == j @candidate_count.times do |k| next if (i == k) || (j == k) @play_matrix[j, k] = [@play_matrix[j, k], [@play_matrix[j, i], @play_matrix[i, k]].min].max end end end end
in_tie?(idx, idx2)
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 136 def in_tie?(idx, idx2) @play_matrix[idx, idx2] == @play_matrix[idx2, idx] && @ranking[idx] == @ranking[idx2] && @winners_array[idx] == @winners_array[idx2] end
play()
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 45 def play @play_matrix = build_play_matrix find_matches_with_wins find_strongest_paths end
rank()
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 99 def rank @ranking = @result_matrix.row_vectors.map { |rm| rm.inject(0) { |a, e| a + e } } end
result()
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 80 def result @result_matrix = ::Matrix.scalar(@candidate_count, 0).extend(Vote::Matrix) @result_matrix.each_with_index do |e, x, y| next if x == y @result_matrix[x, y] = e + 1 if @play_matrix[x, y] > @play_matrix[y, x] end end
tie_by_idx(idx)
click to toggle source
# File lib/vote/condorcet/schulze/basic.rb, line 132 def tie_by_idx(idx) @ties.find { |tie| tie.any? { |el| el == idx } } end