在Ruby图上生成路径
我有一个有12个节点的无向图,我生成了如下数组:在Ruby图上生成路径,ruby,arrays,algorithm,sorting,graph-algorithm,Ruby,Arrays,Algorithm,Sorting,Graph Algorithm,我有一个有12个节点的无向图,我生成了如下数组: arr = [[3, 12], [8, 12], [0, 3], [0, 5], [0, 10], [7, 9], [5, 5], [4, 9], [5, 12], [0, 1]] 它表示图形的边 我想通过图找到可能最长的路径,例如每条边最多使用一次。例如,它将类似于: arr = [[1, 0], [0, 5], [5, 5], [5, 12], [12, 3], [3, 0], [0, 10]] 我已经在很多源代码中看到了通过搜索Eul
arr = [[3, 12], [8, 12], [0, 3], [0, 5], [0, 10], [7, 9], [5, 5], [4, 9], [5, 12], [0, 1]]
它表示图形的边
我想通过图找到可能最长的路径,例如每条边最多使用一次。例如,它将类似于:
arr = [[1, 0], [0, 5], [5, 5], [5, 12], [12, 3], [3, 0], [0, 10]]
我已经在很多源代码中看到了通过搜索Euler路径来解决这个问题的方法,但都是用其他编程语言编写的. 在Ruby中,我该如何处理它呢?类似的方法可能适合您,尽管可能有更好的方法
def generate_array
a = []
b2 = nil
10.times do
b1,b2 = [b2 || rand(12),rand(12)]
a << [b1,b2]
end
a
end
generate_array
#=> [[0, 4], [4, 4], [4, 11], [11, 4], [4, 8], [8, 11], [11, 4], [4, 2], [2, 6], [6, 0]]
def生成_数组
a=[]
b2=零
10.5倍
b1,b2=[b2 | |兰德(12),兰德(12)]
a[[0,4]、[4,4]、[4,11]、[11,4]、[4,8]、[8,11]、[11,4]、[4,2]、[2,6]、[6,0]]
另外,基于给定输出的注释rand(12)
永远不会返回12
,因为上限是使用0索引设置的,因此返回的最大数字是11一条euler路径恰好访问每一条边一次,所以我想您不需要这样做。我能提供的是这样的东西:
def find_path(arr, first_chain = nil, path = [], available = arr.dup)
edge_idx = available.index do |first, _|
first_chain.nil? || first == first_chain
end
unless edge_idx
return path
end
edge = available.delete_at(edge_idx)
path << edge
find_path(arr, edge.last, path, available)
end
arr = [[0, 5], [3, 0], [5, 5], [1, 0], [0, 10], [5, 12], [12, 3]]
find_path arr
# => [[0, 5], [5, 5], [5, 12], [12, 3], [3, 0], [0, 10]]
find_path arr, 1
# => [[1, 0], [0, 5], [5, 5], [5, 12], [12, 3], [3, 0], [0, 10]]
def find_path(arr,first_chain=nil,path=[],available=arr.dup)
edge_idx=available.index do | first,124;
第一个链子。零第一个==第一个链
结束
除非边缘为idx
返回路径
结束
edge=可用。在(edge\U idx)处删除
路径[[0,5],[5,5],[5,12],[12,3],[3,0],[0,10]]
查找路径arr,1
# => [[1, 0], [0, 5], [5, 5], [5, 12], [12, 3], [3, 0], [0, 10]]
该算法查找以第一个元素或给定的任何其他整数开始的路径。它不能保证它使用所有元素,甚至不能保证它是最长的,但它是一条路径
对于非方向图,需要考虑边可能会反转:
def find_path(arr, first_chain = nil, path = [], available = arr.dup)
edge_idx = available.index do |edge|
first_chain.nil? || edge.include?(first_chain)
end
unless edge_idx
return path
end
edge = available.delete_at(edge_idx)
edge = edge.reverse if first_chain && edge.first != first_chain
path << edge
find_path(arr, edge.last, path, available)
end
find_path arr
# => [[0, 5], [5, 5], [5, 12], [12, 3], [3, 0], [0, 1]]
find_path arr, 1
# => [[1, 0], [0, 5], [5, 5], [5, 12], [12, 3], [3, 0], [0, 10]]
def find_path(arr,first_chain=nil,path=[],available=arr.dup)
edge|idx=可用。索引do|edge|
第一个链子。零边缘。包括?(第一条链)
结束
除非边缘为idx
返回路径
结束
edge=可用。在(edge\U idx)处删除
edge=edge.reverse如果第一条链和edge.first!=第一链
路径[[0,5],[5,5],[5,12],[12,3],[3,0],[0,1]]
查找路径arr,1
# => [[1, 0], [0, 5], [5, 5], [5, 12], [12, 3], [3, 0], [0, 10]]
要查找最长路径,需要构建所有可能的路径,并选择最长路径:
def find_longest_path(arr, first_chain = nil, available = arr.dup)
paths = available.each_index.select do |edge_idx|
first_chain.nil? || available[edge_idx].include?(first_chain)
end.map do |edge_idx|
edge = available[edge_idx]
edge = edge.reverse if first_chain && edge.first != first_chain
[edge, *find_longest_path(arr, edge.last,
available[0...edge_idx] + available[edge_idx+1..-1])]
end
# a hack to find longest in all reverse paths
if first_chain.nil? && arr == available
paths << find_longest_path(arr, nil, arr.map(&:reverse))
end
paths.max_by { |path| path.length }
end
arr = [[3, 12], [8, 12], [0, 3], [0, 5], [0, 10], [7, 9], [5, 5], [4, 9], [5, 12], [0, 1]]
find_longest_path arr
# => [[10, 0], [0, 3], [3, 12], [12, 5], [5, 5], [5, 0], [0, 1]]
find_longest_path arr, 1
# => [[1, 0], [0, 3], [3, 12], [12, 5], [5, 5], [5, 0], [0, 10]]
def find_longest_path(arr,first_chain=nil,available=arr.dup)
路径=可用。每个索引。选择do |边| idx |
第一个链子。零可用[edge_idx]。包括?(第一条链)
end.map do | edge_idx|
edge=可用[edge\U idx]
edge=edge.reverse如果第一条链和edge.first!=第一链
[edge,*查找最长路径(arr、edge.last、,
可用[0…edge_idx]+可用[edge_idx+1..-1])]
结束
#在所有反向路径中查找最长路径的黑客
如果第一个_chain.nil?&arr==可用
路径[[10,0]、[0,3]、[3,12]、[12,5]、[5,5]、[5,0]、[0,1]]
查找最长路径arr,1
# => [[1, 0], [0, 3], [3, 12], [12, 5], [5, 5], [5, 0], [0, 10]]
此代码的作用是什么?该算法不获取路径中可以使用的第一条边,而是获取路径中可以使用的所有边 对于每个这样的边,它会构建一条新路径,该路径:
数组中删除边
#hack
的三行是因为当第一条链
为nil
时,算法会找到从任何非反向边开始的最长路径。为了支持反转边,我运行了两次,第二次运行时所有边都反转了
这不是一个已知算法的实现,而是一个简单的暴力实现,它可能不是最有效、最简单或最漂亮的,但它应该让您朝着正确的方向前进。您可能会发现有关在ruby中使用图形的更多信息显然您误解了这个问题,这意味着您需要在图形上生成一条路径,即数组中已经生成了一条链。@ruby您的问题目前还不清楚,路径生成包含的元素不在原始数组中。看起来可能有人做了你想要的好方法,但基于他的初始arr,它返回
[[3,12]]]
作为完整路径。我认为问题在于数组的生成,因为您的方法对满足算法要求的数组效果很好。@engineersmnky-要求不明确,可能他允许更改边的方向。如果我愿意的话,我明天可能会添加这个功能……事实上,你似乎已经根据他的答案回答了这个问题,他正在寻找最长的路径。你的方法做得很好。@uriagassi我学习Ruby,但仍然不太精通语言语法和算法。你能展示一下解决方案是什么吗?为数组的所有元素而不仅仅是第一个元素找到Euler路径?我知道我需要在循环中添加edge_idh?@Ruby-我所做的不是Euler的路径实现,而是直接的蛮力路径查找。你似乎完全编辑了这个问题,这很不幸,因为这不是我想要回答的问题。我可以添加一个查找最长路径的代码版本,但不是根据任何已知算法(AFAIK)