如何找到一张收藏卡的最优惠价格?

时间:2011-05-05 22:24:35

标签: algorithm combinatorics

旅行推销员扮演魔术!

我认为这是一个相当有趣的算法挑战。好奇,如果有人有任何解决它的好建议,或者它已经以已知方式解决。

TCGPlayer.com出售各种游戏的收藏卡,包括 Magic the Gathering 。它们实际上是来自多个供应商的转售商(50+),而不仅仅是从他们的库存中销售卡片。每个供应商都有不同的库存卡和每张卡的不同价格。每个供应商还收取统一运费(通常)。鉴于所有这一切,如何找到一副牌的最佳价格(比如说40到100张卡)?

找到每张卡的最优价格是行不通的,因为如果您从10个不同的供应商订购10张卡,那么您支付运费10次,但如果您从一个供应商订购全部10个付运费

另一个晚上,我写了一个简单的HTML Scraper(使用HTML Agility Pack),它抓住每张卡的所有不同价格,然后找到所有带有卡片中所有卡片的供应商,总计价格。来自每个供应商的卡,并按价格排序。这真的很容易。总价格最终接近所有卡的总中位数价格。

我注意到一些个人卡最终远高于中位数价格。这提出了在多个供应商之间拆分订单的问题,但只有通过将订单拆分以支付额外运费(每个增加的供应商增加另一个运费)才能节省足够的成本。

逻辑上似乎最好的价格可能只涉及一些不同的供应商,但如果这些卡足够昂贵(and some are那么理论上从不同的供应商订购每张卡仍然可以节省足够的资金来证明所有额外运费。

如果你打算解决这个问题,你会怎么做?纯粹的蛮力计算卡/供应商组合的每种可能组合?在我的一生中更有可能完成的过程似乎涉及在固定次数的迭代中的有条理的一系列估计。我有几个想法,但我很好奇其他人的建议。

我正在寻找比实际代码更多的算法。我目前正在使用.NET,如果这有任何区别。

Jace, the Mind Sculptor

8 个答案:

答案 0 :(得分:6)

我会贪婪。

假设您要吃掉运费并从所有供应商那里购买。计算出你得到的绝对最低价格。然后,对于每个供应商计算出能够从他们那里购买一些卡而不是其他人拯救你。通过运输订购供应商 - 增加节省。

从提供最低价值的供应商开始,与该供应商合作,将其卡重新分发给其他供应商,并重新计算增量节省。洗涤,冲洗并重复,直到最边缘的供应商为您省钱。

这应该找到一个好的解决方案,但不能保证找到最佳解决方案。但是,找到绝对最佳的解决方案似乎很难实现NP。

答案 1 :(得分:4)

这与无人问津的facility location问题同构。

  • 卡片中的卡片:客户

  • 供应商:可能的设施位置

  • 供应商运费:在某个地点开设设施的费用

  • 特定供应商的卡的成本:从客户到设施的“距离”

设施位置是组合优化文献中一个经过深入研究的问题。

答案 2 :(得分:1)

我自己也在考虑这个问题。请考虑以下事项:

  

如果需要一周的时间来弄明白,   代码,调试和算法   只提供1%的折扣,是吗?   做到了吗?

答案可能是“不”(除非你把你的终身积蓄花在卡片上,在这种情况下你可能会疯狂)。 =)...或Amazon.com

因此,已经有一个简单的近似算法:

Wait until you're buying lots of cards (reduce the shipping overhead).
Buy the cards from 3 vendors:
    - the two with the cheapest-but-most-diverse inventories
    - a third which isn't really cheap but definitely has every card you'd want.
Optimize accordingly (for each card, buy from the cheaper one).
Also consider local vendors you could just walk to, pre-constructed decks, and trading.

基于第一手和第二经验,我可以说你会发现你可以得到中位数价格,或许你可以多运费几美元,同时仍然可以得到每个中位数。您可能会发现,您可能需要支付更多的费用以支付欠费卡,但这将是很少的,并且运费节省将弥补它。

我记得那句古老的编程格言:“永远不要优化,直到绝对必要;你可能不需要,或者会优化错误的东西。”(例如你的时间是一个资源也是,也有货币价值)

编辑:鉴于此,这是一个非常酷的问题,如果有时间,应该解决它。

答案 3 :(得分:1)

有趣的问题! :)

因此,如果我们有n个卡和m个供应商,那么蛮力方法可能需要检查n ^ m个组合,正确(因为并非每个供应商都有每张卡,但我想这并不重要)在宏伟的计划中;)。

