半分全列挙: 半分ずつ調べて組み合わせよう
半分全列挙は、全パターンを一気に調べる代わりに、半分ずつ列挙して後で組み合わせる方法です。
30個の全探索は大変ですが、15個ずつに分けると、それぞれの結果を組み合わせて考えられます。
使いどころ
- 全探索したいが数が少し多い
- 部分集合の合計を調べる
- 左半分と右半分を組み合わせられる問題
手順
- データを半分に分ける
- 左半分の全パターンを作る
- 右半分の全パターンを作る
- 2つの結果を組み合わせて答えを探す
図で見る
コピペ用コード
def subset_sums(numbers):
sums = [0]
for number in numbers:
sums += [value + number for value in sums]
return sums
numbers = [3, 5, 8, 10]
left = subset_sums(numbers[:2])
right = subset_sums(numbers[2:])
print(left, right)
コードの読み方
subset_sums()は、選んだ数の合計をすべて作る関数です。sums += ...で、今ある合計に新しい数を足した合計を追加しています。leftとrightを後で組み合わせることで、全体の候補を考えます。
注意点
半分全列挙は、全探索よりは軽くなりますが、それでも候補数は多いです。ソートや二分探索と組み合わせることがよくあります。