You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+19-28Lines changed: 19 additions & 28 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,10 +43,10 @@ You'll need to
43
43
* choose or create a SemiringSupport implementation, like FewestNodes.
44
44
* provide a function to convert from a (Node,Node,MaybeAnEdge) tuple to the Label defined by your SemiringSupport.
45
45
** You can use net.walend.scalagraph.semiring.ConvertToLabelGraph to convert from a [scala-graph](http://www.scala-graph.org/) Graph.
46
-
* choose an algorithm to perform the minimization. (You probably want to use Dijkstra's algorithm.)
46
+
* choose an algorithm to perform the minimization. You probably want to use Dijkstra's algorithm.
47
47
* arrange for your code to run the algorithm on your graph
48
48
49
-
Floyd-Warshall provides a Digraph[Node,Label] with your nodes and labels that contain the results of the minimization. Dijkstra provides a Seq[(Node,Node,Label)] where the labels contain the results of the minimization. Brandes provides that plus a Map[Node,Double] that holds each node's betweenness.
49
+
Floyd-Warshall provides a Digraph[Node,Label] with your nodes and labels that contain the results of the minimization. Dijkstra provides a Seq[(Node,Node,Label)] where the labels contain the results of the minimization. Brandes provides that Seq plus a Map[Node,Double] that holds each node's betweenness.
@@ -61,25 +61,25 @@ Floyd-Warshall provides a Digraph[Node,Label] with your nodes and labels that co
61
61
//this will be used to convert from the arc tuples to labels
62
62
val labelForEdge = support.convertEdgeToLabelFunc[String](FewestNodes.convertEdgeToLabel)
63
63
64
-
//finds a shortest path for each pair of nodes if that path exists
65
-
val shortestPaths:Seq[(String,String,Option[FirstStep[String,Int]])] =
64
+
//find the first step in a shortest path for a pair of nodes if that path exists
65
+
val firstSteps:Seq[(String,String,Option[FirstStep[String,Int]])] =
66
66
Dijkstra.allPairsShortestPaths(edges = yourEdges,
67
67
support = support,
68
68
labelForArc = labelForArc)
69
69
70
+
//Find the shortest paths between any pair of nodes
71
+
val shortestPath:Option[Seq[String]] = support.leastPath(start,end)
70
72
71
73
### Algorithms
72
74
73
75
For the second release, ScalaGraphMinimizer supplies
74
76
77
+
* FibonacciHeap -- a generic heap that supports an efficient changeKey operation.
75
78
* The Floyd-Warshall algorithm
76
79
* Dijkstra's algorithm with a Fibonacci Heap
77
80
* Brandes' algorithm for betweenness
78
81
79
-
Peter Empen optimized scala-graph's internal representation in scala-graph to ensure that the graph algorithms scaled at their theoretical limits. I've tested with graphs with up to 1024 nodes. I've tested just the internal representation (todo size)
80
-
81
-
* FibonacciHeap is a generic heap that supports an efficient changeKey operation.
82
-
82
+
I've used a profiler to quench hotspots where I could find ways to speed up algorithms. I've tested performance up to 2048 nodes.
83
83
84
84
### Semirings
85
85
@@ -106,25 +106,17 @@ FloydWarshall, Dijkstra, and Brandes each include a method that take sequences o
106
106
107
107
These are typically very straightforward to create. The decorator semirings listed above each include helper functions that require a similar function to convert the tuple to the core semiring's Label.
These methods also allow for an optional extraNodes Seq. This Seq can contain both extra nodes and any nodes that already exist in the edges, and has some influence over the ordering of the algorithm's output.
111
+
These methods also allow for an optional extraNodes Seq. This Seq can contain both extra nodes and any nodes that already exist in the edges, and can control the ordering of the algorithm's output.
112
112
113
-
FloydWarshall, Dijkstra, and Brandes each also include a method that takes a Digraph implementation. If you use this method then you are responsible for creating the labelDigraph correctly. I included it primarily for computational efficiency, and for a future lazy evaluator for Dijkstra's method.
113
+
FloydWarshall, Dijkstra, and Brandes each also include a method that takes an IndexedDigraph implementation, mutable for FloydWarshall. If you use this method then you are responsible for creating the labelDigraph correctly. I included it primarily for computational efficiency, and for a future lazy evaluator for Dijkstra's method.
114
114
115
115
labelDigraph:IndexedDigraph[Node,Label]
116
116
117
-
You are very likely to need your own LabelGraphBuilder to create a label graph from your own specialized graph. The easiest way is to extend AbstractLabelGraphBuilder and fill in
### Creating A Custom Semiring and Other Support Classes
124
118
125
-
You will likely want to create your own Semirings to match the problems you are solving. That will be enough to run the Floyd-Warshall algorithm. However, Dijkstra's and Brandes' algorithms requires some extra for the heap. Implement SemiringSupport, which includes a Semiring, a HeapOrdering, and a function to convert from Labels to the heap's Keys. Here is an example that can find the most probable paths:
126
-
127
-
TODO update this with the latest
119
+
You will likely want to create your own Semirings to match the problems you are solving. That will be enough to run the Floyd-Warshall algorithm. However, Dijkstra's and Brandes' algorithms requires some extra methods for the heap. Implement SemiringSupport, which includes a Semiring, a HeapOrdering, and a function to convert from Labels to the heap's Keys. Here is an example that can find the most probable paths:
For your Semiring supply identity and annihilator values, and summary and extend operators. Here's an example:
133
+
For your Semiring supply identity and annihilator values, a method to check that a label is in the domain, and summary and extend operators. Here's an example:
142
134
143
135
object MostProbableSemiring extends Semiring {
144
136
@@ -165,7 +157,7 @@ For your Semiring supply identity and annihilator values, and summary and extend
165
157
}
166
158
}
167
159
168
-
The HeapOrdering is actually trickier to get right. The Heap needs a special Key, AlwaysTop, that will always be higher than the highest possible Label and AlwaysBottom, that will only be on the bottom of the heap. The identity and annihilator sometimes work as these special values. Watch out for strange behaviors of floating point infinities and wrap-around with integers.
160
+
The HeapOrdering is actually trickier to get right than the Semiring. The Heap needs a special Key, AlwaysTop, that will always be higher than the highest possible Label and AlwaysBottom, that will only be on the bottom of the heap. The identity and annihilator sometimes work as these special values. Watch out for strange behaviors of floating point infinities and wrap-around with integers. In this example, I want a version that has the highest values on top of the heap. Note that I took a shortcut and made AlwaysTop outside of the Semiring's domain.
169
161
170
162
/**
171
163
* A heap ordering that puts lower numbers on the top of the heap
@@ -210,8 +202,8 @@ The HeapOrdering is actually trickier to get right. The Heap needs a special Key
210
202
211
203
### Next release
212
204
205
+
* Louvain community detection
213
206
* A*
214
-
* MST using a heap and a GraphBuilder
215
207
* Enron test set
216
208
* Timing study with automatically generated graphs (in the test stage) (And comparison with Jung and scala-graph's own)
217
209
@@ -224,9 +216,8 @@ The HeapOrdering is actually trickier to get right. The Heap needs a special Key
0 commit comments