I would like to generate a powerset of a rather big set (about 30-50 elements) and I know that it takes 2^n
to store the powerset.
Is it possible to generate one subset at a time?
I.e. generate a powerset of a set with iterations, saving each generated subset to disk/database, removing it from the stack/memory and only then continuing to generate other subsets?
Unfortunately I have failed to modify Erlang and Ruby examples to my needs.
Edit: Added the enumerator (as @Jörg W Mittag) if no block is given.
Output
One way to generate a powerset of a list (which is in fact the one that your Erlang example uses) is to iterate over all numbers
x
from 0 to 2^n (exclusive) and for eachx
, generate the list that contains thei
th element of the original list if and only if thei
th bit ofx
is set.Since using this approach generating the current list only depends on the value of
x
and not on any of the previously generated lists, you don't have to keep the lists in memory after using them. So this approach can be used to do what you want.This uses the standard "bit array" trick for generating power sets (and it uses the fact that Ruby's
Integer
s behave as bit arrays). But more importantly, it uses anEnumerator
to generate the sets lazily.This works perfectly fine even for thousands of elements:
EDIT: This is based on @steenslag's solution. I totally forgot about
Array#combination
, since I was too focused on finding a solution that would work for anyEnumerable
. However, my solution requires that theEnumerable
be finite anyway, and any finiteEnumerable
should probably be representable as anArray
, so that's not much of a restriction.