Sha256: 91581d83080b9a48aa772d85feeed0a936d41b0d0ec99c7a1b12304eea8c9182

Contents?: true

Size: 1.09 KB

Versions: 2

Compression:

Stored size: 1.09 KB

Contents

module Apportion
  module Algorithm
    # Selects the next recipient
    module EqualProportions

      BIG_FIXNUM = 2 ** 30

      module_function

      # Selects the next recipient by sorting the equal proportions rank-index of the recipients
      #
      # see Balinski, M. and H. Young, The Quota Method of Apportionment, Amer. Math. Monthly 82 (1975) 701-730.
      #
      # @param weights [Hash] relative integer proportions
      # @param portions [Hash]
      # @return [Symbol] recipient having the highest equal proportions rank-index
      # @example
      #   next_recipient({a: 41, b: 32, c: 27}, {a: 4, b: 3, c: 2})
      #   # => :c

      def next_recipient(weights, portions)
        weights.max_by { |k, v| recipient_rank(v, portions[k]) }[0]
      end

      def recipient_rank(weight, portion)
        return zero_rank(weight) if portion == 0
        weight / Math.sqrt(portion * (portion + 1)).to_f
      end

      # protect from division by zero
      def zero_rank(weight)
        weight * BIG_FIXNUM
      end

      private_class_method :recipient_rank,
        :zero_rank
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
apportion-0.0.2 lib/apportion/algorithm/equal_proportions.rb
apportion-0.0.1 lib/apportion/algorithm/equal_proportions.rb