|
1 | 1 | # graph-dsl |
2 | 2 |
|
3 | | -A groovy dsl for creating and traversing graphs. |
4 | | -For project build status check the [wiki](https://github.com/moaxcp/graph-dsl/wiki). |
| 3 | +A groovy dsl for creating and traversing extensible graphs. The graph can be extended with plugins and traits which |
| 4 | +allow developers to create a graph with the desired behavior and values for their algorithm. For project build status |
| 5 | +check the [wiki](https://github.com/moaxcp/graph-dsl/wiki). |
5 | 6 |
|
6 | 7 | # Usage |
7 | 8 |
|
8 | | -graph-dsl is used to create graphs and algorithms for graphs. |
9 | | -It is designed to be groovy, using closures and metaprogramming for minimal setup. |
10 | | - |
11 | | -## Building a graph |
12 | | - |
13 | 9 | ```groovy |
14 | 10 | #!/usr/bin/env groovy |
15 | 11 | @Grab(group='com.github.moaxcp', module='graph-dsl', version='0.11.0') |
16 | | -import static graph.Graph.graph |
| 12 | +``` |
17 | 13 |
|
18 | | -graph { |
19 | | - apply DirectedGraphPlugin |
20 | | - vertex a { |
21 | | - edgesFirst 'b', 'd' |
22 | | - edgesSecond 'd' |
| 14 | +## Creating a graph |
| 15 | + |
| 16 | +The basic graph structure is held in a map of named vertices and a set of edges. |
| 17 | + |
| 18 | +All referenced vertices are created if they don't exist. |
| 19 | + |
| 20 | +```groovy |
| 21 | +def graph = graph { |
| 22 | + edge step1, step2 |
| 23 | +} |
| 24 | +assert graph.vertices.keySet() == ['step1', 'step2'] as Set //vertices were created! |
| 25 | +assert graph.edges.size() == 1 |
| 26 | +assert graph.edges.first() == new Edge(one:'step1', two:'step2') //edge was created! |
| 27 | +``` |
| 28 | + |
| 29 | +This example of a graph creates two vertices named 'step1' and 'step2' as well as an edge between them. There are many |
| 30 | +other methods for creating vertices and edges. |
| 31 | + |
| 32 | +```groovy |
| 33 | +graph.with { |
| 34 | + edge (A, B) { |
| 35 | + traits Mapping, Mapping |
| 36 | + queue = new LinkedList() |
| 37 | + weight { queue.size() } |
23 | 38 | } |
24 | 39 | |
25 | | - vertex renameMe { |
26 | | - rename 'b' |
27 | | - edgesFirst 'c', 'd' |
| 40 | + vertex A(traits:Mapping) { |
| 41 | + action = { |
| 42 | + println "processing" |
| 43 | + } |
28 | 44 | } |
29 | 45 | |
30 | | - vertex d([edgesFirst:'c']) { |
31 | | - edgesFirst 'e' |
| 46 | + vertex B { |
| 47 | + traits Mapping |
| 48 | + action = { |
| 49 | + println "done processing" |
| 50 | + } |
32 | 51 | } |
33 | | - |
34 | | - edge 'f', 'g' |
35 | | - edge g, d |
36 | | - |
37 | | - eachBfs { |
38 | | - println it.name |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +The Default behavior of a graph is that of an undirected graph. These graphs have a set of edges where only one edge |
| 56 | +can connect any two vertices. This behavior can be changed to a directed graph at any time using the DirectedGraphPlugin |
| 57 | + |
| 58 | +```groovy |
| 59 | +graph.apply DirectedGraphPlugin |
| 60 | +``` |
| 61 | + |
| 62 | +Traits can be added to all edges and vertices. |
| 63 | + |
| 64 | +```groovy |
| 65 | +graph.edgeTraits Mapping, Weight |
| 66 | +graph.vertexTraits Mapping |
| 67 | +``` |
| 68 | + |
| 69 | +## Traversing a graph |
| 70 | + |
| 71 | +Once a graph is created there is a dsl for depthFirstTraversal and breadthFirstTraversal. |
| 72 | + |
| 73 | +```groovy |
| 74 | +graph { |
| 75 | + apply DirectedGraphPlugin |
| 76 | + vertex A { |
| 77 | + edgesFirst 'B', 'D', 'E' |
| 78 | + edgesSecond 'D' |
39 | 79 | } |
| 80 | +
|
| 81 | + vertex D { |
| 82 | + edgesFirst 'C', 'E' |
| 83 | + edgesSecond 'B' |
| 84 | + } |
| 85 | +
|
| 86 | + edge B, C |
| 87 | + depthFirstTraversal { |
| 88 | + root = 'A' |
| 89 | + preorder { vertex -> |
| 90 | + println vertex.name |
| 91 | + } |
| 92 | + } |
| 93 | +
|
| 94 | + breadthFirstTraversal { |
| 95 | + root = 'A' |
| 96 | + visit { vertex -> |
| 97 | + println "bft $vertex.name" |
| 98 | + } |
| 99 | + } |
| 100 | +} |
| 101 | +``` |
| 102 | + |
| 103 | +## Functional methods |
| 104 | + |
| 105 | +There are functional methods build on the depthFirstTraversal and breadthFirstTraversal method. |
| 106 | + |
| 107 | +```groovy |
| 108 | +eachBfs { |
| 109 | + println it.name |
| 110 | +} |
| 111 | +
|
| 112 | +def vertex = findBfs { |
| 113 | + it.name == 'A' |
| 114 | +} |
| 115 | +
|
| 116 | +def bfsOrder = collectBfs { |
| 117 | + it.name |
40 | 118 | } |
41 | 119 | ``` |
42 | 120 |
|
43 | | -# Getting Started |
| 121 | +Note: These methods are not yet implemented for depth first traversal. The depth first traversal methods will be the |
| 122 | +defaults for each, find, inject, findAll, and collect. |
| 123 | + |
| 124 | +## Edge Classification |
| 125 | + |
| 126 | +Depth first traversal supports edge classification where an edge is classified as: |
| 127 | + |
| 128 | +* tree-edge - when the destination vertex is white |
| 129 | +* back-edge - when the destination vertex is grey |
| 130 | +* forward-edge - when the destination vertex is black |
| 131 | +* cross-edge - when the destination vertex is black and in a different tree |
| 132 | + |
| 133 | +## EdgeWeightPlugin |
| 134 | + |
| 135 | +This plugin applies Weight to all edges and changes all traversal methods to follow edges in order of their weight. |
| 136 | + |
| 137 | +# Getting Started With Development/Contributing |
44 | 138 |
|
45 | 139 | ## install git |
46 | 140 |
|
| 141 | +Follow this guide to install git. |
| 142 | + |
47 | 143 | https://git-scm.com/book/en/v2/Getting-Started-Installing-Git |
48 | 144 |
|
49 | 145 | ## install gitflow-avh |
50 | 146 |
|
| 147 | +This project uses gitflow-avh. It is a plugin for git that provides the `git flow` commands. These commands are used to |
| 148 | +follow the gitflow pattern for developing software. For more information see |
| 149 | +[Workflow](https://github.com/moaxcp/graph-dsl/wiki/Workflow) in the wiki. |
| 150 | + |
51 | 151 | https://github.com/petervanderdoes/gitflow-avh/wiki/Installation |
52 | 152 |
|
53 | 153 | ## clone the project |
54 | 154 |
|
| 155 | +clone the project from github. |
| 156 | + |
55 | 157 | git clone https://github.com/moaxcp/graph-dsl.git |
56 | 158 |
|
57 | 159 | ## build |
58 | 160 |
|
| 161 | +The project uses gradle for the build system. Using gradlew, you do not need to install gradle to build the project. |
| 162 | + |
59 | 163 | `./gradlew build` |
60 | 164 |
|
61 | | -# Contributing |
| 165 | +## Contributing |
62 | 166 |
|
63 | 167 | Contributions are welcome. Please submit a pull request to the develop branch in github. |
64 | 168 |
|
@@ -91,6 +195,29 @@ If there are any issues contact me moaxcp@gmail.com. |
91 | 195 |
|
92 | 196 | # Releases |
93 | 197 |
|
| 198 | +## 0.15.0 |
| 199 | + |
| 200 | +This release combines fixes for a few issues on github. |
| 201 | + |
| 202 | +* [#75](https://github.com/moaxcp/graph-dsl/issues/75) Vertex.name, Edge.one, and Edge.two is now @PackageScope. This only |
| 203 | +affects code that is @CompileStatic for now due to [GROOVY-3010](https://issues.apache.org/jira/browse/GROOVY-3010). |
| 204 | +* [#74](https://github.com/moaxcp/graph-dsl/issues/74)Vertices and edges may now be deleted. A vertex cannot be deleted if |
| 205 | +there are edges referencing it. |
| 206 | +* [#73](https://github.com/moaxcp/graph-dsl/issues/73) Added EdgeWeightPlugin. This plugin adds the Weight trait to each |
| 207 | +edge. Traversal methods are ordered by edge weight. |
| 208 | + |
| 209 | +There were also several other changes that were not an issue on github: |
| 210 | + |
| 211 | +Updated gradle to 3.5. Refactored gradle script to use the plugins closure when possible. gradle-gitflow does not work |
| 212 | +with the closure because it is not in the gradle repository. This is another reason to update the plugin. Spock was also |
| 213 | +updated to 1.1. |
| 214 | + |
| 215 | +Added edgeTraits and vertexTraits. These methods will ensure traits are applied to current and future edges and vertices. |
| 216 | + |
| 217 | +Added tests to provide more code coverage in jacoco. |
| 218 | + |
| 219 | +Added more usage details to README.md |
| 220 | + |
94 | 221 | ## 0.14.0 |
95 | 222 |
|
96 | 223 | Just as in 0.13.0, where the config closure was removed from VertexSpec, this release removes the config closure from |
|
0 commit comments