Fereshteh Shahmiri

PhD in Computer Science - School of Interactive Computing - Georgia Institute of Technology

 

Technology Square Research Building
85 Fifth Street NW
Atlanta, GA 30308

© 2017 by Fereshteh Shahmiri. All rights reserved.

Research Project: Robot Milling

Supervisor: Prof. Jeremy Ficca

 

Optimizing (Maximizing) the Volume of Cones subtracted from a Cube

Optimization Method: Genetic Algorithm

 

Carnegie Mellon University- Digital Fabrication Lab

Photo Reference : http://cmu-dfab.org/ Project For Prof. Jeremy Ficca

 INFLUENTIAL PARAMETERS EXISTING IN THE PROJECT

INITIAL SET OF INDIVIDUALS

import random
import pickle
from math import *

# generates individuals
# The generated individuals are not totally random, they have some conditions which prevents cones from passing through top and bottom of the main cube

def randomarray(n):
    a=[]
    ss=random.randint(1,cp)
    a+=[ss]
    if ss/24==0:
        mini=3
        maxi=6
    elif ss/24==1:
        mini=3
        maxi=6
    elif ss/24==2:
        mini=4
        maxi=8
    elif ss/24==3:
        mini=5
        maxi=9
    elif ss/24==4:
        mini=7
        maxi=10
    else:
        mini=7
        maxi=10
    for i in range(n):
        a+=[random.randint(0,3)]
        a+=[random.randint(0,3)]
        if random.random()<0.5:
            if (ss % 16 < 8) :
                a+=[2]
            else:
                a+=[0]
        else:
            if (ss % 4 < 2):
                a+=[3]
            else:
                a+=[1]
        a+=[random.randint(mini,maxi)*10+random.randint(0,9)]
    return a

pkl_file = open("c:\\cone_num.txt", 'rb')
n = pickle.load(pkl_file)
pkl_file.close()
pkl_file = open("c:\\num_indiv.txt", 'rb') #number of individuals in each step
num_tests = pickle.load(pkl_file)
pkl_file.close()
cp = 96 # index of center point which cones are merged

b=[]         #indivuals (possible solutions)


for i in range(num_tests):
    b+=[randomarray(n)]
print b    
output = open("c:\\indiv.txt", "wb")
pickle.dump(b, output)
output.close()   #!/usr/bin/env python
output2 = open("c:\\module.txt", "wb")
output2.close()   #!/usr/bin/env python  


 

Running the Python file in Komodo named “indiv.py” and generating the initial set of individuals for first generation of desired form. This initial set includes all needed indices for 5 variable parameters existing in the project.

SECOND AND ITERATION OF GENERATIONS

in step 2, for having the second generation, runing the python file in Komodo named “modularity.py”This set is saved in following address and will be read by grasshopper when we run that."c:\\module.txt"Back to step 2 and do all mentioned steps you have done first for each generation

import random
import pickle
from math import *

def checkLimitations(indiv):

#(none of cones should pass through top and bottom sides of cube)
    ss=indiv[0]
    if ss/24==0:
        mini=3
        maxi=6
    elif ss/24==1:
        mini=3
        maxi=6
    elif ss/24==2:
        mini=4
        maxi=8
    elif ss/24==3:
        mini=5
        maxi=9
    elif ss/24==4:
        mini=7
        maxi=10
    elif ss/24==5:
        mini=7
        maxi=10
    for i in range(n):
        if ((indiv[i*4+3] / 10)>=mini and (indiv[i*4+3]/10<=maxi)):
            return False
    return True

# generates two new children from two selected parents
def crossover(a1,a2,n):
    c1=random.randint(0,4*n-1)

    # generates the first pivot point (each cone has 4 variables)
    c2=random.randint(c1,4*n) # generates second pivot point
    ax1=[]
    ax2=[]
    for i in range(len(a1)):
        # selects outside of domain [c1,c2] for first child and inside of domain for the second child (first parent)
        # selects inside of domain [c1,c2] for first child and outside of domain for the second child (second parent)
        if (i>c1 and i<c2):
            ax1+=[a2[i]]
            ax2+=[a1[i]]
        else:
            ax1+=[a1[i]]
            ax2+=[a2[i]]
    return (ax1,ax2)


# manipulates one of individuals gene
def mutation(a,n):
    index=random.randint(0,n-1)*4+random.randint(0,3)+1 # random.randint(0,n-1) selects the cone number, random.randint(0,3) selects which variable of cone should be changed
    a[index]=random.randint(0,4)
    return a

# selects the top most optimum quarter of individuals
def selection(a,mod):
    b=[]    #top quarter (1/4) individuals with highest modularity
    modx=sorted(mod)
    for i in range(len(a)):
        if mod[i]>=modx[len(a)-len(a)/4-1] and mod[i] is not None:
            b+=[a[i]]
    return (b,max(mod),a[mod.index(max(mod))]) #top quarter individuals, maximum modularity, individual corresponding to the maximum modularity

cp = 96 # number of center points which cones are merged
mod=[]
pkl_file = open("c:\\cone_num.txt", 'rb')
n = pickle.load(pkl_file) #num_cones
pkl_file.close()

pkl_file = open("c:\\num_indiv.txt", 'rb') #number of individuals in each step
num_tests = pickle.load(pkl_file)
pkl_file.close()

pkl_file = open("c:\\indiv.txt", 'rb')
b = pickle.load(pkl_file)
pkl_file.close()

pkl_file = open("c:\\module.txt", 'rb')
for i in range(len(b)):
    mod += [pickle.load(pkl_file)]
pkl_file.close()
#selects the top most quarter of last generation


(b,maxmod,opt_indiv)=selection(b,mod)
# generates the 3/4 of remaining next generation from previous generation

for i in range(3*num_tests/8):
    i1=random.randint(0,num_tests/4-1) # index of first parent
    i2=random.randint(0,num_tests/4-1) # index of second parent
    (cr1,cr2)=crossover(b[i1],b[i2],n) # generates two new individuals from selected parents
    # each mutation is for one of new generated individuals

    temp = mutation(cr1,n)
    if checkLimitations(temp): # checks if new generated individual meets the limitations (none of cones should pass through top and bottom sides of cube)
        b+=[temp]  #adding next generation after crossover and mutation
    temp = mutation(cr2,n)
    if checkLimitations(temp): # checks if new generated individual meets the limitations (none of cones should pass through top and bottom sides of cube)
        b+=[temp]  #adding next generation after crossover and mutation

# new generation of individuals are saving in the following file
output = open("c:\\indiv.txt", "wb")
pickle.dump(b, output)
output.close()
print b

output2 = open("c:\\module.txt", "wb") # clears previous data in the file
output2.close()#!/usr/bin/env python

Grasshopper as the modeling context in connection with external memories and komodo editor

 - database here is text files and data generated in optimization process are read from and write to text files.

 -   As in optimization process we are encountered by a LARGE DATASET and there are limitations in this data set analysis inside the grasshopper we need to use komodo editor to writo the code out of the grasshopper environment.

 -   Also   since grasshopper doesn't have any memory for saving the data, using other database like .txt file is reasonable.

 - (First try was by using galapagos, an add-in for optimization in grasshopper. However, processing many variables and iterations causes many crashes in software environment. Accordingly, the suggested method here, was desgined and utilized. )

Grasshopper File is attached here