2

目標:

果樹園に X 人の労働者がいるとします。プランテーションでは、リンゴ、ナシ、ブドウを栽培しています。

一日の終わりに、職長は各労働者を比率で等級付けします。すべての比率の合計は 100 です。比率は、1 日の終わりに労働者の間で果物を分配する方法を決定するためにあります。

すべてのワーカー間で果物を分配して、それぞれが公平に分配されるようにするにはどうすればよいですか (整数除算を考慮して特定のランダム性内で)。果物全体のみが分割されるため、整数の結果が得られます。そして、すべての果物を配らなければなりません。

私は約 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、ランダムなブール値で初期化され、果物が処理されるたびに切り替えられる 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 に答える