0

次のようなデータセットがあります。

V1 = name:"some name1"
V2 = name:"some name2"
V3 = name:"some name3"
V4 = name:"some name4"

E1 = weight:0.2, StartVertex:V1, EndVertex:V2
E2 = weight:0.3, StartVertex:V1, EndVertex:V3
E3 = weight:0.4, StartVertex:V1, EndVertex:V4
E4 = weight:0.5, StartVertex:V2, EndVertex:V1
E5 = weight:0.6, StartVertex:V2, EndVertex:V3
...

これらの頂点間のいくつかのパスを見つけるグレムリン クエリがあります。

そこでやりたいことが2つあります。

1: パス内のすべての重みの積を見つけられるようにしたい (path_edge1.weight * path_edge2.weight * ...)

2: 終了頂点に基づいて、各パスの結果の積を合計できるようにしたいと考えています。

私が達成したいことの擬似コード:

g.V().has('name',REGEX,\".+some_query.+\").inE.outV.inE.FindingAPathSomehow.path{path_score = 1 : foreach edge e: path_score = path_score * e.weight}{it.lastV().id}.sumWhereIdIsEqual(it[1])

うまくいけば、これはある程度理解できます。

RexPro を使用しているので、すべてを純粋な gremlin/groovy スクリプトで実行できるようにしたいと考えています。

私は答えを広く探しましたが、これを行う方法をまだ見つけることができませんでした。


上記が不明な場合の追加説明:

クエリを実行するとき、「some_query」に等しい部分文字列を持つ頂点を探しています。これにより、一連の開始頂点が得られます。

これらの頂点を使用して、グラフ内の特定のパスを探しています。これにより、次のようないくつかのパスが得られます。

V = Vertex
E = Edge

Path1 = V3 - E2 - V1
Path2 = V4 - E5 - V7 - E1 - V1

これらのエッジにはそれぞれ重みプロパティがあります。これで、シーケンスの結果である「Big Pi」または「Capital Pi」と呼ばれるものを取得したいと考えています。足し算ではなく掛け算で足し算 (Σ) を考えてみてください。

の結果は、上記の例でPath1は E2 の重みになります。上記の例では、 0.3WhilePath2の重みはになります。E5.weight * E1.weight0.6 * 0.2 = 0.12

この場合、頂点V3とから開始しV4、両方とも で終了しV1ます。この場合、両端の頂点が であるため、Path1との重みを合計したいと思います。これにより、 の合計スコアが得られます。end Vertexと scoreを持つがあった場合、結果のリストはその中の要素でなければなりません。.Path2V1V10.3 + 0.12 = 0.42Path3V20.34{[V1, 0.42], [V2,0.34] }

4

1 に答える 1

1

次のようなことができます。

gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.v(1).as('s').outE.inV.loop('s'){it.loops<3}{true}.path
==>[v[1], e[7][1-knows->2], v[2]]
==>[v[1], e[8][1-knows->4], v[4]]
==>[v[1], e[9][1-created->3], v[3]]
==>[v[1], e[8][1-knows->4], v[4], e[10][4-created->5], v[5]]
==>[v[1], e[8][1-knows->4], v[4], e[11][4-created->3], v[3]]

上記は、おもちゃのグラフを使用して、同じエンドポイントで複数の結果を生成するいくつかのパスを取得します。各パスのエッジの重みを掛けてから、パスを終了する頂点ごとにそれらを合計するため、これらすべての適切な戻り値Mapは、重みのリストのリストである値を使用して、最後の頂点でキー設定されるように思われます。各パス。それを行うには、次を使用しましたgroupBy

gremlin> m=g.v(1).as('s').outE.inV.loop('s'){it.loops<3}{true}.path.groupBy{it[it.size()-1]}{it.findAll{it instanceof Edge}.collect{it.getProperty("weight")}}.cap.next()
==>v[3]=[[0.4], [1.0, 0.4]]
==>v[2]=[[0.5]]
==>v[5]=[[1.0, 1.0]]
==>v[4]=[[1.0]]

への最初のクロージャーがgroupByキーを提供します (つまり、パスの最後の頂点)。2 番目のクロージャーは、Edgeオブジェクトをフィルタリングし、各キーのパスのリストに格納する重みを取り除きます。ここからmまたはで操作しMapて計算を終了できます。この時点では、基本的に単純な Groovy を実行しているだけです。以下は、重みの積の計算を示しています。

gremlin> m.collect{k,v->[(k):v.collect{p->p.inject{product,weight->product*weight}}]}           
==>{v[3]=[0.4, 0.4000000059604645]}
==>{v[2]=[0.5]}
==>{v[5]=[1.0]}
==>{v[4]=[1.0]}

それだけの量が得られたら、終了頂点ごとの合計の計算は、groovysum関数を使用して行うだけです。

gremlin> m.collect{k,v->[(k):v.collect{p->p.inject{product,weight->product*weight}}.sum()]}
==>{v[3]=0.800000011920929}
==>{v[2]=0.5}
==>{v[5]=1.0}
==>{v[4]=1.0}

説明を簡単にし、読みやすくするために、これを複数の Gremlin ステートメントに分割していることに注意してください。ただし、単一行スタイルが気に入った場合は、そのようにすることもできます。単一行に戻す最良の方法はgroupBy、重み積/合計を計算するための削減ステップとして機能する に 3 番目のクロージャを追加することです。

于 2013-12-09T16:36:56.560 に答える