シリーズ「コンピュータの誤り訂正のしくみ」 第4回

回路が「言い当てる」とは?

ランプを、3 つに

ここまでの回を、短く振り返っておこう。

第1回は、4 桁の知らせに、1 の数を偶数にそろえる検査の桁を 1 つ足した(パリティ)。 これだけで、どの 1 桁が化けても、受け取った側のランプが光った。けれど、どこが化けたかは分からなかった。

前回は、知らせを 2 行 2 列に並べ、行ごと・列ごとにパリティをかけた。 1 か所化けると、光った横のランプと縦のランプが交わるところに、化けた桁があった。 0 と 1 しかないので、場所さえ分かれば、その桁を反転するだけで直る。 検査の桁そのものが化けても、「横だけ」「縦だけ」という光り方で見分けがついた。

前回の終わりに、ランプの光り方を数えた。 4 つのランプの光り方は 16 通り。 そのうち使っていたのは、無事と、8 か所のどれが化けたかの 9 通りだけだった。

ランプを減らしても、化けた場所を言い当てられないか。 これが、前回の終わりに残った問いである。

3 つのランプで、何通り

ランプを 3 つにしてみる。

ランプ 1 つは、光るか消えているかの 2 通り。 3 つなら、光り方は 2 × 2 × 2 = 8 通りある。

そのうち 1 通り、1 つも光らないのは「無事」に使う。 残りは 7 通り。 化けた場所ごとに違う光り方を割り当てられれば、7 か所まで見分けられる。

ここで、前回のことを思い出したい。 化けるのは、知らせの桁だけではない。検査の桁も化ける。

ランプを 3 つにするなら、検査の桁も 3 つになる。 見分けなければならない場所は、その 3 つも含めて 7 か所だ。 すると、知らせに使えるのは、7 − 3 = 4 桁。

ちょうど、このシリーズでずっと送ってきた知らせの長さである。

送る桁数は、7 桁。 3 回送るやり方は 12 桁、前回の縦横のパリティは 8 桁だった。 それより、さらに 1 桁少ない。

ただ、ここまでは数を数えただけだ。 本当に 7 か所を見分けられるかどうかは、光り方の割り当て方しだいである。

光り方を、配る

3 つのランプを、ランプ A・B・C と呼ぶことにする。 どのランプも、第1回のパリティの検査だ。 前回の横のランプが 1 つの行だけを見ていたように、それぞれ、決まった桁の組だけを見る。

これから、7 か所に光り方を 1 つずつ配っていく。 「この桁が化けたら、このランプが光る」と決めるのは、「このランプの検査は、この桁を見る」と決めるのと同じことだ。

まず、検査の桁から。 前回、横の検査の桁は、横の検査にしか見られていなかった。だから、化けると横のランプ 1 つだけが光った。 ここでも同じにする。 ランプ A の検査の桁は、ランプ A にだけ見られる。 化けると、A だけが光る。 B と C も同じだ。 1 つだけ光る 3 通りは、検査の桁に配る。

残る光り方は 4 通り。 2 つが光る 3 通り(A と B、A と C、B と C)と、3 つとも光る 1 通りだ。 これを、知らせの 4 桁に配る。

どう配ってもいいのだが、ここでは次のように配っておく(この順にした理由は、あとで分かる)。

  • 知らせの 1 桁目 … B と C
  • 知らせの 2 桁目 … A と C
  • 知らせの 3 桁目 … A と B
  • 知らせの 4 桁目 … A と B と C

表にすると、こうなる。 ● は「そのランプの検査が、その桁を見ている」印だ。 行はランプ。列の見出しの「知1」は知らせの 1 桁目、「検A」はランプ A の検査の桁のこと。

知1知2知3知4検A検B検C
A●●●●
B●●●●
C●●●●

横に読むと、そのランプの検査が見ている桁。 縦に読むと、その桁が化けたときに光るランプ。 7 つの列の点の並びは、どれも違う。

検査の桁の値は、第1回と同じ決め方で決める。 自分のランプが見ている桁の、1 の数を偶数にそろえる。

