以下内容来自 Ruby 2.3.1 文档,该文档根据应用于原始集合中每对元素的某些标准将集合划分为其子集。基本上,如果集合中的两个数字彼此相距在 1 个单位以内,则它们属于原始集合的子集集合中的同一子集。
require 'set'
numbers = Set[1, 3, 4, 6, 9, 10, 11]
set = numbers.divide { |i,j| (i - j).abs == 1 }
p set # => #<Set: {#<Set: {1}>,
# #<Set: {11, 9, 10}>,
# #<Set: {3, 4}>,
我认为我正在处理的问题可以使用此功能。这就是问题。有一个包含 n 个事物的集合 S 以及来自 S 的事物对的邻近函数,该函数对于该集合中的某些对具有正值。对于未指定邻近函数值的对,可以假设这些值为 0。还有一个阈值参数。该程序的目标是在集合 S 上引入一个分区(一组成对不相交且相互穷举的子集),使得如果两个事物的邻近函数值超过阈值参数(相反不一定是真的)。
该程序的输入是这种形式
t<-threshold 参数(大于 0 的浮点数)
n<- 要遵循的行数(整数)
Thing_i_1 Thing_j_1proximity_ij_1(Thing_i_1 和 Thing_j_1 是整数,proximity_ij_1 是浮点数并且大于 0)
.... .... Thing_i_n Thing_j_nproximity_ij_n
输出是上述原始集合的成对不相交且相互穷举的子集的集合,使得具有接近函数值至少等于阈值参数的两个事物落入同一子集中。
我编写了下面的程序来完成此操作,但它无法形成相关集合的子集。我的意见是这样的
0.2
3
1 2 0.3
3 4 0.1
2 5 0.25
输出应该是 {{1,2,5},{3},{4}},因为 1,2 应该属于同一个子集,2,5 也应该属于同一个子集,因为每种情况下的接近函数值都超过了阈值参数(所以 1和 5 实际上属于同一个子集),并且 3 和 4 形成它们自己的子集。
require 'set'
t=gets.chomp.to_f
n=gets.chomp.to_i
edge=Struct.new(:n1,:n2)
se=Array.new
af=Array.new
sv=Set.new
for i in (0..n-1)
s=gets.chomp.split(" ")
se.insert(-1,edge.new(s[0],s[1]))
af.insert(-1,s[2].to_f)
if (sv.member? s[0])==false
sv.add(s[0])
end
if (sv.member? s[1])==false
sv.add(s[1])
end
end
c=sv.divide { |i,j| (k=se.index(edge.new(i,j)))!=nil && af[k]>=t }
p c
输出:
#<Set: {#<Set: {"5"}>, #<Set: {"2"}>, #<Set: {"1"}>, #<Set: {"3"}>, #<Set: {"4"}
>}>
除法功能似乎不起作用。我做错什么了吗?为什么我得到五个不相交的子集而不是预期的三个?我在除法块中打印出条件的值,并且对于 1,2 和 2,5 完全正确,但 1、2 和 5 最终在不同的子集中。有人可以帮忙吗?谢谢你。