我一直在尝试实现深度优先搜索的不同方法。我找到了一些工作方法,但它们涉及一些相当繁琐的字典工作。我使用列表开发了一个新想法,但此实现返回的操作与所需的结果不匹配。我会尝试尽可能清楚地评论代码:
start = problem.getStartState() ## returns an (x, y) tuple
children = problem.getSuccessors(start) ##returns the children of a parent node in ((start
state), action, cost) format.
stack = Stack() ##creates a Stack (LIFO) data structure
visited = [] ##list of visited nodes
visited.append(start)
for child in children:
stack.push((child, [], [], 0)) ##push children to fringe in the format of (child,
while stack: ##path taken, actions taken, cost)
parent = stack.pop()
node = parent[0]
if parent[0] in visited: continue
visited.append(parent[0])
path = parent[1] + [node[0]] ##assigns previous path/actions/cost to new
actions = parent[2] + [node[1]] ##node, creating a cumulative, ordered list of
print actions ##the path/actions and a cumulative cost
cost = parent[3] + node[2]
if problem.isGoalState(node[0]):
print parent[2]
return parent[2] ## returns list of actions
children = problem.getSuccessors(node[0])
if children != []:
for child in children:
stack.push((child, path, actions, cost)) ##assigns cumulative lists to child
任何人都可以看到我的问题可能存在于此实施中?顺便说一下,我知道DFS对于大多数情况来说是一种效率低下的算法。但是,一旦我实现了这个实现,它应该能够通过简单地改变存储父节点子节点的数据结构来交叉到其他搜索算法。
答案 0 :(得分:6)
CS188朋友:D这里读代码真的很难......所有那些索引%) 使用更多变量,它会更清楚。 我的解决方案:
def depthFirstSearch(problem): fringe = util.Stack(); expanded = set(); fringe.push((problem.getStartState(),[],0)); while not fringe.isEmpty(): curState, curMoves, curCost = fringe.pop(); if(curState in expanded): continue; expanded.add(curState); if problem.isGoalState(curState): return curMoves; for state, direction, cost in problem.getSuccessors(curState): fringe.push((state, curMoves+[direction], curCost)); return [];
我希望我不需要发表评论。这很容易阅读:) 祝你有个美好的一天;)
答案 1 :(得分:4)
你似乎有一个名字冲突。请注意:
children = problem.getSuccessors(start) ##returns the children of a parent node in ((start
...
for child in children:
...
while stack:
...
children = problem.getSuccessors(node[0])
...
在第一次迭代之后,你的原始孩子会丢失,因为它被内循环中的孩子覆盖了。
通常,DFS最好使用recursive function实现,大致如下(未经测试):
def dfs(problem, state, visited):
visited.append(state)
# have we reached the goal?
if problem.isGoalState(state):
return [state]
for child in problem.getSuccessors(state):
# if child is already visited, don't bother with it
if child in visited: continue
# otherwise, visit the child
ret = dfs(problem, child, visited)
if ret is not None:
# goal state has been reached, accumulate the states
ret.append(state)
return ret
return None # failed to find solution here
# note that Python return None by default when reaching the end of a function