Is there a way to create a comprehensive set of conditional combinations

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

gotcha thanks again!

1 Like

Your welcome!

1 Like