Upload
cryolite
View
1.473
Download
1
Embed Size (px)
Citation preview
1
2010/10/23 Cryolite
Boost.勉強会 #3 関西
S t a
T
L
a
a
a
e m
n d dr
rri b
p l t e
y
自己紹介
• 名前: Cryolite
• 特技: C++ とかできます
2
STLとは「コンテナ×イテレータ×アルゴリズム」
3
コンテナ アルゴリズム
findsortremove・・・・・
vectordequelist・・・・・
STLとは「コンテナ×イテレータ×アルゴリズム」
4
コンテナ アルゴリズム
findsortremove・・・・・
vectordequelist・・・・・
STLとは「コンテナ×イテレータ×アルゴリズム」
5
コンテナ アルゴリズム
findsortremove・・・・・
vectordequelist・・・・・
(組み合わせの数)
=(データ構造の数)×(アルゴリズムの数)かける
STLとは「コンテナ×イテレータ×アルゴリズム」
コンテナ アルゴリズム
findsortremove・・・・・
vectordequelist・・・・・
イテレータ
6
STLとは「コンテナ×イテレータ×アルゴリズム」
コンテナ アルゴリズム
findsortremove・・・・・
vectordequelist・・・・・
イテレータ
(組み合わせの数)
=(データ構造の数)+(アルゴリズムの数)たす
7
STLとは「コンテナ×イテレータ×アルゴリズム」
コンテナ アルゴリズム
findvectordeque イテレータ
8
STLとは「コンテナ×イテレータ×アルゴリズム」
コンテナ アルゴリズム
findvectordeque イテレータ
コンテナ側に変化があっても……
9
STLとは「コンテナ×イテレータ×アルゴリズム」
コンテナ アルゴリズム
findvectordeque イテレータ
コンテナ側に変化があっても……
アルゴリズム側に影響しない
10
STLとは「コンテナ×イテレータ×アルゴリズム」
コンテナ アルゴリズム
findvectordeque イテレータ
コンテナ側に変化があっても……
アルゴリズム側に影響しない
コンテナ側の変化に対するファイアウォール 11
イテレータに注目!
コンテナ アルゴリズム
findsortremove・・・・・
vectordequelist・・・・・
イテレータ
ちうもく!!12
コンテナのイテレータには3つの機能がある!
13
コンテナのイテレータは
• コンテナ中の場所(コンテナ中の1要素)を指し示す
14
//同じ場所なら trueだよ!iter == jter;
コンテナのイテレータは
• コンテナ中の場所(コンテナ中の1要素)を指し示す
• コンテナ中の全要素を列挙する
15
//同じ場所なら trueだよ!iter == jter;
//次の場所に移動するよ!//繰り返せば列挙になるよ!++iter;
コンテナのイテレータは
• コンテナ中の場所(コンテナ中の1要素)を指し示す
• コンテナ中の全要素を列挙する
•指し示している場所の値を取り出せる
16
//同じ場所なら trueだよ!iter == jter;
//次の場所に移動するよ!//繰り返せば列挙になるよ!++iter;
//あたいったら取り出すね!*iter;
イテレータの3つの機能(※イメージです)
17
2 3 5 7 11 13 17 ・・・
コンテナ
イテレータの3つの機能(※イメージです)
18
2 3 5 7 11 13 17 ・・・
場所を指示
コンテナ
イテレータの3つの機能(※イメージです)
19
2 3 5 7 11 13 17 ・・・
列挙する場所を指示
コンテナ
イテレータの3つの機能(※イメージです)
20
2 3 5 7 11 13 17 ・・・
5値を取り出す
列挙する場所を指示
コンテナ
STL 最大の欠点– Cryoliteの眼: C++pro
21
Inspired by http://itpro.nikkeibp.co.jp/article/Watcher/20101015/352993/
STL 最大の欠点– Cryoliteの眼: C++pro
配列†のインデックスを再評価してもいいのでは?
22
Inspired by http://itpro.nikkeibp.co.jp/article/Watcher/20101015/352993/
STL 最大の欠点– Cryoliteの眼: C++pro
23
配列†のインデックスを再評価してもいいのでは?
筆者がここで言いたいのは,そろそろ配列†のインデックスを使ってみてもいいのでは?ということだ.
†一般にはランダムアクセスコンテナ
Inspired by http://itpro.nikkeibp.co.jp/article/Watcher/20101015/352993/
24
温故知新–故きを温ね新しきを知る
25
古代暗黒魔法が封印された禁書を開いてみると,そこには古代語で書かれたプログラムとおぼしきものが!
温故知新–故きを温ね新しきを知る
26
古代暗黒魔法が封印された禁書を開いてみると,そこには古代語で書かれたプログラムとおぼしきものが!
vector<int> v;.....for (size_t i = 0; i != v.size(); ++i) {cout << v[i] << endl;
}
温故知新–故きを温ね新しきを知る
27
古代暗黒魔法が封印された禁書を開いてみると,そこには古代語で書かれたプログラムとおぼしきものが!
vector<int> v;.....for (size_t i = 0; i != v.size(); ++i) {cout << v[i] << endl;
}
温故知新–故きを温ね新しきを知る
ランダムアクセスコンテナならイテレータを使わなくてもインデックスで要素を列挙できるもんっ!
• コンテナ中の場所を指し示す
• コンテナ中の全要素を列挙する
•指し示している場所の値を取り出せる
28
//同じ場所なら trueだよ!iter == jter;
//次の場所に移動するよ!//繰り返せば列挙になるよ!++iter;
//あたいったら取り出すね!*iter;
イテレータの機能を思い出してみよう!
29
ランダムアクセスコンテナのインデックスは……
• コンテナ中の場所を指し示す
30
//同じ場所なら trueだよ!i == j;
ランダムアクセスコンテナのインデックスは……
• コンテナ中の場所を指し示す
• コンテナ中の全要素を列挙する
31
//同じ場所なら trueだよ!i == j;
//次の場所に移動するよ!//繰り返せば列挙になるよ!++i;
ランダムアクセスコンテナのインデックスは……
• コンテナ中の場所を指し示す
• コンテナ中の全要素を列挙する
•指し示している場所の値を取り出せ……る?
32
//同じ場所なら trueだよ!i == j;
//次の場所に移動するよ!//繰り返せば列挙になるよ!++i;
// コ,コンテナオブジェクトさえあれば!v[i];
ランダムアクセスコンテナのインデックスは……
値の取り出し方を抽象化しましょう← 結論
33
値の取り出し方を抽象化しましょう← 結論
34
イテレータもインデックスもコンテナ中の場所を指し示せる
値の取り出し方を抽象化しましょう← 結論
35
v[i];
イテレータもインデックスもコンテナ中の場所を指し示せる
*iter;
値を取り出す構文が違う
値の取り出し方を抽象化しましょう← 結論
36
v[i];
イテレータもインデックスもコンテナ中の場所を指し示せる
*iter;
値の取り出し方を抽象化しましょう
値を取り出す構文が違う
get(pm, desc);
値の取り出し方を抽象化しましょう← 結論
37
v[i];
イテレータもインデックスもコンテナ中の場所を指し示せる
*iter;
値の取り出し方を抽象化しましょう
値を取り出す構文が違う
get(pm, desc);
イテレータだったりインデックスだったり
【再掲】イテレータの機能(イメージ)
38
2 3 5 7 11 13 17 ・・・
5値を取り出す
列挙する場所を指示
コンテナ
値の取り出し方を抽象化したイメージへ……
・・・
モノの集まり
39
・・・
1つのモノを指示
モノの集まり
40
値の取り出し方を抽象化したイメージへ……
・・・
列挙する1つのモノを指示
モノの集まり
41
値の取り出し方を抽象化したイメージへ……
・・・
5
列挙する1つのモノを指示
モノの集まり
32 7モノと値を関連付ける
11 13 1942
値の取り出し方を抽象化したイメージへ……
疑問
・・・
5
列挙する1つのモノを指示
モノの集まり
32 7モノと値を関連付ける
11 13 19
こんな風に考えて何がうれしいの?
43
疑問への回答その1
・・・
5
列挙する1つのモノを指示
モノの集まり
32 7モノと値を関連付ける
11 13 19
こんな風に考えて何がうれしいの?
44
モノの指し示し方を柔軟にできるよ!イテレータ,インデックス, etc…
・・・
5
列挙する1つのモノを指示
モノの集まり
32 7モノと値を関連付ける
11 13 19
こんな風に考えて何がうれしいの?
45
モノに対して柔軟に値を関連付けられるよ!
疑問への回答その2
・・・
1
モノの集まり
11 1
定数を関連付ける
1 1 146
疑問への回答その2 (例1)
・・・
モノの集まり
3×22×2 7×2 11×2 13×2 19×247
5×2
値を加工して関連付ける
疑問への回答その2 (例2)
・・・
5
列挙する1つのモノを指示
モノの集まり
32 7モノと値を関連付ける
11 13 19
こんな風に考えて何がうれしいの?
1つのモノに対して複数の値を関連付けられるよ!
48
疑問への回答その3
・・・
49
疑問への回答その3 (例)
・・・
532 7 11 13 19
モノと値を関連付けその1
50
疑問への回答その3 (例)
・・・
532 7 11 13 19
‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘,’ ‘_’
モノと値を関連付けその1
モノと値を関連付けその2
51
疑問への回答その3 (例)
それぞれの機能を担うオブジェクトに名前を付けよう!
・・・
5
列挙する1つのモノを指示
モノの集まり
32 7モノと値を関連付ける
11 13 1952
・・・
5
列挙する
モノの集まり
32 7モノと値を関連付ける
11 13 1953
デスクリプタ
それぞれの機能を担うオブジェクトに名前を付けよう!
・・・
5
モノの集まり
32 7モノと値を関連付ける
11 13 1954
デスクリプタ (デスクリプタを列挙する)
イテレータ
それぞれの機能を担うオブジェクトに名前を付けよう!
・・・
5
モノの集まり
32 7プロパティマップ
11 13 1955
デスクリプタ (デスクリプタを列挙する)
イテレータ
それぞれの機能を担うオブジェクトに名前を付けよう!
56
Boost.PropertyMap
2010/10/23 Cryolite
Boost.勉強会 #3 関西
プロパティマップとは
57
デスクリプタを受け取って,値を返すインタフェイスを定義
デスクリプタと書き込む値を受け取って,書き込むインタフェイスを定義
get(pm, desc); // 値が返る
put(pm, desc, val);
プロパティマップとは
• イテレータにおける「値を取り出す」「値を書き込む」機能に対応
• うれしいこと3つ
– モノの指し示し方が超柔軟に
– モノに関連付けられた値の取り出し方・書き込み方が超柔軟に
– 1つのモノに対して複数の値・書き込み先を関連付ける
58
プロパティマップとは
59
このライブラリだけ説明しても意味不明!
STL のコンテナとアルゴリズムの関係を話さずにイテレータを説明してもおそらく意味不明!
≒
イテレータ in STL
60
コンテナ アルゴリズム
findsortremove・・・・・
vectordequelist・・・・・
イテレータ
プロパティマップin 汎用グラフライブラリ
61
グラフデータ構造
汎用グラフアルゴリズム
DijkstraDFSA*・・・・・
隣接リスト隣接行列edge list・・・・・
イテレータ
デスクリプタ
プロパティマップ
ビジター
プロパティマップin 汎用グラフライブラリ
62
グラフデータ構造
汎用グラフアルゴリズム
DijkstraDFSA*・・・・・
隣接リスト隣接行列edge list・・・・・
イテレータ
デスクリプタ
プロパティマップ
ビジター
Boost.PropertyMapの本領–グラフにおける汎用アルゴリズム
63
ab
c
d
e
f
グラフのデータ構造とプロパティマップ-グラフのデータ構造は多種多様
64
a
b
c
d
e
f
a b d g
b c d
a c f
a c g
b f
c d e
隣接リスト (例1)
グラフのデータ構造とプロパティマップ-グラフのデータ構造は多種多様
65
a
b
c
d
e
f
a b d g
b c d
a c f
a c g
b f
c d e
隣接リスト (例2)
グラフのデータ構造とプロパティマップ-グラフのデータ構造は多種多様
66隣接行列
0 1 1 1 0 0
1 0 1 0 1 0
1 1 0 1 0 1
1 0 1 0 0 1
0 1 0 0 0 1
0 0 1 1 1 0
a b c d e fabcde
f
グラフアルゴリズムは頂点や辺に関連付けられた値を駆使
67
グラフアルゴリズムは
• 頂点の重み,インデックス,親,色
• スタートから各頂点までの距離
• 辺の重み,インデックス
• 辺のインデックス
などを使わないと実行できない
色々なグラフデータ構造に対してこれらをどう関連付けるのか?
デスクリプタ・イテレータ・プロパティマップによる汎用なグラフアルゴリズム
68
⇒(デスクリプタを返す) イテレータを使います
頂点や辺を一意に特定する必要があります
頂点や辺に様々な値を関連付ける必要があります
頂点や辺を様々な形で列挙する必要があります
⇒頂点や辺を指すデスクリプタを使います
⇒プロパティマップを使います
具体的な例 – ランダムアクセスコンテナ & イテレータ
69
vector<Edge>
struct Edge {double getWeight() const;void setWeight(double w);
};
double get(WeightPMap, Iterator iter) {return iter->getWeight();
}
辺の重みの読み出し
iter
具体的な例 – ランダムアクセスコンテナ & イテレータ
70
vector<Edge>
struct Edge {double getWeight() const;void setWeight(double w);
};
void put(WeightPMap, Iterator iter, double val) {iter->setWeight(val);
}
辺の重みの書き込み
iter
具体的な例 – ランダムアクセスコンテナ & イテレータ
71
vector<Edge>
struct IteratorIndexPMap {Iterator first_; // = v.begin()
};
size_t get(IteratorOffsetPMap pm, Iterator iter) {return iter - pm.first_;
} 辺のインデックスの読み出し (read-only)
iter
具体的な例 – ランダムアクセスコンテナ & インデックス
72
vector<Edge>
struct Edge {double getWeight() const;void setWeight(double w);
};
struct WeightPMap { vector<Edge> &v_; };
double get(WeightPMap pm, Index idx) {return pm.v_[idx].getWeight();
}
辺の重みの読み出し
idx
具体的な例 – ランダムアクセスコンテナ & インデックス
73
vector<Edge>
struct Edge {double getWeight() const;void setWeight(double w);
};
struct WeightPMap { vector<Edge> &v_; };
void put(WeightPMap pm, Index idx, double val) {pm.v_[idx].setWeight(val);
}
辺の重みの書き込み
idx
具体的な例 – ランダムアクセスコンテナ & インデックス
74
vector<Edge>
struct IdentityPMap {};
size_t get(IdentityPMap, Index idx) {return idx;
} 辺のインデックスの読み出し (read-only)
idx
様々なプロパティマップの例
75
vector<Edge>
0 1 2 3 4 インデックス
76
vector<Edge>
0 1 2 3 4 インデックス
another_vec[idx]
2 3 5 7 11
様々なプロパティマップの例
vector<Edge>
77
0 1 2 3 4 インデックス
another_vec[idx]
2 3 5 7 11
様々なプロパティマップの例インデックスを踏み台にして,他のランダムアクセスコンテナで別の値をさらに関連付ける
Edge クラスが元々持っていない種類の値を非侵入的に関連付け
78
list<Edge>
double get(WeightPMap, Iterator iter) {return iter->getWeight();
}
void put(WeightPMap, Iterator iter, double val) {iter->setWeight(val);
}
iter
様々なプロパティマップの例
79
list<Edge>
unordered_map<Iterator, double>
2 3 5 7 11
iter
様々なプロパティマップの例
80
list<Edge>
unordered_map<Iterator, size_t>
0 1 2 3 4
iter
インデックス
様々なプロパティマップの例
81
list<Edge>
unordered_map<Iterator, size_t>
0 1 2 3 4
iter
インデックス
2 3 5 7 11
another_vec[idx]
様々なプロパティマップの例
様々なプロパティマップの例
list<Edge>
82
unordered_map<Iterator, size_t>
0 1 2 3 4
iter
インデックス
2 3 5 7 11
another_vec[idx]
実メモリ上に記録したインデックスを踏み台にして,他のランダムアクセスコンテナで別の値をさらに関連付ける
Edge クラスが元々持っていない種類の値を非侵入的に関連付け
プロパティマップin 汎用グラフライブラリ
83
グラフデータ構造
汎用グラフアルゴリズム
プロパティマップget(pm, desc), put(pm, desc, val)
プロパティマップin 汎用グラフライブラリ
84
グラフデータ構造
汎用グラフアルゴリズム
プロパティマップget(pm, desc), put(pm, desc, val)
アルゴリズムはプロパティマップのみに依存どんなデータ構造に対しても
汎用で再利用可能
85
ダイクストラ法で必要なプロパティ種類 Read / Write
頂点 距離 Read & Write
先行頂点 Read & Write
インデックス Read
辺 重み Read
グラフアルゴリズムに対する要求も多種多様
86
ダイクストラ法で必要なプロパティ種類 Read / Write
頂点 距離 Read & Write
先行頂点 Read & Write
インデックス Read
辺 重み Read
ゴールまでの最小の辺の数が知りたいだけなんだけど
グラフアルゴリズムに対する要求も多種多様
辺の重みプロパティマップが定数1を返せばよい
87
ダイクストラ法で必要なプロパティ種類 Read / Write
頂点 距離 Read & Write
先行頂点 Read & Write
インデックス Read
辺 重み Read
ゴールまでの最短距離だけが知りたい実際の経路は別に分からなくてもよいのだが
グラフアルゴリズムに対する要求も多種多様
先行頂点の書き込みプロパティマップに何もしないダミーを設定すればよい
プロパティマップ –まとめ
• イテレータにおける「値を取り出す」「値を書き込む」機能の抽象インタフェイス定義
• うれしいこと3つ
– モノの指し示し方が超柔軟に
– モノに関連付けられた値の取り出し方・書き込み方が超柔軟に
– 1つのモノに対して複数の値・書き込み先を関連付ける
• 汎用グラフライブラリで威力を発揮 88