我怎样才能找到所有“长”的东西?图中的简单非循环路径?

发布于 2024-12-15 05:05:40 字数 716 浏览 2 评论 0原文

假设我们有一个完全连接的有向图G。顶点是[a,b,c]。每个顶点之间都有两个方向的边。

给定一个起始顶点a,我想在所有方向上遍历图形,并仅当我遇到路径中已经存在的顶点时才保存路径。

因此,函数 full_paths(a,G) 应该返回:

- [{a,b}, {b,c}, {c,d}]
- [{a,b}, {b,d}, {d,c}]
- [{a,c}, {c,b}, {b,d}]
- [{a,c}, {c,d}, {d,b}]
- [{a,d}, {d,c}, {c,b}]
- [{a,d}, {d,b}, {b,c}]

我不需要像 [{a,b}][{a ,b}, {b,c}],因为它已经包含在第一个结果中。

除了生成 G 的幂集并过滤掉一定大小的结果之外,还有其他方法吗?

我该如何计算这个?

编辑:正如Ethan指出的,这可以通过深度优先搜索方法来解决,但不幸的是我不明白如何修改它,使其在回溯之前存储路径(我使用Ruby Gratr 来实现我的算法)

Let's say we have a fully connected directed graph G. The vertices are [a,b,c]. There are edges in both directions between each vertex.

Given a starting vertex a, I would like to traverse the graph in all directions and save the path only when I hit a vertex which is already in the path.

So, the function full_paths(a,G) should return:

- [{a,b}, {b,c}, {c,d}]
- [{a,b}, {b,d}, {d,c}]
- [{a,c}, {c,b}, {b,d}]
- [{a,c}, {c,d}, {d,b}]
- [{a,d}, {d,c}, {c,b}]
- [{a,d}, {d,b}, {b,c}]

I do not need 'incomplete' results like [{a,b}] or [{a,b}, {b,c}], because it is contained in the first result already.

Is there any other way to do it except of generating a powerset of G and filtering out results of certain size?

How can I calculate this?

Edit: As Ethan pointed out, this could be solved with depth-first search method, but unfortunately I do not understand how to modify it, making it store a path before it backtracks (I use Ruby Gratr to implement my algorithm)

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

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

发布评论

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

评论(2

埖埖迣鎅 2024-12-22 05:05:41

您是否研究过深度优先搜索或其他变体?深度优先搜索会遍历尽可能远的距离,然后回溯。每次需要回溯时都可以记录路径。

Have you looked into depth first search or some variation? A depth first search traverses as far as possible and then backtracks. You can record the path each time you need to backtrack.

梦罢 2024-12-22 05:05:41

如果您知道图 G 是完全连通的,则当 N 时,有 N! 条长度为 N 的路径 是图 G 中的顶点数。您可以通过这种方式轻松计算它。您有 N 种选择起点的可能性,那么对于每个起点,您可以选择 N-1 个顶点作为路径上的第二个顶点,依此类推,当您只能选择最后一个时每条路径上未访问过的顶点。所以你有 N*(N-1)...*2*1 = N! 条可能的路径。当您无法选择起点(即给出)时,它与在具有 N-1 顶点的图 G' 中查找路径相同。所有可能的路径都是所有顶点集的排列,即在您的情况下是除起点之外的所有顶点。当您有排列时,您可以通过以下方式生成路径:

perm_to_path([A|[B|_]=T]) -> [{A,B}|perm_to_path(T)];
perm_to_path(_) -> [].

在您的情况下,如何生成排列的最简单方法是

permutations([]) -> [];
permutations(L) ->
  [[H|T] || H <- L, T <- permutations(L--[H])].

paths(A, GV) -> [perm_to_path([A|P]) || P <- permutations(GV--[A])].

其中 GV 是图 G 的顶点列表强>。

如果您想要更高效的版本,则需要更多的技巧。

If you know your graph G is fully connected there is N! paths of length N when N is number of vertices in graph G. You can easily compute it in this way. You have N possibilities of choice starting point, then for each starting point you can choose N-1 vertices as second vertex on a path and so on when you can chose only last not visited vertex on each path. So you have N*(N-1)*...*2*1 = N! possible paths. When you can't chose starting point i.e. it is given it is same as finding paths in graph G' with N-1 vertices. All possible paths are permutation of set of all vertices i.e. in your case all vertices except starting point. When you have permutation you can generate path by:

perm_to_path([A|[B|_]=T]) -> [{A,B}|perm_to_path(T)];
perm_to_path(_) -> [].

simplest way how to generate permutations is

permutations([]) -> [];
permutations(L) ->
  [[H|T] || H <- L, T <- permutations(L--[H])].

So in your case:

paths(A, GV) -> [perm_to_path([A|P]) || P <- permutations(GV--[A])].

where GV is list of vertices of graph G.

If you would like more efficient version it would need little bit more trickery.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文