Skip to content

Library: apportion()

Eugene Lazutkin edited this page Jul 2, 2018 · 6 revisions

apportion() module is a function, which distributes a given number of whole items according to a list of fractional buckets using a given quantum of distribution so the total error is minimized and the exact number of items is assigned to buckets. This feat is achieved using the Hamiltons algorithm.

Usage

In a module-enabled environment (like Babel) it can be accessed like that:

import apportion from '@researchnow/reno/src/utils/apportion';

In global-based environments (like a browser) it is frequently mapped to Reno.utils.apportion.

apportion(total, buckets, quantum=1)

The function takes the following arguments:

  • total is a positive integer, which should be distributed by buckets. If quantum is not (the default),totalshould be divisible byquantum` without a reminder.
  • buckets is an array of positive numbers, which indicate a relative proportion of total, which should be allocated to a bucket. There are no special requirements for the bucket numbers.
    • Example: [2, 3, 5] is the same as [0.2, 0.3, 0.5] because only their relative ratio is used.
  • quantum is a positive integer, which indicates an allocation quantum. The default: 1.
    • Example: if it is 10, total is going to be distributed in tens.

The returned value is an array of positive integers. It has the same length as buckets and each item corresponds to a bucket item with the same index.

Examples

Equivalency of quantum:

assert(total % quantum === 0);
isEqual(apportion(total, buckets, quantum),
  apportion(total / quantum, buckets).map(value => quantum * value)) === true

The total sum of returned items equals total:

apportion(total, buckets, quantum).reduce((acc, value) => acc + value, 0) === total

Each allocated item is divisible by quantum without a reminder:

apportion(total, buckets, quantum).every(value => value % quantum === 0) === true

Clone this wiki locally