Class: NetworkX::Graph

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

Overview

Describes the class for making Undirected Graphs

Direct Known Subclasses

DiGraph, MultiGraph

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**graph_attrs) ⇒ Graph

Constructor for initializing graph

Examples:

Initialize a graph with attributes 'type' and 'name'

graph = NetworkX::Graph.new(name: "Social Network", type: "undirected")

Parameters:

  • graph_attrs (Hash{ Object => Object })

    the graph attributes in a hash format



17
18
19
20
21
22
23
# File 'lib/networkx/graph.rb', line 17

def initialize(**graph_attrs)
  @nodes = {}
  @adj = {}
  @graph = {}

  @graph = graph_attrs
end

Instance Attribute Details

#adjHash{ Object => Hash{ Object => Hash{ Object => Object } } } (readonly)

Stores the edges and their attributes in an adjencency list form

Returns:

  • (Hash{ Object => Hash{ Object => Hash{ Object => Object } } })

    the current value of adj



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

def adj
  @adj
end

#graphHash{ Object => Object } (readonly)

Stores the attributes of the graph

Returns:

  • (Hash{ Object => Object })

    the current value of graph



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

def graph
  @graph
end

#nodesHash{ Object => Hash{ Object => Object } } (readonly)

Stores the nodes and their attributes

Returns:

  • (Hash{ Object => Hash{ Object => Object } })

    the current value of nodes



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

def nodes
  @nodes
end

Instance Method Details

#add_edge(node_1, node_2, **edge_attrs) ⇒ Object

Adds the respective edges

Examples:

Add an edge with attribute name

graph.add_edge(node1, node2, name: "Edge1")

Add an edge with no attribute

graph.add_edge("Bangalore", "Chennai")

Parameters:

  • node_1 (Object)

    the first node of the edge

  • node_2 (Object)

    the second node of the edge

  • edge_attrs (Hash{ Object => Object })

    the hash of the edge attributes



36
37
38
39
40
41
42
43
# File 'lib/networkx/graph.rb', line 36

def add_edge(node_1, node_2, **edge_attrs)
  add_node(node_1)
  add_node(node_2)

  edge_attrs = (@adj[node_1][node_2] || {}).merge(edge_attrs)
  @adj[node_1][node_2] = edge_attrs
  @adj[node_2][node_1] = edge_attrs
end

#add_edges(edges) ⇒ Object

Adds multiple edges from an array

Examples:

Add multiple edges without any attributes

graph.add_edges([['Nagpur', 'Kgp'], ['Noida', 'Kgp']])

Parameters:

  • edges (Array<Object, Object>)


50
51
52
53
54
55
56
57
58
# File 'lib/networkx/graph.rb', line 50

def add_edges(edges)
  case edges
  when Array
    edges.each { |node_1, node_2, **attrs| add_edge(node_1, node_2, attrs) }
  else
    raise ArgumentError, 'Expected argument to be an Array of edges, '\
                         "received #{edges.class.name} instead."
  end
end

#add_node(node, **node_attrs) ⇒ Object

Adds a node and its attributes to the graph

Examples:

Add a node with attribute 'type'

graph.add_node("Noida", type: "city")

Parameters:

  • node (Object)

    the node object

  • node_attrs (Hash{ Object => Object })

    the hash of the attributes of the node



67
68
69
70
71
72
73
74
# File 'lib/networkx/graph.rb', line 67

def add_node(node, **node_attrs)
  if @nodes.key?(node)
    @nodes[node].merge!(node_attrs)
  else
    @adj[node] = {}
    @nodes[node] = node_attrs
  end
end

#add_nodes(nodes) ⇒ Object

Adds multiple nodes to the graph

Examples:

Adds multiple nodes with attribute 'type'

graph.add_nodes([["Noida", type: "city"], ["Kgp", type: "town"]])

Parameters:

  • nodes (Array<Object, Hash{ Object => Object }>)

    the Array of pair containing nodes and its attributes



82
83
84
85
86
87
88
89
90
# File 'lib/networkx/graph.rb', line 82

def add_nodes(nodes)
  case nodes
  when Set, Array
    nodes.each { |node, **node_attrs| add_node(node, node_attrs) }
  else
    raise ArgumentError, 'Expected argument to be an Array or Set of nodes, '\
                         "received #{nodes.class.name} instead."
  end
end

#add_weighted_edge(node_1, node_2, weight) ⇒ Object

Adds weighted edge

Examples:

graph.add_weighted_edge('Noida', 'Bangalore', 1000)

Parameters:

  • node_1 (Object)

    the first node of the edge

  • node_2 (Object)

    the second node of the edge

  • weight (Integer)

    the weight value



160
161
162
# File 'lib/networkx/graph.rb', line 160