知らせが 1011 なら、こうなる。

  • ランプ A は、知らせの 2・3・4 桁目を見る。0 1 1 で、1 は 2 個。偶数だから、検査 A は 0
  • ランプ B は、知らせの 1・3・4 桁目を見る。1 1 1 で、1 は 3 個。奇数だから、検査 B は 1
  • ランプ C は、知らせの 1・2・4 桁目を見る。1 0 1 で、1 は 2 個。偶数だから、検査 C は 0

送るのは、知らせ 1011 と検査 010 の 7 桁だ。

受け取った側は、ランプごとに、点のある桁の 1 の数を確かめる。 奇数なら、そのランプを光らせる。

押して、確かめる

下のシミュレータは、前回までと同じく、知らせの 4 桁のあとに検査の桁を並べた。 受け取る側の 7 桁の下に、さっきの点の表を置いてある。 行の右端が、そのランプだ。

3 つのランプ シミュレータ

⚡ で 1 桁化かし、同じ光り方の列を、点の表から探してみてください

送る側

知らせ
検査
0
1
0

紫=検査の桁(自動で決まる)。下の表で、同じ行に点のある桁の 1 の数を偶数にそろえる

↓ 7 桁を送る。通り道(⚡ を押した桁が反転する)

↓ 化けた桁:0 か所

受け取る側

知らせ
検査
1
0
1
1
0
1
0
A
B
C

光ったランプ:なし

点=そのランプの検査が見ている桁
ランプ=点のある桁の 1 の数が奇数なら光る

受け取った側の回路は、送った知らせを知らない

ランプは 1 つも光っていない。どのランプの見ている桁も、1 の数は偶数だ。

⚡ で、知らせの 2 桁目を化かしてほしい。

ランプ A と C が光る。 表の中で、A の行と C の行にだけ点があり、B の行には点がない列を探すと、知らせの 2 桁目の列が見つかる。

ほかの桁も、1 つずつ化かしてみてほしい。 光り方は、7 か所ですべて違う。 紫の検査の桁を化かすと、そのランプだけが光る。

ここでも、いつもの確認をしておこう。 受け取った側の回路は、送った知らせを知らない。 赤い枠は、画面の前のあなたにだけ見えている。 回路に分かるのは、3 つのランプのどれが光ったか、それだけだ。

それでも、7 か所の光り方がすべて違うのだから、光り方さえ分かれば、場所は決まる。 ランプ 3 つで、7 か所を見分けられた。

ただ、少し面倒だ。 光り方を見るたびに、表の 7 列と見比べて、同じ並びの列を探さなければならない。

前回の縦横のパリティなら、光った行と列の交わるところを見に行けばよかった。 今度の表には、そういう手がかりがない。 光り方と場所の組み合わせを覚えておくか、そのつど表を引くしかない。

番号順に、並べる

ここで少し、数の書き方の話をしよう。

ふだん使っている数の書き方では、右から 1 の位、10 の位、100 の位と並ぶ。 左へ 1 つ進むごとに、位の重みが 10 倍になる。 305 なら、100 が 3 つと、1 が 5 つだ。

0 と 1 しか使わない書き方でも、考え方は同じだ。 ただ、左へ 1 つ進むごとに、重みが 2 倍になる。 右から 1 の位、2 の位、4 の位。 この書き方を 2 進数という。

101 なら、4 の位が 1、2 の位が 0、1 の位が 1。 4 + 1 で、5 を表す。

3 桁の 2 進数は、000 から 111 まで、2 × 2 × 2 = 8 通りある。

2 進数計算数
000—0
00111
01022
0112 + 13
10044
1014 + 15
1104 + 26
1114 + 2 + 17

8 通り。3 つのランプの光り方と、同じ数だ。

『計算のしくみ』を読んだ人は、第4回で、一番左の桁の名札を「8 の位」から「-8 の位」に貼り替えたのを思い出してほしい。同じ 0 と 1 の並びでも、名札しだいで表す数が変わった。

では、3 つのランプに名札を貼ってみよう。 上から、ランプ A に 4、B に 2、C に 1。 光っていれば 1、消えていれば 0 と読むと、光り方が 0 から 7 までの数になる。

