如何在javascript中使用缓冲区实现公平划分(?)?

时间:2017-07-06 17:12:37

标签: javascript algorithm division

为了解释,假设我有101个实体。这些实体都是人。

在第一个实体中,它有x个"土豆",我希望它有y土豆,现在我将以950为例,故意选择比1000更尴尬的数字进行测试

var personOne = {
     ...
     potatoes: 100
}

我有100多个这些实体,可能有任意数量的土豆,但我设置了一个恒定的缓冲区,至少100为了例子 - 必须留在每个人。

这意味着对于所有超过100的实体,我将从它们中取出一些 - 我希望这些实体在所有实体中按比例共享,因此850不能从前两个或三个中获取,但所有那些能够提供这样数额的人都取得了10或5个。

任何方法的想法?

可选:我使用的土地多于一个土豆"属性,但我计划循环遍历每个类型并重新使用我找到的方法。我不确定这是否会影响答案。

重要/简化
一个权利是拉土豆"在所有其他实体中,它们并未在所有实体中均匀分布 - 它们被带到一个实体。我只是不想以与其他所有100个实体不成比例的方式来做这件事。

这比削减蛋糕更具税收。我正在努力谷歌或想到数学问题的正确名称。

1 个答案:

答案 0 :(得分:1)

我希望这次我能理解这个问题。我会计算获得所需马铃薯量所需的多余马铃薯的百分比,并计算每个参与者多余马铃薯的百分比,或者如果总量不够,则计算所有马铃薯的百分比。

这是一些澄清的演示代码。它可能过于冗长,但只应该用来表明意图。我假设有一个非常精确的土豆切割机,因为没有规定如何处理圆角。产出是参与者在重新分配之前和之后的土豆。我将NUMBER_OF_PARTICIPANTS设置为4,因此输出有点可读。

const MAXIMUM_START_POTATOES = 1234;
const MINIMUM_KEPT_POTATOES = 100;
const ENTITY_TAKING_POTATOES = 0;
const DESIRED_POTATOES = 950;
const NUMBER_OF_PARTICIPANTS = 4;

//generate NUMBER_OF_PARTICIPANTS entities with random amount of potatoes
let entities = [];
for (let i = 0; i < NUMBER_OF_PARTICIPANTS; i++) {
  entities.push(Math.floor(Math.random() * (MAXIMUM_START_POTATOES + 1)));
}

console.log(entities);

let required_potatoes = DESIRED_POTATOES - entities[ENTITY_TAKING_POTATOES];

if (required_potatoes <= 0) console.log("nothing to do.");
else {
  let excess_potatoes = 0;
  //Sum excess available potatoes
  for (let i = 0; i < NUMBER_OF_PARTICIPANTS; i++) {
    if (i === ENTITY_TAKING_POTATOES) continue;
    excess_potatoes += Math.max(0, entities[i] - MINIMUM_KEPT_POTATOES);
  }

  if (excess_potatoes < required_potatoes) {
    //just take all excess potatoes
    for (let i = 0; i < NUMBER_OF_PARTICIPANTS; i++) {
      if (i === ENTITY_TAKING_POTATOES) continue;
      entities[i] = Math.min(entities[i], MINIMUM_KEPT_POTATOES);
    }
    entities[ENTITY_TAKING_POTATOES] += excess_potatoes;
  } else {
    //calculate percentage of the excess potatoes that is needed
    let percentage_required = required_potatoes / excess_potatoes;
    //Take that percentage off every participant's excess potatoes
    for (let i = 0; i < NUMBER_OF_PARTICIPANTS; i++) {
      if (i === ENTITY_TAKING_POTATOES) continue;
      entities[i] -= Math.max(0, entities[i] - MINIMUM_KEPT_POTATOES) *  percentage_required;
    }
    //Assume double precision is enough for this to never be an issue
    entities[ENTITY_TAKING_POTATOES] = DESIRED_POTATOES;
  }
  console.log(entities);
}