[pgrouting-dev] New TSP algorithm and refactoring - take 2
Stephen Woodbridge
woodbri at swoodbridge.com
Sun Mar 31 07:18:25 PDT 2013
So, here is another look at this problem, by looking at the data the
needs to flow through the problem.
I am ambivalent about using the ARRAY objects but they are convenient
for representing ordered collections of objects and specifically the
dmatrix data.
Solve TSP based on Euclidean distances:
1. list of N points to optimize using TSP
REC(seq, x, y) or ARRAY[P1, P2, P3, ..., PN]
2. compute euclidean dmatrix from points
ARRAY[
ARRAY[0.0, d2, d3, d4, ..., dN],
ARRAY[d1, 0.0, d3, d4, ..., dN],
ARRAY[d1, d2, 0.0, d4, ..., dN],
ARRAY[d1, d2, d3, 0.0, ..., dN],
...,
ARRAY[d1, d2, d3, d4, ..., 0.0]
]
3. solve TSP and get order list of dmatrix indices
ARRAY[i1, i2, i3, i4, ..., iN]
4. return ordered list of edge pairs
REC(1, n1, n2, LINESTRING(P[i1], P[i2]))
REC(2, n2, n3, LINESTRING(P[i2], P[i3]))
REC(3, n3, n4, LINESTRING(P[i3], P[i4]))
REC(4, n4, n5, LINESTRING(P[i4], P[i5]))
...
REC(N, nN, n1, LINESTRING(P[iN], P[i1]))
The above is the simple case. We don't need to compute routes. This
would also have application of solving non-routing optimization problems
where you have a distance/cost matrix and need to optimize the path
through it.
Solve TSP based on Driving Distance:
1. list of N points to optimize using TSP
REC(seq, x, y) or ARRAY[P1, P2, P3, ..., PN]
2. map points to list of N node_ids
ARRAY[N1, N2, N3, ..., NN]
3. compute dmatrix by routing between nodes
this step needs to keep more information like the list of edges for
for each route in the matrix, so we can reconstitute the optimized
route in the final step. This needs some error handling to deal with
duplicate nodes, unreachable nodes (ie: failure to route to or from
a node).
ARRAY[
ARRAY[0.0, d2, d3, d4, ..., dN],
ARRAY[d1, 0.0, d3, d4, ..., dN],
ARRAY[d1, d2, 0.0, d4, ..., dN],
ARRAY[d1, d2, d3, 0.0, ..., dN],
...,
ARRAY[d1, d2, d3, d4, ..., 0.0]
]
4. solve TSP and get order list of matrix indices
ARRAY[i1, i2, i3, i4, ..., iN]
5. return ordered list of routes
REC(1, n1, n2, route_from_dmatrix(n1, n2))
REC(1, n2, n3, route_from_dmatrix(n2, n3))
REC(1, n3, n4, route_from_dmatrix(n3, n4))
REC(1, n4, n5, route_from_dmatrix(n4, n5))
...
REC(1, nN, n1, route_from_dmatrix(nN, n1))
For this we need to cache the computed routes so we don't compute them
twice. I think that this can get done using a WITH clause to cache the
routes in a temp table and use a aggregate to assemble the dmatrix.
Something like:
WITH distances (i, j, dist, route[]) as
select * from compute_routes(node_ids[], ...)
select * from TSP(make_dmatrix_symmetric(i, j, dist));
There are also some optimizations that can be done if we are working
with symmetric case vs a non-symmetric case.
Anyway, this is as far as I have gotten try to look at how the data
needs to flow between the various sub processes to generate a result.
Thoughts,
-Steve
More information about the pgrouting-dev
mailing list