kruskal
Ruby
code posted
by
AndrewCap
created at 18 Dec 23:48
Edit
|
Back
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
require 'pp' require 'benchmark' def file @file ||= File.readlines("edges.txt") end def has_cycles(edge) node_one, node_two = edge[:from], edge[:to] @minimum_spanning_tree.each { |x| x[:explored] = false } cycle_between(node_one, node_two, @minimum_spanning_tree.dup) end def cycle_between(one, two, edges) adjacent_edges = edges.select { |edge| edge[:to] == one || edge[:from] == one} return false if adjacent_edges.empty? adjacent_edges.reject {|edge| edge[:explored] }.each do |edge| edge[:explored] = true other_node = (edge[:from] == one) ? edge[:to] : edge[:from] return true if other_node == two || cycle_between(other_node, two, edges) end false end @minimum_spanning_tree = [] edges = file.drop(1).map { |x| x.gsub(/\n/, "").split(" ").map(&:to_i) }. map { |one, two, weight| { :from => one, :to => two, :weight => weight}}. sort_by { |x| x[:weight]} Benchmark.bm (10){ |x| x.report("Kruskal time: "){ edges.each do |edge| @minimum_spanning_tree << edge unless has_cycles edge end } puts } puts "MST:" pp @minimum_spanning_tree puts puts "Cost: #{@minimum_spanning_tree.inject(0) { |acc, x| acc + x[:weight]}}" |
1.22 KB in 4 ms with coderay