in cassovary-core/src/main/scala/com/twitter/cassovary/graph/TestGraph.scala [289:323]
def generateRandomUndirectedGraph(numNodes: Int, probEdge: Double,
graphDir: StoredGraphDir = StoredGraphDir.BothInOut,
rand: Random = new Random,
parallelismLimit: Int = 2) = {
val futurePool = new BoundedFuturePool(FuturePool.unboundedPool, parallelismLimit)
val nodes = Array.fill(numNodes){new ConcurrentLinkedQueue[Int]()}
def addMutualEdge(i: Int)(j: Int) {nodes(i).add(j); nodes(j).add(i)}
val binomialDistribution = new BinomialDistribution(numNodes - 1, probEdge)
// Sampling edges only from nodes with lower id to higher id. In order to
// reuse the same binomial distribution we match nodes in pairs, so that
// one with id 0 is matched with one with id (n - 1), id 1 is matched with (n - 2)
// and so on. Observe, that there is (n - 1) potential edges for every pair, that
// connect from lower id node to higher. Thus for each pair we need to sample a vector
// of Bernoulli variables of size (n - 1), from which we interprete first (lowerNode - 1)
// bits as edges from higherNode and the rest from the node with lower id.
val futures = (0 to (numNodes - 1) / 2) map {
lowerNode => futurePool {
val higherNode = numNodes - 1 - lowerNode
val (higherNodeNeighbors, lowerNodeNeighbors) = randomSubset(binomialDistribution,
0 until numNodes - 1, rand) partition (_ < lowerNode)
lowerNodeNeighbors.map(_ + 1) foreach addMutualEdge(lowerNode)
if (lowerNode != higherNode)
higherNodeNeighbors map (higherNode + _ + 1) foreach addMutualEdge(higherNode)
}
}
Await.ready(Future.join(futures))
val nodesEdges = nodes.indices map { i =>
NodeIdEdgesMaxId(i, nodes(i).asScala.toArray)
}
ArrayBasedDirectedGraph(nodesEdges, graphDir,
NeighborsSortingStrategy.LeaveUnsorted)
}