Document

大規模データに対する
効率的な列挙アルゴリズム
宇野 毅明 (情報学研究所)
(総合研究大学院大学)
牧野 和久 (東京大学)
有村 博紀 (北海道大学)
佐藤 健 (情報学研究所)
佐藤 寛子 (情報学研究所)
清見 礼 (北陸先端~大学)
ゲノムの方々 (情報学研究所など)
2006年 12月20日 小島研総合ゼミ
今日の講演内容
・ 列挙問題、列挙アルゴリズムの特徴
問題の難しさ、研究の動向、歴史
・ 応用事例 (モデル化とアルゴリズムの キモ )
- クリークの列挙
- サイクルの列挙
- (類似項目ペアの列挙)
列挙とその応用の基本
OR的アプローチのボトルネック
典型的なOR的なアプローチは、データ収集でつまづくことが多い
典型的な OR(+数理計画) 的アプローチ
問題発見
定式化
解法(最適化)
できたモデルを実際に使う
データ収集
(システム構築)
ここがボトルネック
であることが多い
求解
運用
その一方で、データが
あふれている場所もある
データ中心の科学
・ 近年、IT技術の発達で、大規模なデータが半自動的に収集で
きるようになった
(POS、web、文書、顧客データ、財務、利用者、人事…)
ならば、データがそろっているところでモデルを作ればいい
データの選別
モデル化
データ処理
いわば、データを出発点とした問題解決の科学
(人工知能、データマイニング、自然言語処理、セマンティックweb…)
データ中心ゆえの難しさとアプローチ
web ページの検索 (見つけたいページを見つける)
① キーワードを指定
② キーワードを含むページを列挙
③ 見つかったページを実際に検証
候補
Web ページ
データベース
キーワード検索
Enumerations
from databases
solve many
problems and
Enumerations
give new
from databases
knowledge
Enumerations
solve many
Enumerations
from
databases
problems and
from
databases
solve
many
give new
solve
many
problems
and
knowledge
problems andgive new
give new knowledge
knowledge
Enumerations
from databases
solve many
problems and
give new
knowledge
実際にページ
を見て検証
・ 数理的な部分をコンピュータで解く (候補の列挙)
・ 残りはユーザに任せる (候補の絞込み)
データ中心科学の特徴
・ データが整形されていない
目的がはっきりしない、あるいは異なる目的のために集められたデータを用いるため、
必要なものがすぐ取り出せるとは限らない。また、ノイズや不正確な情報も含まれうる。
・ 目的関数があいまい
データが情報の塊のようなものなので、そこから得られるものはやはり情報であること
が多い(知識、特徴分析といったもの)。それら情報の価値は数理的な尺度では計りにく
い。また、従来の最適化とは異なる尺度を用いることが多い。(グラフクラス、シークエ
ンス、情報量、隣接性、類似度、頻出度・・・)
・ データが巨大で、構造を持つ
半自動で集められたデータであるので、データは通常、巨大である。しかし各
項目が持つ属性は少なく、疎である。
・ データ処理は比較的簡単なものが多い
データ処理の計算は、最適化のような複雑ではなく、
組合せの検索や整形などいくつかの簡単な処理の組合せ
組合せの検索
つまり、列挙
列挙問題とは何でしょう
列挙問題: 与えられた問題の解を全て重複なく見つけ出す問題
・ グラフの2点間を結ぶパス
・ 数の合計の可能性
B
A
...
・ 1,3,5,8,14 の中から数字を
選んでできる合計を列挙せよ
解)
0, 1, 3, 4, 5, 6, 8, 9, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 22,
23, 25, 26, 27, 28, 30, 31
情報科学の基礎的な問題
・頂点 A と B を結ぶパスを列挙せよ
解)
…
近年、広く使われ始めている
列挙は多面的
・ 最適化は問題の一部分を見つける
 列挙は問題の全ての部分を見つける
