カントール集合。切れてるのに連続体
1.整数全体と自然数は同等
このワークシートはMath by Codeの一部です。
無限の数のあつまりを数えるにはどうしたらよいでしょうか。
数えるための道具は自然数です。
数えるための技術は写像です。
たとえば、整数全体と自然数は同等な個数(基数、濃度)とわかります。
同等(対等)は、(等号、合同、同値、同型)と同じ構造の概念なので、
自同律、反射律、推移律を満たします。(A=A。A=BならB=A。A=B,B=CならA=C。)
また、自然数の個数をℵ0(アレフゼロ)というラベルをはることが多いので、
これからその習慣に従いましょう。
N=[1,2,3,4,5,6,7,......]に対して、
Z=[0,1,-1,2,-2,3,-3,.....]というリストを作るとすべての整数はこのリストに出てきます。
逆にZ[n]=mとなるようなnをmから逆算することもできますね。
質問:自然数n番目の整数Zをm=Z[n] とするとき、関数f:n→mとその逆関数をつくりコード化するにはどうしますか。Zのサイズが100のリストをつくりましょう。
m=Z[n]はnが偶数ならばm=n/2, nが奇数ならばm=(1-n)/2です。
m=Z[n]となるnは、mが正の数ならn=2m, mが0以下ならn=1- 2mです。
ZとNは同等
2.数えられるものはもっとある
<有理数は自然数と同等>
分数は帯分数を仮分数にすれば、すべて分母と分子の2数組に直せるね。
ということは、分母+分子が決まった数になる。
分母+分子をN+1と決めるとそれに属する分数はN分の1から1分のNまでのN個ある。
分母+分子=和を2,3,...と決めて並べてみよう。
分子、分母の順にならべたタプルで分数を表示すると
和がN+1のものがN個だから、和を2,3,4,....と動かすと、個数は1,2,3,....と増えていく。
和 2:(1,1)
和 3:(1,2),(2,1)
和 4:(1,3),(2,2),(3,3)
.................................................
これで、正の分数Q+はNと同等になるね。
Nの順に対応させた、タプルのリストQPは次のようになる。
QP=[(1,1),(1,2),(2,1),(1,3),(2,2),(3,1),.........]
順序づけはともかく、分数の居場所が1つに決まるやり方は簡単です。
分数は2成分、2次元だから、m分のnつまり、{n,m}はm行n列にかくとしたら、
なんの計算もなく場所が1対1に対応します。
これを自然数Nと同等だと確認する方法はm+n=kのグループ化をGkとかくと、
G2,G3,G4,.......とグループ順にならべます。そのグループ内で、nの順にならべればよいですね。
質問:Nの番号nからQPの分数を返したり、その逆をコードで実行するにはどうしたらよいでしょうか。
グループのサイズを数列の和は|G2|+|G3|+|G4|=1+2+3=6=3(3+1)/2 と、三角数になります。
番号nが和がx+1までグループを過ぎて、和がx+2のグループにあるとすると
x(x+1)/2< n ≦(x+1)(x+2)/2となるね。
x2+x-2n<0 and x2+3x+2-2n≧0 and xは整数。
両方を=0にしてsolveで解をもとめて整数化すれば、はさまれる整数xは求められる。
これを満たすx=kと決まったとする。
k+2グループの中の番号はh=n-k(k+1)/2だ。hは列目を表すから、行はk+2-h。
これから、分数は{h, k+2-h}となるね。
逆に、分数{n,m}はグループG(n+m)にあり、グループのn番目。
1つ前のG(n+m-1)には分数がn+m-2個ある。
そこまでの分数の個数は(n+m-2)(n+m-2+1)/2だから、さらにnをたせばよい。
分数{n,m}の番号は、(n+m-2)(n+m-1)/2+nとなるね。
では、次は有理数全体QをNに対応させます。
これは、いつか来た道ですね。
そうです。NからZに対応させたとき, [0, 1, -1, 2, -2,3,-3,4,-4,.... ]と並べました。
NからQに対応させるには、[(0,1), (1,1),-(1,1),(1,2),-(1,2),(2,1),-(2,1),(1,3),-(1,3),(2,2),-(,22),....]
同じようにやればいいですね。
これで、NとQが同等になりました。
数の並びは大小関係だけで数直線に並べてイメージするのが簡単です。だから、無意識にそうするでしょう。しかし、個数の同等性を調べるには、単純な大小関係だけではない視点が役立つということだね。
<代数的数も自然数と同等>
たとえば、x2-2=0の解であるx=√2など無理数も入れたら自然数、無理数よりも大量にある気がする
かもしれません。
係数が整数の代数方程式の実数解を代数的数といいます。
無理数も入っている代数的数も自然数と同等なのです。
これも単純な大小関係だけではない視点を使うと説明できます。
代数的数は代数方程式に対応させられます。
係数の最大公約数が1になるようにすれば、一意的に作れますね。
代数方程式の次数に係数の絶対値を加えた合計値を高さと定義しましょう。
すると、どの代数方程式にも高さを決めることができます。
の代数方程式に対して高さhを決めます。
とします。
たとえば、
h=0,1はなし。
h=2: x=0の1個
h=3: x+1=0, x-1=0, 2x=0,x2=0の4個。
h=4: x+2=0, x-2=0, 2x+1=0,2x-1=0,3x=0;x2+1=0,x2-1=0,2x2=0;x2-x=0,x2+x=0; x3=0の11個
このようにして、高さ順、方程式の順(nの小さい順、係数は正から負の順、などと決めて)で、
代数的数をすべて並べることができる。
だから、代数的数も自然数と同等だね。
3.実数は自然数と無限のレベルがちがう
有名な対角線論法を使うとℵ0よりも多い集合があることがわかります。
<対角線論法>
対象とする集合が自然数と同じ個数だとして要素に番号をつけて小さい順にならべます。
Rで正のものに限ると、Rの要素は0.abcdef.......のようになります。
有限小数の場合は99999....と表記する。
Rの数列は無限だが、無限列について新たな実数xを作る。
xの小数第n位を決めるときに、Rのn番目の数の小数第n位がpならばp以外で0でも9でもないものにする。こうして、xを決めるとこれですべてと思われた実数Rのどれともちがう実数ができてしまう。
こんな矛盾がおきたのは、集合Rが自然数Nと同等だとする仮定があったからだ。
つまり、実数は自然数、有理数、代数的数これらの個数(基数)とはレベルがちがう
無限さをもつ個数、基数だということだ。これをℵ(アレフ)とかく。ℵ0<ℵ
ℵ0の個数の集合を可付番集合と名付けたりする。
だから、実数の基数ℵを連続体濃度と名付けたりする。
この論法と同様の論法によって、実数と同じ連続体濃度の集合が他にもあることがわかります。
くわしい証明ははぶきます。
(例)数字0,1だけでできた無限数列全体の集合Xはℵと同等。
(例)数直線にある両端を含む線分の区間を閉区間といいます。区間の3等分をして真ん中を捨てる。
[0,1]からスタートしてこれを無限に繰り返した集合をカントール集合といいます。
これもℵと同等。
カントール集合は、
{[0,1],
[0,1/3]+[2/3,0],
[0,1/9]+[2/9,3/9]+ [6/9, 7/9]+[8/9,1]
,......}
質問:カントール集合をgeogebraのツールを活用して視覚化するにはどうしたらよいでしょう。
コードが複雑になることと帰納的な記述が必要になることから、「新規ツール」の作成を繰り返して
まるで、関数のように手続きをかたまりにして扱ってみよう。
カントール集合は3つにわけることがポイントではない。
線分の端点の個数が2,4,8,16,32, .........と倍々になることだ。
点は数値で表現できるので、数値のリストの長さを倍にしていくプロセスが本質になる。
そのためには、点を2個セットにして取り出すというTakeコマンドと、
flattenコマンドでリスト群を1つのリストにすることがカギになります。
もちろん、線分の3等分によって端点の間に2点が追加されるという手続きが最初に必要になるね。
たとえば、次のようなやり方もできるでしょう。
(注意:ツールはツール名で反応するわりには、コマンド群が先読みして別のツール名になって邪魔したりします。だから、数式をエディターとして使うには不安定です。簡単な例を入れて動きをためすには
とても便利ですが、複雑なものや1行が長くなるもの、カッコが多重になるものは編集が自由にできません。そこで、メモ帳やテキストアプリなどをたちあげて、それをエディターとして一行書いて、一行単位で、数式に張り付けるという作業をお勧めします。2025現在。geogebraのサポーター、推進メンバーの方々のエディター改善を希望します。)
・線分の3等分関数をつくる。
数式に次のように3行入れます。
M1={0,1}
d=((M1(2)-M1(1))/(3))
M2={M1(1),M1(1)+d,M1(2)-d,M1(2)} //M1を入力するとなら {0,1/3.2/3,1}を出力します。
右上角のメインメニューから「ツール」を選び、「新規ツールの作成」をします。
「入力」タブのプルダウンからM1を選び、「出力」タブのプルダウンからM2を選びます。
ツールの名前をbaiListなどとします。これで下にある「終了」を押すと、新規ツールできます。
M2=baiList(M1)となる関数を作ったことになります。
・偶数個の数値リストから倍の個数の数値リストを作る。
L1={1,2,3,4}
L2=Flatten(Sequence(baiList(Take(L1,a,a+1)),a,1,Length(L1),2))
入力をL1、出力をL2として、L2=pairsbaiList(L1)となる新規ツールを作ります。
リストの先頭から2個ずつ取り出し、それをbaiListをして3等分データにしたリスト群をFlatten()
で1つのリストとしてに平らにつぶしたものがL2となります。
データがないと作れないのでL1は数値4個ですが、数値が偶数個なら同じ動きをします。
・数値リストから2個単位で線分列にします。
h=0
L1={1,2,3,4}
S=Sequence(Segment((L1(a),h),(L1(a+1),h)),a,1,Length(L1),2)
入力をリストL1と数値h、出力をSとして、S=segList(L1,h)となる新規ツールを作ります。
・ここまでが関数群の作成です。ここからが、再帰的なデータ作成になります。
M1という2要素がl1=baiList(M1)//{0,1/3,2/3,1}で4要素になります。
l2=baiList(l1)//{0,1/9,2/9,3/9,6/9,7/9,8/9,1}で4要素になります。
こうして、8要素のl3,16要素のl4,32要素のl5,64要素のl6,128要素のl7を作ります。
hを適当に少しづつ増やしてhiを求め
segList(l1,h1)からsegList(l7,hy)を作りましょう。
描画と画素の限界のために、4段階目あたりからはちがいがわからなくなりますが、
拡大すると細かい線分を見ることができるでしょう。
intervalという変数に線分の隙間のサイズが入るようにして、スライダーで可変にすると
インタラクティブに視覚化を変える体験ができますね。