php - 基于案例大小的最低成本

时间:2013-05-11 16:29:00

标签: php shipping knapsack-problem

我正在研究葡萄酒的运输模块,并且想知道是否有人可以帮助我 - 基本上:

葡萄酒可以在8瓶,12瓶或15瓶的情况下运输,每瓶都有自己的价格。该模块需要获取订单中的瓶子总数,并确定哪种组合的案例能够获得最低价格。例如,在31瓶的订单中,最低价格为1箱15和2箱8箱(而不是2箱15和1的8,或12和2中的一个)。目前,我有以下几乎可以工作,但错过了一些可能的组合

    foreach ($rates as $case_size => $case_price) 
    {
      $price = floor($total_bottles / $case_size) * $case_price;
      $rem = $total_bottles % $case_size;
      if($rem > 12)
      {
       //needs to use another case of 15 
       $price = $price + $rates[15];
      }
      elseif($rem > 8)
      {
        //needs an extra case of 12
        $price = $price + $rates[12];
      }
      elseif($rem > 0)
      {
        //needs an extra case of 8
        $price = $price + $rates[8];
      }
      $quotes[] = $price;
    }

    return min($quotes);

2 个答案:

答案 0 :(得分:0)

从您的帖子中您可以说,最具性价比的系统不仅仅是使用每瓶容器成本最低的系统,而且还需要最有效地填充容器。但是你的算法只会考虑使用最少的大盒子。您需要一种能够完全填写每种情况的算法。

我会做这样的事情:使用递归程序找到最能完全填满每个案例的组合。

function fit_case($number, $case_size) {
     $rem = $number % $case_size;
     $next_size=magic_voodo0();
     if($rem==0) {        //if perfectly fills it you're done
           return ($number/$case_size)*$rates[$case_size];
     } else if(($rem % $next_size)/$next_size>.5) {               
     //if over 50% fills the next case add the next smaller case
           return floor($number/$case_size)*$rates[$case_size]+fit_case($rem, $next_size);
      } else {        //otherwise back off 1 of the biggest cases, and fill the rest
         return (floor($number/$case_size)-1)*$rates[$case_size]+fit_case($rem, $next_size);

希望这有帮助。

答案 1 :(得分:0)

不同的方法。使用包含特定数量瓶子的所有盒子组合的查找表。

  • 1瓶 - 8
  • ...
  • 31瓶 - 15-8-8,15-15-8,8-8-8-8,等等

使用另一个查找表,了解每个国家/地区每盒的不同费率

在你的功能中

  • 获取国家/地区价格的表格行
  • 获取瓶数的不同组合
  • 对组合进行foreach循环
  • 保存第一个循环到变量的价格和组合
  • 将下一个循环的价格与保存的值进行比较
  • 如果它更低,保存价格和组合/如果没有,继续
  • 遍历所有组合
  • 返回最低价格/盒子组合