Идея состоит в том, чтобы иметь структуру данных, к которой вы можете обращаться к ее элементам только случайным образом, но на основе вероятностного коэффициента, определенного пользователем для каждого элемента. Таким образом, если вероятность структуры, которая содержит 100 элементов для получения x
, равна 0,5, то теоретически, если мы попытаемся извлечь случайный элемент сто раз, то x
будет возвращено примерно в ~ 50 раз.
Я не смог найти готовое решение, которое бы это делало, так что я взял это на себя:
import kotlin.math.absoluteValue
/**
*@author mhashim6 on 13/10/2019
*/
class ProbabilitySet<T>(private val items: Array<out Pair<T, Float>>) {
private var probabilityIndices: List<Int>
private fun calcFutureSize(count: Int, probability: Float) =
((count / (1f - probability)) - count).toInt().absoluteValue
init {
probabilityIndices = items.withIndex().flatMap { (i, item) ->
item.act { (_, probability) ->
calcFutureSize(items.size, probability).minus(items.size).act { delta ->
Iterable { ConstIterator(delta, i) }
}
}
}
}
fun next(): T = items.random().first
}
class ConstIterator(private var size: Int, private val const: Int) : IntIterator() {
override fun nextInt(): Int {
size--
return const
}
override fun hasNext(): Boolean = size > 0
}
fun <E> probabilitySetOf(vararg items: Pair<E, Float>) = ProbabilitySet(items)
inline fun <T, R> T.act(action: (T) -> R) = action(this)
Я пытался сделать его изменчивым, но я столкнулся с множеством сложностей, касающихся времени и памяти,Так что пока он неизменен.
Это жизнеспособная реализация? Есть ли реализация для этой проблемы уже? Как сделать его изменчивым?