如何找到一副收藏卡的最佳价格?

发布于 2024-11-05 05:52:06 字数 1295 浏览 1 评论 0原文

或者旅行推销员玩魔术!

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

TCGPlayer.com< /a> 出售各种游戏的收藏卡,包括万智牌。他们实际上不仅仅是从库存中销售卡片,而是来自多个供应商(50+)的转售商。每个供应商都有不同的卡片库存以及每张卡片不同的价格。每个供应商还收取统一运费(通常)。考虑到所有这些,人们如何找到一副纸牌(例如 40 - 100 张纸牌)的最佳价格?

仅仅找到每张卡的最佳价格是行不通的,因为如果您从 10 个不同的供应商处订购 10 张卡,那么您支付 10 次运费,但如果您从一个供应商处订购所有 10 张卡,您只需支付一次运费

有一天晚上,我编写了一个简单的 HTML Scraper(使用 HTML Agility Pack)来抓取所有内容每张卡片的不同价格,然后找到携带这副卡片中所有卡片的所有供应商,将每个供应商的卡片价格相加并按价格排序。那真的很容易。总价格最终接近所有卡的总中位价格。

我确实注意到一些单张卡的价格最终远高于中间价格。这就提出了将订单拆分给多个供应商的问题,但前提是通过拆分订单可以节省足够的费用以支付额外的运费(每个添加的供应商都会增加另一笔运费)。

从逻辑上讲,最好的价格可能只涉及几个不同的供应商,但如果卡足够昂贵(有些是),那么理论上从不同的供应商订购每张卡仍然可以节省足够的费用来证明所有额外的运费是合理的。

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

我更多地寻找算法而不是实际代码。不过,我目前正在使用 .NET,如果这有什么区别的话。

心灵雕塑家杰斯

Or The Traveling Salesman plays Magic!

I think this is a rather interesting algorithmic challenge. Curious if anyone has any good suggestions for solving it, or if it is already solvable in a known way.

TCGPlayer.com sells collectible cards for a variety of games, including Magic the Gathering. Instead of just selling cards from their inventory they are actually a re-seller from multiple vendors (50+). Each vendor has a different inventory of cards and a different price per card. Each vendor also charges a flat rate for shipping (usually). Given all of that, how would one find the best price for a deck of cards (say 40 - 100 cards)?

Just finding the best price for each card doesn't work because if you order 10 cards from 10 different vendors then you pay shipping 10 times, but if you order all 10 from one vendor you only pay shipping once.

The other night I wrote a simple HTML Scraper (using HTML Agility Pack) that grabs all the different prices for each card, and then finds all the vendors that carry all the cards in the deck, totals the price of the cards from each vendor and sorts by price. That was really easy. The total prices ended up being near the total median price for all the cards.

I did notice that some of the individual cards ended up being much higher than the median price. That raises the question of splitting an order over multiple vendors, but only if enough savings could be made by splitting the order up to cover the additional shipping (each added vendor adds another shipping charge).

Logically it seems that the best price will probably only involve a few different vendors, but if the cards are expensive enough (and some are) then in theory ordering each card from a different vendor could still result in enough savings to justify all the extra shipping.

If you were going to tackle this how would you do it? Pure brute force figuring every possible combination of card / vendor combinations? A process that is more likely to be done in my lifetime would seem to involve a methodical series of estimates over a fixed number of iterations. I have a couple ideas, but am curious what others might suggest.

I am looking more for the algorithm than actual code. I am currently using .NET though, if that makes any difference.

Jace, the Mind Sculptor

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

狠疯拽 2024-11-12 05:52:06

我只是贪婪而已。

假设您要承担运费并向所有供应商购买。计算出您获得的绝对最低价格。然后,针对每个供应商计算出从他们那里购买一些卡与从其他人那里购买卡相比可以节省多少费用。通过运输向供应商订购 - 增量节省。

从提供最少价值的供应商开始,砍掉该供应商,将其卡重新分配给其他供应商,并重新计算增量节省。清洗、漂洗,然后重复,直到最边缘的供应商为您省钱。

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

I would just be greedy.

Assume that you are going to eat the shipping cost and buy from all vendors. Work out the absolute lowest price you get. Then for each vendor work out how much being able to buy some cards from them versus someone else saves you. Order the vendors by shipping - incremental savings.

Starting with the vendors who provide the least value, axe that vendor, redistribute their cards to the other vendors, and recalculate incremental savings. Wash, rinse, and repeat until your most marginal vendor is saving you money.

This should find a good solution but is not guaranteed to find the best solution. Finding the absolute best solution, though, seems likely to be NP-hard.

仲春光 2024-11-12 05:52:06

这与无能力的设施位置问题同构。

  • 牌组中的卡:客户

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

  • 供应商运费:在某个地点开设设施的成本位置

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

