All Downloads are FREE. Search and download functionalities are using the official Maven repository.

izumi.fundamentals.graphs.tools.random.RandomGraph.scala Maven / Gradle / Ivy

package izumi.fundamentals.graphs.tools.random

import izumi.fundamentals.graphs.struct.IncidenceMatrix

import scala.annotation.nowarn
import scala.collection.mutable
import scala.reflect.ClassTag
import scala.util.Random

@nowarn("msg=Unused import")
object RandomGraph {
  import scala.collection.compat._

  def makeDG[N: Generator: ClassTag](nodes: Int, maxEdges: Int, random: Random = Random): IncidenceMatrix[N] = {
    assert(nodes > 0)
    assert(maxEdges > 0)
    val ordered = makeShuffledNodes(nodes, random)

    val out = new mutable.HashMap[N, Set[N]]()
    for ((n, idx) <- ordered.zipWithIndex) {

      val links = if (idx > 0) {
        (0 until maxEdges).flatMap {
          _ =>
            if (random.nextBoolean()) {
              Seq(ordered(Random.nextInt(ordered.length)))
            } else {
              Seq.empty
            }
        }.toSet
      } else {
        Set.empty[N]
      }
      out.put(n, links)
    }

    IncidenceMatrix(out.toMap)

  }

  def makeDAG[N: Generator: ClassTag](nodes: Int, maxEdges: Int, random: Random = Random): IncidenceMatrix[N] = {
    assert(nodes > 0)
    assert(maxEdges > 0)
    val ordered = makeShuffledNodes(nodes, random)

    val out = new mutable.HashMap[N, Set[N]]()
    for ((n, idx) <- ordered.zipWithIndex) {

      val links = if (idx > 0) {
        (0 until maxEdges)
          .flatMap(
            rndIdx =>
              if (random.nextBoolean()) {
                Seq(ordered(rndIdx % idx))
              } else {
                Seq.empty
              }
          )
          .toSet
      } else {
        Set.empty[N]
      }
      out.put(n, links)
    }

    IncidenceMatrix(out.toMap)
  }

  private def makeShuffledNodes[N: Generator: ClassTag](nodes: Int, random: Random): Array[N] = {
    val gen = implicitly[Generator[N]]
    val initial = (0 until nodes).map(_ => gen.make())
    val toFix = initial.to(mutable.HashSet)
    while (toFix.size < nodes) {
      toFix.add(gen.make())
    }

    val ordered = new Array[N](toFix.size)
    toFix.copyToArray(ordered)

    for (idx <- 0 to ordered.length / 2) {
      val swapWith = random.nextInt(ordered.length)
      val t = ordered(idx)
      ordered.update(idx, ordered(swapWith))
      ordered.update(swapWith, t)
    }
    ordered
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy