Color adaptability through a genetic algorithm.

Genetic Algorithm 1.0: Color adaptability

COMPUTATIONAL DESIGN
1.9– 22.9 2016

This script creates a population of rectangles with different colors. There is a target color which these rectangles should reach through a genetic algorithm. It works through a process where its manipulating hex color codes. Ex: #FF0000.

 Genetic Algorithm 1.1 - It begins with columns with random colors and they evolve to a specific target color. Here it is yellow.
Genetic Algorithm 1.1 – It begins with columns with random colors and they evolve to a specific target color. Here it is yellow.
Genetic Algorithm 1.0 - It begins with rectangles with random colors and they evolve to a specific target color.
Genetic Algorithm 1.0 – It begins with rectangles with random colors and they evolve to a specific target color.

This script creates a population of rectangles with different colors. There is a target color which these rectangles should reach through a genetic algorithm.

/*
    Spatial Experiments I
    22-09-16
    
    Architecture and color
    "This script creates a population of rectangles with different colors.
    There is a target color which these rectangles should reach through a
    genetic algorithm."
    
    Version 1.0
*/

// Setup variables
// Target color
String target;

// Building a Mating pool ArrayList
ArrayList matingPool;

// Population total
int totalPopulation = 15;

// Mutation rate
float mutationRate;

// Population of architecture array
Architecture[] population;

void setup() {
    // background properties
    size(500,500);
    background(255);
    //frameRate(4);
     
    // Target color
    // "hex color only needs 6 numbers after 'FF'"
    target = "FFFF0000"; 
    // Mutation rate
    mutationRate = 0.01;
     
    // STEP 1: INITIALIZE POPULATION
    population = new Architecture[totalPopulation];
     
    // Create the population
    for (int i = 0; i < population.length; i++) {
        population[i] = new Architecture();  
    }
         
} // End setup


// THE LOOP
void draw() {
    background(255);
    // Display the objects
    for (int j = 0; j < population.length; j++) {
        population[j].display();
    }  
    
    // STEP 2. NATURAL SELECTION
    
    // A) Calculate fitness
    for (int k = 0; k < population.length; k++) {
         population[k].fitness();
    } // End
    
    // B) Building the mating pool
    // list contains Architecturs objects
    ArrayList matingPool = new ArrayList(); 
    
    for (int m = 0; m < population.length; m++) {
        // Add each member n times according to its fitness score.
        int newFitnessScore = int(population[m].fitness * 100); // EX. 0.25 * 100 = 25
        println(">> " + newFitnessScore + " out of 100 <<");
        for (int n = 0; n < newFitnessScore; n++) {
            matingPool.add(population[m]);
        }
    } // End

    // STEP 3: REPRODUCTION   
    for (int i = 0; i < population.length; i++) {
        int a = int(random(matingPool.size()));
        int b = int(random(matingPool.size()));
        Architecture partnerA = matingPool.get(a);
        Architecture partnerB = matingPool.get(b);
        
        // A) Crossover
        Architecture child = partnerA.crossover(partnerB);
        
        // B) Mutation
        child.mutate(mutationRate);
    
        // Note that we are overwriting the population with the new
        // children.  When draw() loops, we will perform all the same
        // steps with the new population of children.
        population[i] = child;
    }
} // End draw

The second file containing the Architecture objects.

class Architecture {
    // changing variables 
    color c;
    float x, y;
    float WIDTH, HEIGHT;
    
    // Genes adressed as color
    String buildingColor;
    char[] charColorList;
    
    // Counting fitness
    float fitness;
     
    // class constructor 
    Architecture()
    {
         c = color(random(255), random(255), random(255));
         x = random(640);
         y = random(640);
         WIDTH = random(20, 100);
         HEIGHT = random(100,30);
         buildingColor = hex(c); // store the color as string
         charColorList = buildingColor.toCharArray(); // convert string into char list
    }
    
    // methods
    void display() {
        
        String convertMe = new String();
        
        //int count = 0;
        for ( char i : charColorList ) {
            convertMe = convertMe + i;
            /*if ( count == 0 ) {
                convertMe = "#" + convertMe;
            }
            count++;*/
        }
        
        // unhex methods only works on true hex colors
        // so some hex codes that are mutated and inherited 
        // are not true hex color and it causes an error
        try {
            // Protected code
            int hi = unhex(convertMe); 
            //println(convertMe);
            //println(hi);
            // EX. rect(30, 20, 55, 55, 3, 6, 12, 18);
            rect(x, y, HEIGHT, WIDTH);
            fill(hi);
            noStroke();
            
        } catch(NumberFormatException e1) {
            // Catch block
            //color def = color(255,255,255);
            println("It was not a hexcolor");
            
            //rect(x, y, HEIGHT, WIDTH);
            //fill(def);
            //noStroke();
            
        } // End throw error
    } // End display
    
     // Display colors
     String colorRange() {
         // Converting hexcode to String
         String buildingColor = hex(c); 
         println(buildingColor);
         // Looping through each letter in the hex code
         for ( char letter : buildingColor.toCharArray() ) {
             println(letter);
         }
         return buildingColor;
     }  // End colorRange
    
    // Calculate fitness
    void fitness() {
         int score = 0;
         // Looping through char list and target color list
         // comparing each letter in the two of them and 
         // giving it a fitness score if they are equal
         for ( int i = 2; i < charColorList.length; i++ ) {
              if (charColorList[i] == target.charAt(i)) { 
                  score++;
              }
         }
         // Set the fitness score
         fitness = float(score)/(target.length() - 2); // the target list is 6 not 8
         //println(buildingColor + " " + fitness); // display the fitness for understanding
         /*if (fitness == 1.0) {
            println("Optimal Solution"); 
         }*/
     } // End fitness
    
    // Crossover
    // method crossover has datatype Architecture and parameter of object Architecture
    Architecture crossover(Architecture partner) {
        Architecture child = new Architecture();
        int midpoint = int(random(charColorList.length));
        for (int i = 0; i < charColorList.length; i++) {
            if (i > midpoint) {
                child.charColorList[i] = charColorList[i]; 
            } else {              
                child.charColorList[i] = partner.charColorList[i]; 
            }
        }
        return child;
    } // End crossover
    
    // Mutation
    void mutate(float mutationRate) {
        for (int i = 2; i < charColorList.length; i++) {
            if (random(1) < mutationRate) {
                // random char in ASCII interval  
                // the goal is to get a char A-Z or 0-9
                char randomChar = (char) random(48,90);
                // Control of char
                if ( Character.isLetter(randomChar) == true ||
                     Character.isDigit(randomChar) == true) {
                   
                     //println(randomChar);
                     // Overwriting element with new mutated char
                     charColorList[i] = randomChar;
                
                } else {
                     // println("It was first invalid");
                     boolean boo = true;
          
                     // Run this loop as long as boolean is true
                     while ( boo ) {
                         // Check a new value for randomChar
                         randomChar = (char) random(48,90);
                         if ( Character.isLetter(randomChar) == true ||
                             Character.isDigit(randomChar) == true) {
                           
                             charColorList[i] = randomChar;
                             //println(">> " + randomChar);
                             
                             // End while loop
                             boo = false;
                         } // End if statement
                     } // End while loop
                } // End if statement
                    
                    
                    
            } // End if
        } // End for loop through charColorList length
    } // End mutation method
    
    
} // End Architecture Class