愛想モルフィズム

I saw what I am

ムゲンの実の数学 #2 低次における味の総数の最大値

見切れている数式はスクロールで!


dafuyafu.hatenablog.com

ムゲンの実の数学#2です.

今回は,前回の記事で定義した  S_n について,その低次の具体例,すなわち  S_1, S_2 について考えてみたいと思います.

前回の振り返り

ムゲンの実というお菓子は赤色のシャリシャリの実,黄色のシュワシュワの実,そして青色のヒエヒエの実からなります.ムゲンの実1袋につき,3種類の実がそれぞれ15個ずつ,合計45個入っていると仮定します.このムゲンの実が  n 袋ある状態を  n ムゲンの実モデル ( n-IBM ) といいます.

さて,ムゲンの実は無限個の実がある場合はそれらを重複を許して無限個組み合わせることで無限通りの味を食べることができます.では, n-IBMでは何種類の味を食べることができるか?ということについて考えていました.この味の種類の最大値を  S_n と表します.

定理 2.1  S_1 = 16.

定理1の主張は「1袋のムゲンの実では最大16種類の味を食べることができる」ということです.無駄に難しく書いているふうに思うかもしれませんが,これは数学的正確性を失わずに記述するためには絶対に必要な手続きです.

証明(概略) まず,前回の記事で16種類の味を構成した.よって  S_1 \geq 16 である.ここで,これ以上の味の種類を作ることができないことを示す.
ここで,前回の記事の通り,この16種類の味を構成した時点で残っている実の数は3つであり,3つの組み合わせで得られる味はすべて網羅しているのでこの構成方法ではこれ以上の味を構成できない.
よって,この構成方法を用いないで構成する必要がある.4つ実を使って得られる組み合わせの代わりに5つ以上実を使って得られる組み合わせを採用する.しかし,この方法だと余剰の実の数が少なくなり得られる味の個数も増えることがない.よって16個以上の味は作ることができない. \square

証明2 Pythonを用いて実際にすべての組み合わせを計算した.

# ibm.py

import itertools as it
import numpy as np

if __name__ == '__main__':
    l = ['R', 'Y', 'B']
    proj = []
    for i in range(4): # 4種類までに制限
        h = list(it.combinations_with_replacement(l, i + 1))
        for v in h:
            r = 0
            y = 0
            b = 0
            for e in v:
                if e == 'R':
                    r += 1
                elif e == 'Y':
                    y += 1
                elif e == 'B':
                    b += 1
            vec = np.array([r,y,b])
            for c in range(4):
                flag = True
                for p in proj:
                    if np.array_equal((c + 2) * p, vec):
                        flag = False
                        break
                if not flag:
                    break
            if flag:
                proj.append(vec)

    maximum = 0
    for i in range(len(proj) - 1):
        reg = it.combinations(proj, i + 1)
        for r in reg:
            s = np.array([0,0,0])
            for v in r:
                s += v
            if s[0] <= 15 and s[1] <= 15 and s[2] <= 15:
                maximum = i + 1
            else:
                pass

    print("S_1 = " + maximum)
S_1 = 16

これを計算すると  S_1 = 16 となる. \square

これを実行すると計算終了までに5分くらいかかります.並列化などを使って高速化させると1分ぐらいまでに短縮できました.

f:id:dafuyafu:20200227103249j:plain
S_1 = 16

定理 2.2  S_2 = 26.

残念ながら上記のプログラムの方針では (値を変えても) うまく計算できませんでした.itertools.combination() での組合せの生成で組合せ爆発が生じており,5つの実を使って得られる味10個の組み合わせを列挙しようとするとメモリが足りませんでした.改良が求められます.

一般論

さて,一般的な場合を考えるときに以下の数列を考えます.

 {\displaystyle C_k =\  _{3} \mathrm{H}_k - \sum_{i \lneq k,\ i | k} C_i}

 C_k はちょうど  \mathbb{P} の点  P = [a:b:c] であって  m_a + m_b + m_c = k を満たす点  P の個数を表していることがわかると思います.例えば  k = 1 のときは

 C_1 = \ _{3} \mathrm{H}_1 = \ _{3} \mathrm{C}_1 = 3

となりますが,ちょうどこれは  m_a + m_b + m_c = 1 を満たす点が

 [1:0:0], [0:1:0], [0:0:1]

の3つあることと対応しています.同様に  C_2

 C_2 = \ _{3} \mathrm{H}_2 - C_1 = \ _{4} \mathrm{C}_2 - 3 = 3

となり, k = 4 のときは前回の記事でやったとおり,

 C_4 = \ _{3} \mathrm{H}_4 - \{C_1 + C_2 \}= \ _{6} \mathrm{C}_4 - 3 - 3 = 9

となります.IBMの言葉で書き下すと,3種類の実を  k 個使って食べられる味の総数から, k 個未満でまかなえるものは除いた味の総数を  C_k は表しているのです.

ここで,さらに

 {\displaystyle T_k = \sum_{i = 1}^k C_i}
 {\displaystyle B_k = \sum_{i = 1}^k i C_i}

とします.これはそれぞれ, T_k は1個から  k 個まで使って食べられる味の総数 B_k は1個から  k 個まで使って全種類の味を食べるのに必要な実の総数(の最小値)を表しています.

実際, [1:0:0] という味を食べるのに赤を2個食べてしまうと実の総数は1個分多くなってしまいます.よって正確には B_k は最も効率的に全種類食べたときの実の総数を表していると言えます.

補題 2.3 ある  k > 0 が存在して  B_{k-1} \leq 45 n \leq B_k と表せるとき,

 T_{k-1} + 1 \leq S_n \leq T_k

証明 読者への課題とする(迫真)

この補題は,前回の記事でやったように,少ない個数の実を使うやり方から順番にとっていけば,食べられる味の総数を最大化できるということを意味しています.また,味の個数の最大値の存在範囲は,実の絶対数によって制限できることも分かります.

系 2.4

  1.  23 \leq S_2, S_3 \leq 40
  2.  41 \leq S_4, S_5 \leq 55
  3.  56 \leq S_6, S_7, S_8, S_9, S_{10} \leq 88

(2.3)により,あらかたの食べられる味の総数の目算が建てられるようになります.例えば,ムゲンの実を10袋買ってきたとしても,食べられる味の総数は多くても88種類しかないということが分かります.これだとムゲン感はあまりないかもしれませんね.


今回は具体的な計算を実際に行い,それを求めるプログラムを制作し, S_n の粗方の目算を建てる不等式を得ることができました.次回はより深い考察を得るために,実を割るという操作を許し,言及を避けてきた射影空間  \mathbb{P} について考えたいと思います.

査読よろしくお願い致します.