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

io.github.dataunitylab.fuzzysets.FuzzySet.scala Maven / Gradle / Ivy

package io.github.dataunitylab.fuzzysets

import scala.collection.immutable.HashMap

object FuzzySet {
  def apply[T](element: (T, Float)): FuzzySet[T] = {
    FuzzySet(List(element).toMap)
  }
}

final case class FuzzySet[T](
    val elements: Map[T, Float] = HashMap.empty[T, Float]
) {
  def +(other: FuzzySet[T]): FuzzySet[T] = {
    FuzzySet((elements.keySet ++ other.elements.keySet).map { key =>
      key -> elements
        .getOrElse(key, 0.0f)
        .max(other.elements.getOrElse(key, 0.0f))
    }.toMap)
  }

  def &(other: FuzzySet[T]): FuzzySet[T] = {
    FuzzySet(
      (elements.keySet ++ other.elements.keySet)
        .map { key =>
          key -> elements
            .getOrElse(key, 0.0f)
            .min(other.elements.getOrElse(key, 0.0f))
        }
        .filter(_._2 != 0.0f)
        .toMap
    )
  }

  def unary_! : FuzzySet[T] = {
    FuzzySet(
      elements
        .map { case (key, value) => key -> (1 - value) }
        .filter(_._2 != 0.0f)
    )
  }

  def contains(element: T): Float = elements.getOrElse(element, 0.0f)

  def size: Int = elements.size

  def add(element: T, degree: Float): FuzzySet[T] = {
    FuzzySet(
      elements + (element -> degree.max(elements.getOrElse(element, 0.0f)))
    )
  }

  def remove(element: T, degree: Float): FuzzySet[T] = {
    FuzzySet(
      (elements + (element -> degree.min(elements.getOrElse(element, 0.0f))))
        .filter(_._2 != 0.0f)
    )
  }

  def similarity(other: FuzzySet[T]): Float = {
    val allKeys = elements.keySet ++ other.elements.keySet
    allKeys.toSeq.map { key =>
      val u = elements.getOrElse(key, 0.0f)
      val v = other.elements.getOrElse(key, 0.0f)
      if (u == 0.0f && v == 0.0f) {
        1
      } else {
        (u * v) / (u * u + v * v - u * v)
      }
    }.sum / allKeys.size
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy