我正在编写一个网络抓取工具,我需要找到两个网址之间的最小距离。
我用哈希表示网络。不在网络末端的每个节点都被键入到它所连接的节点的向量:
hash = {:v0 => [:v1, :v2, :v3],
:v1 => [:v4, :v5, :v6],
:v2 => [:v7, :v8, :v9],
:v3 => [:v10, :v11, :v12],
:v4 => [:v13, :v14, :v15]}
此解决方案无效。问题是我只在找到目标时增加距离(dist变量),因此结果总是1
:
def path src, target, hash, dist
return -1 if hash[src] == nil # invalid distance if source is invalid
return dist += 1 if hash[src].include? target
arr = Array.new
for i in hash[src] do
arr.push path(i, target, hash, dist)
end
arr = arr.delete_if {|x| x < 0} # delete invalid values
return -1 if arr.empty?
return arr.min # return the shortest distance
end
如何修复它以便它会在网络的每一层上递增?
答案 0 :(得分:1)
看起来你还没有完全理解递归的想法。为此,首先写下你的“路径距离”的定义。我引用的原因是我希望你要么想要距离,要么你想要路径(路径的长度是距离),但我真的不知道你需要什么。
现在,重要的原因是,在这种情况下,它可能类似于“路径是从当前URL到目标URL的最短距离”。实现类似于“如果目标URL是直接邻居,距离是1,否则它是距离任何邻居加1的最短距离”。在你的情况下,你传入一个现有的距离,这不是真的错,但不寻常。接下来,如果你在hash[src]
中找到了这个URL,那么你增加那个距离(Ruby是按引用传递,BTW?)和返回它。那时,我实际上希望你返回1,因为这是当前位置和目标之间的距离。同样,稍后,在将其传递给递归调用之前,您可能还需要递增dist
。
现在,存在一个完全不同的问题,那就是你的算法效率低下,以至于只有少数几个URL就会变得无用。让我们假设URL连接像“A - X - T”,X是开头,T是目标。如果你运气不好,你首先进入A,这可能是成千上万的URL云。在遍历整个图之后,这些中的每一个都将找到到T的路径。看一下广度优先搜索(BFS)和深度优先搜索(DFS)之间的区别,它将为您提供如何修复它的提示。
还有两件事:
答案 1 :(得分:0)
我修好了。这是代码,如果它对某人有帮助。
def distance src, target, hash
return 0 if src == target
return nil if hash[src].nil?
dist = 1
if hash[src].include? target
return dist
else
arr = hash[src].map {|x| distance x, target, hash}
end
arr = arr.delete_if {|x| x.nil?}
return dist + arr.min if !arr.empty?
return nil
end