 # Signal/Collect

Allows you to process large graphs in seconds.

## Fast and scalable

Algorithms are automatically executed in parallel.

## Easy to use

Many algorithms can be expressed in just a few lines of code.

## Configurable

The defaults get you started quickly, but everything can be customized.

## How it works

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.

## Example Algorithms

```import com.signalcollect._

object PageRank extends App {
val graph = GraphBuilder.build
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.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)
}
}
```