2010-02-01 5 views
2

저는 스칼라에서 EA (evolutionary alg) 프로젝트를위한 프레임 워크를 연구 중입니다. 이것에는 공통된 EA 코드를 구현하고이 형질을 구현하는 클래스에 유전자형 변환 및 체력 테스트와 같은 문제가되는 코드를 남기는 특성이 있습니다. 그러나 다른 인구 선택 프로토콜/전략을 테스트하기 때문에 실제로 실행되기 전에이 특성을 완전히 구현하기를 원하지 않습니다. 이 프로토콜/전략은 선택이 끝난되는 런타임 코드스칼라에서 리플렉션을 통해 추상 클래스 구현/인스턴스화

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 
    } 
} 

을 제공합니다

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) 
} 

SelectionStrategies/SelectionProtocols 객체는 EAProblem에서 다른 코드에 대한 참조 clusures이 포함되어 있습니다.

내가 원했던 것은 반사 (또는 다른 메커니즘)를 사용하여 OneMax와 같은 다른 추상 클래스를 인스턴스화하는 몇 가지 방법입니다. 의사 코드 :

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) 
    */ 
} 

답변

1

추상화 방법을 정의하면서 동시에 리플렉션으로 인스턴스화 할 수 있는지 여부는 알 수 없습니다. 또는, 적어도, 쉽게.

왜 이러한 방법을 기능으로 사용하지 않습니까? 물론

private var _selectionStrategy: Option[Population => List[(Individual, Double)]] = None 
def selectionStrategy(p: Population) = _selectionStrategy.getOrElse(error("Uninitialized selection strategy!"))(p) 
def setSelectionStrategy(f: Population => List[(Individual, Double)]) = if (_selectionStrategy.isEmpty) 
    _selectionStrategy = f 
else 
    error("Selection strategy already initialized!") 

// Same thing for nextGeneration 

, OneMax 다음 추상적하지 않을 것이다 : 나는 그것에 대해 갈 것이라고하는 방법은 다음과 같이한다. 실제로, 그것은 일종의 요지입니다. 그런 다음 리플렉션을 사용하여 비교적 똑 바른 OneMax의 새 인스턴스를 만들고 setSelectionStrategysetNextGeneration을 사용하여 함수를 설정합니다.

0

정말 이런 식으로 리플렉션 (런타임 코드 컴파일 포함)을 사용하고 싶다면 파이썬 같은 언어를 사용하는 것이 더 나을 것이라고 생각합니다. 그러나 저는 여러분이 정말로 이러한 방식으로 반사를 사용하고 싶지 않다고 생각합니다.

나는 최선의 방법은 특성보다는 체력 측정을 수행하는 루틴을 포함하는 두 번째 클래스를 갖는 것이라고 생각한다. 예를 들어,

abstract class Selector { 
    def fitness(ind: Individual): Double 
    def name: String 
} 
class Throughput extends Selector { 
    def fitness(ind: Individual) = ind.fractionCorrect/ind.computeTime 
    def name = "Throughput" 
} 

하면 다음

val selectors = List(new Throughput, new ...) 
val userInputMap = List.map(t => (t.name , t)).toMap 

수 및 이름으로 올바른 선택을 찾아보십시오.

그런 다음 OneMax (및 다른 사람들)가 selector를 생성자 인수로 사용하여 userInputMap을 통해 문자열에서 제공 할 수 있습니다.

1
  1. 당신이 추상 클래스를

체력을 필요로하지 않는 추상 클래스를

  • 을 인스턴스화 할 수 없습니다, selectionStrategy, 차세대 - 모든 "독립적 인"변수입니다. 따라서 하나의 인터페이스에서 이들을 묶어서 문제의 본성에 맞서게됩니다.

    type Fitness = Individual => Double 
    type SelectionStrategy = Population = > List[(Individual, Double)] 
    type NextGeneration = Population => Population 
    
    case class EAProblem(
        fitness: Fitness, 
        selectionStrategy: SelectionStrategy, 
        nextGeneration: NextGeneration) { /* common code */ } 
    
    val fitnesses = List(OneMax, classA, classB, ...) 
    val strategies = List(
        SelectionStrategies.sigmaScalingMatingSelection, 
        SelectionStrategies.boltzmannSelection) 
    
    fitnesses.map (fitness => 
        strategies.map (strategy => 
        EAProblem(fitness, strategy, SelectionProtocols.fullReplacement))) 
    

    편집 : CGLIB와 ... 당신은 추상 클래스를 인스턴스화 할 수 또는

    이 시도
  • 관련 문제