最近遇到了这个面试编程测试:
我觉得我有一个非常可行的解决方案,但我想知道他们是否在寻找我错过的具体内容。
(如果它有所作为 - 这不是我自己的面试,所以我不是想欺骗任何未来的雇主)
以下是我的假设:
第三个要求有点模糊 - 从技术上讲,如果你有任何确切的解决方案,你就“评估了所有可能的对”。
第一遍:将艺术家姓名转换为数字ID;将最喜欢的数据存储在临时文件中;为每位艺术家保留用户收藏的数量。
需要string-> int map来跟踪指定的ID;如果空间比速度更重要,则可以使用Patricia树(需要1/5的空间和两倍于我的时间,不可否认的是非常严格的测试)。
第二遍:迭代临时文件;抛弃那些没有单独地满足截止值的艺术家;保持2d矩阵中的对数。
将需要n(n-1)/2
字节(或短路,或整数,取决于数据大小)加上数组引用开销。不应该是一个问题,因为n
最多只有622K的0.01-0.05。
这似乎可以使用少于100MB的内存处理任何大小的真实数据集。
如果您无法进行多次传递(出于任何人为的原因),请使用Bloom过滤器数组来保持对数:对于您遇到的每对,找到它(可能)最高的过滤器,并添加到下一个最高的一个所以,第一次将它加到bf [0],第二次加到bf [1],依此类推,直到bf [49]。或者可以恢复到在某一点之后保持实际计数。
我没有运行这些数字,但是最少的几个过滤器会相当大 - 这不是我最喜欢的解决方案,但它可以工作。
还有其他想法吗?
答案 0 :(得分:3)
您应该考虑挖掘关联规则的现有方法之一。这是一个研究得很好的问题,本土解决方案不太可能更快。一些参考文献:
维基百科有一个非常糟糕的实施清单http://en.wikipedia.org/wiki/Association_rule_learning。
引用我以前的答案:What is the most efficient way to access particular elements in a SortedSet?。
此处有一个现有实施的存储库:http://fimi.ua.ac.be/src/。这些是几年前参加表演比赛的工具;他们中的许多都带有指示性文件来解释他们如何/何时/为什么比其他算法更快。
答案 1 :(得分:0)
有两点要求是关于不精确的解决方案,我猜他们正在寻找快速的快捷方式而不是穷举搜索。所以这是我的想法:
假设粉丝对喜爱的艺术家的选择之间绝对没有相关性。当然,这肯定是错误的。喜欢伦勃朗的人更有可能也喜欢鲁本斯,然后他也喜欢波洛克。 (你说过我们选的是最喜欢的艺术家,对吧?)我马上回过头来看看。
然后传递数据,计算不同艺术家的数量,粉丝的数量,以及每个艺术家出现的最喜欢的频率。当我们完成这个传递时:(1)消除任何没有单独显示所需数量的“配对时间”的艺术家。如果一个武器只出现40次,他就不可能被包括在40多对中。 (2)对于剩下的艺术家,将每个“像计数”转换为百分比,即这个艺术家被10%的粉丝所喜欢。然后对于每对艺术家,将他们的百分比加倍,然后乘以粉丝的总数。这是他们作为一对出现的估计次数。
例如,假设1000名粉丝,200名说他们喜欢伦勃朗,100名说他们喜欢Michaelangelo。这意味着Rembrandt为20%,Michaelangelo为10%。因此,如果没有相关性,我们估计20%* 10%* 1000 = 20两者都是如此。这低于阈值,所以我们不会包括这一对。
对此的关注是“喜欢”之间几乎肯定存在相关性。我的第一个想法是研究一些实际数据,看看有多少相关性,即实际对数与估计值的差异。如果我们发现,实际计数很少超过估计计数的两倍,那么我们可以说任何估计超过阈值1/2的对我们都声明为“候选”。然后我们对候选人进行详尽的统计,看看有多少人真正符合这个条件。这将使我们能够消除所有低于阈值的对,因为“不太可能”,因此不值得调查。
当艺术家几乎总是一起出现时,这可能会错过对。比如,像毕加索这样的100位粉丝,像梵高这样的60位粉丝,以及喜欢梵高50位的60位粉丝也喜欢毕加索,他们的估计会比他们的实际价格低很多。如果这种情况很少发生,则可能属于可接受的“不需要的确切答案”类别。如果它一直发生这种方法将不起作用。