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

evodef.SearchSpace.kt Maven / Gradle / Ivy

There is a newer version: 0.3.0
Show newest version
package evodef

import java.io.FileReader
import java.lang.AssertionError
import kotlin.reflect.KClass

/**
 * Created by sml on 16/08/2016.
 *
 * This models a search space where there is a fixed number of dimensions
 * but each dimension may have a different cardinality (i.e. a different number of possible values)
 *
 */
interface SearchSpace {
    // number of dimensions
    fun nDims(): Int

    // number of possible values in the ith dimension
    fun nValues(i: Int): Int

    fun name(i: Int): String

    fun value(d: Int, i: Int): Any {
        return 0.00
    }

    fun sampleAt(indices: IntArray): DoubleArray {
        return doubleArrayOf(0.0)
    }

    fun valueAt(indices: IntArray): DoubleArray {
        return doubleArrayOf(0.0)
    }
}

private fun setupSearchDimensions(fileName: String): List {
    val allDimensions = if (fileName != "") FileReader(fileName).readLines() else emptyList()
    return allDimensions.filter { it.contains(",") }  // this filters out any dimension with only one entry
}

abstract class AgentSearchSpace(val searchDimensions: List, val types: Map>) : SearchSpace {
    constructor(fileName: String, types: Map>) : this(setupSearchDimensions(fileName), types)

    //  val searchDimensions: List = setupSearchDimensions(fileName)

    val searchKeys: List = searchDimensions.map { it.split("=").first() }
    val searchTypes: List> = searchKeys.map {
        types[it] ?: throw AssertionError("Unknown search variable $it")
    }
    val searchValues: List> = searchDimensions.zip(searchTypes)
        .map { (allV, cl) ->
            allV.split("=")[1]      // get the stuff after the colon, which should be values to be searched
                .split(",")
                .map(String::trim).map {str ->
                    when (cl) {
                        Int::class, Int::class.javaObjectType, Int::class.javaPrimitiveType -> str.toInt()
                        Double::class, Double::class.javaObjectType, Double::class.javaPrimitiveType -> str.toDouble()
                        Boolean::class.java, Boolean::class.javaObjectType, Boolean::class.javaPrimitiveType -> str.toBoolean()
                        String::class.java, String::class.javaObjectType -> str
                        else -> if (cl.isEnum) {
                            cl.enumConstants.find { it.toString() == str } ?: throw AssertionError("Enum not found : " + str + " in " + cl.enumConstants.joinToString())
                        } else
                            throw AssertionError("Currently unsupported class $cl.")
                    }
                }
        }

    fun convertSettings(settings: IntArray): DoubleArray {
        return settings.zip(searchValues).map { (i, values) ->
            val v = values[i]
            when (v) {
                is Int -> v.toDouble()
                is Double -> values[i]
                is Boolean -> if (v) 1.0 else 0.0
                is String -> i.toDouble() // if a String, then we return the index of this
                else -> settings[i].toDouble()      // if not numeric, default to the category
            } as Double
        }.toDoubleArray()
    }

    fun settingsToMap(settings: DoubleArray): Map {
        return settings.withIndex().map { (i, v) ->
            searchKeys[i] to when (searchTypes[i]) {
                Int::class, Int::class.javaObjectType, Int::class.javaPrimitiveType -> (v + 0.5).toInt()
                Double::class, Double::class.javaObjectType, Double::class.javaPrimitiveType -> v
                Boolean::class.java, Boolean::class.javaObjectType, Boolean::class.javaPrimitiveType -> v > 0.5
                else ->  searchValues[i][(v + 0.5).toInt()]
            }
        }.toMap()
    }

    abstract fun getAgent(settings: IntArray): T
    override fun nValues(i: Int) = searchValues[i].size
    override fun nDims() = searchValues.size
    override fun name(i: Int) = searchKeys[i]
    override fun value(d: Int, i: Int) = searchValues[d][i]
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy