我试图了解进化和健身功能是如何工作的。我实现了我自己的背包问题,它试图从给定的集合中找到3件最有价值的物品。这是我自己的成本职能:
static int counter=1;
static double MyCostFunction(boolean[] chromosome, double[] data){
System.out.println("COST FUNCTION: "+counter++);
double sum = 0;
int count = 0;
for (int i =0; i<chromosome.length; i++){
if (chromosome[i]){
sum += data[i];
count ++;
}
}
return count<=3 ? sum : 0;
}我打印出来只是为了看看执行了多少次MyCostFunction。现在,我正在处理一小部分8项内容。下面是:
public static void main(String[] args) {
double[] data = {-15,-7, -1, -1,7,100,200,300};
Integer[] items = new Integer[data.length];
int i = 0;
for (double d : data){
items[i] = i;
i++;
}
ISeq<Integer> zbiorDlaGA = ISeq.of(items);
final ISProblem knapsack= new ISProblem(zbiorDlaGA,
chromosome -> ISProblem.MyCostFunction( chromosome, data)
);这是我使用的引擎:
final Engine<BitGene,Double> engine= Engine.builder(knapsack)
.executor( Runnable::run)
.populationSize(5)
.survivorsSelector(new TournamentSelector<>(3))
.offspringSelector(new RouletteWheelSelector<>())
.alterers(
new Mutator<>(1.0),
new SinglePointCrossover<>(0.0)
).build();我就是这样获得统计数据的:
final EvolutionStatistics<Double,?> statistics=EvolutionStatistics.ofNumber();
final Phenotype<BitGene,Double> best=engine.stream()
// .limit(bySteadyFitness(15))
.limit(5)
.peek(r-> System.out.println("########CURRENT GEN: "
+r.generation()+
": "+ r.totalGenerations()+
": "+r.bestPhenotype()+
" ALTERED: "+r.alterCount()+
" INVALID: "+r.invalidCount()+
" GENOTYPE: "+r.genotypes()))
.peek(statistics)
.collect(toBestPhenotype());
System.out.println(statistics);
System.out.println(best);关于您库中的一些行为,我不太理解:即使我将突变概率设置为1.0 (我认为应该改变每一点),它还是给了我这样的结果:
COST FUNCTION: 1
COST FUNCTION: 2
COST FUNCTION: 3
COST FUNCTION: 4
COST FUNCTION: 5
COST FUNCTION: 6
COST FUNCTION: 7
COST FUNCTION: 8
########CURRENT GEN: 1: 1: [01100000] -> 300.0 ALTERED: 24 INVALID: 0 GENOTYPE: [[10110100],[00011011],[01011101],[00111001],[01100000]]
COST FUNCTION: 9
COST FUNCTION: 10
COST FUNCTION: 11
########CURRENT GEN: 2: 2: [00011011] -> 0.0 ALTERED: 24 INVALID: 0 GENOTYPE: [[00011011],[01011101],[10100101],[01111010],[00001011]]
COST FUNCTION: 12
COST FUNCTION: 13
COST FUNCTION: 14
########CURRENT GEN: 3: 3: [10100101] -> 0.0 ALTERED: 24 INVALID: 0 GENOTYPE: [[10100101],[01011101],[01111011],[01010011],[10010101]]
COST FUNCTION: 15
COST FUNCTION: 16
COST FUNCTION: 17
########CURRENT GEN: 4: 4: [10000010] -> 293.0 ALTERED: 24 INVALID: 0 GENOTYPE: [[01011101],[01010011],[01111011],[10000010],[00001001]]
COST FUNCTION: 18
COST FUNCTION: 19
COST FUNCTION: 20
########CURRENT GEN: 5: 5: [10000010] -> 293.0 ALTERED: 24 INVALID: 0 GENOTYPE: [[10000010],[01011101],[01000100],[10111100],[10011001]]
+---------------------------------------------------------------------------+
| Time statistics |
+---------------------------------------------------------------------------+
| Selection: sum=0,003352000000 s; mean=0,000670400000 s |
| Altering: sum=0,010647600000 s; mean=0,002129520000 s |
| Fitness calculation: sum=0,011403300000 s; mean=0,002280660000 s |
| Overall execution: sum=0,033579600000 s; mean=0,006715920000 s |
+---------------------------------------------------------------------------+
| Evolution statistics |
+---------------------------------------------------------------------------+
| Generations: 5 |
| Altered: sum=120; mean=24,000000000 |
| Killed: sum=0; mean=0,000000000 |
| Invalids: sum=0; mean=0,000000000 |
+---------------------------------------------------------------------------+
| Population statistics |
+---------------------------------------------------------------------------+
| Age: max=4; mean=0,560000; var=1,090000 |
| Fitness: |
| min = -23,000000000000 |
| max = 300,000000000000 |
| mean = 41,840000000000 |
| var = 10763,306666666665 |
| std = 103,746357365773 |
+---------------------------------------------------------------------------+
[01100000] -> 300.0为什么它只计算三个人的健康?它是否在某种程度上缓存了已经为同一条染色体计算的值?
为什么在第一代计算8次?
被改变个体的数量总是3*8,这意味着在进化过程中只有3条染色体被修改。为什么?我认为这与TournamentSelector sampleSize有关,但它不会改变染色体的数目。
在变异概率为100%和交叉prob.=100%的情况下,染色体的每一个点都会发生变化,因此每代染色体只有2个版本,但不能做到这一点。为什么?它是随机选择位的值还是设置相反的值?
在人口/世代中,设置为true的位数是否必须是常数(或近似不变)?
我使用这些奇怪的值来表示交叉和变异概率,因为我之前想知道为什么它没有给出与populationSize*NumberOfGenerations相同的适合度计算的数量。所以我开始做实验。
发布于 2022-05-11 21:08:47
所描述的行为与预期的相同:)
以下事实导致观察到的结果:
在进化过程中,种群被划分为后代和survivors.
。
结果:
前五次健康评价的原因是由新鲜的、初始的群体5。certainty.
我想这解释了输出,不是吗?
控制最初设置的位数
如果要控制BitChromosome的初始位数,可以使用原始Codec来创建自己的变体。
public static <T> InvertibleCodec<ISeq<T>, BitGene>
ofSubSet(final ISeq<? extends T> basicSet, final double onesProbability) {
final InvertibleCodec<ISeq<T>, BitGene> codec = Codecs.ofSubSet(basicSet);
return InvertibleCodec.of(
Genotype.of(BitChromosome.of(basicSet.length(), onesProbability)),
codec.decoder(),
codec.encoder()
);
}https://stackoverflow.com/questions/72206412
复制相似问题