All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
ntbea.NTupleSystemExp.kt Maven / Gradle / Ivy
package ntbea
import evodef.SearchSpace
import utilities.StatSummary
import kotlin.math.*
class NTupleSystemExp(override var searchSpace: SearchSpace, val halfN: Int, val minWeightExplore: Double = 0.5,
val weightFunction: (Int) -> Double = { visits: Int -> 1.0 - exp(-(visits.toDouble()) / halfN) },
val weightExplore: Boolean = false, val exploreWithSqrt: Boolean = false) : NTupleSystem(searchSpace) {
companion object {
val emptyStats = StatSummary()
val meanFunction = { tuple: NTuple, data: IntArray ->
tuple.getStats(data)?.mean() ?: Double.NaN
}
}
override fun getMeanEstimate(x: IntArray): Double {
val retValue = getWeighting(x, IntArray(x.size) { it }, 0.0, meanFunction, weightFunction)
// println("${x.joinToString()} has mean estimate $retValue")
return retValue
}
override fun getExplorationEstimate(x: IntArray): Double {
if (!weightExplore) {
return super.getExplorationEstimate(x)
}
return getWeighting(x, IntArray(x.size) { it }, minWeightExplore, { tuple, data ->
val ss = tuple.getStats(data) ?: emptyStats
if (exploreWithSqrt)
sqrt(sqrt(1.0 + tuple.nSamples()) / (epsilon + ss.n()))
else
sqrt(ln(1.0 + tuple.nSamples()) / (epsilon + ss.n()))
}, weightFunction)
}
override fun getExplorationVector(x: IntArray): DoubleArray {
// idea is simple: we just provide a summary over all
// the samples, comparing each to the maximum in that N-Tuple
// not used with EXP_FULL
val vec = tuples.map { tuple ->
val ss = tuple.getStats(x) ?: emptyStats
if (exploreWithSqrt)
sqrt(sqrt(1.0 + tuple.nSamples()) / (epsilon + ss.n()))
else
sqrt(ln(1.0 + tuple.nSamples()) / (epsilon + ss.n()))
}
return vec.toDoubleArray()
}
fun getWeighting(x: IntArray, indices: IntArray, minWeight: Double,
valueFunction: (NTuple, IntArray) -> Double,
weightFunction: (Int) -> Double): Double {
// valueFunction returns the simple value of the NTuple
// weightFunction takes the number of visits to the NTuple, and returns a number in [0, 1] for its weighting
if (indices.size < minTupleSize) return 0.0
val allSubTuples = tuples.filter { it.tuple.all(indices::contains) }
if (allSubTuples.isEmpty())
throw AssertionError("WTF")
val largestSize = allSubTuples.map(NTuple::tuple).map { it.size }.maxOrNull()
val allTuplesAtLevel = allSubTuples.filter { it.tuple.size == largestSize }
val tupleMeans = allTuplesAtLevel.map { t ->
val stats = t.getStats(x) ?: emptyStats
var baseResult = valueFunction(t, x)
val weight = when {
indices.size == minTupleSize -> 1.0
baseResult.isNaN() -> {
baseResult = 0.0;
0.0
}
else -> max(minWeight, weightFunction(stats.n()))
}
weight * baseResult + (1.0 - weight) * t.tuple.map { excludedIndex ->
getWeighting(x, t.tuple.filterNot { it == excludedIndex }.toIntArray(), minWeight, valueFunction, weightFunction)
}.average()
}
return tupleMeans.filterNot(Double::isNaN).average()
}
// fun getExponentialWeighting(x: IntArray, indices: IntArray, minWeight: Double, f: (NTuple, IntArray) -> Double): Double {
// return getWeighting(x, indices, minWeight, f, { visits: Int -> 1.0 - exp(-(visits.toDouble()) / halfN) })
// }
}