rbgraph 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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!