How to get all possible paths in 0/1 matrix better way?
You can use NearestNeighborGraph
with pos
directly:
nng = NearestNeighborGraph[pos, VertexCoordinates -> RotationTransform[-Pi/2][pos],
VertexLabels->"Name"]
Row[HighlightGraph[nng, Subgraph[nng, #], ImageSize -> 300] & /@
FindPath[nng, {1, 4}, {8, 9}, ∞, All], Spacer[5]]
If a binary matrix m
is given as input, you can use pos = SparseArray[m]["NonzeroPositions"]
before the first line of code above.
To show ArrayPlot
and the graph together we need to translate the vertex coordinates to align with cells in ArrayPlot
:
Show[ArrayPlot[SparseArray[pos -> 1], ColorRules -> {1->Opacity[.5, Yellow]}, Mesh -> All],
NearestNeighborGraph[pos,
VertexCoordinates -> TranslationTransform[{-.5, 9.50}]@RotationTransform[-Pi/2][pos],
VertexLabels -> "Name"]]
Use IndexGraph @ NearestNeighborGraph[...]
above to replace each vertex with its index:
Maybe this helps. It requires Szabolcs' package "IGraphM`"
. It is very easy to install and it provides many useful tools for working with graphs.
Needs["IGraphM`"]
A = Reverse@(1 - m);
R = ArrayMesh[Normal@A];
{i, j} = Transpose@UpperTriangularize[IGMeshCellAdjacencyMatrix[R, 2, 2], 1][ "NonzeroPositions"];
vertices = A["NonzeroPositions"][[All, {2, 1}]];
edges = Transpose[{vertices[[i]], vertices[[j]]}];
G = Graph[vertices, UndirectedEdge @@@ edges,
VertexCoordinates -> vertices,
VertexLabels -> "Name"
]
An now, we can request all paths:
paths = FindPath[G, {4, 9}, {9, 2}, Infinity, All];
GraphicsRow[
HighlightGraph[G, Subgraph[G, #]] & /@ paths,
ImageSize -> Full
]
I'd do it like this with IGraph/M:
mesh = ArrayMesh@Normal[1 - m]
g = IGMeshCellAdjacencyGraph[mesh, 2, VertexCoordinates -> Automatic,
VertexLabels -> Automatic]
There are two paths:
paths = FindPath[g, {2, 1}, {2, 36}, Infinity, All]
Length[paths]
(* 2 *)
If PathGraph
didn't dislike certain vertex names that are lists, we could show them like this:
HighlightGraph[g, PathGraph[#]] & /@ paths
To work around this limitation, we define our own pathGraph
function:
pathGraph[path_] := Graph[UndirectedEdge @@@ Partition[path, 2, 1]]