rbgraph 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a0fe2bf64b05c39412353c43e2b61be62802eba8
4
- data.tar.gz: 275c4daead8f24d392d04287e4f05c16e3538745
3
+ metadata.gz: 48930f7885070f0f57459ad7b36759d8be7d7d48
4
+ data.tar.gz: a6eb4e8ae29f93011695334241bdd192f670a1b2
5
5
  SHA512:
6
- metadata.gz: 661096f726414cdd4cd59282a9844647a77389355eba19a71cd69bf5abb08c7de7c3bec7a8a94acd34e4dfa2446ca353762671eb62a7a00182615dee4da80a4e
7
- data.tar.gz: e36ba691c1ccb04c3747c9169346264d701ce7e7262933930d00b88d7590fb5376fea9c7c94c13d6d0872ff7d219095fd40c5a86537ada41f6b438a9eafc722a
6
+ metadata.gz: 68715928c6e71ae2606a85e8a8d56d0e232a54f1981bc9837866af3419a44f4174164fff77f77bf5dfe531c892fb0729af221bf81be62b27e35f8fb6cd275ace
7
+ data.tar.gz: 0c6107d685f112847d7a09ced014740fbf448d332b838670278ab8f9dab27a425a1355bb3a0ee3f596a0e60bc4b3f1397952de2ec09323e1356956b3ab218f6a
data/README.md CHANGED
@@ -49,5 +49,32 @@ node.out_degree
49
49
  ```
50
50
  depending on if you constructed a Directed or Undirected graph.
51
51
 
52
+ Version 0.0.8+
53
+
54
+ Support for weighted edges.
55
+ ```ruby
56
+ graph = Rbgraph::UndirectedGraph.new()
57
+ graph.add_edge!({id: 1}, {id: 2})
58
+ graph.add_edge!({id: 2}, {id: 3})
59
+ graph.edges["1==2"].weight => 1
60
+ graph.add_edge!({id: 1}, {id: 2})
61
+ graph.edges["1==2"].weight => 2
62
+ graph.add_edge!({id: 1}, {id: 2}, {weight: 3})
63
+ graph.edges["1==2"].weight => 5
64
+ ```
65
+
66
+ Support for node merging.
67
+ ```ruby
68
+ graph = Rbgraph::UndirectedGraph.new()
69
+ graph.add_edge!({id: 1}, {id: 2})
70
+ graph.add_edge!({id: 2}, {id: 3})
71
+ graph.add_edge!({id: 3}, {id: 4})
72
+
73
+ # 1 -> 2 -> 3 -> 4
74
+ graph.merge_nodes!([2, 3])
75
+ # 1 -> 2 => 4
76
+ ```
77
+
78
+
52
79
  ### Disclaimer
53
80
  This project is written on a need to use basis for inclusion to other projects I'm working on for now, so completion is not an immediate goal.
data/lib/rbgraph/edge.rb CHANGED
@@ -3,17 +3,21 @@ module Rbgraph
3
3
  class Edge
4
4
 
5
5
  attr_accessor :id
6
+ attr_accessor :graph
6
7
  attr_accessor :node1
7
8
  attr_accessor :node2
9
+ attr_accessor :weight
8
10
  attr_accessor :directed
9
11
  attr_accessor :attributes
10
12
 
11
13
  def initialize(node1, node2, attributes = {})
12
14
  self.node1 = node1
13
15
  self.node2 = node2
16
+ self.directed = !!attributes.delete(:directed)
17
+ interpolated_node_ids = directed ? [node1.id, node2.id] : [node1.id, node2.id].sort
18
+ self.id = attributes.delete(:id) || ("%s=#{attributes[:kind]}=%s" % interpolated_node_ids)
19
+ self.weight = attributes.delete(:weight) || 1
14
20
  self.attributes = attributes
15
- self.id = attributes[:id] || "#{node1.id}=#{attributes[:kind]}=#{node2.id}"
16
- self.directed = !!attributes[:directed]
17
21
  end
18
22
 
19
23
  def ==(node)
@@ -25,12 +29,17 @@ module Rbgraph
25
29
  id
26
30
  end
27
31
 
32
+ def has_node?(node)
33
+ node == node1 || node == node2
34
+ end
35
+
28
36
  def other_node(node)
29
37
  # ([node1, node2] - [node]).first ! Fails for edge connecting a node to itself
30
38
  node == node1 ? node2 : node1
31
39
  end
32
40
 
33
41
  def merge(edge)
42
+ self.weight += edge.weight unless edge.weight.nil?
34
43
  attributes.merge!(edge.attributes.reject { |k, v| k == :id })
35
44
  self
36
45
  end
@@ -39,7 +48,7 @@ module Rbgraph
39
48
  if directed
40
49
  node == node1
41
50
  else
42
- node == node1 || node == node2
51
+ has_node?(node)
43
52
  end
44
53
  end
45
54
 
@@ -47,7 +56,7 @@ module Rbgraph
47
56
  if directed
48
57
  node == node2
49
58
  else
50
- node == node1 || node == node2
59
+ has_node?(node)
51
60
  end
52
61
  end
53
62
 
data/lib/rbgraph/graph.rb CHANGED
@@ -16,6 +16,7 @@ module Rbgraph
16
16
 
17
17
  def add_node!(node)
18
18
  node = node.is_a?(Node) ? node : Node.new(node)
19
+ node.graph = self
19
20
  if nodes[node.id].nil?
20
21
  nodes[node.id] = node
21
22
  else
@@ -28,6 +29,7 @@ module Rbgraph
28
29
  node1 = add_node!(node1)
29
30
  node2 = add_node!(node2)
30
31
  edge = Edge.new(node1, node2, edge_attributes)
32
+ edge.graph = self
31
33
  edge = if edges[edge.id].nil?
32
34
  edges[edge.id] = edge
33
35
  else
@@ -37,6 +39,32 @@ module Rbgraph
37
39
  edge
38
40
  end
39
41
 
42
+ def remove_node!(node)
43
+ node = node.is_a?(Node) ? node : nodes[node]
44
+ if node
45
+ node.edges.values.each { |edge| remove_edge!(edge) }
46
+ nodes.delete(node.id)
47
+ end
48
+ end
49
+
50
+ def remove_edge!(edge)
51
+ edge = edge.is_a?(Edge) ? edge : edges[edge]
52
+ edge.node1.remove_neighbor(edge.node2)
53
+ edge.node2.remove_neighbor(edge.node1)
54
+ edges.delete(edge.id)
55
+ end
56
+
57
+ def merge_nodes!(node_ids, &block)
58
+ node_ids = node_ids || yield
59
+ first_node = nodes[node_ids.shift]
60
+ if !first_node.nil? && !node_ids.empty?
61
+ node_ids.each do |node_id|
62
+ node = nodes[node_id]
63
+ first_node.absorb!(node)
64
+ end
65
+ end
66
+ end
67
+
40
68
  def connect_nodes(node1, node2, edge)
41
69
  raise NotImplementedError("Cannot connect nodes on a general graph! Use either Directed or Undirected subclasses")
42
70
  end
data/lib/rbgraph/node.rb CHANGED
@@ -3,6 +3,7 @@ module Rbgraph
3
3
  class Node
4
4
 
5
5
  attr_accessor :id
6
+ attr_accessor :graph
6
7
  attr_accessor :attributes
7
8
  attr_accessor :neighbors
8
9
  attr_accessor :edges
@@ -10,7 +11,7 @@ module Rbgraph
10
11
  def initialize(attributes = {})
11
12
  self.attributes = attributes
12
13
  raise "Node should have an id attribute!" if attributes[:id].nil?
13
- self.id = attributes[:id]
14
+ self.id = attributes.delete(:id)
14
15
  self.neighbors = {}
15
16
  self.edges = {}
16
17
  end
@@ -37,6 +38,22 @@ module Rbgraph
37
38
  self
38
39
  end
39
40
 
41
+ def remove_neighbor(node)
42
+ neighbors.delete(node.id)
43
+ end
44
+
45
+ def absorb!(node)
46
+ node.edges.each do |edge_id, edge|
47
+ other_node = edge.other_node(node)
48
+ if edge.out_for?(node)
49
+ graph.add_edge!(self, other_node, edge.attributes) unless other_node == self
50
+ elsif edge.in_for?(node)
51
+ graph.add_edge!(other_node, self, edge.attributes) unless other_node == self
52
+ end
53
+ end
54
+ graph.remove_node!(node)
55
+ end
56
+
40
57
  def outgoing_edges
41
58
  edges.select { |eid, edge| edge.out_for?(self) }
42
59
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbgraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - George Lamprianidis
@@ -60,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
60
  version: '0'
61
61
  requirements: []
62
62
  rubyforge_project:
63
- rubygems_version: 2.4.3
63
+ rubygems_version: 2.4.6
64
64
  signing_key:
65
65
  specification_version: 4
66
66
  summary: Ruby graphs!