public interface FitnessFunction { int getArity(); //- long run(long[] genom); // . }
public class GeneticEngine{ public GeneticEngine(FitnessFunction fitnessFunction) {...} // public long[] run() {...} // private void generateFirstGeneration() {...} // private void selection(){...} // private void crossing() {...} // private void mutation() {...} // }
public enum SelectionType { TOURNEY, ROULETTE_WHEEL } public enum CrossingType { ONE_POINT_RECOMBINATION, TWO_POINT_RECOMBINATION, ELEMENTWISE_RECOMBINATION, ONE_ELEMENT_EXCHANGE }
private int genomLength; // private long generationCount; //- private int individualCount; //- (,) private SelectionType selectionType; // private CrossingType crossingType; // private boolean useMutation; // private double mutationPercent; //
private void selection(){ switch (selectionType) { case ROULETTE_WHEEL:{ float[] wheel = new float[this.individualCount]; wheel[0] = // 1- for (int i=1;i<this.individualCount;i++){ wheel[i] = wheel[i-1] + // i- } float all = wheel[this.individualCount-1]; for (int i=0;i<this.individualCount;i++){ float index = Math.abs(this.random.nextFloat())*all; int l = 0; int r = individualCount-1; int c = 0; while (l < r){ c = (l+r) >> 1; if (index <= while[c]){ r = c; }else{ l = c + 1; } } this.genomListOffsprings[i] = this.genomListParents[l].clone(); } break; } case TOURNEY:{ for (int i=0;i<this.individualCount;i++){ int index1 = random.nextInt(individualCount); int index2 = random.nextInt(individualCount); long fr1 = // index1 long fr2 = // index2 this.genomListOffsprings[i] = fr1 > fr2 ? this.genomListParents[index1].clone() : this.genomListParents[index2].clone(); } break; } }
public static final int OCTET_LENGTH = 64; // - public static final int MASK_FOR_MOD = OCTET_LENGTH - 1; // "x%64" "x & MASK_FOR_MOD" public static final int SHIFT_FOR_DIVISION; // "x/64" - "x >> SHIFT_FOR_DIVISION"
private void cross(long[] genom1, long[] genom2) { switch (crossingType) { ... case ELEMENTWISE_RECOMBINATION:{ for (int outerOffset = 0; outerOffset < this.sizeOfArray; outerOffset++) { long mask = this.random.nextLong(); // , (1- , 0-) long swapMask = (genom1[outerOffset] ^ genom2[outerOffset]) & mask; genom1[outerOffset] ^= swapMask; genom2[outerOffset] ^= swapMask; } break; } }
private void mutation() { for (long[] genom : this.genomListOffsprings) { if (random.nextDouble() <= mutationPercent) { mutate(genom); } } } private void mutate(long[] genom) { int index = this.random.nextInt(this.genomLength); int outerOffset = index >> SHIFT_FOR_DIVISION; int innerOffset = (index & MASK_FOR_MOD); long mask = 1L << innerOffset; genom[outerOffset] ^= mask; }
public long[] run() { generateFirstGeneration(); while (currentGeneration < generationCount) { selection(); this.crossing(); if (useMutation) { mutation(); } currentGeneration++; } return . }
MyFitnessFunction ff = new MyFitnessFunction(); GeneticEngine ge = new GeneticEngine(ff); ge.setIndividualCount(1000); // - ge.setGenerationCount(10000); // - ge.setSelectionType(SelectionType.TOURNEY); // ge.setCrossingType(CrossingType.ELEMENTWISE_RECOMBINATION); // ge.setUseMutation(true); // ge.setMutationPercent(0.02d); // long[] better = ge.run(); //
IndividualCount = 100; GenerationCount = 10000; SelectionType = SelectionType; CrossingType = ELEMENTWISE_RECOMBINATION; UseMutation = true; MutationPercent = 0.02d;
IndividualCount = 1000; GenerationCount = 10000;
IndividualCount = 10000; GenerationCount = 100000;
Source: https://habr.com/ru/post/138091/
All Articles