Class: Rbgraph::Graph

Inherits:
Object
  • Object
show all
Defined in:
lib/rbgraph/graph.rb

Direct Known Subclasses

DirectedGraph, UndirectedGraph

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(nodes = {}, edges = {}) ⇒ Graph

Returns a new instance of Graph.



8
9
10
11
# File 'lib/rbgraph/graph.rb', line 8

def initialize(nodes = {}, edges = {})
  self.nodes = nodes
  self.edges = edges
end

Instance Attribute Details

#edgesObject

Returns the value of attribute edges.



6
7
8
# File 'lib/rbgraph/graph.rb', line 6

def edges
  @edges
end

#nodesObject

Returns the value of attribute nodes.



5
6
7
# File 'lib/rbgraph/graph.rb', line 5

def nodes
  @nodes
end

Instance Method Details

#add_edge!(node1, node2, weight = 1, kind = nil, edge_data = {}, &block) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rbgraph/graph.rb', line 30

def add_edge!(node1, node2, weight = 1, kind = nil, edge_data = {}, &block)
  node1 = add_node!(node1[:id], node1[:data])
  node2 = add_node!(node2[:id], node2[:data])
  new_edge = Edge.new(self, node1, node2, weight, kind, edge_data)
  if edges[new_edge.id].nil?
    edges[new_edge.id] = new_edge
  else
    if block_given?
      yield(self, edges[new_edge.id], new_edge)
    else
      edges[new_edge.id].weight += weight
    end
  end
  connect_nodes(node1, node2, edges[new_edge.id])
  edges[new_edge.id]
end

#add_node!(node_id, node_data, &block) ⇒ Object



21
22
23
24
25
26
27
28
# File 'lib/rbgraph/graph.rb', line 21

def add_node!(node_id, node_data, &block)
  if nodes[node_id].nil?
    nodes[node_id] = Node.new(self, node_id, node_data)
  else
    yield(self, nodes[node_id], node_data) if block_given?
  end
  nodes[node_id]
end

#as_json(options = {}) ⇒ Object



97
98
99
# File 'lib/rbgraph/graph.rb', line 97

def as_json(options = {})
  {nodes: nodes, edges: edges}
end

#connect_nodes(node1, node2, edge) ⇒ Object



88
89
90
# File 'lib/rbgraph/graph.rb', line 88

def connect_nodes(node1, node2, edge)
  raise NotImplementedError("Cannot connect nodes on a general graph! Use either Directed or Undirected subclasses")
end

#directed?Boolean

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


17
18
19
# File 'lib/rbgraph/graph.rb', line 17

def directed?
  raise NotImplementedError
end

#inspectObject



92
93
94
# File 'lib/rbgraph/graph.rb', line 92

def inspect
  edges.values.map(&:inspect)
end

#merge_nodes!(node_ids, new_node_id = nil, new_node_data = {}, merge_options = {}, &block) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/rbgraph/graph.rb', line 64

def merge_nodes!(node_ids, new_node_id = nil, new_node_data = {}, merge_options = {}, &block)
  node_ids = nodes.values_at(*node_ids).compact.map(&:id)
  return nil if node_ids.empty?
  if new_node_id.nil?
    # If new_node_id is nil then select the first from the list as the surviving node.
    new_node = nodes[node_ids.shift]
  else
    # Otherwise either check if a node with the given id exists, or create a new one.
    if nodes[new_node_id].nil?
      new_node = add_node!(new_node_id, new_node_data)
    else
      new_node = nodes[new_node_id]
      random_not_existent_id = nodes.keys.sort_by { |k| -k.to_s.length } .first.to_s + "_"
      new_node.merge!(Node.new(self, 0, new_node_data))
      node_ids.delete(new_node_id)
    end
  end
  node_ids.each do |node_id|
    node = nodes[node_id]
    new_node.merge!(node, merge_options, &block)
  end
  new_node
end

#remove_edge!(edge) ⇒ Object



55
56
57
58
59
60
61
62
# File 'lib/rbgraph/graph.rb', line 55

def remove_edge!(edge)
  edge = edge.is_a?(Edge) ? edge : edges[edge]
  edge.node1.neighbors.delete(edge.node2.id)
  edge.node2.neighbors.delete(edge.node1.id)
  edge.node1.edges.delete(edge.id)
  edge.node2.edges.delete(edge.id)
  edges.delete(edge.id)
end

#remove_node!(node) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/rbgraph/graph.rb', line 47

def remove_node!(node)
  node = node.is_a?(Node) ? node : nodes[node]
  if node
    node.edges.values.each { |edge| remove_edge!(edge) }
    nodes.delete(node.id)
  end
end

#sizeObject



13
14
15
# File 'lib/rbgraph/graph.rb', line 13

def size
  nodes.values.length
end

#to_json(options = {}) ⇒ Object



101
102
103
# File 'lib/rbgraph/graph.rb', line 101

def to_json(options = {})
  JSON.generate({nodes: nodes, edges: edges})
end