Getting distance and cost from an MCP
David Orme
david.orme at gmail.com
Wed Apr 23 06:43:49 EDT 2014
Hi,
I have a solution, but it is a hack and only works for the special case
where the distance (not cost) within cells is constant. I suspect it is
also a hostage to floating point precision.
Basically, add a downscaled resolution to the cost values - downscaled so
that this additional value doesn't interfere with the cost pathways. Then
run find_costs() on both versions of the cost matrix and the difference
(scaled back up) is the physical distance. I think the traceback matrix
provides a test for when the hack fails by interfering with the pathing.
If anyone has anything more elegant, I'd love to know about it!
Cheers,
David
from skimage import graph
import numpy
cost = numpy.array([[9,1,9,9,9,9,9,9,9],
[9,1,9,9,9,9,9,9,9],
[9,2,9,9,9,9,9,9,9],
[9,1,9,9,9,9,9,9,9],
[9,1,9,9,9,9,9,9,9],
[9,1,9,9,9,9,9,9,9],
[9,3,9,9,9,9,9,1,9],
[9,1,9,9,9,9,9,1,9],
[9,1,9,9,9,9,9,2,9],
[9,1,9,9,9,9,9,1,9],
[9,2,9,9,9,9,9,1,9],
[9,1,9,9,9,9,9,3,9],
[9,1,9,9,9,9,9,1,9],
[9,1,2,1,1,3,1,1,9],
[9,9,9,9,9,9,9,9,9]], dtype='float')
# add the resolution to each cost, downscaled so that
# it won't interfere with path choice
resolution = 250
scale = 1e7
costPlusDist = cost + resolution/scale
# get two sets of cumulative costs
costMCP = graph.MCP_Geometric(cost, fully_connected=True)
cumcost, trace = costMCP.find_costs([(0,1)])
costDistMCP = graph.MCP_Geometric(costPlusDist, fully_connected=True)
cumcostdist, trace2 = costDistMCP.find_costs([(0,1)])
if (trace == trace2).all():
dist = (cumcostdist - cumcost)*scale
else:
print "Hack failed - different minimum cost paths used"
On Tuesday, 22 April 2014 14:59:34 UTC+1, David Orme wrote:
>
> Hi,
>
> I'm running some road building simulations in Python across a cost
> surface. What I'd like to be able to do is to get both the cost of paths
> to a set of starting points and the actual physical distance that those
> paths would cover.
>
> I can easily find the cumulative costs of paths using MCP_Geometric from
> the graph module but I can't figure out how to get a surface of cumulative
> distance along the least cost paths. I could iterate over each cell in the
> cost array in turn to get the cheapest path and fetch the distance using
> pythogoras on the steps, but my intuition from the documentation is that
> the MCP_Flexible class in 0.10dev - particularly the travel_cost method -
> might allow me to get at this more quickly.
>
> In the toy example, below I'd like to find costs from a start point at
> [0,1] in the cost array. Most of the array is expensive to traverse, but
> the valley means that there are big differences in the length of the
> cheapest road needed to get between points. If the entries in the cost
> array represent cells with a resolution of 250 metres across, the path from
> [0,1] to [0,5] has a cost of 32.0 along a road of length 1.5 km (4 steps
> E). In contrast, the path from [0,1] to [6,7] has a cost of 35.04 along a
> road of length 6.21 km (12 steps S - 3km, 1 step SE - 0.354km, 4 steps E -
> 1km, 1 step NE - 0.354km, and 6 steps N - 1.5km).
>
> Any suggestions would be very welcome.
> Cheers,
> David
>
> import numpy
> from skimage import graph
>
> cost = numpy.array([[9,1,9,9,9,9,9,9,9],
> [9,1,9,9,9,9,9,9,9],
> [9,2,9,9,9,9,9,9,9],
> [9,1,9,9,9,9,9,9,9],
> [9,1,9,9,9,9,9,9,9],
> [9,1,9,9,9,9,9,9,9],
> [9,3,9,9,9,9,9,1,9],
> [9,1,9,9,9,9,9,1,9],
> [9,1,9,9,9,9,9,2,9],
> [9,1,9,9,9,9,9,1,9],
> [9,2,9,9,9,9,9,1,9],
> [9,1,9,9,9,9,9,3,9],
> [9,1,9,9,9,9,9,1,9],
> [9,1,2,1,1,3,1,1,9],
> [9,9,9,9,9,9,9,9,9]], dtype='float')
>
> costMCP = graph.MCP_Geometric(cost, fully_connected=True)
> cumcost, trace = costMCP.find_costs([(0,1)])
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/scikit-image/attachments/20140423/87fa658c/attachment.html>
More information about the scikit-image
mailing list