vote-schulze 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +12 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.rubocop.yml +18 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +7 -6
- data/Gemfile.lock +53 -19
- data/LICENSE.txt +17 -16
- data/README.md +22 -31
- data/Rakefile +4 -41
- data/bin/console +15 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bin/setup +8 -0
- data/exe/vote-schulze +57 -0
- data/lib/vote.rb +2 -4
- data/lib/vote/matrix.rb +5 -7
- data/lib/vote/schulze.rb +15 -0
- data/lib/vote/schulze/basic.rb +87 -0
- data/lib/vote/schulze/input.rb +70 -0
- data/lib/vote/schulze/version.rb +7 -0
- data/lib/vote_schulze.rb +3 -0
- data/vote-schulze.gemspec +29 -61
- metadata +114 -53
- data/.document +0 -5
- data/.rvmrc +0 -2
- data/VERSION +0 -1
- data/lib/vote-schulze.rb +0 -15
- data/lib/vote/condorcet.rb +0 -7
- data/lib/vote/condorcet/schulze.rb +0 -11
- data/lib/vote/condorcet/schulze/basic.rb +0 -117
- data/lib/vote/condorcet/schulze/input.rb +0 -89
- data/lib/vote/condorcet/schulze/win_and_lost.rb +0 -14
- data/spec/spec_helper.rb +0 -12
- data/spec/vote-schulze_spec.rb +0 -9
data/.document
DELETED
data/.rvmrc
DELETED
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.2.0
|
data/lib/vote-schulze.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
# $:<<`pwd`.strip
|
4
|
-
# require 'vote-schulze'
|
5
|
-
|
6
|
-
require 'matrix'
|
7
|
-
require 'vote'
|
8
|
-
require 'vote/matrix'
|
9
|
-
|
10
|
-
autoload :Vote, 'vote'
|
11
|
-
|
12
|
-
SchulzeInput = Vote::Condorcet::Schulze::Input
|
13
|
-
SchulzeBasic = Vote::Condorcet::Schulze::Basic
|
14
|
-
SchulzeWinAndLost = Vote::Condorcet::Schulze::WinAndLost
|
15
|
-
|
data/lib/vote/condorcet.rb
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
module Vote
|
4
|
-
module Condorcet
|
5
|
-
module Schulze
|
6
|
-
|
7
|
-
class Basic
|
8
|
-
|
9
|
-
def load vote_matrix, candidate_count=nil
|
10
|
-
input = vote_matrix.is_a?(Vote::Condorcet::Schulze::Input) ? \
|
11
|
-
vote_matrix : \
|
12
|
-
Vote::Condorcet::Schulze::Input.new(
|
13
|
-
vote_matrix,
|
14
|
-
candidate_count
|
15
|
-
)
|
16
|
-
@vote_matrix = input.matrix
|
17
|
-
@candidate_count = input.candidates
|
18
|
-
@vote_count = input.voters
|
19
|
-
self
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def play
|
25
|
-
@play_matrix = ::Matrix.scalar(@candidate_count,0).extend(Vote::Matrix)
|
26
|
-
# step 1: find matches with wins
|
27
|
-
@candidate_count.times do |i|
|
28
|
-
@candidate_count.times do |j|
|
29
|
-
next if i==j
|
30
|
-
if @vote_matrix[i,j] > @vote_matrix[j,i]
|
31
|
-
@play_matrix[i,j] = @vote_matrix[i,j]
|
32
|
-
end #loop3
|
33
|
-
end #loop2
|
34
|
-
end #loop1
|
35
|
-
#step 2: find strongest pathes
|
36
|
-
@candidate_count.times do |i|
|
37
|
-
@candidate_count.times do |j|
|
38
|
-
next if i==j
|
39
|
-
@candidate_count.times do |k|
|
40
|
-
next if i==k
|
41
|
-
next if j==k
|
42
|
-
@play_matrix[j,k] = [
|
43
|
-
@play_matrix[j,k],
|
44
|
-
[ @play_matrix[j,i], @play_matrix[i,k] ].min
|
45
|
-
].max
|
46
|
-
end #loop3
|
47
|
-
end #loop2
|
48
|
-
end #loop1
|
49
|
-
end #def
|
50
|
-
|
51
|
-
|
52
|
-
def result
|
53
|
-
@result_matrix = ::Matrix.scalar(@candidate_count,0).extend(Vote::Matrix)
|
54
|
-
@result_matrix.each_with_index do |e,x,y|
|
55
|
-
next if x==y
|
56
|
-
@result_matrix[x,y] = e+1 if @play_matrix[x,y] > @play_matrix[y,x]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def rank
|
61
|
-
@ranking = @result_matrix.
|
62
|
-
row_vectors.map { |e| e.inject(0) { |s,v| s += v } }
|
63
|
-
end
|
64
|
-
|
65
|
-
def rank_abc
|
66
|
-
r = @ranking
|
67
|
-
rmax = r.max
|
68
|
-
abc = r.map{|e|
|
69
|
-
[e,(r.index(e)+65).chr] # => [int,letter]
|
70
|
-
}.
|
71
|
-
sort.reverse. # bring in correct order
|
72
|
-
map{|e| "#{e[1]}:#{rmax-e[0]+1}" } # => "letter:int"
|
73
|
-
@ranking_abc = abc
|
74
|
-
end
|
75
|
-
|
76
|
-
public
|
77
|
-
|
78
|
-
def run
|
79
|
-
play
|
80
|
-
result
|
81
|
-
rank
|
82
|
-
rank_abc
|
83
|
-
end
|
84
|
-
|
85
|
-
def vote_matrix
|
86
|
-
@vote_matrix
|
87
|
-
end
|
88
|
-
def play_matrix
|
89
|
-
@play_matrix
|
90
|
-
end
|
91
|
-
def result_matrix
|
92
|
-
@result_matrix
|
93
|
-
end
|
94
|
-
def ranks
|
95
|
-
@ranking
|
96
|
-
end
|
97
|
-
def ranks_abc
|
98
|
-
@ranking_abc
|
99
|
-
end
|
100
|
-
def voters
|
101
|
-
@vote_count
|
102
|
-
end
|
103
|
-
|
104
|
-
# All-in-One class method to get a calculated SchulzeBasic object
|
105
|
-
def self.do vote_matrix, candidate_count=nil
|
106
|
-
instance = new
|
107
|
-
instance.load vote_matrix, candidate_count
|
108
|
-
instance.run
|
109
|
-
instance
|
110
|
-
end
|
111
|
-
|
112
|
-
end #Basic
|
113
|
-
|
114
|
-
end #Schulze
|
115
|
-
end #Condorcet
|
116
|
-
end #Vote
|
117
|
-
|
@@ -1,89 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
module Vote
|
4
|
-
module Condorcet
|
5
|
-
module Schulze
|
6
|
-
|
7
|
-
class Input
|
8
|
-
|
9
|
-
def initialize vote_list, candidate_count = nil
|
10
|
-
@vote_list = vote_list
|
11
|
-
@candidate_count = candidate_count
|
12
|
-
|
13
|
-
if @candidate_count.nil?
|
14
|
-
insert_vote_file(@vote_list) if vote_list.is_a?(File)
|
15
|
-
|
16
|
-
else
|
17
|
-
@vote_matrix = ::Matrix.scalar(@candidate_count,0).extend(Vote::Matrix)
|
18
|
-
insert_vote_array(@vote_list) if vote_list.is_a?(Array)
|
19
|
-
insert_vote_string(@vote_list) if vote_list.is_a?(String)
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def insert_vote_array va
|
25
|
-
va.each do |vote|
|
26
|
-
@vote_matrix.each_with_index do |e,x,y|
|
27
|
-
next if x==y
|
28
|
-
@vote_matrix[x,y] += 1 if vote[x]>vote[y]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
@vote_count = va.size
|
32
|
-
end
|
33
|
-
|
34
|
-
def insert_vote_string vs
|
35
|
-
vote_array = []
|
36
|
-
|
37
|
-
vs.split(/\n|\n\r|\r/).each do |voter|
|
38
|
-
voter = voter.split(/=/)
|
39
|
-
vcount = (voter.size==1) ? 1 : voter[0].to_i
|
40
|
-
|
41
|
-
vcount.times do
|
42
|
-
tmp = voter.last.split(/;/)
|
43
|
-
tmp2 = []
|
44
|
-
|
45
|
-
tmp.map!{|e| [e,@candidate_count-tmp.index(e)] }
|
46
|
-
# find equal-weighted candidates
|
47
|
-
tmp.map do |e|
|
48
|
-
if e[0].size > 1
|
49
|
-
e[0].split(/,/).each do |f|
|
50
|
-
tmp2 << [f,e[1]]
|
51
|
-
end #each
|
52
|
-
else
|
53
|
-
tmp2 << e
|
54
|
-
end #if
|
55
|
-
end #tmp.map
|
56
|
-
|
57
|
-
vote_array << (tmp2.sort.map{|e| e = e[1] }) # order, strip & add
|
58
|
-
end #vcount.times
|
59
|
-
end #vs.split.each
|
60
|
-
|
61
|
-
insert_vote_array vote_array
|
62
|
-
end
|
63
|
-
|
64
|
-
def insert_vote_file vf
|
65
|
-
vf.rewind
|
66
|
-
@candidate_count = vf.first.strip.to_i #reads first line for count
|
67
|
-
@vote_matrix = ::Matrix.scalar(@candidate_count,0).extend(Vote::Matrix)
|
68
|
-
insert_vote_string vf.read # reads rest of file (w/o line 1)
|
69
|
-
vf.close
|
70
|
-
end
|
71
|
-
|
72
|
-
def matrix
|
73
|
-
@vote_matrix
|
74
|
-
end
|
75
|
-
|
76
|
-
def candidates
|
77
|
-
@candidate_count
|
78
|
-
end
|
79
|
-
|
80
|
-
def voters
|
81
|
-
@vote_count
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
data/spec/spec_helper.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
-
require 'rspec'
|
4
|
-
require 'vote-schulze'
|
5
|
-
|
6
|
-
# Requires supporting files with custom matchers and macros, etc,
|
7
|
-
# in ./support/ and its subdirectories.
|
8
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
-
|
10
|
-
RSpec.configure do |config|
|
11
|
-
|
12
|
-
end
|