Php 合并两个数组,使整数值尽可能接近相等

Php 合并两个数组,使整数值尽可能接近相等,php,algorithm,sorting,math,distribution,Php,Algorithm,Sorting,Math,Distribution,在仓库之间分配库存的应用程序 我有两个数组 有一个仓库列表和当前数量:这可以是一个或多个位置的动态列表 [ ['location_name' => 'Toronto', 'current_qty' => 3], ['location_name' => 'Mississauga','current_qty' => 7], ['location_name' => 'London', 'current_qty' =>

在仓库之间分配库存的应用程序

我有两个数组

有一个仓库列表和当前数量:这可以是一个或多个位置的动态列表

[
    ['location_name' => 'Toronto',    'current_qty'   => 3],
    ['location_name' => 'Mississauga','current_qty'   => 7],
    ['location_name' => 'London',     'current_qty'   => 5],
]
另一个阵列具有将投入的库存量:

[
     'qty' => 5
]
并希望在各个位置之间分配数量,以便每个位置的当前数量几乎相等。因此,我们希望返回一个数组,其中包含需要添加到每个位置的数字。比如:在这里,5个人中有3个去了多伦多,2个去了伦敦。所以可以看出,在最近的均衡之后,剩余的分布可以随机进行

[
    ['location_name' => 'Toronto',    'add_qty'   => 3],
    ['location_name' => 'Mississauga','add_qty'   => 0],
    ['location_name' => 'London',     'add_qty'   => 2],
]

只是无法理解这个算法的逻辑。我真的很感激你的指点。非常感谢。

我会这样做,但不确定是否有任何性能问题。我不知道你的数据集有多大

$locations = [
    ['location_name' => 'Toronto', 'current_qty' => 3, 'add_qty' => 0],
    ['location_name' => 'Mississauga', 'current_qty' => 7, 'add_qty' => 0],
    ['location_name' => 'London', 'current_qty' => 5, 'add_qty' => 0],
];

$supplies = 5;

// This function sorts locations, by comparing the sum of the current quantity and the quantity the location will get.
$locationsByQuantityAscending = function ($locationA, $locationB) {
    return ($locationA['current_qty'] + $locationA['add_qty']) - ($locationB['current_qty'] + $locationB['add_qty']);
};

// Sort the locations, getting the ones with the lowest quantity first.
usort($locations, $locationsByQuantityAscending);

// Keep dividing, until we're out of supplies
while ($supplies > 0) {
    $locations[0]['add_qty']++; // Add one to the location with the lowest supplies
    $supplies--; // Decrease the supplies by one
    usort($locations, $locationsByQuantityAscending); // Sort the locations again.
}

print_r($locations);
最后,这将输出:

Array
(
    [0] => Array
        (
            [location_name] => Toronto
            [current_qty] => 3
            [add_qty] => 3
        )

    [1] => Array
        (
            [location_name] => London
            [current_qty] => 5
            [add_qty] => 2
        )

    [2] => Array
        (
            [location_name] => Mississauga
            [current_qty] => 7
            [add_qty] => 0
        )

)
如果你真的需要表现,你也可以按当前数量对位置进行一次排序。然后继续添加到第一个位置,直到其库存高于第二个位置。然后,直到第二个位置的数量高于第三个位置,将一个添加到第一个和第二个位置,以此类推

我认为这会更有效,因为你不必对所有地点进行排序X乘以要分配的供应数量X。我将把实现留给您


提示:have

我会这样做,但不确定是否存在任何性能问题。我不知道你的数据集有多大

$locations = [
    ['location_name' => 'Toronto', 'current_qty' => 3, 'add_qty' => 0],
    ['location_name' => 'Mississauga', 'current_qty' => 7, 'add_qty' => 0],
    ['location_name' => 'London', 'current_qty' => 5, 'add_qty' => 0],
];

$supplies = 5;

// This function sorts locations, by comparing the sum of the current quantity and the quantity the location will get.
$locationsByQuantityAscending = function ($locationA, $locationB) {
    return ($locationA['current_qty'] + $locationA['add_qty']) - ($locationB['current_qty'] + $locationB['add_qty']);
};

// Sort the locations, getting the ones with the lowest quantity first.
usort($locations, $locationsByQuantityAscending);

// Keep dividing, until we're out of supplies
while ($supplies > 0) {
    $locations[0]['add_qty']++; // Add one to the location with the lowest supplies
    $supplies--; // Decrease the supplies by one
    usort($locations, $locationsByQuantityAscending); // Sort the locations again.
}

print_r($locations);
最后,这将输出:

Array
(
    [0] => Array
        (
            [location_name] => Toronto
            [current_qty] => 3
            [add_qty] => 3
        )

    [1] => Array
        (
            [location_name] => London
            [current_qty] => 5
            [add_qty] => 2
        )

    [2] => Array
        (
            [location_name] => Mississauga
            [current_qty] => 7
            [add_qty] => 0
        )

)
如果你真的需要表现,你也可以按当前数量对位置进行一次排序。然后继续添加到第一个位置,直到其库存高于第二个位置。然后,直到第二个位置的数量高于第三个位置,将一个添加到第一个和第二个位置,以此类推

我认为这会更有效,因为你不必对所有地点进行排序X乘以要分配的供应数量X。我将把实现留给您


提示:如果性能非常关键,并且输入数据通常比此处显示的数据大,例如,要分配的位置或数量要多得多,则使用

。您可能需要考虑使用:

例如:

<?php

$helper = new class extends SplMinHeap
{
    public function compare($a, $b): int
    {
        return ($b['current_qty'] + $b['add_qty']) <=> ($a['current_qty'] + $a['add_qty']);
    }
};

$locations = [
    ['location_name' => 'Toronto',     'current_qty' => 3, 'add_qty' => 0],
    ['location_name' => 'Mississauga', 'current_qty' => 7, 'add_qty' => 0],
    ['location_name' => 'London',      'current_qty' => 5, 'add_qty' => 0],
];

foreach ($locations as $entry) {
    $helper->insert($entry);
}

$qty = 10000;
while ($qty-- > 0) {
    $min = $helper->extract();
    $min['add_qty']++;

    $helper->insert($min);
}

print_r(iterator_to_array($helper));

如果性能非常关键,且输入数据通常比此处显示的数据大,例如,要分配的位置或数量要多得多。您可能需要考虑使用:

例如:

<?php

$helper = new class extends SplMinHeap
{
    public function compare($a, $b): int
    {
        return ($b['current_qty'] + $b['add_qty']) <=> ($a['current_qty'] + $a['add_qty']);
    }
};

$locations = [
    ['location_name' => 'Toronto',     'current_qty' => 3, 'add_qty' => 0],
    ['location_name' => 'Mississauga', 'current_qty' => 7, 'add_qty' => 0],
    ['location_name' => 'London',      'current_qty' => 5, 'add_qty' => 0],
];

foreach ($locations as $entry) {
    $helper->insert($entry);
}

$qty = 10000;
while ($qty-- > 0) {
    $min = $helper->extract();
    $min['add_qty']++;

    $helper->insert($min);
}

print_r(iterator_to_array($helper));

@鲁克,谢谢你的评论。这就是逻辑。均匀分布。您可以使用1.的伪代码。。n:添加数量+当前数量的当前最小值添加1?!这在很大程度上取决于近似相等的度量。我假设你想最小化数组的排列,排列为maxarr minarr?@ruakh这是增加的数量,如:3+3,7+0,5+2,6,7,7,如此接近相等。@Yoshi:哦,我明白了。谢谢@鲁克,谢谢你的评论。这就是逻辑。均匀分布。您可以使用1.的伪代码。。n:添加数量+当前数量的当前最小值添加1?!这在很大程度上取决于近似相等的度量。我假设你想最小化数组的排列,排列为maxarr minarr?@ruakh这是增加的数量,如:3+3,7+0,5+2,6,7,7,如此接近相等。@Yoshi:哦,我明白了。谢谢谢谢你的回复@yoshi。这个解决方案非常干净。谢谢你的帮助。谢谢你的回复@yoshi。这个解决方案非常干净。谢谢你的帮助。谢谢你的回复。这个解决方案可以完成这项工作。但我认为@yoshi的解决方案会更有效。谢谢你的时间。谢谢你的回复。这个解决方案可以完成这项工作。但我认为@yoshi的解决方案会更有效。谢谢你的时间。