商品订单拆单组合

问题:跨境电商在一个物流订单是有限制商品重量以及商品价值的,在一次性购买多个商品的时候,需要将商品拆分成多个订单,如何将挑选商品组合,才能使这个商品最合理?

实现思路:动态规划 背包问题

 有i个商品(多个商品拆分为多个数量为1),每件商品的重量为w[i]价值为v[i]

最大重量j,i个商品的最大重量为f[i][j]

状态转移方程 f[i][j]=max(f[i-1][j-w[i]]+w[i],f[i-1][j])

主要是第i个商品是否加入的的问题

加入: 背包装的重量f[i][j] =背包减去当前重量后的最大容量(f[i-1][j-w[i]])+当前背包容量(w[i])

不加入: 背包装的重量f[i][j] = f[i-1][j]

判断最大的存放在f[i][j];

有背包容量10

重量 2,2,6,5,4 

枚举j 从0->10 ,i 从1->5


如 f[5][10]=max(f[4][6]+w[5],f[4][10])

    f[4][10] =max(f[3][5]+w[4],f[3][10])

     f[4][6]=max(f[3][1]+w[4],f[3][6])  

                 。。。。

    直到获取前一个数是一个确定值   

下面是PHP 的实现代码 ,获取在不超过最大价值的情况下的最大重量组合

$weight =50;
$val = 10;
$list=[
    ['w'=>2,'v'=>8],
    ['w'=>2,'v'=>4],
    ['w'=>6,'v'=>7],
    ['w'=>5,'v'=>12],
    ['w'=>4,'v'=>17],
];
//枚举所有最大值f[i][j] 
$value=[];
//初始化 背包容量为0时候背包装的重量
for($i=0;$i<=count($list);$i++){
    $value[$i][0]=['w'=>0,'v'=>0];
}
//初始化 商品为0时候背包容量装的重量
for($j=0;$j<=$weight;$j++){
    $value[0][$j]=['w'=>0,'v'=>0];
}
for($i=1;$i<=count($list);$i++){
    for($j=1;$j<=$weight;$j++){
        $value[$i][$j]=$value[$i-1][$j];
        if($j>=$list[$i-1]['w'] ){
            $tempW = $value[$i-1][$j-$list[$i-1]['w']]['w']+$list[$i-1]['w'];
            $tempV = $value[$i-1][$j-$list[$i-1]['w']]['v']+$list[$i-1]['v'];
        }else{
            $tempW = 0;
            $tempV = 0;
        }
        //不超过最大价值,以及大于f[i-1][j]
        if($list[$i-1]['w']<=$j && $tempW>$value[$i][$j]['w'] && $tempV<$val){
            $value[$i][$j]=['w'=>$tempW,'v'=>$tempV];
        }
    }
}

$maxWeight= $value[count($list)][$weight]['w'];
//逆推选中的商品
$lastWeight=$maxWeight;
$res=[];
$i=count($list);
do{
    if(($lastWeight-$list[$i-1]['w'])>=0 &&($value[$i-1][$lastWeight-$list[$i-1]['w']]['w']+$list[$i-1]['w'])==$lastWeight){
        $lastWeight = $lastWeight-$list[$i-1]['w'];
        $res[]=$i-1;
    }
    $i--;
}while($i>0);复制代码

递归处理$list商品直到里面的所有商品处理完

首次做相关的业务,有不足的,请指教



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值