设施位置是组合优化文献中经过充分研究的问题。

This is isomorphic to the uncapacitated facility location problem.

  • card in the deck : client

  • vendor : possible facility location

  • vendor shipping rate : cost of opening a facility at a location

  • cost of a card with a particular vendor : "distance" from a client to a facility

Facility location is a well-studied problem in the combinatorial optimization literature.

海拔太高太耀眼 2024-11-12 05:52:06

有趣的问题! :)

因此,如果我们有 n 张卡和 m 个供应商,那么暴力方法可能必须检查最多 n^m 个组合,对吧(有点少,因为不是每个供应商都有每张卡,但我想这并不重要宏伟的计划;)。

让我们暂时假设每个供应商都有每张卡,然后看看如果没有,情况会如何变化。

  1. 找到最便宜的单一供应商解决方案。
  2. 按价格订购卡,找到在其他供应商处更便宜的最贵的卡。
  3. 对于来自供应商 1 的所有卡,如果供应商 2 更便宜,请将它们移至供应商 2。
  4. 如果添加供应商 2 不会使订单更便宜,则撤消并终止,否则从步骤 2 重复。

因此,如果一个供应商没有所有卡,则必须从多供应商情况开始。对于每个供应商,您可以首先购买那里存在的所有卡,然后将算法应用于剩余的卡。

显然,您可能无法使用此方法利用定价中的所有微妙之处。但如果我们假设很大一部分价格差异是由个别高价卡弥补的,我想你可以通过这种方式找到一个合理的解决方案。


好吧,写完这一切后我意识到, n^m 假设实际上是错误的。
一旦您选择了一组要购买的供应商,您只需为每张卡选择最便宜的供应商即可。这是一个很大的优势,因为购买每张卡的个人选择不会相互干扰。

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

Interesting question! :)

