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

cilib.Selection.scala Maven / Gradle / Ivy

There is a newer version: 2.0.1-30-g5ca4090
Show newest version
package cilib

import scalaz.{Ordering => _, _}
import Scalaz._

object Selection {

  private implicit class RicherEphemeralStream[A](val s: EphemeralStream[A]) extends AnyVal {
    def drop(n: Int): EphemeralStream[A] = {
      def go(count: Int, c: Option[EphemeralStream[A]]): EphemeralStream[A] =
        if (count > 0) go(count - 1, c.flatMap(_.tailOption))
        else c.cata(x => x, EphemeralStream())

      go(n, Option(s))
    }
  }

  def indexNeighbours[A](n: Int): (NonEmptyList[A], A) => List[A] =
    (l: NonEmptyList[A], x: A) => {
      val list = l
      val size = l.size
      val point =
        l.list.indexWhere(_ == x) match {
          case None    => 0
          case Some(i) => (i - (n / 2) + size) % size
        }
      lazy val c: EphemeralStream[A] = EphemeralStream(list.toList: _*) ++ c

      c.drop(point).take(n).toList
    }

  def latticeNeighbours[A: scalaz.Equal]: (NonEmptyList[A], A) => List[A] =
    (l: NonEmptyList[A], x: A) => {
      val list = l.list
      val np = list.length
      val index: Option[Int] = list.indexOf(x) // This returns Option[Int] instead of Int, which is awesome :)
      val sqSide = math.round(math.sqrt(np.toDouble)).toInt
      val nRows = math.ceil(np / sqSide.toDouble).toInt
      val row: Option[Int] = index.map(_ / sqSide)
      val col: Option[Int] = index.map(_ % sqSide)

      @inline def indexInto(r: Int, c: Int) =
        r * sqSide + c

      @inline val colsInRow =
        (r: Int) => if (r == nRows - 1) np - r * sqSide else sqSide

      val result = for {
        r <- row
        c <- col
        north <- list.index(
          indexInto((r - 1 + nRows) % nRows - (if (c >= colsInRow(r - 1 + nRows) % nRows) 1 else 0),
                    c))
        south <- list.index(indexInto(if (c >= colsInRow(r + 1) % nRows) 0 else (r + 1) % nRows, c))
        east <- list.index(indexInto(r, (c + 1) % colsInRow(r)))
        west <- list.index(indexInto(r, (c - 1 + colsInRow(r)) % colsInRow(r)))
      } yield List(x, north, south, east, west)

      result.getOrElse(sys.error("error in latticeNeighbours"))
    }

  def distanceNeighbours[F[_]: Foldable, A: Order](distance: MetricSpace[F[A], A])(n: Int) =
    (l: NonEmptyList[F[A]], x: F[A]) => l.sortBy(li => distance.dist(li, x)).toList.take(n)

  def wheel[A] =
    (l: NonEmptyList[A], a: A) => {
      if (l.head == a) l.toList
      else List(l.head, a)
    }

  def star[A] =
    (l: NonEmptyList[A], x: A) => l.toList

  def tournament[F[_], A](n: Int, l: NonEmptyList[F[A]])(
      implicit F: Fitness[F, A]): Comparison => RVar[Option[F[A]]] =
    o =>
      RVar
        .sample(n, l)
        .map(_.reduceLeftOption((a, c) => o.apply(a, c)))
        .run
        .map(_.flatten)

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy