【问题标题】:Get all possible paths from one point of a square matrix to another with obstacles获取从方阵的一个点到有障碍物的另一个点的所有可能路径
【发布时间】:2020-05-20 15:17:15
【问题描述】:

我有一个带有多个起点和终点的方阵(比如 5x5)(比如 3 组):

最终目标是为每对点找到路径,这样就不会有路径与另一对点相交。在那个简单的例子中,可能有不止一个解,但在现实生活中,一旦你开始添加更多的点对,就会有一个唯一的解,它会填充整个矩阵,这样就不会留下任何正方形。

然而,我的第一步是为每一对点找到从一个起点到其对应终点的所有可能路径,以便我可以丢弃所有路径与另一点相交的路径。如果可能的话,我想这样做而不必求助于图论,因为 1)我对此一无所知,并且 2)它似乎没有在 Octave 中实现。

我对此进行了大量研究,发现GitHub 中的以下函数几乎完全符合我的目标,但确实依赖于图论:

function pth = pathbetweennodes(adj, src, snk, verbose)
%PATHBETWEENNODES Return all paths between two nodes of a graph
%
% pth = pathbetweennodes(adj, src, snk)
% pth = pathbetweennodes(adj, src, snk, vflag)
%
%
% This function returns all simple paths (i.e. no cycles) between two nodes
% in a graph.  Not sure this is the most efficient algorithm, but it seems
% to work quickly for small graphs, and isn't too terrible for graphs with
% ~50 nodes.
%
% Input variables:
%
%   adj:    adjacency matrix
%
%   src:    index of starting node
%
%   snk:    index of target node
%
%   vflag:  logical scalar for verbose mode.  If true, prints paths to
%           screen as it traverses them (can be useful for larger,
%           time-consuming graphs). [false]
%
% Output variables:
%
%   pth:    cell array, with each cell holding the indices of a unique path
%           of nodes from src to snk.

% Copyright 2014 Kelly Kearney

我的问题是尝试计算邻接矩阵。不熟悉图论,我有点理解邻接矩阵的概念,但在实际生成所述矩阵时不知所措。

如果我分别对待每一对并将其他占用的方格视为“禁区”,那么每个场景我将有 25 - 4 = 21 个节点,并且我可以在纸上手动写下边缘,但我没有不知道如何编码?有人可以帮忙吗?

如果我们使用上面的示例并按行对节点进行排序,考虑到蓝色的点对,我们会得到类似的结果,目标是从节点 1 到节点 17(反之亦然,没有涉及方向性):

 1  2  3  4  5 
    6     7  8
 9 10 11 12 13
14 15 16 17
18    19 20 21

边缘是有效的移动(垂直或水平,无对角线),例如:

1 - 2
2 - 1
2 - 3
2 - 6
3 - 2
3 - 4
etc...

你如何从这个到一些代码?

当然,如果有更好的方法来解决这个问题,我愿意接受任何建议。就问题的规模而言,它可以达到一个 10x10 的网格,具有 10 对起点/终点,即 82 个节点。

【问题讨论】:

    标签: matrix octave graph-theory adjacency-matrix


    【解决方案1】:

    邻接矩阵是一个矩阵,如果节点n 与所有其他元素相邻,则元素adj(n,:) 将通过布尔值(或路径长度)告诉您。例如在您的情况下,adj(14,:) 除了adj(14,9)adj(14,15)adj(14,18) 之外全为零。

    不过,您是从一个不错但稍有偏离的初始开始的。没有连接的节点仍然是系统中的节点。这将使您的生活更轻松!

    您的初始矩阵只是node_ids=1:25,或者如果您想要node_ids=reshape(1:25,5,5)。您不想访问的节点可以描述为不与任何东西相邻的节点。因此,对此进行编程的方法是首先为 5x5(或任何大小)网格创建邻接矩阵,然后删除所有不需要的路径,例如adj(:,6)=0(对于所有节点,请确保它们不与节点 6 相邻(注意,节点是您示例中的第一个红色圆圈)。

    要构建这个矩阵,您只需要知道哪些节点是相邻的,但是对于立方体,找到一个方程来给出它的相邻节点很容易(或者只需检查node_ids(ind2sub(your_node)+[0 1]) 和其他组合)

    【讨论】:

    • 我明白了。谢谢,我会试一试并报告。
    • 谢谢,我首先创建一个零矩阵,然后在有效移动的地方添加一个(为此我使用了一堆 if..elseif...else 语句来检查)如果矩阵元素位于外部边界之一或矩阵的中心 - 可能有更好的方法可以做到这一点,但它有效)然后将那些被占用的节点的行和列设置为 0。查看生成的邻接矩阵(假设节点按列编号,从左上角的 1 开始),我确信有一种更快的方法来定义,但现在我有一个解决方案。
    • 我现在在尝试查找多条路径的交集时遇到了另一个问题,但这是一个不同的话题,所以我会接受这个并提出另一个问题。再次感谢。
    • @am304 快速的方法是创建一个更大的矩阵,计算方向差异,然后裁剪结果,这样就可以避免边界条件的 ifs。
    猜你喜欢
    • 1970-01-01
    • 2011-04-27
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多