Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Ruby图上生成路径_Ruby_Arrays_Algorithm_Sorting_Graph Algorithm - Fatal编程技术网

在Ruby图上生成路径

在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

我有一个有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]]

我已经在很多源代码中看到了通过搜索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)