## the CloneproofSSDVote classes but should not be used directly.
class CondorcetVote < ElectionVote
-
- attr_accessor :results
-
+
def initialize(votes=nil)
unless defined?(@candidates)
@candidates = Array.new
end
end
super(votes)
- @results = Array.new
end
def tally_vote(vote=nil)
- vote.each_with_index do |winner, index|
+ vote.each_with_index do |winners, index|
if vote.flatten.length < @candidates.length
- implied_losers = @candidates.select { |c| not vote.include?(c) }
+ implied_losers = @candidates.select { |c| not vote.flatten.include?(c) }
vote.push(implied_losers)
end
if vote.length - 1 == index
place = [place] unless place.class == Array
place.each do |loser|
+ winners = [winners] unless winners.class == Array
+ next if winners.include?(loser)
+ winners.each do |winner|
+ @votes[winner] = Hash.new unless @votes.has_key?(winner)
+ @votes[loser] = Hash.new unless @votes.has_key?(loser)
+
+ if @votes[winner].has_key?(loser)
+ @votes[winner][loser] += 1
+ else
+ @votes[winner][loser] = 1
+ end
- @votes[winner] = Hash.new unless @votes.has_key?(winner)
- @votes[loser] = Hash.new unless @votes.has_key?(loser)
-
- if @votes[winner].has_key?(loser)
- @votes[winner][loser] += 1
- else
- @votes[winner][loser] = 1
+ # make sure we have a comparable object
+ @votes[loser][winner] = 0 unless @votes[loser].has_key?( winner )
end
-
- # make sure we have a comparable object
- @votes[loser][winner] = 0 unless @votes[loser].has_key?( winner )
end
end
end
end
- def results
- if @results.size < 2 && (not @candidates.empty?)
- tabulate
- end
- @results
- end
-
- def result
- find_only_winner unless @winner
- @winner
- end
-
protected
def verify_vote(vote=nil)
vote.instance_of?( Array ) and
vote == vote.uniq
end
-
- def tabulate
- find_only_winner unless @winner
- until @candidates.empty?
- aResult = resultFactory( self )
- @results << aResult.winners
- filter_out(aResult)
- end
- end
-
- def find_only_winner
- @winner = resultFactory( self )
- @results << @winner.winners
- filter_out(@winner)
- end
-
end
class PureCondorcetVote < CondorcetVote
- def resultFactory(init)
- PureCondorcetResult.new(init)
+ def result
+ PureCondorcetResult.new(self)
end
end
class CloneproofSSDVote < CondorcetVote
- def resultFactory(init)
- CloneproofSSDResult.new(init)
+ def result
+ CloneproofSSDResult.new(self)
end
-
end
## directly.
class CondorcetResult < ElectionResult
+ attr_reader :matrix
+
def initialize(voteobj=nil)
unless voteobj and voteobj.kind_of?( CondorcetVote )
raise ArgumentError, "You must pass a CondorcetVote array.", caller
end
super(voteobj)
+ @matrix = voteobj.votes
+ end
+
+ def victories_and_ties
+ victories_ties = {}
+ candidates = @matrix.keys.sort
+
+ candidates.each do |candidate|
+ candidates.each do |challenger|
+ next if candidate == challenger
+ diff = @matrix[candidate][challenger] - @matrix[challenger][candidate]
+ victories_ties[candidate] = {} unless victories_ties.key?(candidate)
+ if diff >= 0
+ victories_ties[candidate][challenger] = diff
+ end
+ end
+ end
+
+ return victories_ties
end
- protected
+ def ranked_candidates
+ if not defined?(@ranked_candidates)
+ @ranked_candidates = build_ranked_candidates()
+ end
+ @ranked_candidates
+ end
+
+ protected
def defeats(candidates=nil, votes=nil)
- candidates = @election.candidates unless candidates
- votes = @election.votes unless votes
+ candidates ||= @election.candidates || []
+ # we're assumign that if there are candidates, there must be at
+ # least one vote for them
+ votes ||= @election.votes
defeats = Array.new
- candidates = [candidates] unless candidates.class == Array
candidates.each do |candidate|
candidates.each do |challenger|
next if candidate == challenger
defeats
end
+
+ def build_ranked_candidates
+ # build a lis of ranked candidates by dropping the winner and
+ # cursing
+
+ ranked_candidates = []
+
+ resultobj = self.dup
+ candidates = self.election.candidates
+
+ until candidates.empty?
+ ranked_candidates << resultobj.winners
+
+ new_voteobj = resultobj.election.dup
+ candidates = new_voteobj.candidates
+ new_voteobj.candidates.delete_if {|x| resultobj.winners.include?(x)}
+ resultobj = new_voteobj.result
+ end
+
+ ranked_candidates
+ end
end
end
protected
-
+
def condorcet
votes = @election.votes
candidates = @election.candidates
+ unless votes.length > 0 and candidates.length > 0
+ return @winners=[]
+ end
+
victors = Hash.new
candidates.each do |candidate|
victors[candidate] = Array.new
def cpssd
votes = @election.votes
- candidates = *@election.candidates
+ candidates = @election.candidates.dup
def in_schwartz_set?(candidate, candidates, transitive_defeats)
candidates.each do |challenger|