class Vote::Schulze::Basic

Attributes

candidate_count[R]
play_matrix[R]
ranking[R]
ranking_abc[R]
result_matrix[R]
voting_count[R]
voting_matrix[R]

Public Class Methods

call(voting_matrix, candidate_count = nil) click to toggle source

All-in-One class method to get a calculated SchulzeBasic object

# File lib/vote/schulze/basic.rb, line 7
def self.call(voting_matrix, candidate_count = nil)
  new(voting_matrix, candidate_count).call
end
new(voting_matrix, candidate_count = nil) click to toggle source
# File lib/vote/schulze/basic.rb, line 14
def initialize(voting_matrix, candidate_count = nil)
  unless voting_matrix.is_a?(Vote::Schulze::Input)
    voting_matrix = Vote::Schulze::Input.new(voting_matrix, candidate_count)
  end
  @voting_matrix = voting_matrix.voting_matrix
  @candidate_count = voting_matrix.candidate_count
  @voting_count = voting_matrix.voting_count
  @play_matrix = ::Matrix.scalar(@candidate_count, 0).extend(Vote::Matrix)
  @result_matrix = ::Matrix.scalar(@candidate_count, 0).extend(Vote::Matrix)
end

Public Instance Methods

call() click to toggle source
# File lib/vote/schulze/basic.rb, line 25
def call
  tap do
    find_matches_with_wins
    find_strongest_paths
    calculate_result
    calculate_ranking
    calculate_ranking_abc
  end
end

Private Instance Methods

calculate_ranking() click to toggle source
# File lib/vote/schulze/basic.rb, line 73
def calculate_ranking
  @ranking = @result_matrix.row_vectors.map { |e| e.inject(0) { |s, v| s + v } }
end
calculate_ranking_abc() click to toggle source
# File lib/vote/schulze/basic.rb, line 77
def calculate_ranking_abc
  @ranking_abc =
    @ranking
    .map { |e| [e, (@ranking.index(e) + 65).chr] }
    .sort
    .reverse
    .map { |e| "#{e[1]}:#{@ranking.max - e[0] + 1}" } # => "letter:int"
end
calculate_result() click to toggle source
# File lib/vote/schulze/basic.rb, line 65
def calculate_result
  @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
find_matches_with_wins() click to toggle source
# File lib/vote/schulze/basic.rb, line 37
def find_matches_with_wins
  @candidate_count.times do |i|
    @candidate_count.times do |j|
      next if i == j

      @play_matrix[i, j] = @voting_matrix[i, j] if @voting_matrix[i, j] > @voting_matrix[j, i]
    end
  end
end
find_strongest_paths() click to toggle source
# File lib/vote/schulze/basic.rb, line 47
def find_strongest_paths # rubocop:disable Metrics/MethodLength
  @candidate_count.times do |i|
    @candidate_count.times do |j|
      next if i == j

      @candidate_count.times do |k|
        next if i == k
        next if j == k

        @play_matrix[j, k] = [
          @play_matrix[j, k],
          [@play_matrix[j, i], @play_matrix[i, k]].min
        ].max
      end
    end
  end
end