歐拉路徑訪問每邊緣恰好一次,所以我猜你不需要這個。我可以提供的是這樣的:
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 |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_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]]
這段代碼做了什麼?
而不是採取第一邊緣,可以在我們的路徑中使用,此算法需要所有邊緣,可以在我們的路徑中使用。
對於每個這樣的邊緣,它建立一個新的路徑,其中:
- 開始與所選擇的邊緣
- 從
available
陣列
- 繼續與最長路徑去除邊緣購自開始邊緣的外頂點(遞歸)
這建立了所有的列表po可行路徑。從這個方法返回最長(最大長度)。
三個線I標記爲# hack
是因爲當first_chain
是nil
算法找到開始反向邊緣任何非最長路徑。爲了支持顛倒的邊緣,我運行了兩次 - 第二次顛倒了所有的邊緣。
這是不是執行一個已知的算法,但一個簡單的蠻力執行,可能不是最有效,最簡單或最美好的,但它應該把你放在正確的方向。您可能會發現更多關於在ruby中使用圖形的信息here
不錯的方法,但基於他的初始arr它返回' [[3,12]]作爲完整的路徑。我認爲問題在於數組的生成,因爲您的方法對於滿足算法要求的數組非常有用。 – engineersmnky
@engineersmnky - 要求不清楚,也許他允許改變邊緣的方向。我可能明天添加這個功能,如果我覺得它... –
其實它似乎你已經回答了基於他的[重複](http://stackoverflow.com/questions/23272571/generating-graph-path-從陣列與數字在紅寶石)被關閉,他正在尋找最長的路徑。你的方法完美無缺。 – engineersmnky