Jenetics:正确使用编解码器与列 Genotype
Jenetics: proper usage of codec with column Genotype
目前我正在研究 Jenetics (link to jenetics) 实现以优化粒子加速器束线。我的健身函数调用加速器检测器,定义如下:
private double fitness(final DoubleChromosome chromosomes) {
// private double fitness(final Genotype<DoubleGene> chromosomes) {
// Convert genes to a format the device scanner can understand
// we will inject a 1:n Set<List<Double>>
final Set<List<Double>> trimValues = new HashSet<>();
final List<Double> valueList = new ArrayList<>();
for (final DoubleGene chromosome : chromosomes) {
valueList.add(Double.valueOf(chromosome.doubleValue()));
}
trimValues.add(valueList);
....
more code specific to application
}
Jenetics 的流引擎在特定方法中初始化:
public void initAlgorithm(final Object scanParameters) throws Exception {
if (scanParameters != null) {
/// See constructor of EvolvingImagesWorker
_geneticScanParameters = (GeneticScanParameters) scanParameters;
}
if (_geneticScanParameters.getTrimParameterSets() != null) {
final int chromosomeCount = _geneticScanParameters.getTrimParameterSets().size();
if (chromosomeCount > 0) {
ISeq<DoubleChromosome> chromosomeSet = ISeq.empty();
// create an ISeq of genes
for (final TrimParameterValueSet valueSet : _geneticScanParameters.getTrimParameterSets()) {
final double minValue = valueSet.getMinValue();
final double maxValue = valueSet.getMaxValue();
final double initialValue = (maxValue + minValue) / 2;
final DoubleGene doubleGene = DoubleGene.of(initialValue, minValue, maxValue);
final DoubleChromosome doubleChromosome = DoubleChromosome.of(doubleGene.newInstance());
chromosomeSet = chromosomeSet.append(doubleChromosome.newInstance());
}
Codec<DoubleChromosome, DoubleGene> codec = null;
try {
final Genotype<DoubleGene> genotype = Genotype.of(chromosomeSet);
codec = Codec.of(genotype.newInstance(), //
gt -> (DoubleChromosome) gt.getChromosome());
} catch (final IllegalArgumentException ex) {
MessageLogger.logError(getClass(), Thread.currentThread(), ex);
throw ex;
}
_scannerEngine = Engine.builder(this::fitness, codec) //
.executor(Executors.newSingleThreadExecutor()) // without this command, engine will be executed
// in
// parallel threads
.populationSize(_geneticScanParameters.getPopulationSize()) //
.optimize(_geneticScanParameters.getOptimizationStrategy()) //
.offspringFraction(_geneticScanParameters.getOffspringSize()) //
.survivorsSelector(new RouletteWheelSelector<>()) //
.offspringSelector(new TournamentSelector<>(_geneticScanParameters.getTournamentSizeLimit())) //
.alterers( //
new Mutator<>(_geneticScanParameters.getMutator()), //
new MeanAlterer<>(_geneticScanParameters.getMeanAlterer()) //
) //
.build();
} else {
throw new IllegalStateException(ERROR_INITSCANNER_NO_SETTING_DEVICE);
}
}
}
其中:
private Engine<DoubleGene, Double> _scannerEngine = null;
我想做的是调用适应度函数,这样我就可以在适应度函数中使用基因型来访问基因值(我发送到加速器的设置)。
我已经尝试如下定义 fitness() :
private double fitness(final Genotype<DoubleChromosome> genotype) {
...
}
但是这个调用会导致编译错误。
我看过你的代码,我想你想做这样的事情:
class Foo {
// Your parameter class.
class TrimParameterSet {
double min, max;
}
static double fitness(final double[] values) {
// Your fitness function.
return 0;
}
public static void main(final String[] args) {
final List<TrimParameterSet> valueSets = ...;
final DoubleRange[] ranges = valueSets.stream()
.map(p -> DoubleRange.of(p.min, p.max))
.toArray(DoubleRange[]::new);
final Codec<double[], DoubleGene> codec = Codecs.ofVector(ranges);
final Engine<DoubleGene, Double> engine = Engine.builder(Foo::fitness, codec)
.build();
// ...
}
}
您的适应度函数的 double[]
数组具有不同的范围,根据您 TrimParameterSet
class 中定义的范围。如果你想定义一个直接适应度函数,你必须定义一个基因型作为参数类型。
double fitness(Genotype<DoubleGene> gt) {...}
由于评论功能不允许我完成记录我的最终实现,这里是实际代码:
ISeq<DoubleChromosome> chromosomeSet = ISeq.empty();
// create an ISeq of genes
for (loop criteria) {
final DoubleGene doubleGene = DoubleGene.of(initialValue, minValue, maxValue);
final DoubleChromosome doubleChromosome = DoubleChromosome.of(doubleGene.newInstance());
chromosomeSet = chromosomeSet.append(doubleChromosome.newInstance());
}
_genotype = Genotype.of(chromosomeSet);
_scannerEngine = Engine.builder(this::fitness, _genotype)
... // engine settings
.build();
double fitness(Genotype<DoubleGene> gt) {...}
目前我正在研究 Jenetics (link to jenetics) 实现以优化粒子加速器束线。我的健身函数调用加速器检测器,定义如下:
private double fitness(final DoubleChromosome chromosomes) {
// private double fitness(final Genotype<DoubleGene> chromosomes) {
// Convert genes to a format the device scanner can understand
// we will inject a 1:n Set<List<Double>>
final Set<List<Double>> trimValues = new HashSet<>();
final List<Double> valueList = new ArrayList<>();
for (final DoubleGene chromosome : chromosomes) {
valueList.add(Double.valueOf(chromosome.doubleValue()));
}
trimValues.add(valueList);
....
more code specific to application
}
Jenetics 的流引擎在特定方法中初始化:
public void initAlgorithm(final Object scanParameters) throws Exception {
if (scanParameters != null) {
/// See constructor of EvolvingImagesWorker
_geneticScanParameters = (GeneticScanParameters) scanParameters;
}
if (_geneticScanParameters.getTrimParameterSets() != null) {
final int chromosomeCount = _geneticScanParameters.getTrimParameterSets().size();
if (chromosomeCount > 0) {
ISeq<DoubleChromosome> chromosomeSet = ISeq.empty();
// create an ISeq of genes
for (final TrimParameterValueSet valueSet : _geneticScanParameters.getTrimParameterSets()) {
final double minValue = valueSet.getMinValue();
final double maxValue = valueSet.getMaxValue();
final double initialValue = (maxValue + minValue) / 2;
final DoubleGene doubleGene = DoubleGene.of(initialValue, minValue, maxValue);
final DoubleChromosome doubleChromosome = DoubleChromosome.of(doubleGene.newInstance());
chromosomeSet = chromosomeSet.append(doubleChromosome.newInstance());
}
Codec<DoubleChromosome, DoubleGene> codec = null;
try {
final Genotype<DoubleGene> genotype = Genotype.of(chromosomeSet);
codec = Codec.of(genotype.newInstance(), //
gt -> (DoubleChromosome) gt.getChromosome());
} catch (final IllegalArgumentException ex) {
MessageLogger.logError(getClass(), Thread.currentThread(), ex);
throw ex;
}
_scannerEngine = Engine.builder(this::fitness, codec) //
.executor(Executors.newSingleThreadExecutor()) // without this command, engine will be executed
// in
// parallel threads
.populationSize(_geneticScanParameters.getPopulationSize()) //
.optimize(_geneticScanParameters.getOptimizationStrategy()) //
.offspringFraction(_geneticScanParameters.getOffspringSize()) //
.survivorsSelector(new RouletteWheelSelector<>()) //
.offspringSelector(new TournamentSelector<>(_geneticScanParameters.getTournamentSizeLimit())) //
.alterers( //
new Mutator<>(_geneticScanParameters.getMutator()), //
new MeanAlterer<>(_geneticScanParameters.getMeanAlterer()) //
) //
.build();
} else {
throw new IllegalStateException(ERROR_INITSCANNER_NO_SETTING_DEVICE);
}
}
}
其中:
private Engine<DoubleGene, Double> _scannerEngine = null;
我想做的是调用适应度函数,这样我就可以在适应度函数中使用基因型来访问基因值(我发送到加速器的设置)。 我已经尝试如下定义 fitness() :
private double fitness(final Genotype<DoubleChromosome> genotype) {
...
}
但是这个调用会导致编译错误。
我看过你的代码,我想你想做这样的事情:
class Foo {
// Your parameter class.
class TrimParameterSet {
double min, max;
}
static double fitness(final double[] values) {
// Your fitness function.
return 0;
}
public static void main(final String[] args) {
final List<TrimParameterSet> valueSets = ...;
final DoubleRange[] ranges = valueSets.stream()
.map(p -> DoubleRange.of(p.min, p.max))
.toArray(DoubleRange[]::new);
final Codec<double[], DoubleGene> codec = Codecs.ofVector(ranges);
final Engine<DoubleGene, Double> engine = Engine.builder(Foo::fitness, codec)
.build();
// ...
}
}
您的适应度函数的 double[]
数组具有不同的范围,根据您 TrimParameterSet
class 中定义的范围。如果你想定义一个直接适应度函数,你必须定义一个基因型作为参数类型。
double fitness(Genotype<DoubleGene> gt) {...}
由于评论功能不允许我完成记录我的最终实现,这里是实际代码:
ISeq<DoubleChromosome> chromosomeSet = ISeq.empty();
// create an ISeq of genes
for (loop criteria) {
final DoubleGene doubleGene = DoubleGene.of(initialValue, minValue, maxValue);
final DoubleChromosome doubleChromosome = DoubleChromosome.of(doubleGene.newInstance());
chromosomeSet = chromosomeSet.append(doubleChromosome.newInstance());
}
_genotype = Genotype.of(chromosomeSet);
_scannerEngine = Engine.builder(this::fitness, _genotype)
... // engine settings
.build();
double fitness(Genotype<DoubleGene> gt) {...}