- # The recursion ends if there is nothing to delete
- return matrix, keys if delete.empty?
-
- delete.reverse.each do |i|
- matrix, keys = delete_row(matrix, keys, i)
+ ##
+ # Removes a delete_index'th player and returns a new object.
+ #
+ def delete_row(delete_index)
+ copied_cols = []
+ (0...size).each do |i|
+ next if i == delete_index
+ row = @matrix.get_row(i) # get_row returns a copy of the row
+ row.delete_at(delete_index)
+ copied_cols << row
+ end
+ new_matrix = Matrix::Int[*copied_cols]
+ new_keys = @keys.clone
+ new_keys.delete_at(delete_index)
+ return WinLossMatrix.new(new_keys, new_matrix)
+ end
+
+ ##
+ # Removes players in a rows; [1,3,5]
+ #
+ def delete_rows(rows)
+ obj = self
+ rows.sort.reverse.each do |index|
+ obj = obj.delete_row(index)
+ end
+ obj
+ end
+
+ ##
+ # Removes players who do not pass a criteria to be rated, and returns a new object.
+ #
+ def filter
+ $stderr.puts @keys.inspect if $DEBUG
+ $stderr.puts @matrix.inspect if $DEBUG
+ delete = []
+ (0...size).each do |i|
+ row = @matrix.row(i)
+ col = @matrix.col(i)
+ win = row.sum
+ loss = col.sum
+ if win < 1 || loss < 1 || win + loss < $GAMES_LIMIT
+ delete << i
+ end
+ end
+
+ # The recursion ends if there is nothing to delete
+ return self if delete.empty?
+
+ new_obj = delete_rows(delete)
+ new_obj.filter
+ end
+
+ ##
+ # Cuts self into connecting groups such as each player in a group has at least
+ # one game with other players in the group. Returns them as an array.
+ #
+ def connected_subsets
+ g = RGL::AdjacencyGraph.new
+ (0...size).each do |k|
+ (0...size).each do |i|
+ next if k == i
+ if @matrix[k,i] > 0
+ g.add_edge(k,i)
+ end
+ end
+ end
+
+ subsets = []
+ g.each_connected_component do |c|
+ new_keys = []
+ c.each do |v|
+ new_keys << keys[v.to_s.to_i]
+ end
+ subsets << new_keys
+ end
+
+ subsets = subsets.sort {|a,b| b.size <=> a.size}
+
+ result = subsets.collect do |keys|
+ matrix =
+ Matrix::Int[*
+ ((0...keys.size).collect do |k|
+ p1 = @keys.index(keys[k])
+ ((0...keys.size).collect do |j|
+ if k == j
+ 0
+ else
+ p2 = @keys.index(keys[j])
+ @matrix[p1][p2]
+ end
+ end)
+ end)]
+ WinLossMatrix.new(keys, matrix)
+ end
+
+ return result
+ end
+
+ def to_s
+ "size : #{@keys.size}" + "\n" +
+ @keys.inspect + "\n" +
+ @matrix.inspect