Ich arbeite an einem Framework für ein EA (Evolutionary Alg) Projekt in Scala. Darin habe ich einen Trait, der allgemeinen EA-Code implementiert und problem-spezifischen Code wie Genotyp-Konvertierung und Fitness-Tests an Klassen überlässt, die diesen Trait implementieren. Allerdings möchte ich den Trait nicht vollständig implementieren, bevor er tatsächlich ausgeführt wird, um verschiedene Protokolle/Strategien für die Populationsauswahl zu testen. Daraus ergibt sich der Code
trait EAProblem{
// common code ...
def fitness(ind:Individual):Double
def selectionStrategy(p: Population): List[(Individual, Double)]
def nextGeneration(p: Population): Population
}
/* Silly test problem */
abstract class OneMax(logPath: String) extends EAProblem {
def phenotype(ind:Individual) = {
ind.genotype
}
def fitness(ind: Individual): Double = {
ind.genotype.size.toFloat / ind.genotype.capacity
}
}
Zur Laufzeit wird das Protokoll/die Strategie gewählt:
object EASelectionStrategyProtocolDemo {
def main(args: Array[String]) {
val problem_impl = List[EAProblem](
// Full replacement
new OneMax("sigma_strat_full-rep_prot_onemax.log.dat") {
def selectionStrategy(p: Population): List[(Individual, Double)] =
SelectionStrategies.sigmaScalingMatingSelection(p)
def nextGeneration(p: Population): Population = SelectionProtocols.fullReplacement(p)
},
new OneMax("boltz_strat_full-rep_prot_onemax.log.dat") {
def selectionStrategy(p: Population): List[(Individual, Double)] =
SelectionStrategies.boltzmannSelection(p)
def nextGeneration(p: Population): Population = SelectionProtocols.fullReplacement(p)
})
for(problem <- problem_impl)
new Simulator(problem)
}
Die SelectionStrategies/SelectionProtocols-Objekte enthalten Klammern mit Verweisen auf anderen Code in EAProblem.
Was ich jetzt möchte, ist eine Möglichkeit, andere abstrakte Klassen wie OneMax (ich habe viele von ihnen) mit Reflexion (oder einen anderen Mechanismus) zu instanziieren. Pseudocode:
val listOfClassNames = List("OneMax", "classA", "classB", ...)
for(className <- listOfClassNames){
class_sigma = Class.forname(className)
/*
Implement class_class with this code and instantiate it
def selectionStrategy(p: Population): List[(Individual, Double)] =
SelectionStrategies.sigmaScalingMatingSelection(p)
def nextGeneration(p: Population): Population = SelectionProtocols.fullReplacement(p)
*/
class_boltz = Class.forname(className)
/*
Implement class_boltz with this code and instantiate it
def selectionStrategy(p: Population): List[(Individual, Double)] =
SelectionStrategies.boltzmannSelection(p)
def nextGeneration(p: Population): Population = SelectionProtocols.fullReplacement(p)
*/
}