【问题标题】:Neo4J - Traveling SalesmanNeo4J - 旅行推销员
【发布时间】:2014-09-04 19:35:12
【问题描述】:

我正在尝试使用图形数据库解决增强的 TSP 问题,但我很挣扎。我对 SQL 很擅长,但对 cypher 完全是个菜鸟。我创建了一个包含城市(节点)和航班(关系)的简单图表。

设置:以最低的总飞行成本前往 8 个不同的城市(每周 1 个城市,无重复)。我正在尝试解决一个最佳路径,以尽量减少每周变化的航班成本。

Here is a file on pastebin 包含我的节点和关系。只需针对 Neo4JShell 运行它即可插入数据。

我开始使用 this article 作为基础,但它不能处理不断变化的距离(或者在我的情况下是飞行成本)

我知道这在语法上很糟糕/不可执行,但这是我到目前为止所做的只获得两个航班;

MATCH (a:CITY)-[F1:FLIGHT{week:1}]->(b:CITY) -[F2:FLIGHT{week:2}]->(c:CITY) RETURN a,b,c;

但这并没有运行。

接下来,我以为我会尝试从第一周开始查找所有城市和航班,但它也无法正常工作,因为我得到了第 1 周和 =1 的航班

MATCH (n) WHERE (n)-[:FLIGHT { week:1 }]->() RETURN n

有人可以帮忙吗?

PS - 我不喜欢使用图形数据库来解决这个问题,我刚刚读过它们,并认为它很适合尝试它,另外给了我一个与它们合作的理由,但是所以到目前为止,我没有太多(或任何)成功。

【问题讨论】:

  • 我已将 David 的回答标记为已接受的解决方案。我希望使用 Neo4J,但听起来我需要研究 IP 求解器。经过更多的研究,Neo4J 可能更擅长建模这种类型的关系问题,但它的计算能力仍然不足以解决 NP 难题,比暴力破解更好。

标签: algorithm neo4j cypher traveling-salesman


【解决方案1】:

也许这个 Cypher 查询会给你一些想法。

MATCH (from:Node {name: "Source node" })
MATCH path = (from)-[:CONNECTED_TO*6]->()
WHERE ALL(n in nodes(path) WHERE 1 = length(filter(m in nodes(path) WHERE m = n)))
AND length(nodes(path)) = 7
RETURN path,
    reduce(distance = 0, edge in relationships(path) | distance + edge.distance)
    AS totalDistance
ORDER BY totalDistance ASC
LIMIT 1

它对等于节点数的可用路径进行所有排列(在本例中为 7),计算所有这些路径的长度并返回最短的路径。

【讨论】:

    【解决方案2】:

    neo4j 可能是一款不错的软件,但我不认为它对解决这个 NP 难题有多大帮助。相反,我会为您指出一个整数程序求解器(可能是this one,但我不能保证),并建议您将这个问题表述为一个整数程序,如下所示。

    对于每个航班 f,我们创建一个 0-1 变量 x(f),如果航班 f 已乘坐,则为 1,如果航班 f 未乘坐,则为 0。目标是最小化航班的总成本(我将假设每次购买都是一个独立的决定;如果不是,那么您还有一些工作要做)。

    minimize sum_{flights f} cost(f) x(f)
    

    现在我们需要一些约束。每周,我们只购买一个航班。

    for all weeks i, sum_{flights f in week i} x(f) = 1
    

    我们一次只能在一个地方,所以如果我们飞入城市v 一周i,那么我们飞出城市v 一周i+1。我们用一个奇怪但惯用的线性方程来表达这个约束。

    for all weeks i, for all cities v,
      sum_{flights f in week i to city v} x(f) -
        sum_{flights f in week i+1 from city v} x(f) = 0
    

    每个城市最多只能飞一次。每个城市最多只能飞出一次。这就是我们强制访问一次的约束的方式。

    for all cities v,
      sum_{flights f to city v} x(v) <= 1
    
    for all cities v,
      sum_{flights f from city v} x(v) <= 1
    

    我们快完成了。在这一点上,我将假设旅程开始和结束于一个提前知道的家乡u。第一周,删除所有未从u 起飞的航班。上周,删除所有未到达u 的航班。然而,整数规划的灵活性意味着很容易做出其他安排。

    【讨论】:

    • 如果你不打算使用 neo4j,因为只有 8 个! = 40320 种可能性,全部尝试似乎更容易......
    • @FalkHüffner 给定数据集,看起来该应用程序要访问 32 个不同的 NFL 主办城市中的 8 个,而 32 的下降幂 8 对于方便的蛮力来说有点太大了。
    猜你喜欢
    • 2011-09-08
    • 2015-04-28
    • 2017-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多