def add_weighted_edge(node_1, node_2, weight)
  add_edge(node_1, node_2, weight: weight)
end

#add_weighted_edges(edges, weights) ⇒ Object

Adds multiple weighted edges

Examples:

graph.add_weighted_edges([['Noida', 'Bangalore'],
                          ['Noida', 'Nagpur']], [1000, 2000])

Parameters:

  • edges (Array<Object, Object>)

    the array of edges

  • weights (Array<Integer>)

    the array of weights

Raises:

  • (ArgumentError)


172
173
174
175
176
177
178
179
180
# File 'lib/networkx/graph.rb', line 172

def add_weighted_edges(edges, weights)
  raise ArgumentError, 'edges and weights array must have equal number of elements.'\
                       unless edges.size == weights.size
  raise ArgumentError, 'edges and weight must be given in an Array.'\
                       unless edges.is_a?(Array) && weights.is_a?(Array)
  (edges.transpose << weights).transpose.each do |node_1, node_2, weight|
    add_weighted_edge(node_1, node_2, weight)
  end
end

#clearObject

Clears the graph

Examples:

graph.clear


186
187
188
189
190
# File 'lib/networkx/graph.rb', line 186

def clear
  @adj.clear
  @nodes.clear
  @graph.clear
end

#directed?Boolean

Returns:

  • (Boolean)


337
338
339
# File 'lib/networkx/graph.rb', line 337

def directed?
  ['NetworkX::DiGraph', 'NetworkX::MultiDiGraph'].include?(self.class.name)
end

#edge?(node_1, node_2) ⇒ Boolean

Checks if the the edge consisting of two nodes is present in the graph

Examples:

graph.edge?(node_1, node_2)

Parameters:

  • node_1 (Object)

    the first node of the edge to be checked

  • node_2 (Object)

    the second node of the edge to be checked

Returns:

  • (Boolean)


209
210
211
# File 'lib/networkx/graph.rb', line 209

def edge?(node_1, node_2)
  node?(node_1) && @adj[node_1].key?(node_2)
end

#edge_subgraph(edges) ⇒ Object

Returns subgraph conisting of given edges

Examples:

graph.edge_subgraph([%w[Nagpur Wardha], %w[Nagpur Mumbai]])

Parameters:

  • edges (Array<Object, Object>)

    the edges to be included in the subraph



315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/networkx/graph.rb', line 315

def edge_subgraph(edges)
  case edges
  when Array, Set
    sub_graph = NetworkX::Graph.new(@graph)
    edges.each do |u, v|
      raise KeyError, "Edge between #{u} and #{v} does not exist in the graph!" unless @nodes.key?(u)\
                                                                                && @adj[u].key?(v)
      sub_graph.add_node(u, @nodes[u])
      sub_graph.add_node(v, @nodes[v])
      sub_graph.add_edge(u, v, @adj[u][v])
    end
    return sub_graph
  else
    raise ArgumentError, 'Expected Argument to be Array or Set of edges, '\
    "received #{edges.class.name} instead."
  end
end

#get_edge_data(node_1, node_2) ⇒ Object

Gets the edge data

Examples:

graph.get_edge_data(node_1, node_2)

Parameters:

  • node_1 (Object)

    the first node of the edge

  • node_2 (Object)

    the second node of the edge

Raises:

  • (KeyError)


231
232
233
234
# File 'lib/networkx/graph.rb', line 231

def get_edge_data(node_1, node_2)
  raise KeyError, 'No such edge exists!' unless node?(node_1) && edge?(node_2)
  @adj[node_1][node_2]
end

#get_node_data(node) ⇒ Object

Gets the node data

Examples:

graph.get_node_data(node)

Parameters:

  • node (Object)

    the node whose data is to be fetched

Raises:

  • (ArgumentError)


219
220
221
222
# File 'lib/networkx/graph.rb', line 219

def get_node_data(node)
  raise ArgumentError, 'No such node exists!' unless node?(node)
  @nodes[node]
end

#multigraph?Boolean

Returns:

  • (Boolean)


333
334
335
# File 'lib/networkx/graph.rb', line 333

def multigraph?
  ['NetworkX::MultiGraph', 'NetworkX::MultiDiGraph'].include?(self.class.name)
end

#neighbours(node) ⇒ Object

Retus a hash of neighbours of a node

Examples:

graph.neighbours(node)

Parameters:

  • node (Object)

    the node whose neighbours are to be fetched

Raises:

  • (KeyError)


242
243
244
245
# File 'lib/networkx/graph.rb', line 242

def neighbours(node)
  raise KeyError, 'No such node exists!' unless node?(node)
  @adj[node]
end

#node?(node) ⇒ Boolean

Checks if a node is present in the graph

Examples:

graph.node?(node_1)

Parameters:

  • node (Object)

    the node to be checked