列挙では解の全てを見つけるため、
問題の構造を全体的に把握することができる
「最適ではないが、役に立つ解」を、見つけ損なわない
問題の構造を調べたいとき、数理的にクリアでない
目的関数で解を得たいときに、列挙が有効
モデルから見ると
モデルが
・ シンプルかつ小規模なら、最適化が有効
(きれいな問題の良質な解を1つ求める)
・ 複雑あるいは大規模ならばシミュレーションが有効
(複雑・大規模な問題の多数の解を見つける)
列挙は中間に位置する
シンプルなモデル
をじっくり解く
線形計画
局所探索
組合せ最適化
最適
化
複雑なモデル
を粗く解く
列挙
良質な解を多数見つける
シミュレ
ーション
アドホック
ネットワーク
物理現象の計算
列挙研究の歴史
計算機パワーの増大
実用の可能性が発現
応用の発達
応用で使われ始める
(データマイニングなど)
1960
黎明期:
基礎問題と計算量
解が多さで、実用
の観点はなし
1990
2000
逆探索
の出現
極大元
列挙法
の出現
複雑な構造に対する
列挙法の発達
実用的なアルゴ
リズムの発達
(疎な構造の利用、
巨大データ処理等)
列挙モデルの難しさ
・ 組合せ的に選択可能な箇所があると、解数が爆発
例) 2点を結ぶパス
 最短路のみを列挙すれば、回避できうる
例) グラフのクリーク
大きなクリーク
 極大クリークのみを列挙すれば、回避できうる
極大・極小なもの、代表者をいかに選ぶかが重要
列挙アルゴリズムの難しさ
・ 解は多いが、総当りは非効率
列挙は解が指数個存在するので、ほぼ全ての組合せが解になりうる
 総当り的な検索が計算量の意味で最適
例) 2点間を結ぶパスは指数個ありうる
2点間を結ぶパスは、枝の組合せ全てより指数分の1である
指数個解のある問題は、現実的には解く意味がない
ボトルネック = 解の個数 = 出力の時間
 解が少なければ速く、解が多ければ遅いアルゴリズムが望ましい
- 解1つあたりの計算時間が短い(定数)
- 1秒あたりの出力数が大きい(スループット)
極大クリークの列挙
クリーク列挙問題
グラフのクリーク: 部分グラフで、全ての頂点間に枝があるもの
・ 2部クリークの列挙問題は、グラフの変換でクリーク列挙に
帰着できる
・ 最大クリークを求める問題はNP完全
・ 極大クリークは簡単に求められる
・ 最適化を中心に非常に多くの研究がある
応用:クラスタリング
対象: データの関連を現すグラフ
(データの項目が頂点、関係のある、類似する項目間に枝)
類似する、あるいは互いに
関連するグループ
互いに背反だが、
立場が同じ項目のグループ
・ データの種類・規模で大きさが変わる
・ 通常、それほど密ではない(次数高々100)
・ 局所的に密な部分が存在
・ パワー則、スモールワールドが成り立つことが多
Web コミュニティ発見
Webコミュニティ: 内容や嗜好が似ているweb サイトの集合
モデル: webページ、又はwebサイトのリンク構造からグラフを作る
このグラフのクリーク・2部クリークは、webコミュニティになっている
だろう
(リンクは、似た内容・嗜好のページに貼られるから)
サイト
趣味バイク
バイク好き
サイト
ホンダ
カワサキ
バイク万歳
バイク人生
ラーメン
好き
ラーメン
命
博多
ラーメン
札幌
ラーメン
ヤマハ
・ ごみページを除いた後のグラフの大きさは100万~1億程度
・ 平均次数10程度、パワー則が成り立ち、局所的に密
類義語群の発見
対象: 単語ネットワーク
(単語が頂点、単語AとB を組合せて
複合語ができるとき、枝を張る)
関東
地方
関西
地区
中国
電力
北陸
2部クリークの片側が、
似た意味を持つ単語の集合
・ 大きなものでも、15万語程度
・ 通常、それほど密ではない(次数高々200)
・ 局所的に密な部分が存在
・ パワー則、スモールワールドが成り立つ
類似論文のグループ化
対象: 論文・アブストラクトグラフ
(論文が片側の頂点、単語がもう
片側の頂点で、論文のアブストラクト
が単語を含むときに枝を張る)
論文A
論文
論文C
語1
語2
語3
論文D
語: 研究分野を表す単語群
論文: その分野の論文のグループ
・ 大きなものでも、10万語程度
・ 通常、それほど密ではない(平均次数高々200)
・ 局所的に密な部分が存在
・ パワー則、スモールワールドが成り立つ
既存研究
クリーク列挙: ほぼ自明なので論文はないが、たぶん1960年代
極大クリーク列挙
- 1960年代に指数時間アルゴリズム
- 1978年に築山らの、初の多項式時間アルゴリズム O(|V||E|)
- 1985年に西関らの、アーボリシティを用いた解析 O(a(|V|))
- 1995年ごろから、クラスタリングやデータマイニングで
極大クリーク列挙がはやり出す
- 2002年ごろから、基礎的なツールとの認識(Natureなどに論文)
- 2003年に牧野宇野の疎なグラフ用のアルゴリズム O(Δ4)
および行列演算を用いたアルゴリズム O(|V|2.31)
- 2004年に富田らの、入力サイズに対する最適アルゴリズム
実用上もとても速い
既存研究(2部グラフ)
- ヒューリスティックなものが多数ある
- 1998年ごろより、closed itemset として、データマイニングの
分野で盛んに研究される
- 2002年ごろより、web community として、web 科学の分野で
注目される
- 2002年 Zaki による closed itemset の列挙 (効率的な枝刈り)
- 2003年 有村宇野清見に LCM (今のところ実用上最速)
- 2004年 KDCI (LCMと同じ手法で同じくらい速い)
クリークの単調性
・ クリークの部分集合はクリーク
 単調性が成り立つ
 原点を出発して山を登り、
