假设给定一个非负整数max_diff,这样两个整数n1和n2被认为是“相似的”如果
|n1 - n2| <= max_diff
进一步假设我们得到以下哈希数组:
arr = [
{ "id"=>11486, "opt_ids"=> [3545, 3546, 3548, 3550] },
{ "id"=>12624, "opt_ids"=> [3545, 3396, 3548, 3550] },
{ "id"=>14588, "opt_ids"=> [3394, 3396, 3397, 3399] },
{ "id"=>14589, "opt_ids"=> [3394, 3545, 3398, 3548] },
{ "id"=>14590, "opt_ids"=> [3394, 3396, 3397, 3399] },
{ "id"=>14591, "opt_ids"=> [3545, 3547, 3548, 3551] },
{ "id"=>14592, "opt_ids"=> [3653, 3655, 3657, 3660] },
{ "id"=>14593, "opt_ids"=> [3772, 3775, 3777, 3778] }
]
并指定:
max_diff = 3
我将假设我们将根据我的定义“相似”的元素对数 [h1["opt_ids"][i], h2["opt_ids"][j]] 对这些哈希对(以及因此关联的 "id" 值对)进行排名更多。这可能与您的想法不一致,但它可能是一个有用的起点。我简要说明max_diff 始终为零的情况。
考虑"opt_ids" 的值作为散列arr[0] 和arr[3]:
a0 = arr[0]["opt_ids"]
#=> [3545, 3546, 3548, 3550]
a3 = arr[3]["opt_ids"]
#=> [3394, 3545, 3398, 3548]
如下表所示,a0中的3545类似于a3、3545和3548这两个元素。类似地,a0 中的3546、3548 和3550 分别类似于a3 的2、2 和1 元素,分别表示哈希arr[0] 和@9876可以认为相似度得分为7。
a0 a3 #
____________________
3545: 3545, 3548 (2)
3546: 3545, 3548 (2)
3548: 3545, 3548 (2)
3550: 3548 (1)
我们可以使用下面的辅助方法来实现这个计数。
def count_similar(a1, a2, max_diff)
a1.product(a2).count { |n1,n2| (n1-n2).abs <= max_diff }
end
例如,
count_similar(a0, a3, max_diff)
#=> 7
如果我误解了这个问题并且max_diff 始终为零,并且如果所有数组arr[i]["opt_ids"] 都包含唯一元素(正如问题示例中所做的那样),则可以这样写
def count_similar(a1, a2)
(a1 & a2).size
end
并删除 max_diff 参数。
我们现在可以按如下方式计算 id 对的相似性度量:
def similarities(arr, max_diff)
arr.combination(2)
.map do |h1,h2|
[[h1["id"], h2["id"]],
count_similar(h1["opt_ids"], h2["opt_ids"], max_diff)]
end.to_h
end
similarities(arr, max_diff)
#=> {[11486, 12624]=> 9, [11486, 14588]=>0, [11486, 14589]=> 7, [11486, 14590]=>0,
# [11486, 14591]=>13, [11486, 14592]=>0, [11486, 14593]=> 0, [12624, 14588]=>4,
# [12624, 14589]=> 7, [12624, 14590]=>4, [12624, 14591]=>10, [12624, 14592]=>0,
# [12624, 14593]=> 0, [14588, 14589]=>6, [14588, 14590]=>14, [14588, 14591]=>0,
# [14588, 14592]=> 0, [14588, 14593]=>0, [14589, 14590]=> 6, [14589, 14591]=>7,
# [14589, 14592]=> 0, [14589, 14593]=>0, [14590, 14591]=> 0, [14590, 14592]=>0,
# [14590, 14593]=> 0, [14591, 14592]=>0, [14591, 14593]=> 0, [14592, 14593]=>0}
然后我们可能会计算度量,以确定具有最高相似度分数的五对:
similarities(arr, max_diff).max_by(5, &:last)
#=> [[[14588, 14590], 14], [[11486, 14591], 13], [[12624, 14591], 10],
# [[11486, 12624], 9], [[12624, 14589], 7]]
这表明14588和14590这对id(来自arr[2]和arr[4])具有最高的相似度得分,为14。