├── Circle.class ├── Genetic Algorithm.pdf ├── GeneticAlgorithm.class ├── GeneticAlgorithm.java ├── Genotype.class └── README.md /Circle.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amangoeliitb/Genetic-Algorithm/c0241b9574f55d5ea845cbb64f092f06606df3b2/Circle.class -------------------------------------------------------------------------------- /Genetic Algorithm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amangoeliitb/Genetic-Algorithm/c0241b9574f55d5ea845cbb64f092f06606df3b2/Genetic Algorithm.pdf -------------------------------------------------------------------------------- /GeneticAlgorithm.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amangoeliitb/Genetic-Algorithm/c0241b9574f55d5ea845cbb64f092f06606df3b2/GeneticAlgorithm.class -------------------------------------------------------------------------------- /GeneticAlgorithm.java: -------------------------------------------------------------------------------- 1 | import java.awt.image.BufferedImage; 2 | import java.awt.image.DataBufferByte; 3 | import java.io.*; 4 | import javax.imageio.ImageIO; 5 | import java.awt.Color; 6 | import java.util.*; 7 | 8 | class Circle { 9 | public int x, y; // the coordinates of the center of the circle 10 | public int radius; // the radius of the circle 11 | public int red, green, blue; // the RGB values of the color of the circle 12 | public int alpha; // the alpha value of the color 13 | public int time; // the time when this circle was added to the member to which it belongs 14 | 15 | public boolean isPointInside(int i, int j) { 16 | return (this.x - i) * (this.x - i) + (this.y - j) * (this.y - j) <= this.radius * this.radius; 17 | } 18 | 19 | public Circle() { 20 | 21 | } 22 | 23 | public Circle(Circle other) { 24 | this.x = other.x ; 25 | this.y = other.y ; 26 | this.red = other.red ; 27 | this.green = other.green ; 28 | this.blue = other.blue ; 29 | this.alpha = other.alpha ; 30 | this.time = other.time ; 31 | this.radius = other.radius; 32 | } 33 | } 34 | 35 | class Genotype { 36 | public Circle circles[] = new Circle[GeneticAlgorithm.circleCount]; // each member of population contains a list of circles 37 | public int count; // stores the number of circles in the present member of population 38 | public int bg_red, bg_green, bg_blue; // the RGB values of the background 39 | public int bg_alpha; // the alpha value of the background 40 | public double fitness; 41 | public double cfitness; 42 | public double rfitness; 43 | 44 | public Genotype() { 45 | for(int i = 0 ; i < circles.length ; i++) 46 | this.circles[i] = new Circle(); 47 | } 48 | 49 | public Genotype(Genotype other) { 50 | for(int i = 0 ; i < circles.length ; i++) 51 | this.circles[i] = new Circle(other.circles[i]); 52 | this.count = other.count ; 53 | this.bg_red = other.bg_red ; 54 | this.bg_green = other.bg_green ; 55 | this.bg_blue = other.bg_blue ; 56 | this.bg_alpha = other.bg_alpha ; 57 | this.fitness = other.fitness ; 58 | this.cfitness = other.cfitness ; 59 | this.rfitness = other.rfitness ; 60 | } 61 | 62 | public Color getColorOfPoint(int i, int j) { 63 | TreeMap treemap = new TreeMap (); 64 | for(int k = 0 ; k < circles.length ; ++k) { 65 | if(circles[k].isPointInside(i, j)) 66 | treemap.put(circles[k].time, circles[k]); 67 | } 68 | // Color color = new Color(bg_red, bg_green, bg_blue); 69 | 70 | Iterator it = treemap.entrySet().iterator(); 71 | // int entries = 0; 72 | // int sum_r = 0, sum_g = 0, sum_b=0; 73 | double color_red = bg_red, color_green = bg_green, color_blue = bg_blue, color_alpha = bg_alpha; 74 | while(it.hasNext()) { 75 | // entries ++; 76 | Map.Entry entry = (Map.Entry)it.next(); 77 | Circle c = (Circle)entry.getValue(); 78 | double t = (double)(c.alpha/255.0) ; 79 | // double new_bg_alpha = (double)(color.getAlpha()/255.0); 80 | double new_alpha=(double)(t + (1.0 - t) * color_alpha); 81 | // System.out.println("red = "+Float.toString((double)((t * c.red + (1.0 - t) * color.getRed()*new_bg_alpha )/new_alpha))); 82 | // int bg_red = color.getRed(); 83 | // int bg_green = color.getGreen(); 84 | // int bg_blue = color.getBlue(); 85 | // sum_r += c.red; 86 | // sum_g += c.green; 87 | // sum_b += c.blue; 88 | color_red = (t*c.red + (1.0-t)*color_red*color_alpha)/new_alpha; 89 | color_green = (t*c.green + (1.0-t)*color_green*color_alpha)/new_alpha; 90 | color_blue = (t*c.blue + (1.0-t)*color_blue*color_alpha)/new_alpha; 91 | color_alpha = new_alpha; 92 | // color = new Color((int)((t * c.red + (1.0 - t) *bg_red *new_bg_alpha )/new_alpha), (int)((t * c.green + (1.0 - t) * bg_green*new_bg_alpha)/new_alpha), (int)((t * c.blue + (1.0 - t) * bg_blue*new_bg_alpha)/new_alpha),(int)(new_alpha*255.0) ); 93 | }; 94 | Color color = new Color((int)color_red, (int)color_green, (int)color_blue, (int)(255*color_alpha) ); 95 | // if(entries !=0) 96 | // { 97 | // sum_r = (int)(sum_r/(entries*1.0)); 98 | // sum_g = (int)(sum_g/(entries*1.0)); 99 | // sum_b = (int)(sum_b/(entries*1.0)); 100 | // color = new Color(sum_r, sum_g, sum_b); 101 | // } 102 | 103 | return color; 104 | } 105 | 106 | public int abs(int diff) 107 | { 108 | if(diff < 0) return -1*diff; 109 | return diff; 110 | } 111 | public int idnt(int diff) 112 | { 113 | if(diff == 0) 114 | return 1; 115 | return 0; 116 | } 117 | 118 | public double getFitness(int[][] result) { 119 | double ans = 0; 120 | for(int i = 0 ; i < result.length ; i++) { 121 | for(int j = 0 ; j < result[0].length ; j++) { 122 | Color m = getColorOfPoint(i, j); 123 | Color n = new Color(result[i][j]); 124 | double moda = Math.sqrt(m.getRed()*m.getRed() + m.getGreen()*m.getGreen()+m.getBlue()*m.getBlue()); 125 | double modb = Math.sqrt(n.getRed()*n.getRed() + n.getGreen()*n.getGreen()+n.getBlue()*n.getBlue()); 126 | // System.out.println(((m.getRed()*n.getRed())+(m.getGreen()*n.getGreen())+(m.getBlue()+n.getBlue()))/(moda*modb)); 127 | // ans += ((m.getRed()*n.getRed())+(m.getGreen()*n.getGreen())+(m.getBlue()+n.getBlue()))/((1+moda)*(modb+1)); 128 | ans += ((Math.pow(2,abs(m.getRed() - n.getRed())/255.0) + Math.pow(2,abs(m.getGreen() - n.getGreen())/255.0) + Math.pow(2,abs(m.getBlue() - n.getBlue())/255.0)) )/6.0; 129 | //ans += abs((m.getRed() - n.getRed())) + abs((m.getGreen() - n.getGreen())) + abs((m.getBlue() - n.getBlue())); 130 | //ans += idnt((m.getRed() - n.getRed())) + idnt((m.getGreen() - n.getGreen())) + idnt((m.getBlue() - n.getBlue())); 131 | } 132 | } 133 | // System.out.println(ans); 134 | this.fitness = 100000.0/ans; 135 | return this.fitness; 136 | } 137 | public void print(){ 138 | //for(int i=0;i best) { 261 | best = population[i].fitness; 262 | best_mem = i ; 263 | } 264 | if(population[i].fitness < worst) { 265 | worst = population[i].fitness ; 266 | worst_mem = i ; 267 | } 268 | } 269 | // 270 | // If the best individual from the new population is better than 271 | // the best individual from the previous population, then 272 | // copy the best from the new population; else replace the 273 | // worst individual from the current population with the 274 | // best one from the previous generation 275 | // 276 | if(best >= population[POPSIZE].fitness) 277 | population[POPSIZE] = new Genotype(population[best_mem]); 278 | else 279 | { 280 | population[worst_mem] = new Genotype(population[POPSIZE]); 281 | } 282 | } 283 | 284 | public static void evaluate() { 285 | //System.out.println("inside evaluate"); 286 | for(int member = 0; member < POPSIZE; member++) 287 | population[member].getFitness(result); 288 | } 289 | 290 | public static void initialize() { 291 | population = new Genotype[POPSIZE + 1]; 292 | newpopulation = new Genotype[POPSIZE + 1]; 293 | 294 | Random randomGenerator = new Random(); 295 | 296 | for(int i = 0 ; i <= POPSIZE ; i++) { 297 | population[i] = new Genotype(); 298 | newpopulation[i] = new Genotype(); 299 | population[i].count = circleCount; 300 | for(int j = 0 ; j < circleCount ; j++) { 301 | population[i].circles[j].x = new Integer(randomGenerator.nextInt(row)); 302 | population[i].circles[j].y = new Integer(randomGenerator.nextInt(col)); 303 | population[i].circles[j].blue = new Integer(randomGenerator.nextInt(255)); 304 | population[i].circles[j].red = new Integer(randomGenerator.nextInt(255)); 305 | population[i].circles[j].green = new Integer(randomGenerator.nextInt(255)); 306 | //System.out.println(i + "\t" + j + "\t" + population[i].circles[j].red + "\t" + population[i].circles[j].green + "\t" + population[i].circles[j].red); 307 | population[i].circles[j].alpha = new Integer(randomGenerator.nextInt(255)); 308 | population[i].circles[j].radius = new Integer(randomGenerator.nextInt(RADIUSLIMIT)); 309 | population[i].circles[j].time = new Integer(randomGenerator.nextInt(10000)); 310 | //System.out.println("Radius = " + population[i].circles[j].radius); 311 | } 312 | population[i].bg_red =255; 313 | population[i].bg_green = 255; 314 | population[i].bg_blue = 255; 315 | population[i].bg_alpha = 0; 316 | } 317 | //System.out.println("inside initialize"); 318 | //population[POPSIZE].print(); 319 | } 320 | 321 | public static void keep_the_best() { 322 | int cur_best; 323 | int mem; 324 | int i; 325 | 326 | cur_best = 0; 327 | 328 | for(mem = 1; mem < POPSIZE; mem++) { 329 | if(population[mem].fitness > population[cur_best].fitness) 330 | cur_best = mem; 331 | } 332 | // 333 | // Once the best member in the population is found, copy the genes. 334 | // 335 | population[POPSIZE] = new Genotype(population[cur_best]); 336 | } 337 | 338 | public static void mutate() { 339 | for(int i = 0; i < POPSIZE; i++) { 340 | Random randomGenerator = new Random(); 341 | for(int j = 0 ; j= population[j].cfitness && p < population[j+1].cfitness) { 439 | // System.out.println(i + " Picking : " + (j + 1)); 440 | newpopulation[i] = new Genotype(population[j+1]); 441 | break ; 442 | } 443 | } 444 | } 445 | } 446 | // 447 | // Once a new population is created, copy it back 448 | // 449 | // System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 450 | // System.out.println("New pop"); 451 | // for(i = 0; i < POPSIZE; i++) { 452 | // System.out.println(newpopulation[i].fitness); 453 | // population[i] = new Genotype(newpopulation[i]); 454 | // } 455 | // System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 456 | } 457 | 458 | public static void Xover(int one, int two) { 459 | Genotype a = new Genotype(population[one]); 460 | Genotype b = new Genotype(population[two]); 461 | 462 | Random randomGenerator = new Random(); 463 | int k = randomGenerator.nextInt(a.circles.length); 464 | for(int i = 0 ; i < k ; i++) { 465 | Circle tmp = new Circle(a.circles[i]); 466 | a.circles[i] = new Circle(b.circles[i]) ; 467 | b.circles[i] = new Circle(tmp) ; 468 | } 469 | 470 | // int j=k; //two point crossover 471 | // while(j==k) {j = randomGenerator.nextInt(a.circles.length);} 472 | // for(int i = 0 ; i < j ; i++) { 473 | // Circle tmp = new Circle(a.circles[i]); 474 | // a.circles[i] = new Circle(b.circles[i]) ; 475 | // b.circles[i] = new Circle(tmp) ; 476 | // } 477 | 478 | population[one] = new Genotype(a) ; 479 | population[two] = new Genotype(b) ; 480 | } 481 | 482 | 483 | 484 | public static void main(String[] args) throws IOException { 485 | 486 | PrintWriter writer = new PrintWriter(args[1]+"info.txt", "UTF-8"); 487 | writer.println("The first line"); 488 | writer.println("POPSIZE=" + Integer.toString(POPSIZE)); 489 | writer.println("MAXGENS=" + Integer.toString(MAXGENS)); 490 | writer.println("circleCount=" + Integer.toString(circleCount)); 491 | writer.println("RADIUSLIMIT=" + Integer.toString(RADIUSLIMIT)); 492 | writer.println("PXOVER=" + Double.toString(PXOVER)); 493 | writer.println("PMUTATION=" + Double.toString(PMUTATION)); 494 | writer.println("PMUTATIONCOLOR=" + Double.toString(PMUTATIONCOLOR)); 495 | // public static int MAXGENS = 300000; 496 | // public static double PXOVER = 0.8; 497 | // public static double PMUTATION = 0.2; 498 | // public static Genotype population[]; 499 | // public static Genotype newpopulation[]; 500 | // public static int row, col; 501 | // public static int circleCount = 30; 502 | // public static int[][] result; 503 | // public static int RADIUSLIMIT=70; 504 | // public static double PMUTATIONCOLOR = .4; 505 | // writer.println("The second line"); 506 | writer.close(); 507 | 508 | BufferedImage image = ImageIO.read(GeneticAlgorithm.class.getResource(args[0] + ".jpg")); //read the image into the image object 509 | result = convertTo2D(image); 510 | row = result.length; 511 | col = result[0].length; 512 | Genotype best = null; 513 | initialize(); 514 | //System.out.println("After Initialize"); 515 | best = new Genotype(population[POPSIZE]); 516 | best.print(); 517 | evaluate(); 518 | //System.out.println("After Evaluate"); 519 | best = new Genotype(population[POPSIZE]); 520 | best.print(); 521 | keep_the_best(); 522 | //System.out.println("After Keep_the_best"); 523 | best = new Genotype(population[POPSIZE]); 524 | best.print(); 525 | 526 | double old_fitness = -1; 527 | for(int generation = 0 ; generation < MAXGENS ; generation++) { 528 | selector(); 529 | //System.out.println("After Selector"); 530 | //best = new Genotype(population[POPSIZE]); 531 | //best.print(); 532 | // for(int i = 0 ; i <= POPSIZE ; i++) 533 | // population[i].getFitness(result); 534 | crossover(); 535 | //System.out.println("After Crossover"); 536 | // best = new Genotype(population[POPSIZE]); 537 | //best.print(); 538 | // for(int i = 0 ; i <= POPSIZE ; i++) 539 | // population[i].getFitness(result); 540 | mutate(); 541 | //System.out.println("After Mutate"); 542 | //best = new Genotype(population[POPSIZE]); 543 | //best.print(); 544 | // for(int i = 0 ; i <= POPSIZE ; i++) 545 | // population[i].getFitness(result); 546 | evaluate(); 547 | //System.out.println("After Evaluate"); 548 | // best = new Genotype(population[POPSIZE]); 549 | //best.print(); 550 | // for(int i = 0 ; i <= POPSIZE ; i++) 551 | // population[i].getFitness(result); 552 | elitist(); 553 | //System.out.println("After Elitist"); 554 | best = new Genotype(population[POPSIZE]); 555 | //best.print(); 556 | // for(int i = 0 ; i <= POPSIZE ; i++) 557 | // population[i].getFitness(result); 558 | //System.out.println("Generation " + generation); 559 | // for(int i = 0 ; i < POPSIZE ; i++) { 560 | // System.out.println(population[i].fitness); 561 | // } 562 | double new_fitness = best.fitness; 563 | 564 | if(old_fitness!=new_fitness) 565 | { 566 | int answer[][] = new int[row][col]; 567 | for(int i = 0 ; i < row ; i++) { 568 | for(int j = 0 ; j < col ; j++) { 569 | Color c = population[POPSIZE].getColorOfPoint(i, j); 570 | answer[i][j] = (c.getRed() << 16) | (c.getGreen() << 8) | c.getBlue(); 571 | //answer[i][j] = (c.getRed() << 24) | (c.getGreen() << 16) | (c.getBlue() << 8) | c.getAlpha(); 572 | } 573 | } 574 | convertColorArrayToImage(answer, generation,POPSIZE,args[0], args[1]); 575 | } 576 | old_fitness = new_fitness; 577 | System.out.println(generation + "\t" + population[POPSIZE].fitness); 578 | 579 | 580 | } 581 | } 582 | } 583 | -------------------------------------------------------------------------------- /Genotype.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amangoeliitb/Genetic-Algorithm/c0241b9574f55d5ea845cbb64f092f06606df3b2/Genotype.class -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Genetic-Algorithm 2 | A genetic algorithm implementation in Java 3 | 4 | We have programmed a Genetic Algorithm in Java that takes an image as 5 | input and approximates the image using circles/rectangles of different 6 | dimensions and colors 7 | 8 | Steps to run the algorithm: 9 | 10 | First put the image file (jpg) in the same directory as the algorithm files 11 | 12 | Now running the code is simple. Just provide the image name (without any extension) as the first argument to the java command 13 | 14 | Example: java GeneticAlgorithm my_image 15 | --------------------------------------------------------------------------------