さっきの表の列を、上から読んでみる。

  • 知らせの 1 桁目 … B と C に点 → 011 → 3
  • 知らせの 2 桁目 … A と C に点 → 101 → 5
  • 知らせの 3 桁目 … A と B に点 → 110 → 6
  • 知らせの 4 桁目 … 全部に点 → 111 → 7
  • 検査 A … A だけに点 → 100 → 4
  • 検査 B … B だけに点 → 010 → 2
  • 検査 C … C だけに点 → 001 → 1

7 つの列が、1 から 7 までの数に、ちょうど 1 つずつなった。 無いのは 0 だけ。0 は「1 つも光らない」、無事の印だ。

この数を、その桁の番号と呼ぶことにしよう。 そして、列を番号の順に並べ替える。

1234567
4●●●●
2●●●●
1●●●●

各列の点を上から読むと、001、010、011、100……。 1 から 7 までを、2 進数で順に数えているだけの表になった。

横に見ると、4 のランプは 4〜7 番を、2 のランプは 2・3・6・7 番を、1 のランプは奇数の番を見ている。 どれも、番号を 2 進数で書いたときに、その位が 1 になっている桁だ。

では、検査の桁と知らせの桁は、それぞれ何番に来たのだろう。

検査の桁の列は、点が 1 つだけだった。自分のランプにしか見られていないからだ。 点が 1 つだけの 3 桁の 2 進数は、001、010、100 の 3 つしかない。数にすると、1、2、4。 だから、検査の桁は 1 番・2 番・4 番に来る。 (1、2、4 は、1 から始めて 2 倍、2 倍としていった数だ。こういう数を 2 の累乗という。)

知らせの桁は、残りの 3・5・6・7 番に入る。

  • 知らせの 1 桁目 → 3 番
  • 知らせの 2 桁目 → 5 番
  • 知らせの 3 桁目 → 6 番
  • 知らせの 4 桁目 → 7 番

番号の小さいほうから、知らせの 1 桁目、2 桁目、3 桁目、4 桁目と、もとの順番のまま並んでいる。

知らせの 4 桁に光り方を配ったとき、「B と C」「A と C」「A と B」「全部」の順にしておいたのは、このためだ。 ほかの順で配っていたら、番号順に並べ替えたときに、知らせの桁の順番が入れ替わってしまう。

読むだけで、分かる

番号順に並べたシミュレータで、もう一度化かしてみよう。 ランプの名前も、4・2・1 に変えてある。

番号で言い当てる シミュレータ

⚡ で化かした桁の番号を、ランプが言い当てるか見てください

送る側

1
2
3
4
5
6
7
0
1
0

紫=検査の桁(自動で決まる)。下の表で、同じ行に点のある桁の 1 の数を偶数にそろえる

↓ 7 桁を送る。通り道(⚡ を押した桁が反転する)

↓ 化けた桁:0 か所

受け取る側

1
2
3
4
5
6
7
0
1
1
0
0
1
1
4
2
1

光ったランプ(上から): 000 → 0(化けた桁は無い)

点=そのランプの検査が見ている桁
ランプ=点のある桁の 1 の数が奇数なら光る

受け取った側の回路は、送った知らせを知らない

受け取った側が直した 7 桁

1
2
3
4
5
6
7
0
1
1
0
0
1
1

受け取った知らせ(3・5・6・7 番):1011

緑の ✓ = 回路が反転した桁(回路にも分かる)
赤い ✗ = 送ったのと違う(あなたにだけ見える)

ランプは 1 つも光っていない。そのまま受け取る。

⚡ で、5 番を化かしてほしい。

4 と 1 のランプが光る。 上から読むと 101。 4 + 1 で、5 番。 化けたのは、5 番だ。

今度は、表を探さなくていい。 光ったランプを 2 進数として読めば、それが化けた桁の番号になっている。 受け取った側は、その番号の桁を反転する。「直した 7 桁」で、5 番に緑の ✓ が付き、知らせは元どおりになる。

ほかの番号も、化かしてみてほしい。 3 番なら 011、6 番なら 110。 紫の検査の桁、1・2・4 番を化かしても同じだ。1 番なら 001 で、1 番と読める。

なぜ、こうなるのか。 点の打ち方を、そう決めたからだ。

