我有一个带有x个蛋糕的id的数组和另一个带有y个人ID的关联数组。我想确保每个蛋糕只有2个人享用,并且每个人都能获得相当多的蛋糕。然而,蛋糕必须保持完整(即如果每人的平均蛋糕是一小部分,则该部分将针对某些部分进行四舍五入,而针对其他部分进行下调)。任何人都不能被分配两次相同的蛋糕。例如:
$cake = array(''1','2')
$people = array('1','2','3')
为了做到这一点,我希望创建一个新数组,其中每一行代表一个蛋糕人分配。由于每个蛋糕被分配给两个人,因此该表中的行数应该是蛋糕数量的两倍。这个问题不会有1个解决方案,但上述示例的解决方案是:
$cake_person = array(
'1'=>array('1', '1'),
'2'=>array('1', '2'),
'3'=>array('2', '2'),
'4'=>array('2', '3'),
)
请注意,1号和3号人员正在输掉,但那是因为没有更多蛋糕可供使用了!每个蛋糕必须给两次。
如何为更多人和蛋糕可靠地生成这样的解决方案?
实施了Artefacto的有用回复之后,我决定在下面发布我的代码,万一其他人发现它有用。
数据
//Create people array with 25 people
$people = range(1,25);
//Create cake array with 77 cakes
$cake = range(1,77);
代码
$people_cakes = array();
$totalPeople = count($people);
$idp = 0;
foreach($cakes as $cake) {
$id1 = $idp % $totalPeople;
$id2 = ($idp + 1) % $totalPeople;
$people_cakes[] = array($people[$id + 1], $cake);
$people_cakes[] = array($people[$id + 2], $cake);
$idp = $idp + 2;
}
答案 0 :(得分:2)
实施一种迭代蛋糕并按顺序分配部分的算法:
这不会给出与您的示例相同的结果(第1人将获得两半),但这不是必需的。
示例脚本:
$cakes = range(1, 77);
$people = range(1,25);
$result = array();
$idp = 0;
foreach ($cakes as $cid) {
$result[] = array(
'cake_id' => $cid,
'person_id' => $people[$idp % count($people)],
);
$result[] = array(
'cake_id' => $cid,
'person_id' => $people[($idp+1) % count($people)]
);
$idp += 2;
}
$total = array();
foreach ($result as $a) {
if (!array_key_exists($a['person_id'], $total)) {
$total[$a['person_id']] = 0;
}
$total[$a['person_id']]++;
}
var_dump($total); //gives the number of halves per person
答案 1 :(得分:0)
我没有测试过,但我认为它应该可行
我们以77个蛋糕和25个人为例。
如果每个蛋糕被2个人吃掉,要喂25个人就需要12.5个蛋糕。我们会慷慨并使其成为13(即使用ceiling
)
所以,你有77个蛋糕,这意味着你可以给每个人77 / 13 = 5.92
个蛋糕。
我们将其向下舍入并获得5.为了概括,我将称之为minCakes
所以在这一点上你知道每个人都应该至少 minCakes
蛋糕。还有一些你可以重新分配。
所以现在你一次迭代2个人和
从1到minCakes
从minCakes + 1
到minCakes * 2 + 1
...
在我们的案例中,25岁的人独自:(,所以他会得到他的minCakes
蛋糕,并将1号人的一半给minCakes
。
基本上人n和n + 1将有minCakes * floor(n/2) + 1
到minCakes * floor(n/2) + minCakes
如果人数是奇数,则您需要单独处理最后一个人,因为您必须将另一半蛋糕分发给其他minCakes
人。
现在是时候分发剩下的东西了。在我们的情况下,5 * 24/2 = 60
加上25人的5个蛋糕给了我们总共65个蛋糕,所以剩下77 - 65 = 12
个蛋糕。
你开始分发来自1号(如果人数是偶数的)或者像我们的情况那样从数字minCakes+1
分发那些(因为第一个已经有额外的份额)。
现在你只需要再次对人们进行迭代,并为他们分配一半蛋糕。如果你到25号就回到1。