合并两个数组以使整数值尽可能接近

时间:2019-03-13 19:09:11

标签: php algorithm sorting math distribution

申请在仓库之间分配库存

我有两个数组

一个具有仓库列表以及当前数量:(可以是动态的,具有一个或多个位置)

[
    ['location_name' => 'Toronto',    'current_qty'   => 3],
    ['location_name' => 'Mississauga','current_qty'   => 7],
    ['location_name' => 'London',     'current_qty'   => 5],
]

Other数组具有要输入的库存量:

[
     'qty' => 5
]

并希望在位置之间分配数量,以使每个位置的当前数量彼此接近。因此,要返回一个数组,其中包含需要添加到每个位置的数字。像:在这里,有5名中的到多伦多,有2名到伦敦。因此可以看出,在最接近的均衡之后,其余分布可以随机进行。

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

而且Just无法弄清楚该算法的逻辑。真的很感谢任何指针。非常感谢。

2 个答案:

答案 0 :(得分:3)

我会这样做,不确定所有性能问题。我不知道您的数据集有多大。

$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是要划分的耗材数量)。我将把实施留给您。

提示:拥有a look at recursive functions

答案 1 :(得分:1)

如果性能至关重要,则输入数据通常会更大,然后在此处显示(例如,更多的位置或更多的分布数量)。您可能要考虑使用SplMinHeap

例如:

<?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));

https://3v4l.org/nDOY8