Algorithms are automatically executed in parallel.
Many algorithms can be expressed in just a few lines of code.
The defaults get you started quickly, but everything can be customized.
In Signal/Collect algorithms are written from the perspective of vertices and edges. Once a graph has been specified the edges will signal and the vertices will collect. When an edge signals it computes a message based on the state of its source vertex. This message is then sent along the edge to the target vertex of the edge. When a vertex collects it uses the received messages to update its state. These operations happen in parallel all over the graph until all messages have been collected and all vertex states have converged.
Many algorithms have very simple and elegant implementations in Signal/Collect. Please take the time to explore some of the example algorithms below.
import com.signalcollect._ object PageRank extends App { val graph = GraphBuilder.build graph.addVertex(new PageRankVertex(1)) graph.addVertex(new PageRankVertex(2)) graph.addEdge(1, new PageRankEdge(2)) graph.addEdge(2, new PageRankEdge(1)) graph.execute graph.foreachVertex(println(_)) graph.shutdown } class PageRankVertex(id: Int, baseRank: Double = 0.15) extends DataGraphVertex(id, baseRank) { type Signal = Double def dampingFactor = 1 - baseRank def collect = baseRank + dampingFactor * signals.sum } class PageRankEdge(targetId: Int) extends DefaultEdge(targetId) { type Source = PageRankVertex def signal = source.state * weight / source.sumOfOutWeights }
import com.signalcollect._ object SSSP extends App { val graph = GraphBuilder.build graph.addVertex(new Location(1, Some(0))) graph.addVertex(new Location(2)) graph.addVertex(new Location(3)) graph.addEdge(1, new Path(2)) graph.addEdge(2, new Path(3)) graph.execute graph.foreachVertex(println(_)) graph.shutdown } class Location(id: Int, initialState: Option[Int] = None) extends DataFlowVertex(id, initialState) { type Signal = Int def collect(signal: Int) = state match { case None => Some(signal) case Some(currentShortestPath) => Some(math.min(currentShortestPath, signal)) } } class Path(t: Int) extends OptionalSignalEdge(t) { def signal = source.state match { case None => None case Some(distance: Int) => Some(distance + weight.toInt) } }