[英]Modified Depth-First-Search Python
I'm looking to do a DFS through a graph to find nodes connected in a specific way. 我正在寻找通过图进行DFS查找以特定方式连接的节点。
graphed = {
1: [25, 30], 2: [11], 3: [13], 4: [17], 5: [17],
6: [26], 7: [11, 12], 8: [10, 13], 9: [14, 26],
10: [8, 11, 15], 11: [2, 7, 10], 12: [7, 16, 17],
13: [3, 8, 14], 14: [9, 13, 20], 15: [10, 19],
16: [12, 18], 17: [4, 5, 12], 18: [16, 21, 22],
19: [15, 28, 29], 20: [14, 25], 21: [18, 23],
22: [18, 24], 23: [21, 27], 24: [22, 27], 25: [1, 20],
26: [6, 9], 27: [23, 24], 28: [19], 29: [19], 30: [1]
}
letters = {
'S': [1],
'C': [10, [11], [12], [13], [14], [15], [16], [17],
[18], [19], [20], [21], [22], [23], [24],
[25], [26], [27], [28], [29], [30] ],
'O': [2, [3], [4], [5], [6]],
'N': [7, [8], [9]]}
some_string = 'CO'
def dfs(graph, start, num, visited = None):
# depth first search for connected nodes
k = some_string[num]
y = some_string[(num+1)]
if visited is None:
visited = []
if start in visited:
return
visited.append(start)
# if start corresponds to first letter of string, continue
if start in letters.get(k):
# find all nodes that it is connected too
for each in [x for x in graph[start] if x not in visited]:
# if any of the connected nodes correspond to
# the next letter of string, continue...
if [each] in letters.get(y):
dfs(graph, each, (num+1), visited) #recursion
return visited
lst1 = []
for i in range(1,len(graphed)):
lst1.append(dfs(graphed, i, 0))
print(lst1)
Currently, all that is returned by the DFS function is the original start value, for i in range. 当前,DFS函数返回的所有内容都是原始起始值,对于i在范围内。
[[1], [2], [3], [4], [5], [6], [7], [8], [9], [10],
[11], [12], [13], [14], [15], [16], [17], [18], [19], [20],
[21], [22], [23], [24], [25], [26], [27], [28], [29]]
I expect this: 我期望这样:
[[1], [2], [3], [4], [5], [6], [7], [8], [9], [10],
[11, 2], [12], [13,3], [14], [15], [16], [17,4], [17,5],
[18], [19], [20], [21], [22], [23], [24], [25], [26,6],
[27], [28], [29]]
To clarify: I expect the program to run the dfs function; 需要说明的是:我希望程序运行dfs函数; if the start value is a value in 'C', find all nodes connected and check if they're in 'O';
如果起始值是“ C”中的值,则找到所有连接的节点并检查它们是否在“ O”中; if they are, do the dfs with them;
如果是,请与他们一起进行dfs; if not, return the single value.
如果不是,则返回单个值。
Hopefully this is clear, I can't get my head around why it won't work. 希望这很清楚,我无法理解为什么它不起作用。 Any help is appreciated, thanks.
任何帮助表示赞赏,谢谢。
There are several problems with this code. 此代码存在几个问题。 I recommend that you start over and use incremental programming: write a few lines of code, debug them, and don't continue until they work the way you want.
我建议您重新开始并使用增量编程:编写几行代码,对其进行调试,然后直到它们以所需的方式工作时才继续。 You're not getting some of the functionality your comments seem to assume.
您没有获得您的注释似乎具有的某些功能。
See this lovely debug blog for help. 请参阅这个可爱的调试博客以获取帮助。
I've done a little debugging, including changing some variable names to something more meaningful. 我做了一些调试,包括将一些变量名更改为更有意义的名称。 Here's what I have at the moment, strictly low-tech print statements.
这是我目前所拥有的,严格的低技术印刷声明。
graphed = {
1: [25, 30], 2: [11], 3: [13], 4: [17], 5: [17],
6: [26], 7: [11, 12], 8: [10, 13], 9: [14, 26],
10: [8, 11, 15], 11: [2, 7, 10], 12: [7, 16, 17],
13: [3, 8, 14], 14: [9, 13, 20], 15: [10, 19],
16: [12, 18], 17: [4, 5, 12], 18: [16, 21, 22],
19: [15, 28, 29], 20: [14, 25], 21: [18, 23],
22: [18, 24], 23: [21, 27], 24: [22, 27], 25: [1, 20],
26: [6, 9], 27: [23, 24], 28: [19], 29: [19], 30: [1]
}
letters = {
'S': [1],
'C': [10, [11], [12], [13], [14], [15], [16], [17],
[18], [19], [20], [21], [22], [23], [24],
[25], [26], [27], [28], [29], [30] ],
'O': [2, [3], [4], [5], [6]],
'N': [7, [8], [9]]}
node_path = 'CO'
def dfs(graph, start, num, visited = None):
print("ENTER dfs", start, num, visited)
# depth first search for connected nodes
start_ltr = node_path[num]
end_ltr = node_path[(num+1)]
if visited is None:
visited = []
if start in visited:
return
visited.append(start)
# if start corresponds to first letter of string, continue
print(" search for start node", start, "in list", start_ltr, letters.get(start_ltr))
if start in letters.get(start_ltr):
# find all nodes that it is connected too
for each in [x for x in graph[start] if x not in visited]:
print(" found", each, "in", graph[start])
print(" search in list", end_ltr, letters.get(end_ltr))
# if any of the connected nodes correspond to
# the next letter of string, continue...
if [each] in letters.get(end_ltr):
dfs(graph, each, (num+1), visited) #recursion
print("LEAVE dfs", visited)
return visited
lst1 = []
for i in range(1,15): # I cut back the list for less output.
lst1.append(dfs(graphed, i, 0))
print(lst1)
Output: 输出:
$ python3 so.py
ENTER dfs 1 0 None
search for start node 1 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [1]
ENTER dfs 2 0 None
search for start node 2 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [2]
ENTER dfs 3 0 None
search for start node 3 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [3]
ENTER dfs 4 0 None
search for start node 4 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [4]
ENTER dfs 5 0 None
search for start node 5 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [5]
ENTER dfs 6 0 None
search for start node 6 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [6]
ENTER dfs 7 0 None
search for start node 7 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [7]
ENTER dfs 8 0 None
search for start node 8 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [8]
ENTER dfs 9 0 None
search for start node 9 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [9]
ENTER dfs 10 0 None
search for start node 10 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
found 8 in [8, 11, 15]
search in list O [2, [3], [4], [5], [6]]
found 11 in [8, 11, 15]
search in list O [2, [3], [4], [5], [6]]
found 15 in [8, 11, 15]
search in list O [2, [3], [4], [5], [6]]
LEAVE dfs [10]
ENTER dfs 11 0 None
search for start node 11 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [11]
ENTER dfs 12 0 None
search for start node 12 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [12]
ENTER dfs 13 0 None
search for start node 13 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [13]
ENTER dfs 14 0 None
search for start node 14 in list C [10, [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]]
LEAVE dfs [14]
[[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14]]
Does that get you moving? 那会让你动起来吗?
Your letters
dictionary is malformed. 您的
letters
词典格式错误。
'C': [10, [11], [12], [13], [14], [15], [16], [17],
[18], [19], [20], [21], [22], [23], [24],
[25], [26], [27], [28], [29], [30] ],
'O': [2, [3], [4], [5], [6]],
'N': [7, [8], [9]]}
Note how the first number for each letter is directly in the top-level list, but every other entry is in a sublist by itself. 请注意,每个字母的第一个数字如何直接位于顶层列表中,而其他所有条目本身都位于子列表中。 As a result,
if start in letters.get(k)
will be false for every C node that potentially connects to an O. 结果,
if start in letters.get(k)
, if start in letters.get(k)
对于可能连接到O的每个C节点, if start in letters.get(k)
将为false。
>>> 10 in letters.get("C")
True
>>> 11 in letters.get("C")
False
So I changed the dictionary to this: 因此,我将字典更改为:
letters = {
'S': [1],
'C': [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
'O': [2, 3, 4, 5, 6],
'N': [7, 8, 9]}
You'll have to change this line accordingly: 您必须相应地更改此行:
if [each] in letters.get(y):
To 至
if each in letters.get(y):
Also, to get the results of each recursion call to actually be passed back up, I had to change this line: 另外,要使每个递归调用的结果实际传递回去,我必须更改此行:
dfs(graph, each, (num+1), visited) #recursion
To 至
return dfs(graph, each, (num+1), visited) #recursion
Finally, add a special case at the top of the method for when all of some_string
has been found: 最后,在找到所有
some_string
情况下,在方法顶部添加一个特殊情况:
def dfs(graph, start, num, visited = None):
# depth first search for connected nodes
if (num+1 == len(some_string)):
return visited + [start]
At this point, the search was successful, so there are no more letters to search for! 至此,搜索成功,因此不再需要搜索字母!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.