Especifica se o cromossomo inicial e randomizado ao se iniciar o algoritmo. Ao passar false, teremos um 'Canvas' inicialmente vazio. Passar true parece ajudar na velocidade de convergencia, mas nao estou certo disso. minAlpha, maxAlpha - O valor minimo e maximo do componente alpha da cor, respectivamente. O normal aqui seria especificar 0 e 255, mas podemos cortar um pouco o espaco de busca ao diminuir esse range. Valores entre 0 e 10 para minAlpha e entre 100 e 150 para maxAlpha parecem funcionar bem. A classe ficou um pouco grande, mas a ideia e bem simples: invocamos o metodo evolve em um laco infinito e decodificamos o cromossomo atual, que em seguida e desenhado na tela. Repare que implementamos a interface FitnessDelegate, onde novamente decodificamos o cromossomo em um vetor de poligonos, desenhamos esses poligonos em um buffer e fazemos uma comparacao pixel-a-pixel com a imagem alvo. Repare tambem que a imagem alvo e escaneada uma unica vez no metodo loadTarget, e seus componentes RGBA sao salvos em arrays separadas. Por fim, o metodo checkSnap cria uma imagem da tela e a salva no diretorio atual, caso o intervalo especificado em photo_interval_sec tenha passado. Segue a classe EvolveDraw:import java.awt.*;import java.awt.event.*;import java.awt.image.*;import com.sun.image.codec.jpeg.*;import javax.swing.*;import java.util.concurrent.*;import java.util.*;import java.io.*;public class EvolveDraw extends JPanel implements Runnable, FitnessDelegate{ //polygons protected final int VERTICES; protected final int N_POLY; //nao mude COLOR_COMP! protected final int COLOR_COMP = 4; protected final int MIN_ALPHA; protected final int MAX_ALPHA; protected PolygonColor[] polygons; protected int gen = 0; protected Color bgColor = Color.white; //algorithm params protected float MUTATION_RATE; protected BinaryIntChromosome best; protected boolean RANDOMIZE_START; //images protected final String TARGET_FILE; protected int[] offImagePixels; protected BufferedImage targetImage; protected BufferedImage offImage; protected int[] targetPixels; protected int[] redTarget; protected int[] greenTarget; protected int[] blueTarget; protected int[] alphaTarget; protected int w; protected int h; //save drawings protected final int PHOTO_INTERVAL_SEC; protected long lastPhotoTime = 0L; public EvolveDraw() { new Params(); TARGET_FILE = Params.TARGET_FILE; VERTICES = Params.VERTICES; N_POLY = Params.N_POLY; MUTATION_RATE = Params.MUTATION_RATE; PHOTO_INTERVAL_SEC = Params.PHOTO_INTERVAL_SEC; RANDOMIZE_START = Params.RANDOMIZE_START; MIN_ALPHA = Params.MIN_ALPHA; MAX_ALPHA = Params.MAX_ALPHA; this.setDoubleBuffered(true); this.setBackground(bgColor); this.loadTarget(); } private void loadTarget() { this.targetImage = ImageUtils.imageToBufferedImage(ImageUtils.loadJPG(TARGET_FILE)); this.w = targetImage.getWidth(); this.h = targetImage.getHeight(); this.setPreferredSize(new Dimension(w, h)); this.offImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); this.targetPixels = new int[w * h]; this.offImagePixels = new int[w * h]; this.targetImage.getRGB(0, 0, w, h, targetPixels, 0, w); this.redTarget = new int[w * h]; this.greenTarget = new int[w * h]; this.blueTarget = new int[w * h]; this.alphaTarget = new int[w * h]; for (int i = 0; i < this.targetPixels.length; i++) { int pixel = targetPixels[i]; int alpha = (pixel >> 24) & 0xff; int red = (pixel >> 16) & 0xff; int green = (pixel >> 8) & 0xff; int blue = (pixel) & 0xff; this.redTarget[i] = red; this.greenTarget[i] = green; this.blueTarget[i] = blue; this.alphaTarget[i] = alpha; } } public void run() { int[][] bounds = PolygonDecoder.getChromosomeBounds(w, h, VERTICES, N_POLY, COLOR_COMP, MIN_ALPHA, MAX_ALPHA); HillClimb evolution = new HillClimb(bounds[0], bounds[1], this, MUTATION_RATE, null, RANDOMIZE_START); do { CountDownLatch signal = new CountDownLatch(1); evolution.signal = signal; new Thread(evolution).start(); try { signal.await(); } catch(InterruptedException ex) { ex.printStackTrace(); } best