Есть имя для того, что вы спрашиваете. Он называется блок питания .
Поиск в Google по «алгоритму набора мощности» привел меня к этому рекурсивному решению .
Алгоритм Ruby
def powerset!(set)
return [set] if set.empty?
p = set.pop
subset = powerset!(set)
subset | subset.map { |x| x | [p] }
end
Power Set Intuition
Если S = (a, b, c), тогда powerset (S) - это набор всех подмножеств
powerset (S) = {(), (a), (b), (c), (a, b), (a, c), (b, c), (a, b, в)}
Первый «трюк» - попытаться определить рекурсивно.
Каким будет состояние остановки?
S = () имеет что powerset (S)?
Как получить к нему?
Уменьшить набор на один элемент
Подумайте о том, чтобы убрать элемент - в приведенном выше примере выньте {c}
S = (a, b), затем powerset (S) = {(), (a), (b), (a, b)}
Чего не хватает?
powerset (S) = {(c), (a, c), (b, c), (a, b, c)}
Ммм
Заметили сходство? Посмотри еще раз ...
powerset (S) = {(), (a), (b), (c), (a, b), (a, c), (b, c), (a , б, в)}
вынуть любой элемент
powerset (S) = {(), (a), (b), (c), (a, b), (a, c), (b, c), (a , б, в)} is
powerset (S - {c}) = {(), (a), (b), (a, b)} объединены с
{c} U powerset (S - {c}) = {(c), (a, c), (b, c), (a, b, c)}
powerset (S) = powerset (S - {e i }) U ({e i } U powerset (S - {e i }))
, где e i - элемент S (синглтон)
Псевдо-алгоритм
- Набор передан пустым? Готово (обратите внимание, что для {}} установлено значение мощности {}}
- Если нет, вынуть элемент
- рекурсивный вызов метода для оставшейся части набора
- вернуть набор, составленный из Союза
- powerset набора без элемента (из рекурсивного вызова)
- этот же набор (т. Е. 2.1 ), но с каждым элементом в нем, объединенным с первоначально удаленным элементом