import kotlinx.coroutines.* import approach.domain.KromaiaFormat import approach.encoding.Mapper import approach.encoding.XMLEncodeHelper import approach.simulation.EAlgorithm import util.IO fun main(args: Array): Unit = runBlocking { println("EMoSim - Evolutionary Model Simulation") println("Program arguments: ${if (args.isNotEmpty()) args.joinToString() else "n/a"}\n") println("Please wait, the simulations are running...\n") val names = arrayOf( "Argos", "DaimonTrial", "DaimonZeta", "Orion", "Teuthus", "Vermis" ) val bugs = arrayOf( "BAD_LINK_INDEXES", "HULL_MOVEMENT_BLOCKED", "HULL_NOT_LINKED", "WEAK_POINT_HIDDEN", "WEAK_POINT_OVERLAPPED" ) launchSimulations(names, bugs) } suspend fun launchSimulations( names: Array, bugs: Array, numberOfExecutions: Int = 30 ): Unit = coroutineScope { val confusionMatricesPerBug = mutableMapOf>>>() val confusionMatrices = mutableListOf>>() names.map { model -> async(Dispatchers.IO) { val config = IO.getConfiguration("xmlb/$model.cfg") val models = Mapper.mapFromConfigToModels(config) val encodings = XMLEncodeHelper.encode(models, KromaiaFormat::class) encodings.forEach { bugType -> val confusionMatrix = mutableListOf>() for (i in 0 until numberOfExecutions) { val oracle = IO.getConfiguration( "${bugType.name.substring(0, bugType.name.lastIndexOf('_'))}_oracle.txt" ) val simulation = EAlgorithm(encoding = bugType, name = "B_$model", oracle = oracle.first(), randomSearch = false) .setBounds(maxPopulationSize = 100) .setTimeLimit(0, 0, 10) .runSimulation() confusionMatrix.add(simulation.confusionMatrixRow) } confusionMatricesPerBug.getOrPut(bugs.find { bugType.name.contains(it) }!!) { mutableListOf() } += confusionMatrix confusionMatrices.add(confusionMatrix) IO.writeToFile( "out/${bugType.name.substring(0, bugType.name.length - 4)}.csv", arrayOf("TP;FP;FN;TN") + confusionMatrix.map { it.joinToString(separator = ";") }.toTypedArray() ) } } }.awaitAll() /** * Calculate confusion matrices per bug type. */ for (bug in bugs) { val meanConfusionMatrix = mutableListOf("TP;FP;FN;TN") for (confusionMatrix in confusionMatricesPerBug[bug]!!) { var meanTP = 0.0 var meanFP = 0.0 var meanFN = 0.0 var meanTN = 0.0 for (i in 0 until numberOfExecutions) { meanTP += confusionMatrix[i][0].toDouble() meanFP += confusionMatrix[i][1].toDouble() meanFN += confusionMatrix[i][2].toDouble() meanTN += confusionMatrix[i][3].toDouble() } meanTP /= numberOfExecutions meanFP /= numberOfExecutions meanFN /= numberOfExecutions meanTN /= numberOfExecutions meanConfusionMatrix.add("$meanTP;$meanFP;$meanFN;$meanTN") } IO.writeToFile("out/xmlb/$bug.csv", meanConfusionMatrix.toTypedArray()) } /** * Calculate average global confusion matrix. */ val meanConfusionMatrix = mutableListOf("TP;FP;FN;TN") for (confusionMatrix in confusionMatrices) { var meanTP = 0.0 var meanFP = 0.0 var meanFN = 0.0 var meanTN = 0.0 for (i in 0 until numberOfExecutions) { meanTP += confusionMatrix[i][0].toDouble() meanFP += confusionMatrix[i][1].toDouble() meanFN += confusionMatrix[i][2].toDouble() meanTN += confusionMatrix[i][3].toDouble() } meanTP /= numberOfExecutions meanFP /= numberOfExecutions meanFN /= numberOfExecutions meanTN /= numberOfExecutions meanConfusionMatrix.add("$meanTP;$meanFP;$meanFN;$meanTN") } IO.writeToFile("out/emosimdata.csv", meanConfusionMatrix.toTypedArray()) }