ブロックチェーン講座基礎編 第3回 2018/2/18
前回からの質問
● クロック逓倍器はどうやっている?
○ 電圧制御発振器 (VCO) トランジスタ技術 2004年5月号 バックナンバー
http://toragi.cqpub.co.jp/Portals/0/backnumber/2004/05/p098-099.pdf
● ASIC が作りにくいハッシュ関数とはどういうこと?
○ SHA256 のような単純計算であれば演算装置だけですむが、メモリを大幅に必要とするロジックで
あれば、純粋に ASIC 化のコストに見合わなくなる。単にコンピュータを使ったほうが安くなる
● ハッシュ関数にはほかにどういうのがある?
○ SHA256 (SHA2 系)、SHA3 (Keccak)、scrypt など
● scrypt を使っているコインは?
○ Litecoin, Dodgecoin など
1
ブロックチェーン講座基礎編 第3回 2018/2/18
前回からの質問
● GPU と CPU の違いは?
○ GPU (Graphics Processing Unit) は SIMD (Single Instruction Multiple Data) と言って、一つの命
令で複数のデータを演算するような命令がある。これはグラフィック処理で頻繁に使われるベクトル
演算を効果的に行うため。シェーダ言語などを使って操作する
● マイニングが GPU などで行われいた経緯は?
○ もともと、CPU でマイニングするのが最初だったが、 SHA256 のようなハッシュ関数はひたすら同
一の演算を繰り返すだけなので GPU 化が容易。しかし、さらに高速化するため FPGA で組み、そ
こから回路量産できるほどのコスト投資できる企業が ASIC 化していった
2
ブロックチェーン講座基礎編 第3回 2018/2/18
第3回
アルゴリズムとデータ構造
1. イントロダクション / 計算量
2. 配列, 連結リスト (Linked List)
3. ハッシュ テーブル
4. スタック, キュー
今回の内容の参考書 :
データ構造とアルゴリズム / 五十嵐 健夫 (著)
ISBN: 978-4901683494
画像は https://www.amazon.co.jp/dp/4901683497 より引用
その他、以下の学習アプリも非常におすすめ
https://itunes.apple.com/jp/app/アルゴリズム図鑑/id1047532631 3
ブロックチェーン講座基礎編 第3回 2018/2/18
3-1イントロダクション / 計算量
4
ブロックチェーン講座基礎編 第3回 2018/2/18
データ構造とは
一言でいえば
● データを、計算や保存を目的として、どのように格納するか定めたルール
定義
● データを、読み出しや書き込みする際の操作や格納の一定の規則
例
● 配列、連結リスト (このあと 3-2 で登場)
5
ブロックチェーン講座基礎編 第3回 2018/2/18
アルゴリズムとは
一言でいえば
● 物事を処理するための決まった手順のこと
定義
● ある値を入力としてとり、ある値を出力するような、明確に定義された計算手順のこ
と
6
ブロックチェーン講座基礎編 第3回 2018/2/18
アルゴリズムの例
1. 整列アルゴリズム
● 入力
○ N 個の数列 <a1
, a2
, …, an
>
● 出力
○ a’1
≤ a’2
≤ … ≤ a’n
を満たすように並び替えられた N 個の数列 <a’1
, a’2
, …, a’n
>
2. 検索アルゴリズム
● 入力
○ 互いに異なる N 個の数列 <a1
, a2
, …, an
> と、1 つの数 x
● 出力
○ x が数列の i 番目に見つかった (ai
= x) 場合は i
○ 見つからなかった場合は “No”
7
ブロックチェーン講座基礎編 第3回 2018/2/18
計算量
アルゴリズムを評価するときには、次のような方法で評価する
● 時間計算量 (Computational complexity)
アルゴリズムの実行にあたって、どれだけの時間が必要となるかを示す。一般的に
アルゴリズムの質を測るのにもっとも重要な尺度
● 空間計算量 (Space complexity)
アルゴリズム実行中に、どれだけの記憶領域を必要とするかを示す
● その他
○ 通信複雑性 (Communication complexity)
○ 回路計算量 (Circuit complexity)
8
ブロックチェーン講座基礎編 第3回 2018/2/18
計算量を評価する上での計算機のモデル
アルゴリズムを評価する上で、通常は以下のような計算機をモデルとして考える
● メモリ : 無限の大きさをもち、遅延なく読み書きできる
● CPU : 以下のような単純な命令セットを持つ
○ 最低限の ALU
○ 制御構造 (比較、条件分岐など )
○ メモリの読み書き
(形式言語理論の回で、チューリング機械などを触れる際にまた戻ってきます)
9
ブロックチェーン講座基礎編 第3回 2018/2/18
時間計算量
計算機がアルゴリズムを実行するのにかかる時間。実行する命令の数とかんがえられ
る
例 (数列の合計アルゴリズム)
● 入力: n 個の整数の数列
● 出力: 入力の数列すべてを加算したもの
● 実装: (右のフローチャートを参照)
○ 合計値を格納する変数 sum を 0 で初期化する
○ 数列の値をひとつずつ取得し、 sum に加算
○ sum を出力
合計で (3n + 4) 個の命令を実行することになる
sum = 0
sum += i 番目の数
i < n
i = 0
i++
sum を出力
10
ブロックチェーン講座基礎編 第3回 2018/2/18
ランダウの漸近記法
アルゴリズムの計算量を表示するためには、ランダウの漸近記法を用いる
● Θ 表記 … 上下から抑える
● Ω 表記 … 下から抑える
● Ο 表記 … 上から抑える
通常、Ο 表記 (aka. ビッグ オー ノーテーション) をよく用いる
11
ブロックチェーン講座基礎編 第3回 2018/2/18
Ο 表記
Ο 表記は、それが表示する関数によって上から抑えることができる、ということを示すの
に用いる。オーダーともいう
次の性質がある
● 定数倍
● 和
● 積
例 (数列の合計アルゴリズム, 続き)
合計で (3n + 4) 個の命令で抑えられるということは O(n) クラス
12
ブロックチェーン講座基礎編 第3回 2018/2/18
さまざまな計算量
オーダー 名称 例
O(1) 定数時間 (constant) ハッシュ テーブル
O(log n) 対数時間 (logarithmic) 二分探索
O(n) 線形時間 (linear) 配列の走査
O(n log n) 準線形時間 (quasilinear) 整列
O(n2
) 二乗時間 (quadratic) 遅い整列
O(n3
) 以上 多項式時間 (polynomial) 行列演算など
O(2n
) 指数時間 NP クラスの問題
O(n!) 階乗時間
13
ブロックチェーン講座基礎編 第3回 2018/2/18
3-2配列, 連結リスト
14
ブロックチェーン講座基礎編 第3回 2018/2/18
ポインタの導入
メモリ上の番地をあらわす値、およびそのデータ型。ポインタが示す番地をたどって値を
取得できる。便宜上、0 はどこも指さないポインタとみなす
たとえば右のようなメモリを想定すると
● 整数ポインタ (int*) として 0x10 番地をみれば
0x12 番地 (整数) を示しているので 72
● 文字ポインタ (char*) として 0x14 番地をみれば
0x11 番地 (文字) を示しているので 'Q'
● 文字ポインタのポインタ (char**) として 0x15 番地をみれば
0x10 番地 (文字ポインタ) が 0x12 番地 (文字) を示しているので 'Q'
番地 値
0x10 0x12
0x11 0x51
0x12 0x48
0x13 0x95
0x14 0x11
0x15 0x10
15
ブロックチェーン講座基礎編 第3回 2018/2/18
配列 (Array)
連続した一連のデータ構造。計算機科学的には通常、最初の要素を 0 番目として数え
る
以下の操作が定義される
● i 番目の値を取得する
● i 番目に値を追加する
● i 番目の値を削除する
● i 番目の値を更新する
2
3
5
7
11
長さ 5 の整数配列 (例)
0
1
2
3
4
0x02
0x03
0x05
0x07
0x0B
メモリ上のデータ
0x0100
0x0101
0x0102
0x0103
0x0104
16
ブロックチェーン講座基礎編 第3回 2018/2/18
配列 (例)
2
3
5
7
11
長さ 5 の配列 a
0
1
2
3
4値を変更 (a[4] = 10)
値を参照 (x = a[1])
配列の先頭番地がわかれば、 n 番
目の番地もすぐにわかる。定数時間
で取得できる。O(1)
値の参照 (上記) と同じ。O(1)
値を削除 (a.RemoveAt(0))
値を追加 (a.InsertAt(4, 100))
1 番目以降をひとつずつ前にずら
す。すなわち、i+1 番目の値を読み、
i 番目に書き込む。配列の長さが n
なら、最悪、n-1 回分の読み書き。
O(n)
1 番目以降をひとつずつ後にずら
す。すなわち、i 番目の値を読み、
i+1 番目に書き込む。配列の長さが
n なら、最悪 n 回分の読み書き。
O(n)
17
ブロックチェーン講座基礎編 第3回 2018/2/18
連結リスト (Linked List)
ひとつの値と、次の値へのポインタとを持ったデータ構造。連結していった値を順番に読
んでリストとみなす
以下の操作が定義される
● i 番目の値を取得する
● i 番目に値を追加する
● i 番目の値を削除する
● i 番目の値を更新する
12 1 56
長さ 3 の連結リスト (例)
0x00
0x0C
0x16
0x07
0x38
メモリ上のデータ
0x11 番地に連結リストが入っている
0x10
0x11
0x12
0x13
0x14
0x00
0x01
0x14
0x15
0x16
0x17
18
ブロックチェーン講座基礎編 第3回 2018/2/18
連結リスト (例)
12 1 56
長さ 3 の連結リスト (例)
値を参照, 変更 (int x = b[2])
連結リストの先頭から i 番目の要素まで、ポ
インタをたどらなければいけない。 i 回分の
ポインタ参照。O(n)47
値を追加, 削除 (b.Insert(1, 47))
追加する位置、削除する位置があらかじめわかって
いれば、前後のポインタを操作するだけですむ
O(1)
19
ブロックチェーン講座基礎編 第3回 2018/2/18
配列および連結リストの走査
配列でも連結リストでも、全要素を走査する (値の検索、合計など) ときには、長さが n
としたら O(n) の時間がかかってしまう
int sum = 0;
int[] a = new int[] { 1, 2, 3 };
for (int i = 0; i < a.Length; i++) {
sum += a[0];
}
20
ブロックチェーン講座基礎編 第3回 2018/2/18
配列と連結リストとの時間計算量まとめ
操作 配列 連結リスト
要素の追加・挿入 O(n) O(1)
要素の参照 O(1) O(n)
要素の編集 O(1) O(n)
要素の削除 O(n) O(1)
全走査 O(n) O(n)
* 要素数を n とする
21
ブロックチェーン講座基礎編 第3回 2018/2/18
3-3ハッシュ テーブル
22
ブロックチェーン講座基礎編 第3回 2018/2/18
ハッシュ テーブル
あるキーに紐づけて値を保存するデータ構造 (aka. 辞書、マップ)。ハッシュ関数を使う
以下の操作が定義される
● キー x に対して値 y を保存・更新する
● キー x の紐付けられた値を参照する
りんご
キャベツ
牛乳
0x02
0x04
0x01
ハ
ッ
シ
ュ
関
数
200 円
150 円
350 円
0
1
2
3
4
値の配列ハッシュ テーブル (例)
5
23
ブロックチェーン講座基礎編 第3回 2018/2/18
ハッシュ関数
ハッシュ関数は、与えられた値から別の値に変換する関数である
あらかじめ入力される値がすべてわかっている場合には、各入力値に対して異なる値を
返す (単射) ことができる。この場合のハッシュ関数を完全ハッシュ関数と呼ぶ
定義域が値域よりも大きい場合や完全ハッシュ関数が利用できない場合には、ハッシュ
関数の出力値が同一になる (衝突) ことがある
りんご 0x02
24
ブロックチェーン講座基礎編 第3回 2018/2/18
ハッシュ テーブルにおけるハッシュ関数の衝突
ハッシュ テーブルの実装において、ハッシュ関数が衝突する可能性がある
このような場合を避ける方法として次がある
● 連鎖法
● 開番地法
レタス
キャベツ
0x04
0x04
ハ
ッ
シ
ュ
関
数
200 円
150 円
350 円
0
1
2
3
4
値の配列ハッシュ テーブル (例)
5
25
ブロックチェーン講座基礎編 第3回 2018/2/18
開番地法 (Open Addressing)
ハッシュ値の出た場所からもっとも近い配列の空きがある場所を利用する方法
配列がうまっていくにつれて、効率が悪くなる
また、完全に埋まると値がそれ以上、追加できなくなる
レタス
キャベツ
0x04
0x04
ハ
ッ
シ
ュ
関
数
牛乳
りんご
キャベツ
0
1
2
3
4
キーと値の配列ハッシュ テーブル (例)
レタス5
200 円
150 円
350 円
180 円
26
ブロックチェーン講座基礎編 第3回 2018/2/18
連鎖法 (Separate Chaining)
値の保存する部分を連結リストにする方法
値を参照する場合には、連結リストを走査し、
求めるキーが書かれた連結リストの要素までたどる必要がある
レタス
キャベツ
0x04
0x04
ハ
ッ
シ
ュ
関
数
0
1
2
3
4
連結リストハッシュ テーブル (例)
レタス 350 円
りんご 150 円
牛乳 200 円
キャベツ 180 円
5
27
ブロックチェーン講座基礎編 第3回 2018/2/18
ハッシュ テーブルのリサイズ
キーと値とを保管する配列が埋まってきた場合、参照にかかる時間が遅くなる。より大き
な配列のハッシュ テーブルを作成し、かつハッシュ関数の値域を拡大することで、空き
領域を増やすことができる。既存のハッシュ テーブルのエントリ (キーと値との組) をす
べて再度追加していくことになるので、大きなコストがかかる
牛乳
りんご
キャベツ
0
1
2
3
4
200 円
150 円
350 円
0
1
2
3
4
再ハッシュ
キャベツ
5
6
7
350 円
りんご 150 円
牛乳 200 円
⋮ 28
ブロックチェーン講座基礎編 第3回 2018/2/18
ハッシュ テーブルの時間計算量まとめ
操作 ハッシュ テーブル
キーに対する値の追加 O(1)
キーに対する値の参照 O(1)
(リサイズ) O(n)
* リサイズ前の要素数を n とする
29
ブロックチェーン講座基礎編 第3回 2018/2/18
ブロックチェーンのデータ構造
ハッシュ
Block
500002
Block
500001
前のブロック
00000000000000000024fb37…
(ブロック 500000 のダイジェスト)
内容 ...
前のブロック
0000000000000000005c9959…
(ブロック 500001 のダイジェスト)
内容 ...
中身
第1回 P.15 より
#{10}
#{12}
0x01
0x04
ハ
ッ
シ
ュ
関
数
#{10}
#{11}
#{12}
0
1
2
3
4
Block ID とブロック データの配列
5
Block 10 のデータ
Block 11 のデータ
Block 12 のデータBlock ID はすでに「質の良いハッシュ関数」の
出力なので、下位24 ビットとる、などでも
十分意味がある
#{500002}
#{500001}
#{1}
最新ブロック
ブロックチェーンはその性質
上、連結リストに似た構造を
している。各ブロックの保管
にはハッシュ テーブルが使
えるかもしれない
30
ブロックチェーン講座基礎編 第3回 2018/2/18
(課題) ハッシュ テーブルを実装する
1 … 231
-1 までの範囲の値をキー、任意の数値を値としてとるようなエントリを、合計で
100 まで格納できるハッシュ テーブルを実装せよ
31
ブロックチェーン講座基礎編 第3回 2018/2/18
3-4スタック, キュー
32
ブロックチェーン講座基礎編 第3回 2018/2/18
スタック
後入れ先出し (LIFO, Last-In First-Out) のデータ構造
以下の操作が定義される
● 値を追加する (push)
● 値を取り出す (pop)
45 45
12
45
12
89
45
12
45
Push 45
Push 12
Push 89
Pop 89
Pop 12
Pop 45
スタック (例)
33
ブロックチェーン講座基礎編 第3回 2018/2/18
スタックの利用
● スタック領域 : 計算機がプログラムを実行するとき、関数を呼び出すときに、実行中
のレジスタをメモリ中に保存しておく (Push)。呼び出し関数が終了したら、メモリか
ら呼び出し前のレジスタ状態を復元する (Pop)
0x02
0x15
0x80
$v0
$v1
$fp
0x10PC
...
...
...
0x7E
0x7F
0x80
0x10
0x02
0x15
0x7E
0x7F
0x80
⋮
0x7D$fp
0x20PC
関数呼び出し前 関数呼び出し後
⋮
...
...
$v0
$v1
⋮ ⋮
https://en.wikipedia.org/wiki/Call_stack より引用
34
ブロックチェーン講座基礎編 第3回 2018/2/18
スタックの利用
● スタック マシン : 記憶領域がスタックとして実装されている計算機のモデル。中間
言語の実行環境でよく用いられる。Bitcoin の移動を表すトランザクションで、アドレ
スの記述や、電子署名の検証に利用されている
参照:
https://chainflyer.bitflyer.jp/Transaction/1ce0f4a2a7ba2ba5ecedf4c3a038df7c7bff9ca941580ba9f8f7ebdf0df750eb
https://chainflyer.bitflyer.jp/Transaction/c2df6b674903aa39729d3b0b87b80a50e44a9f045155e76a3b2900e0738dfed6
消費される側のスクリプト (例)消費する側のスクリプト (例)
35
ブロックチェーン講座基礎編 第3回 2018/2/18
先入れ先出し (FIFO, First-In First-Out) のデータ構造
以下の操作が定義される
● 値を追加する (enqueue)
● 値を取り出す (dequeue)
キュー
キュー (例)
47
47
23
23
23 59
23 59 31
Enqueue 47
Enqueue 23
Dequeue 47
Enqueue 59
Enqueue 31
36
ブロックチェーン講座基礎編 第3回 2018/2/18
優先度付きキュー
キューに入れる値に優先度をパラメータとして付属させることができるデータ構造
以下の操作が定義される
● 優先度を指定して値を追加する (enqueue)
● もっとも優先度が高い値を取り出す (dequeue)
37
ブロックチェーン講座基礎編 第3回 2018/2/18
(課題) スタックおよびキューの配列での実装
スタックおよびキューを、計算機で実装するには、どのようにメモリ上に値を配置すれば
よいか。それぞれの操作に対して、どうデータを処理すればよいか考えよ
38
ブロックチェーン講座基礎編 第3回 2018/2/18
第3回 まとめ
1. イントロダクション / 計算量
● アルゴリズム : 入出力が定義され、明確に記述された計算手順のこと
● データ構造 : データを読み書きする際の操作や格納の一定の規則
● 計算量 : 実行に必要な資源の尺度。時間計算量、空間計算量など。O 記法
2. 配列, 連結リスト
● 配列 : 記憶領域上の連続したデータ構造
● 連結リスト : ポインタによって値がつながれたデータ構造
3. ハッシュ テーブル
● 定数時間によってキーと紐付けて値を保存するデータ構造
● 衝突回避の方法 : 開番地法、連鎖法
4. スタック, キュー
● スタック (LIFO) : Push, Pop
● キュー (FIFO) : Enqueue, Dequeue
39

[Basic 3] 計算量 / 配列, 連結リスト / ハッシュ テーブル / スタック, キュー