图函数的深度优先搜索
这是一个家庭作业问题,我正在尝试在Scheme中执行深度优先搜索功能,这是我到目前为止编写的代码:
(define explore
(λ(node visited)
(let* ([neighbors (force (cdr node))]
[next (nextNode visited neighbors)]
[is-visited (member? node visited)])
(cond
;if I have no unvisited neighbours print current node and go up one level
[(equal? next #f)
(begin
(display (car node))
(display " "))]
;if current node is not visited and I have unvisited neighbors
;print current node,mark as visited and visit it's neighbors
[(and (equal? is-visited #f) (not (equal? next #f)))
(begin
(display (car node))
(display " ")
(explore next (cons node visited)))])
;go and visit the next neighbor
(if (not (equal? (nextNode (cons next visited) neighbors) #f ))
(explore (nextNode (cons next visited) neighbors) (cons node visited))))))
'node'是当前节点
“访问”是一个列表,我跟踪我访问过的节点
'nextNode' 是一个函数,返回第一个未访问的邻居(如果有的话),否则返回#f
'成员?'测试节点是否在访问列表中
图形表示使用相邻节点,通过使用letrec对节点的引用来制作,这就是我在“邻居”中使用force的原因: 例如:
(letrec ([node1 (list "NY" (delay (list node2 node3))))],其中node2和node3被定义为node1
我正在处理的问题是我访问的列表失去了对我的一些节点的跟踪当我退出递归时访问了,我该如何解决这个问题?
This is a homework question,I'm trying to do a Depth-first search function in Scheme,Here's the code I've written so far:
(define explore
(λ(node visited)
(let* ([neighbors (force (cdr node))]
[next (nextNode visited neighbors)]
[is-visited (member? node visited)])
(cond
;if I have no unvisited neighbours print current node and go up one level
[(equal? next #f)
(begin
(display (car node))
(display " "))]
;if current node is not visited and I have unvisited neighbors
;print current node,mark as visited and visit it's neighbors
[(and (equal? is-visited #f) (not (equal? next #f)))
(begin
(display (car node))
(display " ")
(explore next (cons node visited)))])
;go and visit the next neighbor
(if (not (equal? (nextNode (cons next visited) neighbors) #f ))
(explore (nextNode (cons next visited) neighbors) (cons node visited))))))
'node' is the current node
'visited' is a list in witch I keep track of the nodes I visited
'nextNode' is a function that returns the first unvisited neighbor if any or #f otherwise
'member?' test's if a node is in the visited list
The Graph representation is using adjacent made using references to nodes with letrec so that's why I use force in 'neighbors':
Eg:
(letrec ([node1 (list "NY" (delay (list node2 node3)))],where node2 and node3 are defined as node1
The problem witch I'm dealing with is that my visited lists looses track of some of the nodes I visited when I come out of recursion,How can I fix this ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您必须从递归调用中获取新的访问列表作为返回值。您要么必须修改explore,以便它返回其访问过的列表,要么定义一个您递归而不是explore的辅助函数。然后,在递归之后,您必须使用函数返回的新访问列表。
编辑:
也许更好的方法是重组你的职能。我认为这比需要的更复杂。你只是在进行深度优先遍历,对吧?真的不是搜索吗?您可以尝试更像这样的方法,使用显式堆栈来跟踪要访问的节点以及访问的节点列表:
由于这是一个家庭作业问题,我为辅助函数留下了两个参数供您填写这种方法最好的一点是,将其更改为广度优先遍历非常简单。
这里有一个提示:两种不同情况的参数会略有不同。
You have to get the new visited list as a returned value from your recursive calls. You'll either have to modify explore so that it returns its visited list, or define a helper function that you recurse on instead of explore. Then after you recurse, you'll have to use the new visited list that the function returns.
EDIT:
Perhaps a better way would be to just restructure your function. I think it's more complicated than it needs to be. You're just doing a depth-first traversal, right? Not really a search? You could try something more like this, using an explicit stack to keep track of nodes to visit, and a list of nodes visited:
Since this is a homework problem, I've left the two parameters for the helper function for you to fill in. The nicest thing about this approach is that it's very simple to change it to a breadth-first traversal.
Here's a hint: the parameters for the two different cases will be slightly different.
我也在此处回答了。
执行此操作的一种方法是仅返回列表,以便您可以在更高级别的递归中访问它。
另一种方法是将列表存储在递归之外的变量中。换句话说,不存储在堆栈中。由于为此使用全局变量不是一个好主意,因此我们需要一些局部递归。
下面的代码是反转列表的愚蠢方法,但它确实说明了我正在讨论的技术。
您可以采用这种技术来达到您的目的吗?
I answered here as well.
One method of doing this is just to return the list so you have access to it at higher levels of recursion.
Another method is to have your list be stored in a variable outside of the recursion. In other words not stored on the stack. Since it is not a good idea to use a global variable for this we need to have some local recursion.
The following code is a foolish way to reverse a list but it does illustrate the technique I am talking about.
Can you adopt this technique for your purposes?