嘿伙计们,我有一种快速约会类型应用程序(不用于约会,只是一个类似的概念),用于比较用户并在基于回合的事件中匹配它们。
目前,我将每个用户存储到用户比较(使用余弦相似度),然后找到两个用户都可用的回合。我目前的设置适用于较小的规模但我似乎在较大的数据集中缺少一些匹配。
For example with a setup like so (assuming 6 users, 3 from each group)
Round (User1, User2)
----------------------------
1 (x1,y1) (x2,y2) (x3,y3)
2 (x1,y2) (x2,y3) (x3,y1)
3 (x1,y3) (x2,y1) (x3,y2)
我的方法现在很有效,以确保我让每个用户都能遇到相应的用户而不会出现重叠,从而省去了用户,只是没有更大的数据集。
My current algorithm
我将x中的每个用户与y的每个用户进行比较,如此
Round, user1, user2, similarity
要构建事件计划,我只需按相似性对比较进行排序,然后迭代结果,为两个用户找到一个开放的回合,如下所示:
event.user_maps.all(:order => 'similarity desc').each do |map|
(1..event.rounds).each do |round|
if user_free_in_round?(map.user1) and user_free_in_round?(map.user2)
#creates the pairing and breaks from the loop
end
end
end
这不是确切的代码,而是构建计划的一般算法。有没有人知道更好的方法来填充项目配对矩阵,其中没有一个项目可以在同一个插槽中的多个位置?
EDIT
对于一些澄清,我遇到的问题是,在较大的集合中,我首先放置最高相似性匹配的算法有时会导致冲突。我的意思是用户配对的方式是没有其他用户可以见到。
像这样:
Round (User1, User2)
----------------------------
1 (x1,y1) (x2,y2) (x3,y3)
2 (x1,y3) (x2,nil) (x3,y1)
3 (x1,y2) (x2,y1) (x3,y2)
我希望能够防止这种情况发生,同时保留在调度中给予更高优先级的更高类似用户的需求。
在真实场景中,有比可用轮次更多的匹配和y用户的x用户数量不均匀,在我的测试用例中,而不是每轮完整我将只有大约90%左右的填充时间像上面这样的碰撞导致了问题。
答案 0 :(得分:1)
我认为即使在编辑之后问题仍然需要澄清,但我可能会遗漏一些东西。
据我所知,你想要的是每个新一轮应该从最佳匹配开始(定义为所有匹配对的余弦相似度的总和)。在一轮中匹配任何一对(x_i,y_j)之后,它们就没有资格进入下一轮。
您可以通过构建二分图来实现这一点,其中X是一侧的节点,Y是另一侧的节点,边权重是余弦相似性。然后在此图中找到最大加权匹配。对于下一轮,您将消除上一轮中已使用的边并再次运行匹配算法。有关如何在二分图中编码最大权重匹配的详细信息,请参阅here。
顺便说一句,这个解决方案不是最佳的,因为我们正以贪婪的方式从一轮到另一轮。我觉得获得最佳解决方案将是NP难,但我没有证据,所以无法确定。答案 1 :(得分:0)
我同意这个问题仍然需要澄清。正如阿米特所表达的那样,我有一种直觉,认为这是一个NP难题,所以我假设你正在寻找一个近似的解决方案。
那就是说,我需要更多关于你愿意做出的权衡的信息(也许我只是在你的问题中遗漏了一些东西)。算法的明确目标是什么?
是否存在较低的相似度阈值,低于此阈值时您不希望配对发生?我仍然有点困惑,为什么会有一些人在一轮比赛中根本无法配对......
基本上,您正在对可能配对的空间进行搜索,对吗?也许您可以使用回溯或某种形式的基于约束的算法来确保您可以获得给定轮次的完整解决方案......?