【问题标题】:php - lowest cost based on case sizesphp - 基于案例大小的最低成本
【发布时间】:2013-05-11 16:29:00
【问题描述】:

我正在开发葡萄酒的运输模块,想知道是否有人可以帮我一把 - 基本上:

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

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

【问题讨论】:

  • 好像有点多余。如果客户 A 购买了 27 瓶并且程序想出了如何装箱,那么您就可以为所有订购 27 瓶的未来客户提供答案。无需一遍又一遍地重新计算。我会使用电子表格或其他东西来找出最有效的方法,然后使用带有选项的数组。
  • 我明白你的意思,但每个国家/地区也有自己的一套针对每个案件大小的费率,所以它有点复杂。真的不想为每个国家、每个可能的订单数量制作电子表格。当然有办法以编程方式做到这一点
  • 好的,然后将查找使用瓶数和目标国家作为输入。创建查找表不应该太复杂。另一方面:是否真的需要最大限度地优化这一点以有利于客户?
  • @RST 可以中途旅行:以编程方式完成,然后缓存它。

标签: php shipping knapsack-problem


【解决方案1】:

从您的帖子中您说,最具成本效益的系统不仅是每瓶容器使用最低成本的系统,而且还需要在填充容器方面效率最高。但是,您的算法只考虑使用尽可能少的大盒子。您需要一种算法来完全满足所有可能的情况。

我会做这样的事情:使用递归程序来找到最能完全满足每种情况的组合。

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

希望这会有所帮助。

【讨论】:

  • 这仍然会导致使用 2x15 和 1x8 框。虽然他说在这种情况下 1x15 和 2x8 盒子会更便宜。
  • 这不会导致 2X15 和 1x8 框。其余的将少于 8 个案例的 50%,因此该算法将使用 1 个减去 15 个案例,并用 8 个案例填充其余部分。所以你会留下 1X15 和 2X8。
  • 你是对的,但我认为它会用一个 12 瓶的盒子代替。
  • 谢谢你——不知道你对 50% 的意思是什么,但像这样的递归函数可能会奏效。我无法将其标记为“有用”,因为我没有“声誉”抱歉。这个想法是为了最大限度地降低成本,而不是最好地装满容器——所以最大的容器是最具成本效益的。但也有少数情况,例如 33 瓶,其中 8 瓶、12 瓶中的一瓶和 15 瓶中的一瓶价格最便宜(与 3x12 或 2x15+1x8 或 4x8 相比)。真令人沮丧,因为我怀疑顾客会买 33 瓶!
  • 你是对的,那么余数超过一个百分比的容差就需要改变了。我认为是 80%。 12/15=80% 和 8/12=75% 所以如果它必须超过 80% 我认为应该找到最有效的组合。
【解决方案2】:

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

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

使用另一个查找表查找每个国家/地区每箱的不同费率

在你的函数中

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-15
    相关资源
    最近更新 更多