So if we have n cards and m vendors, the brute force approach might have to check up to n^m combinations, right (a bit less since not each vendor has each card, but I guess that doesn't really matter in the grand scheme of things ;).

Let's for a second assume each vendor has each card and then see later-on how things change if they don't.

  1. find the cheapest one-vendor solution.
  2. order the cards by price, find the most expensive card that's cheaper at another vendor.
  3. for all cards from vendor 1, move them to vendor 2 if they're cheaper there.
  4. if having added vendor 2 doesn't make the order cheaper, undo and terminate, otherwise repeat from step 2

So if one vendor doesn't have all cards, you have to start with a multi-vendor situation. For each vendor, you might start by buying all cards that exist there, then apply the algorithm to the remaining cards.

Obviously, you may not be able to exploit all subtleties in the pricing with this method. But if we assume that a large portion of the price differences is made up by individual high-price cards, I think you can find a reasonable solution with this way.


Ok after writing all this I realized, the n^m assumption is actually wrong.
Once you have chosen a set of vendors to buy from, you can simply choose the cheapest vendor for each card. This is a great advantage because the individual choices of where to buy each card don't interfere with each other.

What does this mean for our problem? From the first look of it, it means that the selection of dealers is the problem (in terms of computational complexity), not the individual allocation of your buying choices. So instead of n^m, you got 2^m possible configurations in the worst case. So what we need is a heuristic for choosing vendors rather than choosing individual cards. Which might make the heuristic from above actually even more justifiable.

轮廓§ 2024-11-12 05:52:06

我自己也思考过这个问题。考虑以下几点:

如果你需要一周的时间才能弄清楚,
代码、调试和算法
只提供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.

根据第一手和第二次经验,我可以说您会发现您可以获得中间价格,而您可能会多花几美元的运费,否则,同时仍然接近每个中值。您会发现,您可能需要为库存不足的卡多付一点钱,但这种情况很少见,并且节省的运费将弥补这一点。

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

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

I myself have pondered this. Consider the following:

If it takes you a week to figure out,
code, and debug and algorithm that
only provides a 1% discount, would you
do it?

The answer is probably "No" (unless you're spending your entire life savings on cards, in which case you may be crazy). =)... or Amazon.com

Consequently, there is already an easy approximating algorithm:

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.

Based on firsthand and second experience, I can say you will find that you can get the median price with perhaps a few dollars more shipping you could otherwise, while still getting around median on each. You will find that you may have to pay a tiny bit more for understocked cards, but this will be few and far between, and the shipping savings will make up for it.

I recall the old programming adage: "Never optimize, until it's absolutely necessary; chances are you won't need to, or would have optimized the wrong thing." (e.g. your time is a resource too, and also has monetary value)

edit: Given that, this is an amazingly cool problem and one should solve it if one has time.

花伊自在美 2024-11-12 05:52:06

我的算法是这样的,

  1. 为每张卡计算可用的平均价格,即每个供应商的可用价格总和除以供应商的数量。
  2. 现在,为该卡选择一个提供低于或等于平均价格的供应商。
  3. 现在,对于每张卡,我们都会有供应商列表。现在,以这种方式走到十字路口,我们最终会看到一系列供应商以平均或低于平均价格提供最大数量的卡。

我仍在考虑下一步,但我把粗略的想法放在这里

  • ,现在我们剩下的卡片为我们提供了单张卡片。对于此类卡,我们将查看已入围的供应商的价格表,其中卡数量最多,如果价格差异小于运输成本,我们会将卡添加到该供应商列表中。

我知道这需要巨大的优化。但这是我已经弄清楚的希望这会有所帮助

my algorithm goes like this

  1. for each card calculate the average price available i.e sum of the price available from each vendor divide by the no of vendors.
  2. now for that card select a vendor that offers less than or equal to average price.
  3. now for each card we will have the list of vendors. now go for the intersection this way we will end up with series of vendor providing the maximxum no of cards at average or below average price.

i'm still thinking over the next steps but im putting the rough idea over here

  • now we are left with cards which are providing us single card. for such cards we will look into the price list of alredy short listed vendors with max no of cards and if the price diff is less than the shipping cost the we add the card to that vendors list.

i know this will require a huge optimization. but this what i have roghly figured out hope this helps

舟遥客 2024-11-12 05:52:06

怎么样:

  1. 计算所有供应商每张订购卡的平均价格。
  2. 对于至少拥有一张卡的每个供应商,计算订单中所有卡的总节省额,作为该供应商每张卡的价格与平均价格之间的差额。
  3. 从总节省最高的供应商开始,然后选择该供应商的所有卡。
  4. 继续选择总节省额第二高的供应商,直到您选择了订单中的所有卡片。跳过没有您仍然需要的卡的供应商。
  5. 从选定的供应商列表中,将购买的卡重新分配给具有该卡最优惠价格的供应商。
  6. 从剩余的供应商列表中,如果列表足够小,您可以对卡数较少的任何供应商进行暴力强制,看看是否可以将卡转移到其他供应商以消除运输成本。

How about this:

  1. Calculate the average price per ordered card across all vendors.
  2. For each vendor that has at least one of the cards, calculate the total savings for all cards in the order as the difference between each card's price at that vendor and the average price.
  3. Start with the vendor with the highest total savings and select all of those cards from that vendor.
  4. Continue to select vendors with the next highest total savings until you have all of the cards in the order selected. Skip vendors that don't have cards that you still need.
  5. From the selected list of vendors, redistribute the card purchases to the vendors with the best price for that card.
  6. From the remaining list of vendors, and if the list is small enough, you could then brute force any vendors with a low card count to see if you could move the cards to other vendors to eliminate the shipping cost.
命硬 2024-11-12 05:52:06

事实上,我去年就写过这篇文章。加载所有价格后我做的第一件事就是清除我的卡池:

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

不幸的是,这仍然留下了一个巨大的池子。
然后我进行一些排序、一些强力深度优先求和以及一些修剪,最终得到结果。

不管怎样,我把它调整到可以做 70 张牌,并且在一分钟内达到最佳目标 5% 以内。一个小时内,下降了不到 2%。然后,几天后,实际的最终结果出来了。

我将阅读更多有关设施规划的内容。谢谢你的提示!

I actually wrote this exact thing last year. The first thing I do after loading all the prices is I weed out my card pool:

  • Each vendor can have multiple
    versions of each card, as there are
    reprints. Find the cheapest one.
  • Eliminate any card where the card value is greater than the cheapest card+shipping combo. That is, if I can buy the card cheaper as a one-off to a vendor than I can by adding it to an existing order from your store, I will buy it from the other vendor.
  • Eliminate any vendor whose offering I can buy cheaper (for every card) from another vendor. Basically, if another vendor out-prices you on every card, and on the total + shipping, then you are gone.

Unfortunately, this still leaves a huge pool.
Then I do some sorting and some brute-force-depth-first summing and some pruning and eventually end up with a result.

Anyway, I tuned it up to the point that I can do 70 cards and, within a minute, get within 5% of the optimal goal. And in an hour, less than 2%. And then, a couple of days later, the actual, final result.

I am going to read more about facility planning. Thanks for that tip!

拥抱我好吗 2024-11-12 05:52:06

如果使用遗传算法呢?我想我自己也尝试一下。您可以通过添加价格最低的染色体和运输成本最低的染色体来操纵池。

顺便说一句,您最终实施了此处提出的解决方案吗?哪一个?为什么?

干杯!

What about using genetic algorithm? I think I'll try that one myself. You might manipulate the pool by adding both a chromosome with lowest prices, and another with lowest shipping costs.

BTW, did you finally implement any of the solutions presented here? which one? why?

Cheers!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文