neo4j 循环

在过去的几周中,我一直在阅读有关技能建设和将技能分解为更易于管理的部分的信息,最近我有机会分解了学习骑自行车所需的技能。

我最初勾画出了技术进步的草图,但很快意识到我已经绘制了一个依赖图,并认为将其放入Neo4j可以简化事情。

我最初的总体目标是“能够在公共公园中骑自行车”:

MERGE (:Goal:Task {name: "Be able to cycle through a public park"})

对于已经学会骑自行车的人来说,这个目标很容易,但是如果我们从头开始,这会有些艰巨,因此我们需要将其分解为可以练习的简单技能。

我们将用于任务分解的迷你算法是:

  1. 我们现在可以完成给定的任务吗?
  2. 将任务分解为更简单的内容,然后返回1。

要牢记的一件事是,我们不会在第一时间获得完美的故障,因此我们可能需要对其进行更改。 对于一张纸上绘制的图表来说,这很烦人,但是在Neo4j中,这只是一个更简单的重构。

回到骑自行车。 由于目标尚未实现,因此我们需要将其分解为一些容易的事情。 让我们从一个非常简单的事情开始:

MERGE (task:Task {name: "Take a few steps forward while standing over the bike"})
WITH task
MATCH (goal:Goal:Task {name: "Be able to cycle through a public park"})
MERGE (goal)-[:DEPENDS_ON]->(task)

在第一行中,我们创建新任务,然后将其连接到我们先前创建的目标。

图9

踏上自行车后,我们希望坐在自行车上向前旋转几圈时会感到很舒服,但是要做到这一点,我们需要使自行车从站立起步就开始运动。 我们可能还会迈出另一步,我们站在自行车上向前骑行,因为那样可能会更容易一些。

让我们更新图:

// First let's get rid of the relationship between our initial task and the goal
MATCH (initialTask:Task {name: "Take a few steps forward while standing over the bike"})
MATCH (goal:Goal {name: "Be able to cycle through a public park"})
MATCH (goal)-[rel:DEPENDS_ON]->(initialTask)
DELETE rel
 
WITH initialTask, goal, ["Get bike moving from standing start", "Cycle forward while standing", "Cycle forward while sitting"] AS newTasks
 
// Create some nodes for our new tasks
UNWIND newTasks AS newTask
MERGE (t:Task {name: newTask})
WITH initialTask, goal, COLLECT(t) AS newTasks
WITH initialTask, goal, newTasks, newTasks[0] AS firstTask, newTasks[-1] AS lastTask
 
// Connect the last task to the goal
MERGE (goal)-[:DEPENDS_ON]->(lastTask)
 
// And the first task to our initial task
MERGE (firstTask)-[:DEPENDS_ON]->(initialTask)
 
// And all the tasks to each other
FOREACH(i in RANGE(0, length(newTasks) - 2) |
  FOREACH(t1 in [newTasks[i]] | FOREACH(t2 in [newTasks[i+1]] |
    MERGE (t2)-[:DEPENDS_ON]->(t1) 
)))

图10

我们完全不需要学习如何站立时骑自行车-我们可以直接从使自行车前进到坐着向前骑行。 让我们更新图形以反映这一点:

MATCH (sitting:Task {name: "Cycle forward while sitting"})
MATCH (moving:Task {name: "Get bike moving from standing start"})
MERGE (sitting)-[:DEPENDS_ON]->(moving)

图11

一旦我们掌握了这些任务,让我们添加一些其他信息,使我们更接近我们的目标:

WITH [
  {skill: "Controlled stop using brakes/feet", dependsOn: "Cycle forward while sitting"},
  {skill: "Steer around stationary objects", dependsOn: "Controlled stop using brakes/feet"},
  {skill: "Steer around people", dependsOn: "Steer around stationary objects"},
  {skill: "Navigate a small circular circuit", dependsOn: "Steer around stationary objects"},
  {skill: "Navigate a loop of a section of the park", dependsOn: "Navigate a small circular circuit"},
  {skill: "Navigate a loop of a section of the park", dependsOn: "Steer around people"},
  {skill: "Be able to cycle through a public park", dependsOn: "Navigate a loop of a section of the park"}
 
] AS newTasks
 
FOREACH(newTask in newTasks |
  MERGE (t1:Task {name: newTask.skill})   
  MERGE (t2:Task {name: newTask.dependsOn})
  MERGE (t1)-[:DEPENDS_ON]->(t2)
)

最后,让我们摆脱从目标到“坐着向前骑车”之间的关系,因为我们已将其替换为一些中间步骤:

MATCH (task:Task {name: "Cycle forward while sitting"})
WITH task
MATCH (goal:Goal:Task {name: "Be able to cycle through a public park"})
MERGE (goal)-[rel:DEPENDS_ON]->(task)
DELETE rel

最终的依赖图如下所示:

图13

尽管我将其放入Neo4j中是为了可视化依赖关系,我们现在也可以查询数据。 例如,假设我知道如何坐在自行车上向前骑行。 我之间有什么步骤可以环游公园?

MATCH (t:Task {name: "Cycle forward while sitting"}),
      (g:Goal {name: "Be able to cycle through a public park"}),
      path = shortestpath((g)-[:DEPENDS_ON*]->(t))
RETURN path

图14

或者,如果我们想要下一步需要执行的任务的列表,我们可以稍微重新组织查询:

MATCH (t:Task {name: "Cycle forward while sitting"}),
      (g:Goal {name: "Be able to cycle through a public park"}),
      path = shortestpath((t)<-[:DEPENDS_ON*]->(g))
WITH [n in nodes(path) | n.name] AS tasks
UNWIND tasks AS task
RETURN task
 
==> +--------------------------------------------+
==> | task                                       |
==> +--------------------------------------------+
==> | "Cycle forward while sitting"              |
==> | "Controlled stop using brakes/feet"        |
==> | "Steer around stationary objects"          |
==> | "Steer around people"                      |
==> | "Navigate a loop of a section of the park" |
==> | "Be able to cycle through a public park"   |
==> +--------------------------------------------+
==> 6 rows

到此为止,但是我认为这是一种跟踪您如何学习技能的有趣方式。 对于正在学习的一些统计主题,我正在尝试一种类似的方法,但是我发现那里的任务顺序不是那么线性-有趣的是,图而不是树。

翻译自: https://www.javacodegeeks.com/2015/04/neo4j-the-learning-to-cycle-dependency-graph.html

neo4j 循环

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