考虑Java中修补匠的权重的最短路径

时间:2018-11-14 09:41:41

标签: java gremlin shortest-path tinkerpop tinkergraph

我正在尝试考虑边缘的权重属性找到最短路径 我的工作是在TinkerGraph上进行的,我想在Java中完成。

gremlin对我不是很有帮助

INSERT INTO VarTable (Var1, Var2, Var3, Var4, Var5, Var6, Var7, Var8, Var9, Var10, Var11, Var12)
      SELECT SUM(CASE WHEN MonthCol = 1 THEN 1 ELSE 0 END), 
             SUM(CASE WHEN MonthCol = 2 THEN 1 ELSE 0 END),
              . . .
             SUM(CASE WHEN MonthCol = 12 THEN 1 ELSE 0 END)
      FROM #TempTable t;

这给了我最短的路径,而没有考虑边缘的权重属性。

编辑: 我的例子:

已插入边缘:

源,目标

b1,b2

b1,b2

b1,b2

b1,b2

b1,b3

b3,b2

g.V().has(id1).
  repeat(both().simplePath()).
    until(has(id2)).as("path").
  map(unfold().coalesce(values("weight"),
                        constant(0)).
      sum()).as("cost").
  select("cost","path").next().get("path");

换句话说,边缘的权重根据边缘的频率而更新,例如,如果b1,b2出现4次,则边缘的权重为4。现在,我希望Dijkstra返回最短路径,即重量,而不是最短的边缘。路径(b1,b2)= b1-> b3-> b2

2 个答案:

答案 0 :(得分:1)

您的Gremlin几乎是正确的,但您缺少某些东西。我在TinkerPop附带的“现代”玩具图上进行了测试,您应该会发现这可行:

gremlin> g.V().has('person','name','marko').
......1>   repeat(bothE().otherV().simplePath()).
......2>     until(has('software','name','ripple')).
......3>   path().as("path").
......4>   map(unfold().coalesce(values("weight"),
......5>                         constant(0)).sum()).as("cost").
......6>   select("cost","path")
==>[cost:2.0,path:[v[1],e[8][1-knows->4],v[4],e[10][4-created->5],v[5]]]
==>[cost:1.8,path:[v[1],e[9][1-created->3],v[3],e[11][4-created->3],v[4],e[10][4-created->5],v[5]]]

您缺少的关键部分是:

  1. 您需要将both()中的repeat()替换为bothE().otherV(),以便考虑边缘。
  2. 从上一项开始,您需要边缘,以便它们出现在第3行对path()的调用中,而该行也丢失了-对于项1,Path仅包含顶点。如果您看一下第4行,您会发现为什么这很重要,因为Path展开了,并且Path的“ weight”属性加起来就给了您“成本”。

请注意,当TinkerPop 3.4.0发行时,“最短路径”将变成core step,这将使此类操作更加简单。

答案 1 :(得分:0)

根据您的描述,这是您的测试图:

g = TinkerGraph.open().traversal()
g.addV().property(id, 'b1').as('b1').
  addV().property(id, 'b2').as('b2').
  addV().property(id, 'b3').as('b3').
  addE('link').
    from('b1').
    to('b2').
    property('weight', 4).
  addE('link').
    from('b1').
    to('b3').
    property('weight', 1).
  addE('link').
    from('b3').
    to('b2').
    property('weight', 1).
  iterate()

使用以下查询找到最短的加权有向路径:

gremlin> g.withSack(0).V('b1').
......1>   repeat(outE().sack(sum).by('weight').inV().simplePath()).
......2>     emit(hasId('b2')).
......3>   order().
......4>     by(sack()).
......5>   limit(1).
......6>   path().
......7>     by(id).
......8>     by('weight')
==>[b1,1,b3,1,b2]