jumoku 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/README.md +12 -12
- data/lib/jumoku.rb +2 -2
- data/lib/jumoku/builders/raw_tree.rb +4 -4
- data/lib/jumoku/builders/tree.rb +5 -5
- data/lib/jumoku/support/branch.rb +1 -1
- data/lib/jumoku/tree_api.rb +1 -1
- data/lib/jumoku/version.rb +1 -1
- data/spec/raw_tree_spec.rb +1 -1
- data/vendor/git/{graphy → plexus}/CREDITS.md +0 -0
- data/vendor/git/plexus/Gemfile +3 -0
- data/vendor/git/plexus/Gemfile.lock +28 -0
- data/vendor/git/{graphy → plexus}/LICENSE +3 -1
- data/vendor/git/plexus/README.md +208 -0
- data/vendor/git/plexus/Rakefile +25 -0
- data/vendor/git/{graphy → plexus}/TODO.md +1 -1
- data/vendor/git/{graphy → plexus}/VERSION +0 -0
- data/vendor/git/{graphy → plexus}/examples/graph_self.rb +0 -0
- data/vendor/git/{graphy → plexus}/examples/module_graph.jpg +0 -0
- data/vendor/git/{graphy → plexus}/examples/module_graph.rb +0 -0
- data/vendor/git/{graphy → plexus}/examples/self_graph.jpg +0 -0
- data/vendor/git/{graphy → plexus}/examples/visualize.jpg +0 -0
- data/vendor/git/{graphy → plexus}/examples/visualize.rb +0 -0
- data/vendor/git/plexus/lib/plexus.rb +90 -0
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/adjacency_graph.rb +9 -9
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/arc.rb +16 -22
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/arc_number.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/biconnected.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/chinese_postman.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/classes/graph_classes.rb +10 -10
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/common.rb +6 -6
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/comparability.rb +10 -10
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/directed_graph.rb +15 -13
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/directed_graph/algorithms.rb +21 -18
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/directed_graph/distance.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/dot.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/edge.rb +8 -9
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/ext.rb +3 -3
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/graph.rb +51 -56
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/graph_api.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/labels.rb +8 -8
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/maximum_flow.rb +2 -2
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/ruby_compatibility.rb +0 -0
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/search.rb +43 -44
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/strong_components.rb +4 -4
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/support/support.rb +3 -3
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/undirected_graph.rb +13 -14
- data/vendor/git/{graphy/lib/graphy → plexus/lib/plexus}/undirected_graph/algorithms.rb +4 -4
- data/vendor/git/plexus/lib/plexus/version.rb +6 -0
- data/vendor/git/plexus/plexus.gemspec +24 -0
- data/vendor/git/{graphy → plexus}/spec/biconnected_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/chinese_postman_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/community_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/complement_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/digraph_distance_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/digraph_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/dot_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/edge_spec.rb +17 -18
- data/vendor/git/{graphy → plexus}/spec/inspection_spec.rb +13 -15
- data/vendor/git/{graphy → plexus}/spec/multi_edge_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/neighborhood_spec.rb +3 -5
- data/vendor/git/{graphy → plexus}/spec/properties_spec.rb +1 -1
- data/vendor/git/{graphy → plexus}/spec/search_spec.rb +45 -45
- data/vendor/git/{graphy → plexus}/spec/spec.opts +0 -0
- data/vendor/git/{graphy → plexus}/spec/spec_helper.rb +13 -10
- data/vendor/git/{graphy → plexus}/spec/strong_components_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/spec/triangulated_spec.rb +1 -1
- data/vendor/git/{graphy → plexus}/spec/undirected_graph_spec.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/CHANGELOG +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/Makefile +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/README +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/benchmark/dijkstra.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/compare_comments.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/c-vs-rb.png +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/compare_big.gp +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/compare_big.png +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/compare_small.gp +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/compare_small.png +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/doc/results.csv +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/ext/priority_queue/CPriorityQueue/extconf.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/ext/priority_queue/CPriorityQueue/priority_queue.c +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/lib/priority_queue.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/lib/priority_queue/c_priority_queue.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/lib/priority_queue/poor_priority_queue.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/lib/priority_queue/ruby_priority_queue.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/priority_queue.so +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/setup.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/priority-queue/test/priority_queue_test.rb +0 -0
- data/vendor/git/{graphy → plexus}/vendor/rdot.rb +0 -0
- metadata +81 -78
- data/vendor/git/graphy/README.md +0 -186
- data/vendor/git/graphy/Rakefile +0 -61
- data/vendor/git/graphy/graphy.gemspec +0 -149
- data/vendor/git/graphy/lib/graphy.rb +0 -90
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
Jumoku provides you with tree structures and related tools to perform manipulation and computation the easy way. Trees are a subset of graphs, which are used in a whole slew of computer science and mathematical problems: network modelization, datasets storage, scientific computation, load balancing, games and AI designs, … Trees are frequently used to mimic hierarchal structures such as filesystems, or modelize decisionnal patterns, for instance.
|
8
8
|
|
9
|
-
Jumoku is built upon [
|
9
|
+
Jumoku is built upon [Plexus](http://github.com/chikamichi/plexus "Plexus on Github"), a ruby-powered Graph Theory library, and aims at being a fully-fledged, pithy solution for tree-like structures managment. See below for additionnal information about graphs, trees, arborescences, why they're different and how to make good use of them.
|
10
10
|
|
11
11
|
## A few words about *trees*
|
12
12
|
|
@@ -49,15 +49,15 @@ end
|
|
49
49
|
tree = MyTree.new
|
50
50
|
```
|
51
51
|
|
52
|
-
|
52
|
+
The RawTree class is actually implemented this way.
|
53
53
|
|
54
54
|
### What you get
|
55
55
|
|
56
56
|
`tree` is now a Tree object, shipping with some default options:
|
57
57
|
|
58
58
|
* it is a valid tree *per se* (an undirected, acyclic, connected graph)
|
59
|
-
* Jumoku API's methods will ensure it remains so
|
60
|
-
* it has no constraint on
|
59
|
+
* Jumoku API's methods will ensure it remains so as you manipulate it
|
60
|
+
* it has no constraint on the number of branches per node (its branching number)
|
61
61
|
|
62
62
|
## Install, first steps and bootstraping
|
63
63
|
|
@@ -71,17 +71,17 @@ Now you can play in IRB:
|
|
71
71
|
|
72
72
|
``` bash
|
73
73
|
$ irb
|
74
|
-
ruby-1.9.1-p378 > require '
|
74
|
+
ruby-1.9.1-p378 > require 'jumoku'
|
75
75
|
=> true
|
76
76
|
ruby-1.9.1-p378 > include Jumoku # so you won't have to prefix everything with "Jumoku::"
|
77
77
|
=> Object
|
78
78
|
ruby-1.9.1-p378 > t = Tree.new
|
79
|
-
=> #<Jumoku::Tree:0x000000020d5ac8 @vertex_dict={}, @vertex_labels={}, @edge_labels={}, @allow_loops=false, @parallel_edges=false, @edgelist_class=Set>
|
79
|
+
=> #<Jumoku::Tree:0x000000020d5ac8 @vertex_dict={}, @vertex_labels={}, @edge_labels={}, @allow_loops=false, @parallel_edges=false, @edgelist_class=Set>
|
80
80
|
ruby-1.9.1-p378 > t.methods
|
81
81
|
=> # lot of stuff hopefully :)
|
82
82
|
```
|
83
83
|
|
84
|
-
A good way to get you started is by [reading the doc online](http://rdoc.info/projects/chikamichi/
|
84
|
+
A good way to get you started is by [reading the doc online](http://rdoc.info/projects/chikamichi/jumoku "Jumoku on rdoc.info"). You can locally generate the doc with any of the following commands (you'll need to have the `yard` gem installed):
|
85
85
|
|
86
86
|
``` bash
|
87
87
|
rake yard
|
@@ -94,17 +94,17 @@ Be sure to take a look at the tests in `spec/` as well, as they document the pub
|
|
94
94
|
|
95
95
|
Trees are just simple graphs, with specific constraints on edges (branches) and vertices (nodes). In graph theory, a tree is defined as a graph which is undirected, acyclic and connected. A forest is a disjoint union of trees. Let's review those constraints:
|
96
96
|
|
97
|
-
* undirected: the branches of a tree have no direction;
|
97
|
+
* undirected: the branches of a tree have no direction and you can flow either from root toward leaves or reversily;
|
98
98
|
* acyclic: a cycle is defined as a path such that the starting node and the ending node are the same. Such paths are forbidden in a tree;
|
99
|
-
* connected: a tree is such that pair of distinct nodes can be connected through some path (not a cycle).
|
99
|
+
* connected: a tree is such that pair of distinct nodes can be connected through some path (but *not* a cycle).
|
100
100
|
|
101
|
-
This is restrictive, but not *that* restrictive. Instinctively, a tree structure would rather be described as an arborescence, with a root and some leaves. That
|
101
|
+
This is quite restrictive, but not *that* restrictive. Instinctively, a tree structure would rather be described as an arborescence, that is a collection of nodes with a root node and some leaves (ending nodes), that is with a general direction (top-down). That is what you would use to use to modelize nested directories, for instance. From the mathematical point of view, legacy trees and arborescences have some little differencies (the latter are more constrained). Jumoku provides both structures.
|
102
102
|
|
103
|
-
|
103
|
+
Several ruby graph libraries exist, some pure-ruby, some as bindings (for instance, the popular igraph C backend). Jumoku makes use of the most up-to-date project among those available, [Plexus](http://github.com/chikamichi/plexus "Plexus on Github"). It's been forked to implement new features required by Jumoku, and is vendorized within this gem.
|
104
104
|
|
105
105
|
## License
|
106
106
|
|
107
|
-
See the LICENSE file.
|
107
|
+
[MIT License](http://en.wikipedia.org/wiki/MIT_License). See the LICENSE file.
|
108
108
|
|
109
109
|
## Contributing
|
110
110
|
|
data/lib/jumoku.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
libpath = File.expand_path(File.dirname(__FILE__))
|
2
2
|
$:.unshift File.dirname(__FILE__) unless $:.include?(File.dirname(__FILE__)) || $:.include?(libpath)
|
3
|
-
$: << libpath + '/../vendor/git/
|
3
|
+
$: << libpath + '/../vendor/git/plexus/lib'
|
4
4
|
puts $:.inspect
|
5
5
|
|
6
6
|
require 'pathname'
|
7
7
|
require 'pp'
|
8
8
|
require 'active_support'
|
9
9
|
require 'facets'
|
10
|
-
require '
|
10
|
+
require 'plexus'
|
11
11
|
|
12
12
|
module Jumoku
|
13
13
|
# jumoku internals: graph builders and additionnal behaviors
|
@@ -4,7 +4,7 @@ module Jumoku
|
|
4
4
|
# behavior. Those implementations are under the control of the {TreeAPI}.
|
5
5
|
#
|
6
6
|
# A {RawTree} sticks to the standard definition of trees in Graph Theory: undirected,
|
7
|
-
# connected, acyclic graphs. Using
|
7
|
+
# connected, acyclic graphs. Using Plexus::UndirectedGraphBuilder as its backend,
|
8
8
|
# {RawTreeBuilder} ensures the two remaining constraints are satisfied (connected and
|
9
9
|
# acyclic). {RawTreeBuilder RawTree} offers limited functionalities, therefore the main
|
10
10
|
# tree structure you'll likely to use is its extended version, {TreeBuilder Tree}. A
|
@@ -20,7 +20,7 @@ module Jumoku
|
|
20
20
|
# This builder defines a few methods not required by the API so as to maintain consistency
|
21
21
|
# in the DSL.
|
22
22
|
module RawTreeBuilder
|
23
|
-
include
|
23
|
+
include Plexus::UndirectedGraphBuilder
|
24
24
|
|
25
25
|
# This method is called by the specialized implementations
|
26
26
|
# upon tree creation.
|
@@ -39,7 +39,7 @@ module Jumoku
|
|
39
39
|
# Ensure the builder abides by its API requirements.
|
40
40
|
include Jumoku::TreeAPI
|
41
41
|
end
|
42
|
-
super(*params) # Delegates to
|
42
|
+
super(*params) # Delegates to Plexus.
|
43
43
|
end
|
44
44
|
|
45
45
|
# Ensure trees are seen as undirected graphs.
|
@@ -48,7 +48,7 @@ module Jumoku
|
|
48
48
|
def directed?
|
49
49
|
return false
|
50
50
|
end
|
51
|
-
# FIXME: should be able to reach
|
51
|
+
# FIXME: should be able to reach Plexus's method ?!
|
52
52
|
|
53
53
|
# Adds the node to the tree.
|
54
54
|
#
|
data/lib/jumoku/builders/tree.rb
CHANGED
@@ -252,7 +252,7 @@ module Jumoku
|
|
252
252
|
end
|
253
253
|
alias has_nodes_among? nodes_among?
|
254
254
|
alias has_node_among? nodes_among?
|
255
|
-
# FIXME: these helpers could be backported into
|
255
|
+
# FIXME: these helpers could be backported into Plexus.
|
256
256
|
|
257
257
|
# Returns true if i or (i,j) is a {Branch branch} of the tree.
|
258
258
|
#
|
@@ -280,11 +280,11 @@ module Jumoku
|
|
280
280
|
list = maybe_branches.create_branches_list
|
281
281
|
all = true
|
282
282
|
|
283
|
-
# Branch objects are really Edge objects within
|
283
|
+
# Branch objects are really Edge objects within Plexus, therefore
|
284
284
|
# cannot rely on #eql? to compare those structures and must drop
|
285
285
|
# down to the attributes.
|
286
286
|
list.each do |e| # Jumoku::Branch structs
|
287
|
-
all = branches.any? do |b| #
|
287
|
+
all = branches.any? do |b| # Plexus::Edge structs
|
288
288
|
(b[:source] == e[:source]) and (b[:target] == e[:target])
|
289
289
|
end
|
290
290
|
end
|
@@ -305,10 +305,10 @@ module Jumoku
|
|
305
305
|
list = maybe_branches.create_branches_list
|
306
306
|
all = true
|
307
307
|
|
308
|
-
# Branch objects are really Edge objects within
|
308
|
+
# Branch objects are really Edge objects within Plexus, therefore
|
309
309
|
# cannot rely on #eql? to compare those structures and must drop
|
310
310
|
# down to the attributes.
|
311
|
-
branches.each do |e| #
|
311
|
+
branches.each do |e| # Plexus::Edge structs
|
312
312
|
all = list.any? do |b| # Jumoku::Branch structs
|
313
313
|
(b[:source] == e[:source]) and (b[:target] == e[:target])
|
314
314
|
end
|
data/lib/jumoku/tree_api.rb
CHANGED
@@ -4,7 +4,7 @@ module Jumoku
|
|
4
4
|
#
|
5
5
|
# Each implementation module must implement the following routines:
|
6
6
|
#
|
7
|
-
# * add_node!(n, l = nil) — adds a node to the tree and return the tree; l is an optional label (see
|
7
|
+
# * add_node!(n, l = nil) — adds a node to the tree and return the tree; l is an optional label (see Plexus library).
|
8
8
|
# * add_branch!(i, j = nil, l = nil) — adds a branch to the tree and return the tree. i can be a {Branch}, or (i,j) a node pair; l is an optional label.
|
9
9
|
# * remove_node!(n) — removes a node from the tree and return the tree.
|
10
10
|
# * remove_branch!(i, j = nil) — removes an edge from the graph and return the tree. i can be a {Branch}, or (i,j) a node pair.
|
data/lib/jumoku/version.rb
CHANGED
data/spec/raw_tree_spec.rb
CHANGED
@@ -317,7 +317,7 @@ describe "RawTreeBuilder" do
|
|
317
317
|
@tree.add_node! :one
|
318
318
|
@tree.add_node! :two, :one
|
319
319
|
@tree.branches.size.should == 1
|
320
|
-
@tree.branches.first.class.should ==
|
320
|
+
@tree.branches.first.class.should == Plexus::Edge # the Jumoku::Branch class is just
|
321
321
|
# a lazy wrapper of it
|
322
322
|
@tree.should be_valid
|
323
323
|
end
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
plexus (0.5.3)
|
5
|
+
facets
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.1.2)
|
11
|
+
facets (2.9.1)
|
12
|
+
rspec (2.6.0)
|
13
|
+
rspec-core (~> 2.6.0)
|
14
|
+
rspec-expectations (~> 2.6.0)
|
15
|
+
rspec-mocks (~> 2.6.0)
|
16
|
+
rspec-core (2.6.4)
|
17
|
+
rspec-expectations (2.6.0)
|
18
|
+
diff-lcs (~> 1.1.2)
|
19
|
+
rspec-mocks (2.6.0)
|
20
|
+
yard (0.7.2)
|
21
|
+
|
22
|
+
PLATFORMS
|
23
|
+
ruby
|
24
|
+
|
25
|
+
DEPENDENCIES
|
26
|
+
plexus!
|
27
|
+
rspec
|
28
|
+
yard
|
@@ -1,10 +1,12 @@
|
|
1
|
+
Copyright (c) 2010 Jean-Denis Vauguet <jd@vauguet.fr>
|
2
|
+
|
1
3
|
Copyright (c) 2009 Bruce Williams
|
2
4
|
|
3
5
|
Copyright (c) 2007,2006 Shawn Patrick Garbett
|
4
6
|
|
5
7
|
Copyright (c) 2002,2004,2005 by Horst Duchene
|
6
8
|
|
7
|
-
Copyright (c) 2000,2001 Jeremy Siek, Indiana University (jsiek@osl.iu.edu)
|
9
|
+
Copyright (c) 2000,2001 Jeremy Siek, Indiana University (jsiek@osl.iu.edu)
|
8
10
|
|
9
11
|
All rights reserved.
|
10
12
|
|
@@ -0,0 +1,208 @@
|
|
1
|
+
# Plexus (was Graphy). A framework for graph theory, graph data structures and associated algorithms.
|
2
|
+
|
3
|
+
Graph algorithms currently provided are:
|
4
|
+
|
5
|
+
* Topological Sort
|
6
|
+
* Strongly Connected Components
|
7
|
+
* Transitive Closure
|
8
|
+
* Rural Chinese Postman
|
9
|
+
* Biconnected
|
10
|
+
|
11
|
+
These are based on more general algorithm patterns:
|
12
|
+
|
13
|
+
* Breadth First Search
|
14
|
+
* Depth First Search
|
15
|
+
* A* Search
|
16
|
+
* Floyd-Warshall
|
17
|
+
* Best First Search
|
18
|
+
* Djikstra's Algorithm
|
19
|
+
* Lexicographic Search
|
20
|
+
|
21
|
+
## A quick Tour
|
22
|
+
|
23
|
+
### Arcs
|
24
|
+
|
25
|
+
There are two vertices bound classes, `Plexus::Arc` and `Plexus::Edge`. The
|
26
|
+
former defines directional edges, the latter undirected edges.
|
27
|
+
|
28
|
+
### Vertices
|
29
|
+
|
30
|
+
Vertices can be any `Object`.
|
31
|
+
|
32
|
+
### Graph Types
|
33
|
+
|
34
|
+
There are a number of different graph types, each of which provide
|
35
|
+
different features and constraints:
|
36
|
+
|
37
|
+
`Plexus::Digraph` and its alias `Plexus::DirectedGraph`:
|
38
|
+
|
39
|
+
* Single directed edges (arcs) between vertices
|
40
|
+
* Loops are forbidden
|
41
|
+
|
42
|
+
`Plexus::DirectedPseudoGraph`:
|
43
|
+
|
44
|
+
* Multiple directed edges (arcs) between vertices
|
45
|
+
* Loops are forbidden
|
46
|
+
|
47
|
+
`Plexus::DirectedMultiGraph`:
|
48
|
+
|
49
|
+
* Multiple directed edges (arcs) between vertices
|
50
|
+
* Loops on vertices
|
51
|
+
|
52
|
+
`Plexus::UndirectedGraph`, `Plexus::UndirectedPseudoGraph`, and
|
53
|
+
`Graph::UndirectedMultiGraph` are similar but all edges are undirected.
|
54
|
+
|
55
|
+
### Data Structures
|
56
|
+
|
57
|
+
In order to modelize data structures, make use of the `Plexus::AdjacencyGraph`
|
58
|
+
module which provides a generalized adjacency list and an edge list adaptor.
|
59
|
+
|
60
|
+
The `Plexus::Digraph` class is the general purpose "swiss army knife" of graph
|
61
|
+
classes, most of the other classes are just modifications to this class.
|
62
|
+
It is optimized for efficient access to just the out-edges, fast vertex
|
63
|
+
insertion and removal at the cost of extra space overhead, etc.
|
64
|
+
|
65
|
+
## Example Usage
|
66
|
+
|
67
|
+
Using IRB, first require the library:
|
68
|
+
|
69
|
+
``` bash
|
70
|
+
require 'rubygems' # only if you are using ruby 1.8.x
|
71
|
+
require 'plexus'
|
72
|
+
```
|
73
|
+
|
74
|
+
If you'd like to include all the classes in the current scope (so you
|
75
|
+
don't have to prefix with `Plexus::`), just:
|
76
|
+
|
77
|
+
``` bash
|
78
|
+
include Plexus
|
79
|
+
```
|
80
|
+
|
81
|
+
Let's play with the library a bit in IRB:
|
82
|
+
|
83
|
+
``` bash
|
84
|
+
>> dg = Digraph[1,2, 2,3, 2,4, 4,5, 6,4, 1,6]
|
85
|
+
=> Plexus::Digraph[[2, 3], [1, 6], [2, 4], [4, 5], [1, 2], [6, 4]]
|
86
|
+
```
|
87
|
+
|
88
|
+
A few properties of the graph we just created:
|
89
|
+
|
90
|
+
``` bash
|
91
|
+
>> dg.directed?
|
92
|
+
=> true
|
93
|
+
>> dg.vertex?(4)
|
94
|
+
=> true
|
95
|
+
>> dg.edge?(2,4)
|
96
|
+
=> true
|
97
|
+
>> dg.edge?(4,2)
|
98
|
+
=> false
|
99
|
+
>> dg.vertices
|
100
|
+
=> [1, 2, 3, 4, 5, 6]
|
101
|
+
```
|
102
|
+
|
103
|
+
Every object could be a vertex, even the class object `Object`:
|
104
|
+
|
105
|
+
``` bash
|
106
|
+
>> dg.vertex?(Object)
|
107
|
+
=> false
|
108
|
+
|
109
|
+
>> UndirectedGraph.new(dg).edges.sort.to_s
|
110
|
+
=> "[Plexus::Edge[1,2,nil], Plexus::Edge[2,3,nil], Plexus::Edge[2,4,nil],
|
111
|
+
Plexus::Edge[4,5,nil], Plexus::Edge[1,6,nil], Plexus::Edge[6,4,nil]]"
|
112
|
+
```
|
113
|
+
|
114
|
+
Add inverse edge `(4-2)` to directed graph:
|
115
|
+
|
116
|
+
``` bash
|
117
|
+
>> dg.add_edge!(4,2)
|
118
|
+
=> Plexus::DirectedGraph[Plexus::Arc[1,2,nil], Plexus::Arc[1,6,nil], Plexus::Arc[2,3,nil],
|
119
|
+
Plexus::Arc[2,4,nil], Plexus::Arc[4,5,nil], Plexus::Arc[4,2,nil],
|
120
|
+
Plexus::Arc[6,4,nil]]
|
121
|
+
```
|
122
|
+
|
123
|
+
`(4-2) == (2-4)` in the undirected graph (4-2 doesn't show up):
|
124
|
+
|
125
|
+
``` bash
|
126
|
+
>> UndirectedGraph.new(dg).edges.sort.to_s
|
127
|
+
=> "[Plexus::Edge[1,2,nil], Plexus::Edge[2,3,nil], Plexus::Edge[2,4,nil],
|
128
|
+
Plexus::Edge[4,5,nil], Plexus::Edge[1,6,nil], Plexus::Edge[6,4,nil]]"
|
129
|
+
```
|
130
|
+
|
131
|
+
`(4-2) != (2-4)` in directed graphs (both show up):
|
132
|
+
|
133
|
+
``` bash
|
134
|
+
>> dg.edges.sort.to_s
|
135
|
+
=> "[Plexus::Arc[1,2,nil], Plexus::Arc[1,6,nil], Plexus::Arc[2,3,nil],
|
136
|
+
Plexus::Arc[2,4,nil], Plexus::Arc[4,2,nil], Plexus::Arc[4,5,nil],
|
137
|
+
Plexus::Arc[6,4,nil]]"
|
138
|
+
|
139
|
+
>> dg.remove_edge! 4,2
|
140
|
+
=> Plexus::DirectedGraph[Plexus::Arc[1,2,nil], Plexus::Arc[1,6,nil], Plexus::Arc[2,3,nil],
|
141
|
+
Plexus::Arc[2,4,nil], Plexus::Arc[4,5,nil], Plexus::Arc[6,4,nil]]
|
142
|
+
```
|
143
|
+
|
144
|
+
Topological sorting is realized with an iterator:
|
145
|
+
|
146
|
+
``` bash
|
147
|
+
>> dg.topsort
|
148
|
+
=> [1, 6, 2, 4, 5, 3]
|
149
|
+
>> y = 0; dg.topsort { |v| y += v }; y
|
150
|
+
=> 21
|
151
|
+
```
|
152
|
+
|
153
|
+
You can use DOT to visualize the graph:
|
154
|
+
|
155
|
+
``` bash
|
156
|
+
>> require 'plexus/dot'
|
157
|
+
>> dg.write_to_graphic_file('jpg','visualize')
|
158
|
+
```
|
159
|
+
|
160
|
+
Here's an example showing the module inheritance hierarchy:
|
161
|
+
|
162
|
+
``` bash
|
163
|
+
>> module_graph = Digraph.new
|
164
|
+
>> ObjectSpace.each_object(Module) do |m|
|
165
|
+
>> m.ancestors.each {|a| module_graph.add_edge!(m,a) if m != a}
|
166
|
+
>> end
|
167
|
+
>> gv = module_graph.vertices.select {|v| v.to_s.match(/Plexus/) }
|
168
|
+
>> module_graph.induced_subgraph(gv).write_to_graphic_file('jpg','module_graph')
|
169
|
+
```
|
170
|
+
|
171
|
+
Look for more in the examples directory.
|
172
|
+
|
173
|
+
## History
|
174
|
+
|
175
|
+
This library is based on [GRATR][1] by Shawn Garbett (itself a fork of
|
176
|
+
Horst Duchene's [RGL][2] library) which is heavily influenced by the [Boost][3]
|
177
|
+
Graph Library (BGL).
|
178
|
+
|
179
|
+
This fork attempts to modernize and extend the API and tests.
|
180
|
+
|
181
|
+
## References
|
182
|
+
|
183
|
+
For more information on Graph Theory, you may want to read:
|
184
|
+
|
185
|
+
* the [documentation][3] for the Boost Graph Library
|
186
|
+
* [the Dictionary of Algorithms and Data Structures][4]
|
187
|
+
|
188
|
+
## Credits
|
189
|
+
|
190
|
+
See CREDITS.markdown
|
191
|
+
|
192
|
+
## TODO
|
193
|
+
|
194
|
+
See TODO.markdown
|
195
|
+
|
196
|
+
## CHANGELOG
|
197
|
+
|
198
|
+
See CHANGELOG.markdown
|
199
|
+
|
200
|
+
## License
|
201
|
+
|
202
|
+
[MIT License](http://en.wikipedia.org/wiki/MIT_License). See the LICENSE file.
|
203
|
+
|
204
|
+
[1]: http://gratr.rubyforge.org
|
205
|
+
[2]: http://rgl.rubyforge.org
|
206
|
+
[3]: http://www.boost.org/libs/graph/doc
|
207
|
+
[4]: http://www.nist.gov/dads/HTML/graph.html
|
208
|
+
|