和集合・積集合・差集合・補集合をベン図で視覚的に理解する。
集合とは、ある条件を満たすものの「まとまり」のことです。集合に含まれる個々のものを要素(元)と呼びます。たとえば「10以下の偶数の集合 A = { 2, 4, 6, 8, 10 }」のように、波括弧で要素を列挙して表します。
集合には有限集合(要素の数が有限個)と無限集合(自然数の集合など)があります。ここでは主に有限集合を扱います。要素の数を|A|のように書き、これを集合の「濃度」や「要素数」と呼びます。
上のツールでプリセットを選び、演算を切り替えると、ベン図上で結果の領域がハイライトされます。まずは「基本の2集合」で A∪B や A∩B を切り替えて、色が塗られる範囲の違いを確認してみましょう。
和集合 A∪Bは「AまたはBに含まれる要素すべて」を集めたものです。日常の言葉では「AかBのどちらか(もしくは両方)に入っている」という意味で、ベン図では両方の円の領域全体が塗られます。
積集合 A∩Bは「AかつBに含まれる要素」を集めたものです。「両方に共通する部分」だけが該当し、ベン図では2つの円の重なり部分だけが塗られます。たとえば A={ 1,2,3,4,5 }, B={ 3,4,5,6,7 } なら A∩B={ 3,4,5 } です。
上のツールで演算を「A∪B」と「A∩B」で切り替えると、ハイライトされる範囲の違いを確認できます。要素を変更して、共通部分の数がどう変わるかも試してみてください。
差集合 A-Bは「Aには含まれるがBには含まれない要素」の集まりです。ベン図ではAの円からBとの重なりを除いた三日月型の部分が該当します。A={ 1,2,3,4,5 }, B={ 3,4,5,6,7 } なら A-B={ 1,2 } です。
補集合 Āは「全体集合Uのうち、Aに含まれない要素すべて」です。全体集合が U={ 1,2,...,9 } で A={ 1,2,3 } なら Ā={ 4,5,6,7,8,9 } です。ベン図では円の外側がハイライトされます。
差集合は「A∩B̄(AかつBの補集合)」と同じ意味です。この等価性は上のツールで A-B と Ā の結果を見比べると直感的に理解できます。
ド・モルガンの法則は、集合の補集合に関する2つの公式です。「和集合の補集合は、各補集合の積集合に等しい」「積集合の補集合は、各補集合の和集合に等しい」という関係を表します。
具体的には次の2つです。
・法則1:(A∪B)' = A'∩B' — 「AまたはB」の外側 = 「Aの外側」かつ「Bの外側」
・法則2:(A∩B)' = A'∪B' — 「AかつB」の外側 = 「Aの外側」または「Bの外側」
この法則は論理演算やプログラミングのif文にもそのまま適用できます。「!(a && b)」は「!a || !b」と同じ、という書き換えがまさにド・モルガンの法則です。
包除原理(ほうじょげんり)は、和集合の要素数を正しく数えるための公式です。単純に |A| + |B| と足すと、共通部分 A∩B に含まれる要素を二重にカウントしてしまうため、1回分引く必要があります。
2集合の場合:|A∪B| = |A| + |B| - |A∩B|
3集合の場合:|A∪B∪C| = |A|+|B|+|C| - |A∩B| - |A∩C| - |B∩C| + |A∩B∩C|
3集合では3つ全部の重なりを引きすぎるので、最後に1回足し戻します。
上のツールで和集合(A∪B)を選ぶと、チャートの下に包除原理の計算式が表示されます。「3集合」プリセットに切り替えて A∪B∪C の式も確認してみてください。
3つの集合を重ねたベン図には7つの領域(+外側1つで合計8つ)ができます。各領域は、どの集合に属しどの集合に属さないかの組み合わせで決まります。
7つの領域は次のとおりです。
・Aのみ / Bのみ / Cのみ:1つの集合だけに属する(3領域)
・A∩Bのみ / A∩Cのみ / B∩Cのみ:ちょうど2つの集合に属する(3領域)
・A∩B∩C:3つすべてに属する(1領域)
上のツールで「3集合」プリセットを選び、演算を切り替えると、それぞれどの領域が該当するかを視覚的に確認できます。3集合の包除原理は応用範囲が広いので、ぜひ慣れておきましょう。
| 集合演算 | Python | JavaScript |
|---|---|---|
| A∪B | A | B | new Set([...A, ...B]) |
| A∩B | A & B | A.intersection(B) |
| A-B | A - B | A.difference(B) |
| A△B | A ^ B | A.symmetricDifference(B) |
多くのプログラミング言語にはSet型(集合型)が標準ライブラリに用意されています。Pythonではset()、JavaScriptではnew Set()で作成できます。
Set型は重複を自動的に除去し、要素の存在確認が高速(O(1))です。「リストから重複を消したい」「2つのリストの共通要素を取りたい」といった場面で活躍します。数学の集合論がそのままコードになるので、この考え方を身につけておくと実務でも役立ちます。
集合の包含(A⊆B)とは、「Aのすべての要素がBにも含まれている」という関係のことです。ベン図で見ると、Aの円がBの円の中にすっぽり入っている状態です。
なぜ A⊆B になると A∩B = A になるのか。AがBに完全に含まれているということは、A の要素は全部 B にも入っています。だから「A かつ B」の共通部分を取っても、全部 A の要素になる——つまり A∩B はそのまま A と等しくなります。
・A⊆B(AはBの部分集合):AのすべてがBに入っている
・A=B(AとBは等しい):A⊆B かつ B⊆A のとき(互いに包含しあっている)
・A⊂B(AはBの真部分集合):A⊆B かつ A≠B(BにはAにない要素が少なくとも1つある)
身近な例で考えると、「スポーツカーの集合⊆車の集合」のようなイメージです。スポーツカーはすべて車ですが、車にはスポーツカー以外( トラックやバスなど)も含まれます。上のツールで A の要素を B の要素と全部重なるように変えると、A∩B の結果が A と同じになることを確認できます。
なぜ |A|+|B| から |A∩B| を引くのか。答えは「重なり部分を2回数えてしまうから」です。
考え方は次のとおりです。
・|A| を数える:A の要素を全部数える(共通部分も含む)
・|B| を数える:B の要素を全部数える(共通部分も含む)
・このとき、A∩B の要素は A でも B でも数えられ、2回カウントされている
・だから |A∩B| を1回引くと、ちょうど1回だけ数えた正しい値になる
身近な例で考えると、「スポーツが好きな人:6人」「音楽が好きな人:5人」で「両方好きな人:2人」のとき、両方好きな2人は両方のグループに入って数えられているため、単純に 6+5=11 では両方好きな人を2回数えてしまいます。正しくは 6+5-2=9人です。これが包除原理の直感です。