なんとな~くしあわせ?の日記

「そしてそれゆえ、知識そのものが力である」 (Nam et ipsa scientia potestas est.) 〜 フランシス・ベーコン

Neo4jでグラフアルゴリズム

前から調べようと思っていたNeo4jの勉強会に行ってきた。
jp-neo4j-usersgroup.connpass.com

グラフアルゴリズム

AOJ - 深さ優先探索

データセットの用意

入力例 2
6
1 2 2 3
2 2 3 4
3 1 5
4 1 6
5 1 6
6 0

  • こんな感じか?
    • たぶん書き方が冗長になっている気がする
CREATE (g:Graph { u:1, k:2 });
CREATE (g:Graph { u:2, k:2 });
CREATE (g:Graph { u:3, k:1 });
CREATE (g:Graph { u:4, k:1 });
CREATE (g:Graph { u:5, k:1 });
CREATE (g:Graph { u:6, k:0 });

MATCH (s:Graph) WHERE s.u = 1
MATCH (d:Graph) WHERE d.u = 2
CREATE (s)-[:DIRECTED]->(d);

MATCH (s:Graph) WHERE s.u = 1
MATCH (d:Graph) WHERE d.u = 3
CREATE (s)-[:DIRECTED]->(d);

MATCH (s:Graph) WHERE s.u = 2
MATCH (d:Graph) WHERE d.u = 3
CREATE (s)-[:DIRECTED]->(d);

MATCH (s:Graph) WHERE s.u = 2
MATCH (d:Graph) WHERE d.u = 4
CREATE (s)-[:DIRECTED]->(d);

MATCH (s:Graph) WHERE s.u = 3
MATCH (d:Graph) WHERE d.u = 5
CREATE (s)-[:DIRECTED]->(d);

MATCH (s:Graph) WHERE s.u = 4
MATCH (d:Graph) WHERE d.u = 6
CREATE (s)-[:DIRECTED]->(d);

MATCH (s:Graph) WHERE s.u = 5
MATCH (d:Graph) WHERE d.u = 6
CREATE (s)-[:DIRECTED]->(d);
ビジュアライズ

Neo4j Desktopを使ってビジュアライズしてみる

f:id:panzer-jagdironscrap1:20180802233545p:plain

なにこれ高性能過ぎる・・・

アルゴリズム実装

あとはこれをクエリで距離を測ったりいろいろやりたい。

実装するのはこれ

function 深さ優先探索(v)
    v に訪問済みの印を付ける
    v を処理する
    for each v に接続している頂点 i do
        if i が未訪問 then
            深さ優先探索(i)
  • ノード3から辿れるものを出力
    • これで一応有向グラフをたどることはできてんのかな?
    • もともとプログラム側の疑似コードで for each v に接続している頂点 i do ~ done という処理をやらせているのは、グラフの探索のためであった、Neo4j(GQL)では MATCH (src)-[:DIRECTED*]->(dst) にてその指示が完了しているので、そこを考える必要がなくなっている?あとは、後戻り防止のために訪問済みかどうかチェックが付けられればいいのだけど。*1
MATCH (src)-[:DIRECTED*]->(dst)
WHERE src.u = 3
RETURN dst;

f:id:panzer-jagdironscrap1:20180802235638p:plain

*1:そしてそのような処理はFOREACHでできそう