Hi I was just wondering if there was a way to generate a combinatorial collection subject to some condition. For example using the Combinatorics package If I can generate all combinations of some vector
collect(combinations(1:6,2))
15-element Vector{Vector{Int64}}:
[1, 2]
[1, 3]
[1, 4]
[1, 5]
[1, 6]
[2, 3]
[2, 4]
[2, 5]
[2, 6]
[3, 4]
[3, 5]
[3, 6]
[4, 5]
[4, 6]
[5, 6]
However what if I only want the combinations where a certain condition is met, e.g. the second number minus the first is greater than one or the sum of the selected set is equal to some value. Is there a way to input these constraints as a parameter into combinations?
1 Like
how about using something like
filter(x -> (x[2] - x[1])>0 || sum(x) == value, collect(combinations(1:6,2)))
1 Like
You should drop the collect
to avoid allocating memory to store the discarded combos. If you must, add the collect
outside filter
.
2 Likes
oh sorry, just copy-pasted!
note: filter() does not work without using collect() in this case without using collect
.
1 Like
It appears that you need Iterators.filter
if the second argument is an iterator.
Iterators.filter(x → (x[2] - x[1])>0 || sum(x) == value, combinations(1:6,2))
3 Likes
yes this is a more memory friendly version just because it consumes memory when needed only.
1 Like
thanks guys! this is really helpful. When I try to run it with Iterators.filter without collect rather than the actual combinations I get this. Iterators.filter(x -> (x[2] - x[1])>0 ||sum(x) == 6 ,combinations(1:6,2)) Base.Iterators.Filter{var"#15#16", Base.Generator{Combinatorics.Combinations, Combinatorics.var"#10#13"{Combinatorics.var"#reorder#11"{UnitRange{Int64}}}}}(var"#15#16"(), Base.Generator{Combinatorics.Combinations, Combinatorics.var"#10#13"{Combinatorics.var"#reorder#11"{UnitRange{Int64}}}}(Combinatorics.var"#10#13"{Combinatorics.var"#reorder#11"{UnitRange{Int64}}}(Combinatorics.var"#reorder#11"{UnitRange{Int64}}(1:6)), Combinatorics.Combinations(6, 2)))
Is this normal?
1 Like
how about
Iterators.filter(x -> (x[2] - x[1])>0 || sum(x) == value, combinations(1:6,2)) |> collect
1 Like
awesome thanks! quick question what is the piping |>
operator doing and how does that differ from your initial code ?
1 Like
Yes it only collects the result returned by the filtered one.
1 Like