ビットマスクによる部分集合列挙
整数を使ってすべての部分集合を反復します
「ビットマスクによる部分集合列挙」はCoddyKit上の無料Coding Interview Prepレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはCoding Interview Prep学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Coding Interview Prepコースには全4レッスンが含まれています。
数として表す部分集合
n個の要素のすべての部分集合は、1つの整数に対応させられます。0から順に数えると、それぞれの数のビットが、どの要素を含めるかを正確に表します。🙂
部分集合はいくつあるか
n 個の要素からなる集合には、2^n 個の部分集合があります。そのため、整数を 0 から 2^n - 1 まで動かせば、すべての部分集合を一度ずつ訪問できます。
for mask in range(1 << n):
pass # mask is one subset1 << n が個数です
シフト演算 1 << n は、2 の n 乗と等しくなります。部分集合を列挙するループの上限を、簡潔かつ高速に表せます。
ビット i を読み取る
要素 i が部分集合に含まれるか調べるには、1 を i ビット左シフトした値とのビット演算で、そのビットを確認します。結果が 0 でなければ、その要素は含まれています。
if mask & (1 << i):
take(items[i])選択した要素のリストを作る
各ビット位置を調べ、ビットが立っている要素を集めます。これにより、1 つのマスクから、それが表す具体的な部分集合を作れます。
chosen = [items[i] for i in range(n) if mask & (1 << i)]空集合と全体集合
マスク 0 は空集合を表し、すべてのビットが 1 のマスクは全体集合を表します。ループですべての値を扱うため、どちらも自然に含まれます。
部分集合の合計を求める
ループの中で、選択した要素を合計して各部分集合を評価します。これは多くの小規模な全探索解法の中心となる考え方です。
total = sum(v[i] for i in range(n) if mask & (1 << i))立っているビットを数える
選択した要素の数は、マスクのpopcountと等しくなります。Python では bin(mask).count('1') ですぐに求められます。
size = bin(mask).count("1")上限に注意する
部分集合は 2^n 個あるため、この方法は小さな n にしか適していません。すべて列挙する場合、実用上の上限は n が 20 前後です。
ビットマスクが有利な理由
複雑な入れ子のループを 1 つの整数ループに置き換えられ、ビット演算も高速です。コードが短く明快になり、テストもしやすくなります。
再利用できるパターン
maskをループし、ビットを解読して部分集合を評価し、最良の結果を記録します。このテンプレートを覚えておけば、多くの部分集合問題を定型的に解けます。
確認問題
mask で表された部分集合に要素 i が含まれているかを調べたいとします。
まとめ
0 から 2^n - 1 までmaskをループし、mask と 1 を i ビット左シフトした値でビットを読み取り、各部分集合を評価します。小さな n に対する、簡潔な全探索です。🚀
よくある質問
「ビットマスクによる部分集合列挙」レッスンは無料ですか?
はい。「ビットマスクによる部分集合列挙」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Coding Interview Prepコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Coding Interview Prepコースには全4レッスンが含まれています。
「ビットマスクによる部分集合列挙」で何を学びますか?
整数を使ってすべての部分集合を反復します ブラウザで直接実行するハンズオンコードでCoding Interview Prepを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Coding Interview Prepを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのCoding Interview Prepは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「ビットマスクによる部分集合列挙」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このCoding Interview Prepレッスンでコードを書いて実行できますか?
はい。すべてのCoding Interview Prepレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 全探索も有効な戦略
- itertools で列挙する
- ビットマスクによる部分集合列挙
- 探索空間を賢く絞り込む