Julia - 生成 2 个匹配的奇数集
Julia - Generate 2-matching odd Set
在 Julia 中,给定一个名为 S
且长度大于 3 的 Set{Tuple{Int, Int}}
,例如:
julia> S = Set{Tuple{Int,Int}}([(1, 4), (2, 5), (2, 6), (3, 6)])
Set{Tuple{Int64,Int64}} with 4 elements:
(2, 5)
(3, 6)
(2, 6)
(1, 4)
我想要 return S
的子集 T
,其长度大于 3
且为奇数(3, 5, 7, ...),这样,元组的所有第一个值都是唯一的。例如,我不能有 (2, 5) 和 (2, 6) 因为第一个值 2 不是唯一的。这同样适用于第二个值,这意味着我不能有 (2, 6) 和 (3, 6)。
如果不可能,return一个空的元组集就可以了。
最后,对于上面的最小示例,代码应该 return:
julia> T = Set{Tuple{Int,Int}}([(1, 4), (2, 5), (3, 6)])
Set{Tuple{Int64,Int64}} with 3 elements:
(2, 5)
(3, 6)
(1, 4)
如果您认为它比 Set{Tuple{Int, Int}}
更好,我真的对任何其他类型的结构持开放态度 :)
我知道如何使用整数规划来做到这一点。但是,我会 运行 多次使用大型实例,我想知道是否有更好的方法,因为我深信它可以在多项式时间内完成,也许在 Julia 中使用聪明的 map
或其他高效功能!
您需要的是一种过滤集合成员的可能组合的方法。所以创建一个过滤函数。如果您提到的关于奇数 [3, 5, 7...] 序列的部分适用于此处,您可能需要以某种方式将其添加到下面的过滤器逻辑中:
using Combinatorics
allunique(a) = length(a) == length(unique(a))
slice(tuples, position) = [t[position] for t in tuples]
uniqueslice(tuples, position) = allunique(slice(tuples, position))
is_with_all_positions_unique(tuples) = all(n -> uniqueslice(tuples, n), 1:length(first(tuples)))
现在您可以找到组合了。对于大集合,它们的数量会激增,所以一定要在你有足够的时候退出。你可以在这里使用 Lazy.jl,或者只是一个函数:
function tcombinations(tuples, len, needed)
printed = 0
for combo in combinations(collect(tuples), len)
if is_with_all_positions_unique(combo)
printed += 1
println(combo)
printed >= needed && break
end
end
end
tcombinations(tuples, 3, 4)
[(2, 5), (4, 8), (3, 6)]
[(2, 5), (4, 8), (1, 4)]
[(2, 5), (4, 8), (5, 6)]
[(2, 5), (3, 6), (1, 4)]
在 Julia 中,给定一个名为 S
且长度大于 3 的 Set{Tuple{Int, Int}}
,例如:
julia> S = Set{Tuple{Int,Int}}([(1, 4), (2, 5), (2, 6), (3, 6)])
Set{Tuple{Int64,Int64}} with 4 elements:
(2, 5)
(3, 6)
(2, 6)
(1, 4)
我想要 return S
的子集 T
,其长度大于 3
且为奇数(3, 5, 7, ...),这样,元组的所有第一个值都是唯一的。例如,我不能有 (2, 5) 和 (2, 6) 因为第一个值 2 不是唯一的。这同样适用于第二个值,这意味着我不能有 (2, 6) 和 (3, 6)。
如果不可能,return一个空的元组集就可以了。
最后,对于上面的最小示例,代码应该 return:
julia> T = Set{Tuple{Int,Int}}([(1, 4), (2, 5), (3, 6)])
Set{Tuple{Int64,Int64}} with 3 elements:
(2, 5)
(3, 6)
(1, 4)
如果您认为它比 Set{Tuple{Int, Int}}
更好,我真的对任何其他类型的结构持开放态度 :)
我知道如何使用整数规划来做到这一点。但是,我会 运行 多次使用大型实例,我想知道是否有更好的方法,因为我深信它可以在多项式时间内完成,也许在 Julia 中使用聪明的 map
或其他高效功能!
您需要的是一种过滤集合成员的可能组合的方法。所以创建一个过滤函数。如果您提到的关于奇数 [3, 5, 7...] 序列的部分适用于此处,您可能需要以某种方式将其添加到下面的过滤器逻辑中:
using Combinatorics
allunique(a) = length(a) == length(unique(a))
slice(tuples, position) = [t[position] for t in tuples]
uniqueslice(tuples, position) = allunique(slice(tuples, position))
is_with_all_positions_unique(tuples) = all(n -> uniqueslice(tuples, n), 1:length(first(tuples)))
现在您可以找到组合了。对于大集合,它们的数量会激增,所以一定要在你有足够的时候退出。你可以在这里使用 Lazy.jl,或者只是一个函数:
function tcombinations(tuples, len, needed)
printed = 0
for combo in combinations(collect(tuples), len)
if is_with_all_positions_unique(combo)
printed += 1
println(combo)
printed >= needed && break
end
end
end
tcombinations(tuples, 3, 4)
[(2, 5), (4, 8), (3, 6)]
[(2, 5), (4, 8), (1, 4)]
[(2, 5), (4, 8), (5, 6)]
[(2, 5), (3, 6), (1, 4)]