2

目标:

假设我在水果种植园有 X 个工人。他们在种植园种植苹果、梨和葡萄。

在一天结束时,工头按比例对每个工人进行评分。所有比率的总和为 100。该比率用于确定如何在一天结束时在工人之间分配水果。

我如何在所有工人之间分配水果,以便他们每个人都能得到公平的份额(在一定的随机性内考虑整数除法)。只有整个水果被分割,所以整数结果。所有的水果都必须分发出去。

我和大约 20 名工人一起做这个,所以现在这个比例大约是每名工人 0.05。

我试过的(伪代码):

for each worker:
  if applesGiven < appleStock:
    worker.give(ratio * applestock);
  if pearsGiven < pearStock:
    worker.give(ratio * pearStock);
  if grapesGiven < grapeStock:
    worker.give(ratio * grapeStock);

我会让他们给出的 [fruit] 的确切数量由一个boolean Roundup用随机布尔值初始化并在处理完每个水果后切换的 a 确定。

我尝试过的(完整代码):

public void balance() {
        boolean roundUp = random.nextBoolean();
        for (Employee e : employees) {
            double ratio = e.getRatio();
            if (applePlanned < appleNeeded) {
                int apple;
                if (roundUp) {
                    apple = (int) Math.ceil(ratio * appleNeeded);
                } else {
                    apple = (int) Math.floor(ratio * appleNeeded);
                }
                e.setrapple(apple);
                applePlanned += apple;
                roundUp = !roundUp;
            }

            if (pearPlanned < pearNeeded) {
                int pear;
                if (roundUp) {
                    pear = (int) Math.ceil(ratio * pearNeeded);
                } else {
                    pear = (int) Math.floor(ratio * pearNeeded);
                }
                e.setrpear(pear);
                pearPlanned += pear;
                roundUp = !roundUp;
            }

            if (grapePlanned < grapeNeeded) {
                int grape;
                if (roundUp) {
                    grape = (int) Math.ceil(ratio * grapeNeeded);
                } else {
                    grape = (int) Math.floor(ratio * grapeNeeded);
                }
                e.setrgrape(grape);
                grapePlanned += grape;
                roundUp = !roundUp;
            }
}

我遇到的问题:

  • 只有大约 3/4 的物品被分发
  • 当我有偶数个水果时,布尔值在每个新人开始时获得相同的值。

感谢您对此进行调查!

请用java、python或伪代码回答,这就是我能读到的。

4

2 回答 2

1

这不是特别有用,因为我过度使用了 Numpy,但我会分享,因为它是相关的

import numpy
import random

# apple, bannana, grapes, guava, melon, pear
fruits = numpy.array([100, 150, 175, 200, 230, 247])

# Bill, Bob, Dan, Fred, Joe
ratios = numpy.array([21, 7, 32, 13, 27])

# Original fruit amount for each worker: 0
worker_fruits = numpy.zeros((5, 6), dtype=int)
worker_lucky  = numpy.zeros((5, 6), dtype=float)

# For each worker with his ratio
for worker, lucky, ratio in zip(worker_fruits, worker_lucky, ratios):
    # Give him fruits, storing partials as weighting
    to_give = (ratio * fruits) / 100
    lucky  += to_give % 1
    worker += to_give

# Calculate how much we have left over
spares = fruits - worker_fruits.sum(axis=0)

# Share it out in a weighted distribution
for fruit, lucky, numspare in zip(worker_fruits.transpose(), worker_lucky.transpose(), spares):
    if numspare:
        indexes = numpy.arange(len(fruit))
        add_to = numpy.random.choice(indexes, replace=False, size=numspare, p=lucky/numspare)
        fruit[add_to] += 1

# Our results!
worker_fruits
#>>> array([[21, 31, 36, 42, 49, 51],
#>>>        [ 7, 11, 12, 14, 16, 18],
#>>>        [32, 48, 56, 64, 74, 79],
#>>>        [13, 19, 23, 26, 29, 32],
#>>>        [27, 41, 48, 54, 62, 67]])

# Proof it's perfectly shared
fruits - worker_fruits.sum(axis=0)
#>>> array([0, 0, 0, 0, 0, 0])
于 2013-09-21T07:03:13.550 回答
1

使用双重数学,向下取整,然后根据比率随机分发剩余的水果。请注意,您可以使用面向对象和循环使这变得不那么难看,但这是一个开始。

public void distribute(int apple, int pear, int grape) {
    double total = apple + pear + grape;
    double appleRatio = apple/total;
    double pearRatio = pear/total;
    double grapeRatio = grape/total;

    // apple worker
    int appleWorkerApple = (int) (appleRatio*apple);
    int appleWorkerPear = (int) (appleRatio*pear);
    int appleWorkerGrape = (int) (appleRatio*grape);

    // pear worker
    int pearWorkerApple = (int) (pearRatio*apple);
    int pearWorkerPear = (int) (pearRatio*pear);
    int pearWorkerGrape = (int) (pearRatio*grape);

    // grape worker
    int grapeWorkerApple = (int) (grapeRatio*apple);
    int grapeWorkerPear = (int) (grapeRatio*pear);
    int grapeWorkerGrape = (int) (grapeRatio*grape);

    int appleRemain = apple - appleWorkerApple - pearWorkerApple - grapeWorkerApple;
    int pearRemain = pear - appleWorkerApple - pearWorkerApple - grapeWorkerApple;
    int grapeRemain = grape - appleWorkerApple - pearWorkerApple - grapeWorkerApple;

    Random r = new Random();
    while(appleRemain > 0 && pearRemain > 0 && grapeRemain > 0) {
        double target = r.nextDouble();
        switch(r.nextInt(3)) {
        case 0:
            if(appleRemain > 0) {
                appleRemain--
                if(target < appleRatio)
                    appleWorkerApple++;
                else if (target < appleRatio + grapeRatio)
                    pearWorkerApple++;
                else
                    grapeWorkerApple++;
            }
            break;
        case 1:
            if(grapeRemain > 0)
            // etc.
        }
    }
}
于 2013-09-21T05:31:41.633 回答