Returns:

  • (Boolean)


198
199
200
# File 'lib/networkx/graph.rb', line 198

def node?(node)
  @nodes.key?(node)
end

#number_of_edgesObject

Returns number of edges

Examples:

graph.number_of_edges


259
260
261
# File 'lib/networkx/graph.rb', line 259

def number_of_edges
  @adj.values.map(&:length).inject(:+) / 2
end

#number_of_nodesObject

Returns number of nodes

Examples:

graph.number_of_nodes


251
252
253
# File 'lib/networkx/graph.rb', line 251

def number_of_nodes
  @nodes.length
end

#remove_edge(node_1, node_2) ⇒ Object

Removes edge from the graph

Examples:

graph.remove_edge('Noida', 'Bangalore')

Parameters:

  • node_1 (Object)

    the first node of the edge

  • node_2 (Object)

    the second node of the edge

Raises:

  • (KeyError)


128
129
130
131
132
133
134
# File 'lib/networkx/graph.rb', line 128

def remove_edge(node_1, node_2)
  raise KeyError, "#{node_1} is not a valid node." unless @nodes.key?(node_1)
  raise KeyError, "#{node_2} is not a valid node" unless @nodes.key?(node_2)
  raise KeyError, 'The given edge is not a valid one.' unless @adj[node_1].key?(node_2)
  @adj[node_1].delete(node_2)
  @adj[node_2].delete(node_1) if node_1 != node_2
end

#remove_edges(edges) ⇒ Object

Removes multiple edges from the graph

Examples:

graph.remove_edges([%w[Noida Bangalore], %w[Bangalore Chennai]])

Parameters:

  • edges (Array<Object>)

    the array of edges to be removed



142
143
144
145
146
147
148
149
150
# File 'lib/networkx/graph.rb', line 142

def remove_edges(edges)
  case edges
  when Array, Set
    edges.each { |node_1, node_2| remove_edge(node_1, node_2) }
  else
    raise ArgumentError, 'Expected Arguement to be Array or Set of edges, '\
                         "received #{edges.class.name} instead."
  end
end

#remove_node(node) ⇒ Object

Removes node from the graph

Examples:

graph.remove_node("Noida")

Parameters:

  • node (Object)

    the node to be removed

Raises:

  • (KeyError)


98
99
100
101
102
103
# File 'lib/networkx/graph.rb', line 98

def remove_node(node)
  raise KeyError, "Error in deleting node #{node} from Graph." unless @nodes.key?(node)
  @adj[node].each_key { |k| @adj[k].delete(node) }
  @adj.delete(node)
  @nodes.delete(node)
end

#remove_nodes(nodes) ⇒ Object

Removes multiple nodes from the graph

Examples:

graph.remove_nodes(["Noida", "Bangalore"])

Parameters:

  • nodes (Array<Object>)

    the array of nodes to be removed



111
112
113
114
115
116
117
118
119
# File 'lib/networkx/graph.rb', line 111

def remove_nodes(nodes)
  case nodes
  when Set, Array
    nodes.each { |node| remove_node(node) }
  else
    raise ArgumentError, 'Expected argument to be an Array or Set of nodes, '\
                         "received #{nodes.class.name} instead."
  end
end

#size(is_weighted = false) ⇒ Object

Returns the size of the graph

Examples:

graph.size(true)

Parameters:

  • is_weighted (Bool) (defaults to: false)

    if true, method returns sum of weights of all edges else returns number of edges



270
271
272
273
274
275
276
277
278
279
# File 'lib/networkx/graph.rb', line 270

def size(is_weighted=false)
  if is_weighted
    graph_size = 0
    @adj.each do |_, hash_val|
      hash_val.each { |_, v| graph_size += v[:weight] if v.key?(:weight) }
    end
    return graph_size / 2
  end
  number_of_edges
end

#subgraph(nodes) ⇒ Object

Returns subgraph consisting of given array of nodes

Examples:

graph.subgraph(%w[Mumbai Nagpur])

Parameters:

  • nodes (Array<Object>)

    the nodes to be included in the subgraph



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/networkx/graph.rb', line 289

def subgraph(nodes)
  case nodes
  when Array, Set
    sub_graph = NetworkX::Graph.new(@graph)
    nodes.each do |u, _|
      raise KeyError, "#{u} does not exist in the current graph!" unless @nodes.key?(u)
      sub_graph.add_node(u, @nodes[u])
      @adj[u].each do |v, edge_val|
        sub_graph.add_edge(u, v, edge_val) if @adj[u].key?(v) && nodes.include?(v)
      end
      return sub_graph
    end
  else
    raise ArgumentError, 'Expected Argument to be Array or Set of nodes, '\
                         "received #{nodes.class.name} instead."
  end
end