helisa
helisa copied to clipboard
java.lang.IllegalStateException: Can't convert this genotype: [[Predictor()]]
I hope I can get some help here, because I can't find any related issues by googling.
I have a case class that consists of 30 fields. All these field types are IntegerGene-s. The class doesn't extend any chromosome type.
case class Predictor() {
var f1: IntegerGene = IntegerGene.of(3, 50)
var f2: IntegerGene = IntegerGene.of(0, 1)
var f3: IntegerGene = IntegerGene.of(10, 200)
//..... so on
}
I have a case class that represents it's performance called PredictorResult
case class PredictorResult() {
var side: String = ""
var open: Double = 0
var close: Double = 0
var units: Int = 0
var high: Double = 0
var low: Double = 0
}
I'm trying to use the Helisa framework like below, but when trying to get the best phenotype, I get the error I provided to you.
def generatePredictor(): Predictor = new Predictor()
def validatePredictor(predictor: Predictor): Boolean = {
PredictorValidator.validate(predictor)
}
val genotype = () => genotypes.uniform(chromosomes.any(() => generatePredictor(), validatePredictor))
private val evolver = Evolver(fitness, genotype)
.populationSize(15)
.selector(new RouletteWheelSelector())
.geneticOperators(new UniformCrossover(), new SwapMutator(0.3))
.build()
val bestPhenotype = evolver.streamScalaStdLib().head.bestPhenotype
def fitness(predictor:Predictor) => {
val predictorResult: PredictorResult = Rules.applyRulesOnPredictor(
predictor = predictor,
economyElements = economyElements,
examinedPeriod = examinedPeriod,
enteringPrice = enteringPrice
)
(predictorResult.high - predictorResult.low) / predictorResult.high
}
What am I doing wrong?
I had to create a case class Guess(...) in who's constructor I have put all of my Genes as int fields.`Then the evolver started calling the fitness function.
@milosrs : Sorry for the late reply.
First of all, it appears that some of the example is in pseudo-code or erroneously truncated code. This makes it difficult to reproduce the issue, since it's likely that what the code the maintainer ends up with might not mirror your exact problem. I appreciate that a working, compiling (or not compiling in the expected way :slightly_smiling_face: ) example is more work for the reporter, but in the end it helps to solve the issue with less communication overhead.
The second issue is that those case classes... aren't really case classes. They're just classes with the case qualifier appended, but internally containing only mutable fields, not constructor-defined fields. Really, the case qualifier here does more harm than good, as it generates totally incorrect hashCode and equals.
In general, the problems are:
- the fitness function should be defined on the phenotype, i.e.
PredictorResult, and notPredictor. PredictorResultshould be an actual case class, i.e.case class PredictorResult(side: String = "", open: Double = 0,...). The tools that helisa uses for conversion rely on the properties of case classes to work correctly.- BTW, shapeless is used pretty much by almost everything for auto-derivation in the Scala world, so I strongly recommend to read up on the hows and whys of case classes. Will save you a lot of pain in the long run :).
- the genotype
Predictorand phenotypePredictorResultshould also have the same number, sequence, and type of fields. Sorry the message does not specify that in detail, this is still somewhat of a WIP. If you need more fields outside of your GA run, you can convert to another class manually, or via e.g. chimney. - you have a different structure for you genotype and phenotype. Your phenotype is an object with n fields. Your genotype is an object that contains and object with n fields. I'm not sure how you got this working actually, so would be interested in seeing that :slightly_smiling_face: .
Again, sorry for the late reply, and hope it helps.