1
大学数学基礎解説
文献あり

条件 (命題) で考える包除原理

705
0

本文

包除原理 (inclusion-exclusion principle) は、「集合の元の数」を計算する方法として説明されることが多いようですが、現実の問題に適用するときには「条件 (命題) を満たす場合の数」として考えることもあると思います。
そこで本稿では、「条件」という言葉を使って包除原理を記述することを試みます。本質的にはどちらで説明しても内容は変わりません。

基礎

条件Pが真であるときの場合の数を|P|で表すことにします。
また、条件が一つも設定されていない状態をϕで表すことにします。これはつまり、全事象を指します。

条件は「制約」と言い表してもよく、条件の設定を増やすことで場合の数は減っていきます。
すなわち、次が成り立ちます。

  • 任意の条件P,Qに対して、|PQ||Q| および |PQ||Q|
  • とくに、|P||ϕ| および |P||ϕ|

任意の条件Pに対して、実際にはPPのうちいずれか一方が成り立っています。
しかし、部分的な条件の組合せを考えるときには、一部の条件の真理値が不問になることもあることに注意します。
例えば、3つの条件 {P1,P2,P3} があるとき、P1P3P1,P3が真であり、P2については真偽が不問であることを指します。

包除原理で何ができるか

n個の条件 {Pi | 1in} の部分集合は2n個あります。
これらのすべての部分集合について、そのすべての元 (条件) の論理積を満たす場合の数が既知である (与えられる) とき、

  • n個の条件を一つも満たさない場合の数
  • n個の条件のうち少なくとも一つ満たす場合の数

を求めることができます。

「部分集合のすべての元 (条件) の論理積」とは、ある部分集合が {Pk1,Pk2,,Pkm} と表されるとき、Pk1Pk2Pkm を指します。
例えば、{P1,P2,P3} の部分集合 {P1,P3} には P1P3 が対応します。

条件を一つも満たさない場合の数

n個の条件 {Pi | 1in} があり、それらのうち一つも満たさない場合 (Pi=Pi) の数を本節で求めます。
また、それらのうち少なくとも一つ満たす場合 (Pi) の数を求めるには、上記の否定を考えればよいです。

まず、n=1,2,3のときの Pi を考えます。

n=1のとき、
  |P1|=|ϕ||P1|

n=2のとき、
  |P1P2|=|ϕ||P1||P2|+|P1P2|

n=3のとき、
  |P1P2P3|=|ϕ||P1||P2||P3|+|P1P2|+|P1P3|+|P2P3||P1P2P3|

このように、右辺の2n個の項が与えられれば、左辺が求められます。

では、一般のnに拡張しましょう。

包除原理

条件の集合 {Pi | 1in} の部分集合を整数 0x<2n と同一視する。
すべての部分集合xに対し、そのすべての元の論理積を満たす場合の数がc(x)で与えられるとする。
このとき、
(1)   |Pi|=|Pi|=0x<2n(1)popcount(x)c(x)
(2)   |Pi|=c(0)0x<2n(1)popcount(x)c(x)
が成り立つ。
ここで、popcount(x)x2進数で表したときの1の出現数とする。

概略

nについての数学的帰納法により、(1)のみ示せばよい。
任意の条件P,Qに対して、
  |PQ|=|P||PQ|
が成り立つことを利用する (Pで表される領域を2分割する)。

とくに、c(0)は全事象の数を表します。
また、popcount(x) は、部分集合xの元の数と言い換えられます。

例えばn=3のとき、
  |P1P2P3|=c(0)c(1)c(2)c(4)+c(3)+c(5)+c(6)c(7)
  |P1P2P3|=c(1)+c(2)+c(4)c(3)c(5)c(6)+c(7)
です。

c(x)の計算量オーダーをCとすると、全体の時間計算量はO(C2n)となります。

条件をすべて満たす場合の数

n個の条件 {Pi | 1in} があり、それらをすべて満たす場合 (Pi) の数を求めるには、Piの代わりにPiで考えればよいです。
すなわち、n個の条件 {Pi | 1in} を一つも満たさない場合の数と見なし、このすべての部分集合について、そのすべての元 (条件) の論理積を満たす場合の数が与えられれば、定理 1 から求めることができます。

また、{Pi} のうち少なくとも一つ満たさない場合 (Pi=Pi) の数を求めるには、上記の否定を考えればよいです。

実例 (全射の個数)

包除原理を実例で考えてみましょう。

全射の個数

n個の区別できる球をk個の区別できる箱に入れる方法のうち、すべての箱に1個以上の球が入る場合の数を求めよ。

箱の番号を1ikとします。
すると、求める数は、k個の条件「箱iには1個以上の球が入る」をすべて満たす場合の数です。
さらに、これらの否定であるk個の条件「箱iに球は入らない」を一つも満たさない場合の数、と言い換えられます。

これらのk個の条件の任意の部分集合の論理積となる場合の数は簡単に得られます。
実際、部分集合の元の個数をcとすると、各球に対してkc個の箱を自由に選べるため(kc)nです。
したがって、包除原理を適用して、
  S=0x<2n(1)popcount(x)(kpopcount(x))n
これを部分集合の元の個数ごとに整理すると、i=popcount(x)として、
  S=i=0k(1)ikCi(ki)n=i=0k(1)kikCiin
が得られます。

実例 (Euler の totient 関数)

Euler の totient 関数

nを正の整数とする。
n個の整数1,2,,nのうち、nと互いに素なものの個数を求めよ。

nの素因数の種類 (重複なし) が p1,p2,,pm と表せたとします。
すると、求める数は、m個の条件「piと互いに素」をすべて満たす場合の数です。
さらに、これらの否定であるm個の条件「piの倍数」を一つも満たさない場合の数、と言い換えられます。

これらのm個の条件の任意の部分集合の論理積となる場合の数は簡単に得られます。
例えば、「piの倍数」かつ「pjの倍数」は「pipjの倍数」です。
したがって、包除原理を適用して求めることができます。

例えば、n=20のとき、
  ()(2)(5)+(10)=20104+2=8
です。

これは Euler の totient 関数 φ(n) と呼ばれますが、実はこれをさらに簡潔に計算することができます。
上の定理の証明の中で「Pで表される領域を2分割する」と書きましたが、このときに「piの倍数」でない数の割合がpi1piであることが示せます。
したがって、1imに対してこれを乗算していけばよく、
  φ(n)=n1impi1pi
が成り立ちます。
この等式を使えば、全体では素因数分解がボトルネックとなり、時間計算量はO(n)で済みます。

改訂履歴

  • 2021.08.28 全射の個数の例を追記。

参考文献

投稿日:2021824
OptHub AI Competition

この記事を高評価した人

高評価したユーザはいません

この記事に送られたバッジ

バッジはありません。
バッチを贈って投稿者を応援しよう

バッチを贈ると投稿者に現金やAmazonのギフトカードが還元されます。

投稿者

Researcher and Developer for Algorithms, using C# (.NET). 数検1級金賞 (2002).

コメント

他の人のコメント

コメントはありません。
読み込み中...
読み込み中
  1. 本文
  2. 基礎
  3. 包除原理で何ができるか
  4. 条件を一つも満たさない場合の数
  5. 条件をすべて満たす場合の数
  6. 実例 (全射の個数)
  7. 実例 (Euler の totient 関数)
  8. 改訂履歴
  9. 参考文献