5 番の桁は、101 の 1 が立っている位のランプ、つまり 4 のランプと 1 のランプに見られている。 だから 5 番が化けると、その 2 つのランプだけが光る。 光ったランプを読めば、101。元の番号に戻る。

どの番号でも同じだ。 n 番の桁は、n を 2 進数で書いたときの「1 の位置」のランプに見られている。 だから、n 番が化けたときの光り方は、n の 2 進数そのものになる。

言い当てる

ここで、あらためて、受け取った側の立場に立ってみよう。

受け取った側は、送られた知らせを一度も見ていない。 送る側と約束しているのは、点の打ち方、つまり「どのランプが、どの桁を見るか」だけだ。 手元にあるのは、化けたかもしれない 7 桁と、3 つのランプの光り方だけである。

それでも、「5 番が化けた」と、番号で言える。

第1回の回路は、化けたことに気づくだけだった。 前回の回路は、ランプを 4 つ使い、交わるところで場所を突き止めた。 この回の回路は、ランプ 3 つで、化けた桁の番号を言い当てる。

3 つの検査の結果を 2 進数として読むと、化けた桁の番号そのものになる。

番号さえ分かれば、あとは前回と同じだ。 その番号の桁を反転すればいい。 『記憶のしくみ』を読んだ人は、第8回のデコーダを思い出してほしい。番号を受け取って、その番号の線を 1 本だけ選ぶ回路だった。選ばれた線で、その番号の桁を反転すれば、直す回路になる。

この仕組みを考えたのは、アメリカのベル研究所にいた、リチャード・ハミングという人だ。

雪の残る敷地の奥に、赤れんがの建物と緑の屋根が見え、手前に会社名の看板が立っている

ニュージャージー州マレーヒルにある、ベル研究所の建物(2010 年)。看板は、当時の親会社の名前

1947 年のある月曜日。 ハミングは、金曜の夜から週末のあいだ、人のいないまま動かしておいた計算機の結果を待っていた。 継電器(電気で切り替わるスイッチ)をたくさん並べた、大きな計算機である。 ところが、計算機は早いうちに誤りを起こしていて、結果は何も出ていなかった。

当時の計算機は、誤りに気づくことはできた。 けれど、気づいたら、どこが悪いのかを人が突き止めて直すまで、その先の計算は進められない。 週末には、それをする人がいなかった。

ハミングは、こう考えたという。 「機械が、誤りがあると見つけられるのなら、それがどこにあるかを突き止めて、その継電器を 1 から 0 に、0 から 1 に切り替えられないのか」

第1回の「気づく」から、前回の「突き止める」、そして「反転して直す」まで。 このシリーズがたどってきた道を、そのまま 1 つの問いにしたような言葉だ。

ハミングは、1950 年に、この仕組みを論文にまとめた。 論文には、この回と同じ 7 桁の例が載っている。 検査の桁は 1・2・4 番。 そして、検査の結果の 0 と 1 の並びを「2 進数として読むと 5 になる。だから、誤りは 5 番目にある」と書いている。 シミュレータで最初に試した 5 番と、同じ番号だ。

こうした送り方の決まり、つまり「どの検査がどの桁を見るか」「検査の桁をどう決めるか」の約束を、符号という。 この回の 7 桁の送り方は、ハミング符号と呼ばれている。 知らせ 4 桁を 7 桁にして送るので、「(7, 4) ハミング符号」とも呼ぶ。

もっと長く

ランプを増やしたら、どうなるだろう。

ランプを 4 つにすると、光り方は 2 × 2 × 2 × 2 = 16 通り。 無事を除けば、15 か所を見分けられる。 検査の桁 4 つを除くと、知らせは 11 桁送れる。 番号は 1〜15 番で、検査の桁は、やはり 2 の累乗の番、1・2・4・8 番に来る。

ランプ(検査の桁)見分けられる場所(送る桁)知らせの桁送る桁のうち、検査の桁の割合
374約 43%
41511約 27%
53126約 16%
66357約 10%

ランプを 1 つ足すたびに、見分けられる場所は、ほぼ 2 倍になる。 検査の桁は 1 つしか増えないので、送る桁のうち検査の桁が占める割合は、どんどん小さくなる。

