Boost.PropertyMap (.pptx)

Preview:

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