算法引爆点

时间:2013-04-12 15:48:29

标签: algorithm

我是一个完整的算法笨蛋,我有这个问题,我需要找到以单价购买未知数量的小部件的最低成本或通过批量购买x小部件...一个例子将帮助我'我敢肯定: -

1)每单位小工具价格为0.05美元 2)批量小部件的价格为每100个小部件4.00美元

说我想买140个小工具 -

a)按单位计算成本为140 x $ 0.05c => $ 7.00 b)按批次计算成本是2批次100 @ $ 4.00 => 8.00美元(可以忽略超过60个小部件)

所以在这种情况下按单位购买更便宜1.00美元

但是,如果我想购买190个小工具,那么 -

a)按单位计算成本为190 x $ 0.05c => $ 9.50 b)按批次计算成本是2批次100 @ $ 4.00 => 8.00美元(可以忽略多余的小部件)

在这种情况下通过批量购买价格更便宜......

所以我需要找出如何以编程方式找出两种方法之间的'临界点'以获得最便宜的价格。

我希望我已经解释好了,我确信这是一个简单的答案,但我的大脑今天已经快速消退了!

TIA

EDIT ::

好的抱歉 - 我意识到我并没有像我应该那样清楚 - 因为有人指出了混合批次和单位也是可能的,因此对于140小部件示例它也可以是1批和40单位

我想要实现的是以编程方式找到最便宜的方式来购买每个价格为$ XX的X个小部件,并且还给出NN小部件的批量价格YY。

购买批次的任何多余小部件都没有问题,即它可以购买超过X但不能低于X

因此对于140例1批量@ $ 4.00 + 40件@ $ 0.05 => 6.00美元这是我认为最便宜的。和 对于190例子,2批次仍然是最便宜的,我认为1批次+ 90单位是8.50美元......

我希望有一些巧妙的方程可以做到这一点:)

2 个答案:

答案 0 :(得分:1)

如果您只是想到它,那么答案就非常容易了。您已经知道了引爆点'在价格。这是8.00美元。你不知道的是单位为单位,即$ 8.00除以$ 0.05(每单位)=> 160个单位。

请注意,还有机会购​​买100个单位@4.00美元和60个单位@ 0.05美元,总计7.00美元。这是您可能会或可能不会考虑的第三种可能性。

编辑:编辑完成后,事情变得更加简单:

您在$ XX有1件物品,在$ YY有一批NN物品。假设$ YY / NN < $ XX(意思是,批次实际上省钱),你所要做的就是:

  1. 将目标数量除以NN,然后向下舍入。您必须购买此批次数
  2. 将剩余数量乘以$ XX。如果超过$ YY只需购买额外批次,否则以$ XX
  3. 购买剩余数量

答案 1 :(得分:1)

我在python中编写了一个基本的暴力样式脚本来比较两个选项的价格(最多1,000个元素)。它不是最快或最优雅的方法,但似乎有效。

输出格式为:(<unit-count>, (<per-unit-cost>, <per-batch-cost>))

import math
import itertools
import pprint

unitList = range(1000)
pricePerUnit = .05
pricePerBatch = 4.0
numberPerBatch = 100.0

def calculatePerUnit(units):
  """ Calculate the price of buying per unit
  """
  return units * pricePerUnit

def calculatePerBatch(units):
  """ Calculate the price of buying per batch
  """
  return math.ceil(units / numberPerBatch) * pricePerBatch

def main():
  """ Execute the script
  """
  perUnit = map(calculatePerUnit, unitList)
  perBatch = map(calculatePerBatch, unitList)
  comparisonList = zip(perUnit, perBatch)
  perUnitCheaperPriceList = list(itertools.ifilter(lambda x: x[0] < x[1], comparisonList))
  perUnitCheaperUnitList = map(lambda x: int(x[0] / .05), perUnitCheaperPriceList)                                                                              
  pprint.pprint(zip(perUnitCheaperUnitList, perUnitCheaperPriceList))

if __name__=="__main__":
  main()

结果:

[gizmo@test ~]$ python TippingPoint.py 
[(1, (0.050000000000000003, 4.0)),
 ... These are sequential values I left out for brevity ...
 (79, (3.9500000000000002, 4.0)),
 (101, (5.0500000000000007, 8.0)),
 ... These are sequential values I left out for brevity ...
 (159, (7.9500000000000002, 8.0)),
 (201, (10.050000000000001, 12.0)),
 ... These are sequential values I left out for brevity ...
 (239, (11.950000000000001, 12.0)),
 (301, (15.050000000000001, 16.0)),
 ... These are sequential values I left out for brevity ...
 (319, (15.950000000000001, 16.0))]