3 回送るやり方は、どれだけ長い知らせでも、送る桁の 3 分の 2 が繰り返しだった。 それと比べると、ずいぶん安い。

ただし、どの長さでも、直せるのは全体で 1 か所までだ。

2 か所化けたら

最後に、2 か所を同時に化かしてみよう。

番号で言い当てる シミュレータ

⚡ で化かした桁の番号を、ランプが言い当てるか見てください

送る側

1
2
3
4
5
6
7
0
1
0

紫=検査の桁(自動で決まる)。下の表で、同じ行に点のある桁の 1 の数を偶数にそろえる

↓ 7 桁を送る。通り道(⚡ を押した桁が反転する)

↓ 化けた桁:0 か所

受け取る側

1
2
3
4
5
6
7
0
1
1
0
0
1
1
4
2
1

光ったランプ(上から): 000 → 0(化けた桁は無い)

点=そのランプの検査が見ている桁
ランプ=点のある桁の 1 の数が奇数なら光る

受け取った側の回路は、送った知らせを知らない

受け取った側が直した 7 桁

1
2
3
4
5
6
7
0
1
1
0
0
1
1

受け取った知らせ(3・5・6・7 番):1011

緑の ✓ = 回路が反転した桁(回路にも分かる)
赤い ✗ = 送ったのと違う(あなたにだけ見える)

ランプは 1 つも光っていない。そのまま受け取る。

⚡ で、3 番と 5 番を化かしてほしい。

光るのは、4 と 2 のランプ。 読むと 110、6 番。

受け取った側は、6 番を反転する。 けれど、6 番は化けていない。 実際に化けた 3 番と 5 番はそのままで、化けていなかった 6 番まで反転してしまった。 違う桁は、3 か所に増えた。

何が起きたのだろう。

3 番は 011、5 番は 101。 1 のランプは、3 番と 5 番の両方を見ている。2 回反転して、元に戻った。 4 のランプは 5 番だけ、2 のランプは 3 番だけを見ているので、それぞれ 1 回反転して光った。 光ったのは、2 つの番号で点が食い違うところだ。

2 つの番号は違うのだから、点が食い違うところは、必ずある。ランプは、どれかが光る。 そして、その光り方は、2 つのどちらの番号とも違う。 たとえば光り方が 3 番の 011 と同じになるのは、もう片方の番号に点が 1 つも無いときだけだ。けれど、点が 1 つも無い番号、0 番の桁は無い。 だから回路は、必ず、化けていない 3 つ目の桁を指さす。

どの 2 か所を選んでも、そうなる。 知らせ 16 通りと、2 か所の選び方 21 通りの、336 通りを全部確かめても、1 つの例外もなく、化けていない桁を反転した。

物差しの表に、1 行足そう。

やり方送る桁数1 か所化けたら2 か所化けたら
そのまま4気づかない気づかない
パリティ5気づく気づかない
3 回送る12直す別の桁なら直る。同じ桁の 2 回なら、間違った値に直す
縦横のパリティ8直す気づくことが多いが、間違って直すこともある
ハミング符号7直す化けていない桁を直して、3 か所にしてしまう

1 か所なら、いちばん少ない桁で直せる。 2 か所では、いちばん悪い。

これは、ハミング符号の出来が悪いからではない。 3 つのランプの光り方 8 通りを、無事と 7 か所に、1 通りも余さず使い切ったからだ。 前回の縦横のパリティには、使っていない光り方が 7 通りあった。だから、2 か所化けたときに「直せない」と言えることもあった。 ハミング符号には、もう「直せない」と言うための光り方が残っていない。

第2回の多数決を覚えているだろうか。 同じ桁が 2 回化けると、間違った値を選んで、直した顔をした。 ハミング符号も、2 か所化けると、自信満々で間違える。 しかも、化けていない桁まで壊してしまう。

直せる誤りなら、直してほしい。 けれど、直せない誤りまで「直した」ことにされては、かえって困る。

直せないときに、直さないでいてもらうことはできないか。

次回は、検査の桁を、もう 1 つだけ足してみよう。

参考文献

シリーズ「コンピュータの誤り訂正のしくみ」