【问题标题】:PHP - how to distribute items into two arrays base on valuesPHP - 如何根据值将项目分配到两个数组中
【发布时间】:2015-05-07 17:15:48
【问题描述】:

我有这个数组,

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => Item 1
            [price] => 10
            [weight] => 200
        )

    [1] => Array
        (
            [id] => 2
            [name] => Item 2
            [price] => 100
            [weight] => 20
        )

    [2] => Array
        (
            [id] => 3
            [name] => Item 3
            [price] => 30
            [weight] => 300
        )

    [3] => Array
        (
            [id] => 4
            [name] => Item 4
            [price] => 20
            [weight] => 500
        )

    [4] => Array
        (
            [id] => 6
            [name] => Item 6
            [price] => 40
            [weight] => 10
        )

    [5] => Array
        (
            [id] => 7
            [name] => Item 7
            [price] => 200
            [weight] => 10
        )

)

我想把它一分为二,所以我得到了这个结果,

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [name] => Item 1
                    [price] => 10
                    [weight] => 200
                )

            [1] => Array
                (
                    [id] => 3
                    [name] => Item 3
                    [price] => 30
                    [weight] => 300
                )

            [2] => Array
                (
                    [id] => 7
                    [name] => Item 7
                    [price] => 200
                    [weight] => 10
                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [id] => 4
                    [name] => Item 4
                    [price] => 20
                    [weight] => 500
                )

            [1] => Array
                (
                    [id] => 6
                    [name] => Item 6
                    [price] => 40
                    [weight] => 10
                )

            [2] => Array
                (
                    [id] => 2
                    [name] => Item 2
                    [price] => 100
                    [weight] => 20
                )

        )

)

有什么想法吗?

这其中的难点在于,每个包裹的总价不得超过250。而每个包裹的总重量必须尽可能均匀(即使认为不可能)。你可以在这张照片中看到我的意思,

name     weight  price
                          package 1
Item 1   200     10
Item 3   300     30
Item 7   10      200
(total)  510     240

                          package 2    
Item 4   500     20
Item 6   10      40
Item 2   20      100
(total)  530     160

那么是否可以在这两个包裹之间移动物品,以便总重量“均匀”分布?如果不手动“移动”它们,似乎无法实现。我想不出通过自动程序实现目标的任何方法。可以吗?

【问题讨论】:

  • 听起来像是一个动态规划问题
  • a dynamic programming problem 是什么意思?
  • 你搞定了吗...?

标签: php arrays multidimensional-array shopping-cart


【解决方案1】:

它与 PHP 或数组无关。据我了解你的问题是Multiple knapsack problem。所以这是很多数学问题(请参阅一些解决方案 here),也许最简单的方法是以编程方式检查所有可能的变体。

【讨论】:

    【解决方案2】:

    按权重对数组进行排序

    usort($array, function($a, $b) {return $a['weight']>$b['weight'];});
    

    我们用价格和重量计数器初始化我们的结果表

    $sum=Array(
        Array("weight" => 0, "price" => 0, "res" => Array()),
        Array("weight" => 0, "price" => 0, "res" => Array()));
    

    然后我们在数组上循环

    while ($obj=array_pop($array)) {
    

    我们选择较低的结果数组

        $ind=($sum[0]['weight']<$sum[1]['weight']) ? 0 : 1;
    

    除非达到最大数量

        if ($sum[$ind]['price']+$obj['price']>250) {
                $ind=1-$ind;
    
                ## object will be skipped if it can't fit in the allowed amount
                if ($sum[$ind]['price']+$obj['price']>250) continue;
        }
    

    然后我们填充它

        array_push($sum[$ind]['res'], $obj);
        $sum[$ind]['weight']+=$obj['weight'];
        $sum[$ind]['price']+=$obj['price'];
    
    }
    
    print_r($sum);
    

    结果如预期:

     Array
     (
         [0] => Array
             (
                 [weight] => 510
                 [price] => 240
                 [res] => Array
                     (
                         [0] => Array
                             (
                                 [id] => 3
                                 [name] => Item 3
                                 [price] => 30
                                 [weight] => 300
                             )
    
                         [1] => Array
                             (
                                 [id] => 1
                                 [name] => Item 1
                                 [price] => 10
                                 [weight] => 200
                             )
    
                         [2] => Array
                             (
                                 [id] => 7
                                 [name] => Item 7
                                 [price] => 200
                                 [weight] => 10
                             )
    
                     )
    
             )
    
         [1] => Array
             (
                 [weight] => 530
                 [price] => 160
                 [res] => Array
                     (
                         [0] => Array
                             (
                                 [id] => 4
                                 [name] => Item 4
                                 [price] => 20
                                 [weight] => 500
                             )
    
                         [1] => Array
                             (
                                 [id] => 2
                                 [name] => Item 2
                                 [price] => 100
                                 [weight] => 20
                             )
    
                         [2] => Array
                             (
                                 [id] => 6
                                 [name] => Item 6
                                 [price] => 40
                                 [weight] => 10
                             )
    
                     )
    
             )
    
     )
    

    【讨论】:

    • 传入的数组是排序的,你取值从大到小:500,300,200,30,20,10,10。这一行选择了权重最低的数组...
    • 感谢 Adam 解释该行。再说一次,你为什么用array_pop?为什么$ind=1-$ind;?你介意再解释一下吗?
    • 我知道array_pop 是从数组中删除最后一项。但我不明白在这个解决方案中如何从数组中删除最后一项......
    • 数组是排序好的,所以array_pop会得到最大权重的item。首先获得最大权重,您将能够在两个阵列的最后获得更接近的权重。 $ind=1-$ind 反转所选项目:0 变为 1,1 变为 0,以防它值太多
    • 感谢 Adam 的进一步解释。
    猜你喜欢
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 2019-09-06
    • 1970-01-01
    • 2019-09-04
    • 2023-03-13
    相关资源
    最近更新 更多