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

mdd.MDDGenerator.scala Maven / Gradle / Ivy

There is a newer version: 1.8
Show newest version
package mdd

import scala.util.Random
import scala.collection.mutable.HashMap
import scala.collection.mutable.ArrayBuffer


object MDDGenerator {
  /**
   * Robert Floyd algorithm to pick M elements from 1..N
   *
   * initialize set S to empty
   * for J := N-M + 1 to N do
   *   T := RandInt(1, J)
   *   if T is not in S then
   *     insert T in S
   *   else
   *     insert J in S
   */

  /** max is inclusive */
  def randBigInt(max: BigInt, r: Random) = {
    require(max >= 0, max)
    if (max < Int.MaxValue) {
      BigInt(r.nextInt(max.toInt + 1))
    } else {
      var i: BigInt = null

      do {
        i = BigInt(max.bitLength, r) // r.nextInt(max.intValue)
      } while (i > max)

      i
    }
  }

  def tupleSplit(b: BigInt, d: Int, k: Int) = {
    val n = Array.ofDim[Int](k)
    var i = b
    var p = k - 1
    while (i > 0) {
      val (q, m) = i /% d
      n(p) = m.intValue
      i = q
      p -= 1
    }
    n
  }

  def apply(d: Int, k: Int, lambda: Int, rand: Random): MDD = {
    var data: Set[Array[Int]] = Set()
    val n = BigInt(d).pow(k)

    for (j <- (n - lambda) until n) {
      val t = tupleSplit(randBigInt(j, rand), d, k)

      if (data(t)) {
        data += tupleSplit(j, d, k)
      } else {
        data += t
      }
    }

    MDD.fromSeq(data.toSeq)
  }

  def giveStructure(mdd: MDD, q: Double, rand: Random, ts: Int) = {
    val existing = new HashMap[Int, ArrayBuffer[MDD]]()
    val cache = new IdMap[MDD, MDD]

    def giveStruct(n: MDD, k: Int): MDD = {
      if (n eq MDDLeaf) {
        n
      } else cache.getOrElseUpdate(n, {
        val e = existing.getOrElseUpdate(k, new ArrayBuffer())
        if (e.nonEmpty && rand.nextDouble() < q) {
          e(rand.nextInt(e.size))
        } else {
          val newMDD = MDD.fromTrie(
            n.traverseST
              .map {
                case (i, m) => i -> giveStruct(m, k + 1)
              })

          val r = if (newMDD == n) n else newMDD
          e += r
          r
        }

      })
    }

    giveStruct(mdd, 0)
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy