为了解释,假设我有101个实体。这些实体都是人。
在第一个实体中,它有x个"土豆",我希望它有y土豆,现在我将以950为例,故意选择比1000更尴尬的数字进行测试
var personOne = {
...
potatoes: 100
}
我有100多个这些实体,可能有任意数量的土豆,但我设置了一个恒定的缓冲区,至少100为了例子 - 必须留在每个人。
这意味着对于所有超过100的实体,我将从它们中取出一些 - 我希望这些实体在所有实体中按比例共享,因此850不能从前两个或三个中获取,但所有那些能够提供这样数额的人都取得了10或5个。
任何方法的想法?
可选:我使用的土地多于一个土豆"属性,但我计划循环遍历每个类型并重新使用我找到的方法。我不确定这是否会影响答案。
重要/简化
一个权利是拉土豆"在所有其他实体中,它们并未在所有实体中均匀分布 - 它们被带到一个实体。我只是不想以与其他所有100个实体不成比例的方式来做这件事。
这比削减蛋糕更具税收。我正在努力谷歌或想到数学问题的正确名称。
答案 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);
}