Advertisement
Guest User

Untitled

a guest
Aug 20th, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.95 KB | None | 0 0
  1. # This is a very simple hash based graph utility class.
  2. # By Mykl Clason
  3. class Graph
  4. def self.undirected_graph_from_edges(edges)
  5. # Edges are (a,b) pairs with a => b and b => a relationships.
  6. graph = {}
  7. edges.each do |source, adjacency|
  8. graph[source] = Set.new unless graph[source].present?
  9. graph[adjacency] = Set.new unless graph[adjacency].present?
  10. graph[source].add(adjacency)
  11. graph[adjacency].add(source)
  12. end
  13.  
  14. graph
  15. end
  16.  
  17. def self.directed_graph_from_edges(edges)
  18. # Edges are (a,b) pairs with a => b relationships.
  19. graph = {}
  20. edges.each do |source, adjacency|
  21. graph[source] = Set.new unless graph[source].present?
  22. graph[source].add(adjacency)
  23. end
  24.  
  25. graph
  26. end
  27.  
  28. def self.invert(graph)
  29. # Reverses direction of graph
  30. edges = []
  31. graph.each do |node, adjacencies|
  32. adjacencies.each do |adjacency|
  33. edges.push [adjacency, node]
  34. end
  35. end
  36.  
  37. directed_graph_from_edges(edges)
  38. end
  39.  
  40. def self.diff(graph, subgraph)
  41. # Generates a new graph that is graph - subgraph
  42. new_graph = graph.deep_dup
  43. subgraph.each do |node, connections|
  44. new_graph[node] = new_graph[node] - connections if new_graph[node].present?
  45. new_graph.delete(node) unless new_graph[node].present?
  46. end
  47.  
  48. new_graph
  49. end
  50.  
  51. def self.intersect(primary_graph, secondary_graph)
  52. # Generates a new graph that is primary_graph | secondary_graph
  53. new_graph = {}
  54. nodes = (primary_graph.keys + secondary_graph.keys).uniq
  55. nodes.each do |node|
  56. node_intersect = (primary_graph[node] || Set.new) & (secondary_graph[node] || Set.new)
  57. new_graph[node] = node_intersect if node_intersect.present?
  58. end
  59.  
  60. new_graph
  61. end
  62.  
  63. def self.union(primary_graph, secondary_graph)
  64. # Generates a new graph that is primary_graph & secondary_graph
  65. new_graph = {}
  66. nodes = (primary_graph.keys + secondary_graph.keys).uniq
  67. nodes.each do |node|
  68. new_graph[node] = (primary_graph[node] || Set.new) | (secondary_graph[node] || Set.new)
  69. end
  70.  
  71. new_graph
  72. end
  73.  
  74. def self.adjacency_counter_hash(graph)
  75. # Generates a hash of the counts of the adjacencies
  76. hash_counter = {}
  77. graph.values.map(&:size).each do |size|
  78. hash_counter[size] = (hash_counter[size] || 0) + 1
  79. end
  80.  
  81. hash_counter
  82. end
  83.  
  84. def self.adjacency_size_map(graph)
  85. graph.map { |node, adjacencies| [node, adjacencies.size] }.to_h
  86. end
  87.  
  88. def self.adjacency_counts(graph)
  89. graph.values.map(&:size)
  90. end
  91.  
  92. def self.size(graph)
  93. graph_vertex_sizes(graph).sum
  94. end
  95.  
  96. def self.vertex_subset(graph, vertex_set)
  97. # Creates a subset of the graph that contains only the vertex set
  98. vertex_set = vertex_set.to_set
  99.  
  100. new_graph = {}
  101. vertex_set.each do |vertex|
  102. connections = graph[vertex]
  103. next unless connections.present?
  104. connections = (graph[vertex] || Set.new) & vertex_set
  105. new_graph[vertex] = connections if connections.present?
  106. end
  107.  
  108. new_graph
  109. end
  110. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement