Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Alloyへの挑戦

2,294 views

Published on

情報オリンピック夏季セミナー2012に参加したときのスライドです。
Alloyそのものについての説明はほとんどなく、プログラムの反例を出すことがメインです。

Published in: Technology
  • Be the first to comment

Alloyへの挑戦

  1. 1. Alloyへの挑戦 沖縄工業高等専門学校 3年 メディア情報工学科 名渡山夏子 @marin72_com 1
  2. 2. Alloyの特徴Alloyはプログラムの設計用ツール論理パズル等に向いている 2
  3. 3. きゅうりになんかいわれた もしかして:煽り? 3
  4. 4. 今回は考えたアルゴリズムが正しいか確認→アルゴリズムの反例を出す 4
  5. 5. 今回取り組んだ問題最小点カバー問題 5
  6. 6. 最小点カバー問題とは 1 1できるだけ少ない点で 5すべての辺をカバーする。 5これを点カバーという。 66 77 6
  7. 7. 最小点カバー問題とは 1できるだけ少ない辺ですべての点をカバーする。 5 6 7 7
  8. 8. 最小点カバー問題とは 1できるだけ少ない辺ですべての点をカバーする。 5 6 7 [解] 4つ 8
  9. 9. 木に限定した最小点カバー問題根がいる辺でつながっていない点はない→どの点も1つ以上の辺がある 9
  10. 10. 今回は無向木を利用双方向でつながっている 10
  11. 11. 今回は無向木を利用 [例]1. 任意の点を選ぶ2. 任意の点と 繋がっている辺を消す3. 1.と2.を繰り返す少ない点で全ての辺を消す この点を選択 辺は残り3本 11
  12. 12. アルゴリズム今回は間違っているアルゴリズムを使用一部の例ならこのアルゴリズムでよいが、「このパターンなら落ちる」を確認する。 12
  13. 13. アルゴリズムの説明1. 最も多くの辺と繋がっている点を見つける (この点を次数が最大の点と呼ぶ)2. 次数が最大の点と繋がる辺を消す。3. 1.と2.を繰り返す。 13
  14. 14. ソース全貌 14
  15. 15. ソース全貌インクルードオブジェクトの集合条件述語コマンド 15
  16. 16. ソース全貌インクルードオブジェクトの集合を宣言条件述語コマンド 16
  17. 17. ソース全貌インクルードオブジェクトの集合を宣言条件述語コマンド 17
  18. 18. ソース全貌インクルードオブジェクトの集合を宣言オブジェクトの集合条件述語コマンド 18
  19. 19. ソース全貌インクルードオブジェクトの集合を宣言オブジェクトの集合条件述語述語を実行するコマンド \ソース全52行/ 19
  20. 20. アルゴリズムを実装まずは、このアルゴリズムは正しいと仮定し、   アルゴリズムを実装する。このアルゴリズムの反例があるかを確認する  条件は後ほど追加する。 20
  21. 21. インクルードOpen util/ordering[Graph]アルゴリズムの状態遷移を順序よくするためにOrderingを集合Graphに適用するfirst, last, prevs[集合名]等を使える 21
  22. 22. オブジェクトの集合を宣言sig Node { tree_edge: set Node } { }one sig Root in Node { }one sig Last in Graph { } 22
  23. 23. オブジェクトの集合を宣言sig Node { tree_edge: set Node } { }one sig Root in Node { }one sig Last in Graph { } Node集合Nodeの中に RootたったひとつのRootという集合が存在する 23
  24. 24. オブジェクトの集合を宣言sig Node { tree_edge: set Node } { }one sig Root in Node { }one sig Last in Graph { } Graph集合Graphの中に LastたったひとつのLastという集合が存在する 24
  25. 25. オブジェクトの集合を宣言sig Graph →Graphの集合{ !! nodes: set Node,! edge: nodes -> nodes,! max_node: nodes,}! {! ! all n: nodes | #max_node.edge >= #n.edge! ! edge in ~edge! } 25
  26. 26. オブジェクトの集合を宣言sig Graph{ !! nodes: set Node,! edge: nodes -> nodes,! max_node: nodes,}! {! ! all n: nodes | #max_node.edge >= #n.edge! ! edge in ~edge! } 26
  27. 27. オブジェクトの集合を宣言sig Graph{ !! nodes: set Node,! edge: nodes -> nodes,! max_node: nodes,}! {! ! all n: nodes | #max_node.edge >= #n.edge! ! edge in ~edge! } 27
  28. 28. 条件fact{!! no ^tree_edge & iden! all n: Node - Root | one tree_edge.n!! init [first] all g: prevs[Last] | let g = next[g] | del[g, g]! fin [Last]} ※無向木をつくるために一度有向木をつくる 28
  29. 29. 条件fact{!! no ^tree_edge & iden! all n: Node - Root | one tree_edge.n!! init [first]! all g: prevs[Last] | let g = next[g] | del[g, g]! fin [Last]} 29
  30. 30. 条件fact{!! no ^tree_edge & iden! all n: Node - Root | one tree_edge.n!! init [first] all g: prevs[Last] | let g = next[g] | del[g, g]! fin [Last]} →初期化。 firstはGraphの一番初めのこと 30
  31. 31. 条件fact{!! no ^tree_edge & iden! all n: Node - Root | one tree_edge.n!! init [first] →Last以外の全てのGraph!all g: prevs[Last] | let g = next[g] | del[g, g]! fin [Last]} g’ g = ー ? 31
  32. 32. 条件fact{!! no ^tree_edge & iden! all n: Node - Root | one tree_edge.n!! init [first] all g: prevs[Last] | let g = next[g] | del[g, g]! fin [Last] →終了条件} 32
  33. 33. 述語pred init (g: Graph){! g.nodes = Node! g.edge = tree_edge + ~tree_edge} →無向木(双方向)になった 33
  34. 34. 述語pred del (g, g: Graph){! g.nodes = g.nodes - g.max_node! g.edge = g.edge       - g.max_node -> g.nodes       - ~(g.max_node -> g.nodes)! some g.edge} →g’のnodesの集合の中から 次数が最大の点を消去する 34
  35. 35. 述語pred del (g, g: Graph){! g.nodes = g.nodes - g.max_node! g.edge = g.edge       - g.max_node -> g.nodes       - ~(g.max_node -> g.nodes)! some g.edge →g’のedgeの集合の中から} 次数が最大の点と繋がっている 両方向の辺を消去する 35
  36. 36. 述語pred del (g, g: Graph){! g.nodes = g.nodes - g.max_node! g.edge = g.edge       - g.max_node -> g.nodes       - ~(g.max_node -> g.nodes)! some g.edge →gは1つ以上の辺があること} (辺がない場合はLast) 36
  37. 37. 述語pred fin (g: Graph){ no g.edge}→アルゴリズムが終わるときは辺がない 37
  38. 38. 述語を実行するコマンドrun { } for 6→6つ以下の木で 条件に当てはまる結果を出力する 38
  39. 39. 正しく動く例Graph0 39
  40. 40. 正しく動く例有向木(単方向) 無向木(双方向) 40
  41. 41. 正しく動く例有向木(単方向) 無向木(双方向) 41
  42. 42. 正しく動く例Graph0(初期状態) 42
  43. 43. 正しく動く例Graph1 43
  44. 44. 正しく動く例 Graph0 edge(赤線)が2本消えているGraph1 max_nodeが移動している 44
  45. 45. 正しく動く例edgeが全部消えている→辺を全部消せた→辺を全部カバーできたGraph2 45
  46. 46. 正しく動く例の結果 点カバー1全ての辺を消せた。Node4とNode3から繋がる辺が    全ての辺だった 点カバー2このアルゴリズムで点カバーを    求めることに成功(最小点カバーは2つ) 46
  47. 47. 反例をさがす反例が満たす条件を追加する。「述語を実行するコマンド (=run)」に    条件を追加する。 47
  48. 48. 条件を追加run{! some vc: set first.nodes { first.edge in vc -> first.nodes + first.nodes -> vc and! ! ! #prevs [Last] > #vc! }} for 7 先ほどのアルゴリズムで求めた点カバーよりも 点カバーの数が少ない場合を出力 48
  49. 49. 反例Graph0 49
  50. 50. 反例Graph1 50
  51. 51. 反例Graph2 51
  52. 52. 反例Graph3 52
  53. 53. 反例edgeがない→全ての辺をカバーGraph4 53
  54. 54. アルゴリズムの結果全ての辺を消去した。(点カバーを発見)点カバーは全部で4つになった。 54
  55. 55. 反例開始 55
  56. 56. 反例の結果3つで足りる。つまり、あのアルゴリズムは正しくない※アルゴリズムが正しく動く場合もある。 56
  57. 57. 実行時間約132.8ms\爆速/※52行 57
  58. 58. まとめAlloyは条件を与えると          アルゴリズムの反例を考えてくれるコンテストを実施する際、         パターンによっては落ちるアルゴリズムを     Alloyで書くと、落ちるケースを考えてくれる →便利 (適当) 58
  59. 59. 個人的なまとめソースが凄く短い(しかし楽ではない)関係と集合と論理式に悩まされる 59
  60. 60. 伝えたかったこと設計大事 60
  61. 61. 以上で赤い本の発表を終わります。 61

×