mcp.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. from ._mcp import MCP, MCP_Geometric, MCP_Connect, MCP_Flexible # noqa: F401
  2. def route_through_array(array, start, end, fully_connected=True, geometric=True):
  3. """Simple example of how to use the MCP and MCP_Geometric classes.
  4. See the MCP and MCP_Geometric class documentation for explanation of the
  5. path-finding algorithm.
  6. Parameters
  7. ----------
  8. array : ndarray
  9. Array of costs.
  10. start : iterable
  11. n-d index into `array` defining the starting point
  12. end : iterable
  13. n-d index into `array` defining the end point
  14. fully_connected : bool (optional)
  15. If True, diagonal moves are permitted, if False, only axial moves.
  16. geometric : bool (optional)
  17. If True, the MCP_Geometric class is used to calculate costs, if False,
  18. the MCP base class is used. See the class documentation for
  19. an explanation of the differences between MCP and MCP_Geometric.
  20. Returns
  21. -------
  22. path : list
  23. List of n-d index tuples defining the path from `start` to `end`.
  24. cost : float
  25. Cost of the path. If `geometric` is False, the cost of the path is
  26. the sum of the values of `array` along the path. If `geometric` is
  27. True, a finer computation is made (see the documentation of the
  28. MCP_Geometric class).
  29. See Also
  30. --------
  31. MCP, MCP_Geometric
  32. Examples
  33. --------
  34. >>> import numpy as np
  35. >>> from skimage.graph import route_through_array
  36. >>>
  37. >>> image = np.array([[1, 3], [10, 12]])
  38. >>> image
  39. array([[ 1, 3],
  40. [10, 12]])
  41. >>> # Forbid diagonal steps
  42. >>> route_through_array(image, [0, 0], [1, 1], fully_connected=False)
  43. ([(0, 0), (0, 1), (1, 1)], 9.5)
  44. >>> # Now allow diagonal steps: the path goes directly from start to end
  45. >>> route_through_array(image, [0, 0], [1, 1])
  46. ([(0, 0), (1, 1)], 9.19238815542512)
  47. >>> # Cost is the sum of array values along the path (16 = 1 + 3 + 12)
  48. >>> route_through_array(image, [0, 0], [1, 1], fully_connected=False,
  49. ... geometric=False)
  50. ([(0, 0), (0, 1), (1, 1)], 16.0)
  51. >>> # Larger array where we display the path that is selected
  52. >>> image = np.arange((36)).reshape((6, 6))
  53. >>> image
  54. array([[ 0, 1, 2, 3, 4, 5],
  55. [ 6, 7, 8, 9, 10, 11],
  56. [12, 13, 14, 15, 16, 17],
  57. [18, 19, 20, 21, 22, 23],
  58. [24, 25, 26, 27, 28, 29],
  59. [30, 31, 32, 33, 34, 35]])
  60. >>> # Find the path with lowest cost
  61. >>> indices, weight = route_through_array(image, (0, 0), (5, 5))
  62. >>> indices = np.stack(indices, axis=-1)
  63. >>> path = np.zeros_like(image)
  64. >>> path[indices[0], indices[1]] = 1
  65. >>> path
  66. array([[1, 1, 1, 1, 1, 0],
  67. [0, 0, 0, 0, 0, 1],
  68. [0, 0, 0, 0, 0, 1],
  69. [0, 0, 0, 0, 0, 1],
  70. [0, 0, 0, 0, 0, 1],
  71. [0, 0, 0, 0, 0, 1]])
  72. """
  73. start, end = tuple(start), tuple(end)
  74. if geometric:
  75. mcp_class = MCP_Geometric
  76. else:
  77. mcp_class = MCP
  78. m = mcp_class(array, fully_connected=fully_connected)
  79. costs, traceback_array = m.find_costs([start], [end])
  80. return m.traceback(end), costs[end]