クリークでなくなったら、
戻って、他の方向に登る、
というバックトラック式の
列挙ができる
クリークであるかどうかのチェック
はO(n2) 時間、最高 n 方向に登る
 1つあたり O(n3) 時間
111…1
クリーク
000…0
1,2,3,4
1,2,3 1,2,4
1,2
SQL でもかけるが、巨大データでは長時間
1,3
1
1,3,4
1,4
2,3,4
2,3
2,4
3,4
2
3
4
φ
追加できる候補を絞り込む
・ 追加できる頂点を効率よく見つけたい
追加できる  クリークの全ての頂点に隣接
あらかじめ、追加できる候補を調べておくと楽
・ さらに、新しい頂点を1つ追加したとき、
候補に残る頂点  新しい頂点に隣接
候補の集合の更新は、
追加する頂点に隣接する頂点と、
候補の共通部分をとればいい
クリーク一個あたり、頂点の次数の時間
末広がり性
・ バックトラックは、各反復で複数の再帰呼び出しをする
 計算木は、下に行くほど大きくなる
 計算時間を支配するのは一番下の数レベル
次数大きい
頂点
・・・
次数小さい
頂点
ほぼ全ての反復が短時間で終了
(1秒間におよそ100万個)
多くの列挙アルゴリズムが似たような再帰構造を持つので、
下のレベルの仕事を上のレベルがやれば、同様の改良ができる
クリークの個数
・ 実データには、比較的大きなクリークがよくある
・ 大きなクリークの任意の部分集合はやはりクリーク
なので、個数は大きくなる
・ 極大クリークのみを列挙しよう
クリーク
- 数が1/10~1/1000 に減る
- 任意のクリークは極大クリークに
含まれるので、情報の損失がない
- 極大なほうが、中途半端なグループを含みにくく、
モデルとして的確
極大なクリークだけを上手に列挙できるか
探索の難しさと枝刈り
・ 極大クリークは山の頂上に対応
 単純な操作では行きあえない
・ そもそも、原点のそばに極大ク
リークがない
111…1
・ バックトラックが通じない
が、枝刈りをすると実に効率が良い
(上に登っても、以前見つけた
極大クリークに含まれるクリークしか
みつからないとき、枝刈りをする)
クリーク
000…0
極大クリーク枝刈り(富田法)
・ 各反復で、バックトラック法が使う頂点の変更する
- 最初の頂点に隣接するものは後半部分に押しやる
・ 後半部分の頂点に関しては、
再帰呼び出しをしなくて良い
 (見つかるクリーク)+(最初の頂点)
がクリークになっているから
・ 「最初の頂点」には次数の大きい
頂点を使うと有利
現実的には1つあたり定数時間で列挙できる
(1秒間におよそ10万個)
極大クリークの隣接関係 (築山法)
・ 極大クリーク K から、添え字の大きい順に頂点を抜いていく
・ どこかで「現在のクリークを含む辞書順最小の極大クリークK’」
が K でなくなる
(辞書順最小極大クリーク
=添え字の小さい順に頂点を加えてできる極大クリーク)
・ その K’を K の親 とする (一意的に定まる)
・ 親は子どもより必ず辞書順で小さいので、親子関係は非巡回的
 親子関係は有向根付き木を導出する
