枚举树中的所有路径

发布于 2024-11-04 01:43:18 字数 614 浏览 5 评论 0原文

我已经尝试过了;搜索了又搜索,但无法真正找到解决我的问题的算法。我想枚举树中的所有路径(不仅仅是简单路径)那些以叶节点开头和结尾的路径(尽管这是一个简单的约束)。

例如,对于一棵树;

      1
    /   \ 
   2     3
  / \   / \
 4   5 6   7

我希望能够生成以下路径:

4
4-2-5
4-2-5-2-1-3-6
4-2-5-2-1-3-7
4-2-5-2-1-3-6-3-7
4-2-1-3-6
4-2-1-3-7
4-2-1-3-6-3-7
5
5-2-1-3-6
5-2-1-3-7
5-2-1-3-6-3-7
6
6-3-7
7

我想仅此而已。

我尝试了以下解决方案 查找所有简单路径的复杂性使用深度优先搜索? 。但是,这只找到简单路径,因此无法找到 4-2-5-2-1-3-6 等路径。

有什么方法可以指导我,也许是任何算法?

I've tried and tried; searched and searched, but could not really find an algorithm to solve my problem. I want to enumerate all paths in a tree, (not just simple paths) those which start and end with the leaf nodes (this is an easy constraint though).

For example, for a tree;

      1
    /   \ 
   2     3
  / \   / \
 4   5 6   7

I want to be able to generate the following paths:

4
4-2-5
4-2-5-2-1-3-6
4-2-5-2-1-3-7
4-2-5-2-1-3-6-3-7
4-2-1-3-6
4-2-1-3-7
4-2-1-3-6-3-7
5
5-2-1-3-6
5-2-1-3-7
5-2-1-3-6-3-7
6
6-3-7
7

I guess that's all.

I have tried the following solution Complexity of finding all simple paths using depth first search? . However, that only finds the simple paths, therefore paths such as 4-2-5-2-1-3-6 could not be found.

Are there any ways that you can guide me, any algorithm perhaps ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

-小熊_ 2024-11-11 01:43:18

像 4-2-1-2-5 这样的路径算吗?如果是这样,我想我有了答案:

在我看来,您只希望每个边缘被访问“一次”。因此,采用图形的“对偶”并将路径视为边序列而不是顶点序列。这样,边变成了“顶点”,顶点变成了“边”

这应该将您的问题简化为生成图形的简单路径,这是您已经知道如何做的问题。

traverse(path, edg):
    mark edg as visited
    print path
    for each edge (e2) sharing a vertex with edg:
        traverse(e2, path+e2)

(with some sort of precaution to avoid duplicate paths being printed)

Do paths like 4-2-1-2-5 count? If so, I think I have the answer:

It looks to me like you only want each edge to be visited "once" . So take the "dual" of your graph and look at paths as a sequence of edges rather than a sequence of vertices. This way, edges become your "vertices" and vertices become "edges".

This should reduce your problem to generating simple paths of a graph, a problem you already know how to do.

traverse(path, edg):
    mark edg as visited
    print path
    for each edge (e2) sharing a vertex with edg:
        traverse(e2, path+e2)

(with some sort of precaution to avoid duplicate paths being printed)
请帮我爱他 2024-11-11 01:43:18

如果您的树是二叉树,那么这里有一个相当简单的递归算法。在Python中:

def lchild(u):
    return 2 * u

def rchild(u):
    return 2 * u + 1

def paths(u, depth):
    if depth <= 0:
        yield ((), (u,), ())
    else:
        for ldown, lpath, lup in paths(lchild(u), depth - 1):
            yield ((u,) + ldown, lpath, lup + (u,))
        for ldown, lpath, lup in paths(lchild(u), depth - 1):
            for rdown, rpath, rup in paths(rchild(u), depth - 1):
                yield ((u,) + ldown, lpath + lup + (u,) + rdown + rpath, rup + (u,))
        for rdown, rpath, rup in paths(rchild(u), depth - 1):
            yield ((u,) + rdown, rpath, rup + (u,))

if __name__ == '__main__':
    for down, path, up in paths(1, 2):
        print path

IF your tree is a binary tree, here's a reasonably simple recursive algorithm. In Python:

def lchild(u):
    return 2 * u

def rchild(u):
    return 2 * u + 1

def paths(u, depth):
    if depth <= 0:
        yield ((), (u,), ())
    else:
        for ldown, lpath, lup in paths(lchild(u), depth - 1):
            yield ((u,) + ldown, lpath, lup + (u,))
        for ldown, lpath, lup in paths(lchild(u), depth - 1):
            for rdown, rpath, rup in paths(rchild(u), depth - 1):
                yield ((u,) + ldown, lpath + lup + (u,) + rdown + rpath, rup + (u,))
        for rdown, rpath, rup in paths(rchild(u), depth - 1):
            yield ((u,) + rdown, rpath, rup + (u,))

if __name__ == '__main__':
    for down, path, up in paths(1, 2):
        print path
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文