Neo4J - Traveling Salesman

一世执手 提交于 2019-12-21 06:57:31

问题


I'm trying to solve an augmented TSP problem using a graph database, but I'm struggling. I'm great with SQL, but am a total noob on cypher. I've created a simple graph with cities (nodes) and flights (relationships).

THE SETUP: Travel to 8 different cities (1 city per week, no duplicates) with the lowest total flight cost. I'm trying to solve an optimal path to minimize the cost of the flights, which changes each week.

Here is a file on pastebin containing my nodes & relationships. Just run it against Neo4JShell to insert the data.

I started off using this article as a basis but it doesn't handle the changing distances (or in my case flight costs)

I know this is syntactically terrible/non-executable, but here's what I've done so far to get just two flights;

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

But that doesn't run.

Next, I thought I'd just try to find all the cities & flights from week one, but it's not working right either as I get flights where week <> 1 as well as =1

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

Can anyone help out?

PS - I'm not married to using a graph DB to solve this, I've just read about them, and thought it would be well fitted to try it, plus gave me a reason to work with them, but so far, I'm not having much (or any) success.


回答1:


neo4j may be a fine piece of software, but I wouldn't expect it to be of much help in solving this NP-hard problem. Instead, I would point you to an integer program solver (this one, perhaps, but I can't vouch for it) and suggest that you formulate this problem as an integer program as follows.

For each flight f, we create a 0-1 variable x(f) that is 1 if flight f is taken and 0 if flight f is not taken. The objective is to minimize the total cost of the flights (I'm going to assume that each purchase is an independent decision; if not, then you have some more work to do).

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

Now we need some constraints. Each week, we purchase exactly one flight.

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

We can be in only one place at a time, so if we fly into city v for week i, then we fly out of city v for week i+1. We express this constraint with a strange but idiomatic linear equation.

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

We can fly into each city at most once. We can fly out of each city at most once. This is how we enforce the constraint of visiting only once.

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

We're almost done. I'm going to assume at this point that the journey begins and ends in a home city u known ahead of time. For the first week, delete all flights not departing from u. For the last week, delete all flights not arriving at u. The flexibility of integer programming, however, means that it's easy to make other arrangements.




回答2:


Maybe this Cypher query will give you some ideas.

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

It does all permutations of available routes which are equal to the number of nodes (for this example it is 7), calculates lengths of all these paths and returns the shortest one.



来源:https://stackoverflow.com/questions/25673673/neo4j-traveling-salesman

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!