逆探索
親子関係は有向根付き木を導出する
この木を深さ優先探索すれば全ての解を見つけられる
・ 探索には、子供を見つけるアルゴリズムがあれば十分
・ 子供が1つあたり多項式時間で見つかれば、全体も多項式時間
非巡回的な親子関係と、子供を見つける多項式時間アル
ゴリズムがあれば、なんでも多項式時間列挙ができる
子どもの特徴づけ
・ K[i]: K に頂点 i を加え、i に隣接する頂点を取り除きできたク
リークを、含む辞書順最小のクリーク
・ K' が K の子供  K[i] = K' がいずれかの i について成り立つ
i
K[i] だけ調べればよい (高々|V|個)
・ i が K のどの頂点とも隣接しないなら、K[i] の親は i を含む
辞書順最小のクリーク
通常は K に隣接する i のみ調べればよい (高々(Δ+1)2個)
例題
・このグラフで実際の親子関係を見てみる
1, 2
3
1
3
7
5
4
1, 3, 5
6
2, 4, 6, 8
7
10
8
9
12
2
4
11
10
3, 5, 7, 9, 12
11
9, 11
11
6, 8, 10
11
8, 10, 11
4, 8, 11
12
10, 12
例題
・このグラフで実際の親子関係を見てみる
1, 2
3
1
3
7
5
4
1, 3, 5
6
2, 4, 6, 8
7
10
8
9
12
2
4
11
10
3, 5, 7, 9, 12
11
9, 11
11
6, 8, 10
11
8, 10, 11
4, 8, 11
12
10, 12
辞書順最小の極大クリークを求める
・ CAND(K):頂点集合 K の全ての頂点に隣接する頂点の集合
・ CAND(K) の中で最小添え字の頂点を
K に加える、という作業を、
CAND(K) が空になるまで続ける
・ CAND(K∪i) = CAND(K) ∩ (iに隣接する頂点)
なので、 i の次数の時間で更新可能
・ クリークの大きさは、最大次数 Δよりも高々1大きいだけなので、
繰り返し解数は、高々 Δ+1
O(Δ2) 時間で、「K を含む辞書順最小のクリーク」が求められる
親を計算する
・ K のいずれかの頂点に隣接する頂点全てについて、「 K のいく
つの頂点と隣接するか」を記録 (r(v)とする)
 r(v) = |K| ⇒ K に追加可能
・ K の最大添え字の頂点から順に消していき
r(v) を更新する ( O(Δ2) 時間)
 r(v) = |K| となるものができたら
K に追加可能な頂点が現れたということ
・ その時点で、 K を含む極大クリークを見つければよい
O(Δ2) 時間で、K の親が計算できる
子どもを見つける
通常は K に隣接する i のみ調べればよい (高々(Δ+1)2個)
O(Δ2) 時間で、K[i] の親が計算できる
・ 以上から、子どもを全て見つけるのにかかる時間はO(Δ4) であ
ることがわかる
・ アルゴリズムは、各反復で極大クリークを1つ見つける
極大クリークは1つあたり O(Δ4) 時間で列挙できる
子どもの特徴づけ
・ K<i: K に含まれる、添え字が i 未満の頂点の集合
・ C(K): K を含む辞書順最小のクリーク
・ N(v): v に隣接する頂点の集合(近傍)
・ K[i] が K の子ども 
① K<i ∩N(vi) = K[i]<i
② C(K<i ∩N(vi) ) = K
特に ② は、 が Kの親 L に対して、K = L[j]、j<i となることと、
② C(K<i ∩N(vi) )>i = K>i が成り立つことが必要十分
頂点 vi より前のみを見ればよい
高速計算の技法
・ 全ての集合は、配列で保持する(メモリもまとめて確保)
・ アクセスを良くするため、頂点の添え字順に並べておく
① K<i ∩N(vi): 普通に計算すれば、 O(|K<i|+| N(vi)<i| )
 振り分けを使って改良
