我试图从一个距离原点给定的图中找到所有路径的组合。在
事实上,魔兽世界(军团)的新扩展将在游戏中引入神器系统。
这是一个你可以升级的功能,每一级给你1个等级,你可以为树上的每个等级花费1点。
您可以在WowHead上找到每个工件的计算器,我将以这个为例:http://legion.wowhead.com/artifact-calc/rogue/subtlety/
基本上,该计划的目标是:
“我给一个秩,比方说7,它返回给我从图中得到的每一个路径组合,我花了7个点才能到达那里(即,7个唯一节点的列表)”。在
当我看到计算器时,我认为它可以通过将其转换为图形来求解,因此我制作了一个计算器来帮助我通过: Graph
在图上,我不得不从计算器上做一些调整,例如,每一个有3个等级的特征必须表示为3个相互连接的节点。 另外,对于那些解锁了2种继续方式的特性,我不得不将它们表示为4个节点,以“模拟”3个节点的需求来通过。(但我们会看到,这仍然是一个问题,它并没有真正解决问题)
然后,我试图找到一个好的方法列出每一个可能性,所以我在互联网上做了很多研究,以找到解决问题的最佳方法。
我首先尝试用广度优先搜索来解决这个问题,但是从每个节点的原点开始算起并没有多大帮助。
然后我试图使用详尽的搜索。
我现在使用的是一个在上面发布的代码的改编版:“从一个给定的图中查找所有的路径”CodeReview@StackEchange(不能发布超过2个链接)
def paths(graph, v, lmax):
"""Generate the maximal cycle-free paths with a given maximum length lmax in
graph starting at v. Graph must be a mapping from vertices to collections of
neighbouring vertices.
>>> g = {1: [2, 3], 2: [3, 4], 3: [1], 4: []}
>>> sorted(paths(g, 1, 3))
[[1, 2, 3], [1, 2, 4], [1, 3]]
>>> sorted(paths(g, 3, 4))
[[3, 1, 2, 4]]
Credit to Gareth Rees from StackExchange for the original code.
"""
path = [v] # path traversed so far
seen = {v} # set of vertices in path
def search():
dead_end = True
if len(seen) < lmax:
for neighbour in graph[path[-1]]:
if neighbour not in seen:
dead_end = False
seen.add(neighbour)
path.append(neighbour)
yield from search()
path.pop()
seen.remove(neighbour)
if dead_end:
yield list(path)
yield from search()
然后我创建一个函数对结果进行排序,只显示具有所需长度的结果。在
^{pr2}$从那里,我从图中构建了一部分节点的相邻节点(邻居)列表。我不能发布超过2个链接,但子图在8/7/32/31节点处结束,该节点来自之前链接的图。在
g = {
1: [2, 38],
2: [1, 3],
3: [2, 4],
4: [3, 5],
5: [4, 6],
6: [5, 7, 8],
7: [6],
8: [6],
31: [33],
32: [33],
33: [31, 32, 34],
34: [33, 35],
35: [34, 36],
36: [35, 37],
37: [36, 38],
38: [1, 37]
}
然后我调用了我的函数:
artifact(g, 8, 1)
但使用这个列表,我面临一个重大问题。事实上,算法一直走到最后,但它没有回溯到想要的排名(也就是说,经过1-38-37-36-35-34-33-31,它不会回到2-3-。。。如果我有10个点可以花)。
我可以通过在38,37。。。分支或38到2,3。。。分支机构。在
所以我的名单是:
g = {
1: [2, 38],
2: [1, 3, 38],
3: [2, 4, 38],
4: [3, 5, 38],
5: [4, 6, 38],
6: [5, 7, 8, 38],
7: [6, 38],
8: [6, 38],
31: [2, 33],
32: [2, 33],
33: [2, 31, 32, 34],
34: [2, 33, 35],
35: [2, 34, 36],
36: [2, 35, 37],
37: [2, 36, 38],
38: [1, 2, 37]
}
然后我就可以得到我想要的这部分图表。
现在我试着把我的推理扩展到整个图。但我的失败主要有两个原因:
-当我朝一个方向走的时候,代表3个等级的特征的4个节点是有效的,但是如果我填充了整个分支,然后我尝试返回,我计算第4个节点。(我仍然可以在artifact函数中创建一些东西来删除第4个节点,但我认为这不是一个好方法来处理它,应该找到一个聪明的方法来处理它。
-我用来链接前两个分支的技巧并不直接适用于整个图。例如,按照我所做的,我会在29个邻居中添加32个,因为当我从35岁开始时,从29岁开始可以访问32个。但是,如果我从28岁开始,没有在路径上加上27岁,那么从29岁开始,32岁是不可能到达的。
然后我的路径变得无效。在
我不确定我是否能这样解决它,我希望你能帮助我。而且,我觉得我的回溯搜索方式并不完美。
我也认为:
当我在一个分支的末端,我会回到以前的分离,从那里探索。但是,由于节点已经被探索过了,所以它不会走到另一条路,停在那里。在
最后,我想用其他方法来解决我的问题,我不想让别人知道用图形来求解。
也许还有另一种方法可以有效地解决这个问题(比如一步一步地构建图,在节点被解锁的情况下,有许多列需要花费并逐渐花费它们?)。在
提前感谢您的帮助,并为我的英语错误道歉,我是法国人:)
IIUC,你有一个未加权的有向图G,你正在寻找G的所有子图H的集合,它们具有以下两个性质:
有一个简单的算法,在这里你保持所有子图的总长度正好是i,并且在每次迭代中,将它们增长到总长度正好为i+1的所有子图的集合:
当算法终止时,S将包含满足上述要求1和2的所有子图。在最坏的情况下,它需要m乘以输出中不同子图的数目,其中m是图中的边数。注意输出中可能有大量的子图,考虑到n个顶点上的完整图,注意到可能的子图比n中k个项目的组合要多,后者已经很大了。在
如果只想走一条路径,那么可以尝试Dijkstra's Algorithm来获取从初始节点到所有其他节点的距离。然后迭代它们,返回具有所需距离的值。在
如果您想尝试分支路径,这可能会变得更加困难。我的直觉是在其他节点上运行Dijkstra,并使用一些动态编程,但我敢打赌有一种更简单的方法;我的计算机科学问题解决能力不高。在
相关问题 更多 >
编程相关推荐