ruby - 填充项目矩阵的算法,项目对

标签 ruby algorithm matrix

大家好,我有一种快速约会类型的应用程序(不用于约会,只是一个类似的概念),可以比较用户并在基于回合的事件中匹配他们。

目前我正在存储每个用户与用户的比较(使用余弦相似度),然后找到两个用户都可用的回合。我当前的设置适用于较小的规模,但我似乎在较大的数据集中缺少一些匹配项。

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

这不是精确的代码,而是构建时间表的通用算法。有谁知道一种更好的方法来填充项目配对矩阵,在这种矩阵中,任何一项都不能出现在同一个插槽中的多个位置?

编辑

澄清一下,我遇到的问题是,在较大的集合中,我将最高相似度匹配放在首位的算法有时会导致冲突。我的意思是,用户以这样一种方式配对,即他们没有其他用户可以见面。

像这样:

Round (User1, User2)
----------------------------
1  (x1,y1)  (x2,y2)  (x3,y3)
2  (x1,y3)  (x2,nil)  (x3,y1)
3  (x1,y2)  (x2,y1)  (x3,y2)

我希望能够防止这种情况发生,同时保留在调度中给予更高优先级的更高相似用户的需求。

在真实场景中,匹配的数量远远多于可用的回合,x 用户与 y 用户的数量不均匀,在我的测试用例中,我不会让每一轮都充满,而我只会让大约 90% 左右的人被填充,而像上面这样的碰撞导致了问题。

最佳答案

我认为即使在编辑之后这个问题仍然需要澄清,但我可能会遗漏一些东西。

据我所知,您想要的是每一轮新回合都应该以最佳匹配开始(定义为所有匹配对的余弦相似度之和)。任何一对 (x_i,y_j) 在一轮中匹配后,就没有资格进入下一轮。

您可以通过构建一个二部图来做到这一点,其中您的 X 是一侧的节点,Y 是另一侧的节点,边权重是余弦相似度。然后您会在此图中找到最大加权匹配。对于下一轮,您消除了上一轮已经使用的边并再次运行匹配算法。有关如何在二分图中编码最大权重匹配的详细信息,请参阅 here .

顺便说一句,这个解决方案不是最优的,因为我们以贪婪的方式从一轮到下一轮进行。我有一种感觉,获得最佳解决方案将是 NP 困难,但我没有证据,所以不能确定。

关于ruby - 填充项目矩阵的算法,项目对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3983686/

相关文章:

javascript - 在定义构造函数后,实例属性可以添加到 JavaScript 原型(prototype)吗?

algorithm - 找到最大连续总和,找到包含点的线段

algorithm - hash解密,可以用什么算法

python - bool 矩阵形式 Python 的列表字典

java - 递归网格计数器

组织矩阵以使邻居最接近的算法

ruby-on-rails - 从 ruby​​ 中的类方法调用实例方法

ruby-on-rails - 将基于时间的字符串转换为 ISO 格式

ruby-on-rails - 我以错误的方式删除了 Rails gem - 我该怎么办?

algorithm - F# 将列表转换为树