按比例分配整个项目

时间:2013-09-21 05:05:27

标签: java python math pseudocode

目标:

说我在水果种植园有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);

我会让[水果]的确切数字由给定的boolean Roundup确定,该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; } } 用随机布尔值初始化并在处理完每个水果后切换。

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

{{1}}

我遇到的问题:

  • 所有项目中只有3/4是分发
  • 当我有一定数量的水果时,布尔值会在每个新人的开头得到相同的值。

感谢您对此进行调查!

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

2 个答案:

答案 0 :(得分: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.
        }
    }
}

答案 1 :(得分: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])