・ K の各頂点 vj に対し、 N(vj)>j の各頂点のバケツにvjを挿入
・ 終了後、vi のバケツの中身は K<i ∩N(vi)
 計算時間は O(|K<i∩N(vi)<i| )
・ 再帰呼び出しを添え字の大きい順にすることで、バケツは再帰
呼び出し内で繰り返し使える
 初期設定でvi に大きさ N(vi) のバケツを確保すれば、
2度と確保しないでよい
Occurrence Deliver
・ Compute the denotations of P ∪{i} for all i’s at once,
A 1 A2
1,2,5,6,7,9
2,3,4,5
D= 1,2,7,8,9
1,7,9
2,7,9
P = {1,7}
2
Check the frequency for all
items to be added in linear
time of the database size
A5 A6 7
A9
B
2 3 4 5
C 1 C2
7 C8 C9
D 1
7
D9
7
9
E
2
F
2
Generating the recursive calls in reverse
direction, we can re-use the memory
高速計算の技法 (2)
② K[i]<i と C(K<i ∩N(vi) ):
普通は O(∑v∈K[i]<i |N(v)|)、O(∑v∈C(K<i ∩N(vi) |N(v)|)
・ 調べたい K<i ∩N(vi) = K[i]<i 、C(K<i ∩N(vi)) = K の等号が成
り立たないとわかった時点で、計算をやめてよい
 K[i]<i と C(K<i ∩N(vi) ) を添え字順に計算して比べる
・ K<i ∩N(vi) = K[i]<i の例を解説
まず、定義から K<i ∩N(vi) ⊆ K[i]<i は自明
・ K[i]<i の頂点で、K<i ∩N(vi) に含まれないものがあるか?
添え字順に、計算して、比べる
逐次比較の手間
・定義 K[i]<i = C(K<i ∩N(vi) ∪vi)
・ K<i ∩N(vi) の頂点から1つ、次数の小さい頂点 u を選ぶ
 K[i]<i ⊆ N(u) だから、 N(u) の頂点のみ K[i]<i に入るか調べ
ればよい
K<i ∩N(vi) 2 11
・ ある K<i ∩N(vi) に含まれない
頂点が K[i]<i に含まれる
 その頂点が K<i ∩N(vi) ∪vi
の全ての頂点に隣接
・ K<i ∩N(vi) ∪vi の頂点の
次数の合計、の時間がかかる
u 1 2 6 9
vi 1 2 3 5 9
2 4 5 9
K<i ∩N(vi)
1 2 4 6 9
1 2 9 11
スウィープポインタ
・ K<i ∩N(vi) の頂点、および viの頂点隣接リストに対して、始まり
の位置を指すポインタを準備
・ u に隣接する各頂点 vj に対して(小さい順) vj未満でない頂点
が見つかるまでポインタを進める
・ vj 以上のものを指すポインタが
あったら、u に隣接する次の 頂点の
チェックへ進む
・ 全ての頂点に隣接する頂点が
あるなら、K に含まれるか調べる
K<i ∩N(vi)
2 11
4 ∞
u 3 4 6 9
1 3 4 5 9
23 4 5 9
1 2 4 6 9
1 4 9 11
ビットマトリクス
・ スウィープポインタは、隣接行列を持ってないがゆえの工夫
隣接行列を持って入れば、もっと単純に速くできる
・が、大きすぎて構築することすら不可能
・ 隣接行列で、各反復で利用するのはクリークの頂点の行のみ
 その部分のみをアップデートしよう
・ 通常、クリークの大きさは最大でも 20 程度
 ビットで持てば、各列が1つの変数に入る!
ビットマトリクスの定数時間計算
・ 各列を1変数で持っていると、隣接性のチェックが1ステップでで
きる
 u が K<i ∩N(vi) の全ての頂点に隣接するかどうかを判定す
るには、 u の行の変数と、 K<i ∩N(vi) のビットパターンの共通
部分をとり、欠損が無いか(それ自身と等しいか)を調べる
K の頂点
・・・
K<i ∩N(vi)
逆探索の例: 根付き木
親の定義:
左が重くなるように子供をソートし、
一番右の葉を除去する
逆探索の例: フロアプラン
親の定義:
左上の部屋の
右か下の壁をスライドして
左上の部屋をつぶす
(長方形による部屋分け)
計算実験
・言語:
・ マシン:
・ OS&コンパイラ:
C
パソコン PentiumIII 500MHz
Linux、gcc
・ 一般グラフ、2部グラフの問題を解いた
・ 通常のランダムグラフでは面白い実験ができないので、
添え字が近い頂点にしか枝を張らないランダムグラフを作っ
た。
新旧アルゴリズムの比較
30000
25000
既存 r=10
提案 r=10
既存 r=30
提案 r=30
次数巨大あり
20000
15000
10000
5000
0
10
00
30
00
50
00
70
00
90
00
16
00
64 0
00
25 0
60
00
1万個あたりの計算時間(秒)
既存と提案手法の比較
頂点数
新旧アルゴリズムの比較 (2)
10000
8000
既存 r=10
提案 r=10
既存 r=30
提案 r=30
次数巨大あり
6000
4000
2000
0
10
00
33
50
66 7
01
98 5
52
13 1
10
16 27
35
19 33
60
22 41
85
47
1万個あたりの計算時間(秒)
既存と提案手法の比較
頂点数
3500
3000
2500
既存
提案
既存
提案
2000
1500
1000
500
0
10
00
30
00
50
00
70
00
90
00
16
00
0
64
00
25 0
60
00
1万個あたりの計算時間(秒)
2部グラフの場合
頂点数
r=10
r=10
r=30
r=30
次数の変化に対する挙動
1000
100
10
1
10
20
40
80
0.1
※ だいたい、次数の2乗に比例
160
320
実データに対する計算時間
・ 疎なグラフであれば、極大クリークの数は通常非常に小さい
(頂点数の 10から100倍くらい)
辞書データ: 4万頂点 10万枝  50秒
webデータ: 500万頂点 5000万枝  1時間くらい?
…
現実的な疎データでは、だいたい全列挙可能と考えてよい
results
参考文献など
・ 築山らのアルゴリズム (‘78)
初の多項式時間アルゴリズム
・ 宇野らのアルゴリズム (‘03) 改良版。大きく疎なデータでも速い
・ 富田らのアルゴリズム (‘04) 枝刈りを用いた列挙。密でも速い
・ クリークの応用の文献は星の数ほど(Nature などにもある)
“クラスタリング” + “クリーク” などで検索
・ 実装 MACE: (MAximal Clique Enumerator)
http:research.nii.ac.jp/~uno/
宇野のHP
コードレスサイクルの列挙
化合物の立体構造の推定
・ 新たな化合物が得られたときに、その組成は比較的容易
に得られるが、結合の構造は容易に計測できず、さらに立
体的な構造の計測はもっと難しい
NO2
NO2
C6H5NO4
O
化合物
組成
OH
平面構造
すでに構造がわかっている化合物の
データを検索して、構造を推定する
OH
O
立体構造
化合物の立体構造の推定 (2)
・ 推定する化合物と部分的な平面構造が一致する化合物を
データベースから探し出す
 大域的な構造が拾えない
・ 検索結果を、環構造の複雑さ
で絞り込む
 立体構造の要因が入り、精度が増す
グラフのサイクルを列挙することで、どのような
サイクル構造を持つか、全て調べ上げる
遺伝ネットワークの依存関係の解析
・ 遺伝子を頂点とし、遺伝子Aが発現すると、遺伝子Bに影響を
与え、発現するときに 枝を引いたグラフを遺伝ネットワークという
A
・ 循環している系を見ようとすると、
サイクルの構造が必要
B
F
 サイクルを列挙することで、
どのような構造があるかを解析する
C
E
D
サイクル列挙の既存研究
- 1972年に、Read & Tarjan による初の多項式時間アルゴリズム
(1つあたり O(|E|)時間)
- 2000年あたりから、グラフのパス/サイクルを
列挙するモデルが出始める
- 2003年に宇野のコードレスサイクルを列挙するアルゴリズム
(1つあたり O(|E|)時間)
※ コードレスサイクル:
コードを持たないサイクル
分割法による列挙
・ サイクルの集合は、単調性を満たさない
 バックトラックは適用できない
111…1
・ 分割法というアルゴリズムを使う
000…0
・ 最初の枝を選ぶ
・片方の端点に接続する枝それぞれについて、
「その枝を使うサイクル」を再帰的に列挙する
・ ただし、サイクルができない枝は行わない
・最初の枝の、もう片方の端点に帰って
きたところでサイクルがひとつ見つかる
サイクルの存在のチェック
・ 効率良く列挙するためには、選択した枝を含むサイクルが存
在するかどうかを短時間でチェックする必要がある
・ 今まで選択した枝でできるパスの内点を全ての抜いたグラフ
で、端点から端点へ行ければサイクルが存在
グラフ探索1回でできる
探索1回で、加える枝
全てをチェックできる
1つあたりグラフの大き
さの時間で列挙できる
末広がり性の利用
・ 再帰構造の下の部分では、選択したパスの両端点が近い
 幅優先探索でチェックを行えば、
グラフ
小さい範囲しか探索しない
・ 再帰が深くなるほど、
反復が短時間で終了する
実用的には、1つあたり定数時間で列挙できる(1秒10万個)
・ しかし、通常サイクルの数は多い
コードレスサイクルの利用
・ ショートカットを持たないサイクルをコードレスサイクルという
・ 冗長なサイクルはコードレスにならない
(ある意味で極小)
・ サイクルの本質部分が見える
応用上もありがたい
・ 少々の変更で、同様に列挙できる
(すでに通った頂点の隣を通ると、
コードができてしまうので、それを避ける)
化合物データのコードレスサイクル数は小さい
400原子程度の化合物でも高々10万程度  1-2秒
実験結果(計算時間)
・ ランダムグラフを作り実験(1パターンあたり1回)
・ 1万個あたりの計算時間
100
200
400
800
1600
3200
頂点数
10%
40%
70%
80%
90%
0.17
0.18
0.17
0.2
0.24
0.29
0.09
0.09
0.09
0.13
0.13
0.19
0.09
0.09
0.10
0.13
0.21
0.25
0.10
0.11
0.15
0.26
0.29
0.61
0.12
0.17
0.26
0.54
1.30
1.79
密度
実験結果(コードレスサイクル数)
・ コードレスサイクルと、普通のサイクルの数の比較
10
15
20
25
頂点数
10% 30%
50%
70% 90%
0
0
0
0
1
1
8
20
352
165
6620995
637
2099
45
3697
247
771
1775
3
4
34
1470
298
9114038
2049
81
108906
350
908
1928
密度
実験結果(コードレスサイクル数 その2)
・ コードレスサイクル数
10%
30%
50%
70%
90%
50
64383
267435
82607
34137
18873
75
119379652 14504338
1158210
221990
73810
100
-
273504609 8269935
877466
199133
150
-
-
149022507 6641331
200
-
-
-
30334867 2466694
300
-
-
-
-
2167686
11457502
化学シフト値予測システムに組み込み
・ 化学シフト値:核磁気共鳴で原子核の解析をする際に得られ
る、原子の観測値の1つ
・ 局所的な、立体的な構造により、変化するため、化合物の構
造を解析する際に用いられる(化学シフト値から、経験と過去の
解析結果から、構造を予測する)
・ 化学シフト値を精度よく予測すると、立体構造を精度よく予測
できる
化学シフト値予測システムに組み込み (2)
・ CASTシステム:佐藤 寛子 (NII), 越野 広雪 (理研)
立体構造も考慮した、化合物データベース
1. 化学シフト値を予測したい化合物の各原子に対して、
局所的な平面構造が等しく & 環構造が似ている
化合物の原子をデータベースから検索
2. 検索でヒットした原子の化学シフト値の平均で予測する
(環構造が類似 = 各長さに対し、含まれる環の数が類似)
(局所構造のみ見たい & 全ての環を考慮すると、オーバー
フィット  コードレスサイクルが都合よい)
化学シフト値予測システムに組み込み (3)
・ 実験結果
まとめ
・ データ中心の科学: あいまいな目的と不ぞろいなデータ
・ 列挙による解析は多面的
・ 出力数依存アルゴリズム、解数の小さいモデルの重要性
・ クリーク列挙の、末広がり性の利用による高速化
・ 極大クリーク列挙:枝刈りと逆探索
・ 分割法によるコードレスサイクルの列挙
・ データマイニングなどでの応用を意識した、より複雑なモデルに
対する高速アルゴリズムの開発
・ツールとしての完成度を高める(解の圧縮など)