如何找到一副收藏卡的最佳价格?
或者旅行推销员玩魔术!
我认为这是一个相当有趣的算法挑战。好奇是否有人有任何好的建议来解决它,或者它是否已经可以以已知的方式解决。
仅仅找到每张卡的最佳价格是行不通的,因为如果您从 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我只是贪婪而已。
假设您要承担运费并向所有供应商购买。计算出您获得的绝对最低价格。然后,针对每个供应商计算出从他们那里购买一些卡与从其他人那里购买卡相比可以节省多少费用。通过运输向供应商订购 - 增量节省。
从提供最少价值的供应商开始,砍掉该供应商,将其卡重新分配给其他供应商,并重新计算增量节省。清洗、漂洗,然后重复,直到最边缘的供应商为您省钱。
这应该能找到一个好的解决方案,但不能保证找到最好的解决方案。然而,找到绝对最佳的解决方案似乎是 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.
这与无能力的设施位置问题同构。
牌组中的卡:客户
供应商:可能的设施位置
供应商运费:在某个地点开设设施的成本位置
特定供应商的卡成本:从客户到设施的“距离”
设施位置是组合优化文献中经过充分研究的问题。
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.
有趣的问题! :)
因此,如果我们有 n 张卡和 m 个供应商,那么暴力方法可能必须检查最多 n^m 个组合,对吧(有点少,因为不是每个供应商都有每张卡,但我想这并不重要宏伟的计划;)。
让我们暂时假设每个供应商都有每张卡,然后看看如果没有,情况会如何变化。
因此,如果一个供应商没有所有卡,则必须从多供应商情况开始。对于每个供应商,您可以首先购买那里存在的所有卡,然后将算法应用于剩余的卡。
显然,您可能无法使用此方法利用定价中的所有微妙之处。但如果我们假设很大一部分价格差异是由个别高价卡弥补的,我想你可以通过这种方式找到一个合理的解决方案。
好吧,写完这一切后我意识到, 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.
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.
我自己也思考过这个问题。考虑以下几点:
答案可能是“否”(除非您将一生的积蓄都花在信用卡上,在这种情况下您可能会发疯)。 =)... 或 Amazon.com
因此,已经有一个简单的近似算法:
根据第一手和第二次经验,我可以说您会发现您可以获得中间价格,而您可能会多花几美元的运费,否则,同时仍然接近每个中值。您会发现,您可能需要为库存不足的卡多付一点钱,但这种情况很少见,并且节省的运费将弥补这一点。
我记得古老的编程格言:“永远不要优化,除非绝对必要;很可能你不需要,或者会优化错误的东西。”(例如,你的时间也是一种资源,并且也具有货币价值)
编辑:鉴于此,这是一个非常酷的问题,如果有时间就应该解决它。
I myself have pondered this. Consider the following:
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:
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.
我的算法是这样的,
我仍在考虑下一步,但我把粗略的想法放在这里
我知道这需要巨大的优化。但这是我已经弄清楚的希望这会有所帮助
my algorithm goes like this
i'm still thinking over the next steps but im putting the rough idea over here
i know this will require a huge optimization. but this what i have roghly figured out hope this helps
怎么样:
How about this:
事实上,我去年就写过这篇文章。加载所有价格后我做的第一件事就是清除我的卡池:
每张卡的版本,因为有
重印。找最便宜的。
不幸的是,这仍然留下了一个巨大的池子。
然后我进行一些排序、一些强力深度优先求和以及一些修剪,最终得到结果。
不管怎样,我把它调整到可以做 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:
versions of each card, as there are
reprints. Find the cheapest one.
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!
如果使用遗传算法呢?我想我自己也尝试一下。您可以通过添加价格最低的染色体和运输成本最低的染色体来操纵池。
顺便说一句,您最终实施了此处提出的解决方案吗?哪一个?为什么?
干杯!
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!