让我们假设每个供应商都有每张卡片,然后再看看如果事情发生了变化,如果不这样做的话。

  1. 找到最便宜的单一供应商解决方案。
  2. 按价格订购卡片,找到其他供应商便宜的最贵的卡片。
  3. 对于供应商1的所有卡,如果它们更便宜,则将它们移至供应商2。
  4. 如果添加供应商2不会使订单更便宜,则撤消并终止,否则从步骤2重复
  5. 因此,如果一个供应商没有所有卡,您必须从多供应商的情况开始。对于每个供应商,您可以首先购买那里存在的所有卡,然后将算法应用于剩余的卡。

    显然,您可能无法利用此方法利用定价中的所有细微差别。但如果我们假设价格差异的很大一部分是由单个高价卡组成的,我认为你可以用这种方式找到合理的解决方案。


    好的,写完所有这些我意识到,n ^ m假设实际上是错误的。 一旦您选择了一组供应商购买,您就可以为每张卡选择最便宜的供应商。这是一个很大的优势,因为每个卡的购买地点的个人选择不会相互干扰。

    这对我们的问题意味着什么?从它的第一眼看,它意味着经销商的选择是问题(在计算复杂性方面),而不是您的购买选择的个人分配。因此,在最坏的情况下,您可以获得2 ^ m个可能的配置,而不是n ^ m。所以我们需要的是选择供应商而不是选择单个卡的启发式方法。这可能使得上面的启发式实际上更合理。

答案 4 :(得分:1)

我的算法就像这样

    每张卡的
  1. 计算可用的平均价格,即每个供应商可用价格的总和除以供应商的数量。
  2. 现在为该卡选择提供低于或等于平均价格的供应商。
  3. 现在,对于每张卡,我们都会有供应商列表。现在以这种方式走向交叉路口,我们将最终得到一系列供应商,提供平均或低于平均价格的最大卡数。
  4. 我仍然在考虑接下来的步骤,但我把粗略的想法放在这里

    • 现在我们留下了为我们提供单卡的卡片。对于这样的卡,我们将查看alredy短名单供应商的价格表,最多没有卡,如果价格差异小于运费,我们将卡添加到供应商列表。

    我知道这将需要一个巨大的优化。但这就是我有点想通过希望这有助于

答案 5 :(得分:1)

这个怎么样:

  1. 计算所有供应商的每张订购卡的平均价格。
  2. 对于每个至少有一张卡的供应商,计算订单中所有卡的总节省量,即每个卡在该供应商的价格与平均价格之间的差额。
  3. 从节省最多的供应商开始,然后从该供应商处选择所有这些卡。
  4. 继续选择总储蓄次数最高的供应商,直到您选择了所有订单中的所有卡。跳过没有您仍需要的卡片的供应商。
  5. 从选定的供应商列表中,将卡片购买重新分配给具有该卡最优惠价格的供应商。
  6. 从剩余的供应商列表中,如果列表足够小,您可以强行使用卡数较少的任何供应商,看看是否可以将卡移动到其他供应商以消除运费。

答案 6 :(得分:1)

我实际上去年写过这个问题。加载所有价格后我做的第一件事是我清理了我的卡片池:

  • 每个供应商都可以有多个 每张卡的版本都有 重印。找到最便宜的。
  • 消除卡值大于最便宜的卡+运输组合的任何卡。也就是说,如果我可以通过将其添加到您商店的现有订单中而将该卡作为一次性商品更便宜地购买,我将从其他供应商处购买。
  • 消除任何供应商,我可以从其他供应商那里购买更便宜(每张卡)。基本上,如果另一家供应商在每张卡上都为您提供价格,而且总价+运费,那么您就不见了。

不幸的是,这仍然留下了巨大的空间。 然后我做了一些排序和一些暴力深度优先的总结和一些修剪,最终得到了结果。

无论如何,我把它调到我可以做70张牌的地步,并在一分钟内达到最佳目标的5%。而在一个小时内,不到2%。然后,几天后,实际的最终结果。

我将详细了解设施规划。谢谢你的提示!

答案 7 :(得分:1)

使用遗传算法怎么样?我想我会亲自尝试一下。您可以通过添加价格最低的染色体和运输成本最低的染色体来操纵池。

顺便说一句,您最终是否实施了此处提供的任何解决方案?哪一个?为什么呢?

干杯!