Profile
- Name
- GA Mutate v1.1 filt
- ID
- 100590
- Shared with
- Public
- Parent
- None
- Children
- None
- Created on
- January 16, 2015 at 11:03 AM UTC
- Updated on
- January 16, 2015 at 11:03 AM UTC
- Description
Generic Mutate: Grom`s oryginal recipe moved to v2 LUA and added filters auto on/off on scoring.
Best for
Code
-- Converted from v1 lua by Rav3n_pl v1 to v2 converter
--[[
GA Mutate v1.0 by Grom.
Trying to use genetic algorythm to find best aa structure on mutable puzzles:
1. Create initial population by known structures and random ones.
2. Check the score of each one.
3. Make new population:
1) Choose top 3 solutions.
2) Create 5 solutions as crossover of top 3.
3) Create 2 solutions as mutation of top 2.
4) Create 1 solution as structure.MutateSidechainsSelected(1) of 4th of top.
5) Create 1 solution randomly (special for Luckiest people in the world).
4. Go to point 2.
]]
p=print
function filtersOn()
if filters then
behavior.SetSlowFiltersDisabled(false)
end
end
function filtersOff()
if filters then
behavior.SetSlowFiltersDisabled(true)
end
end
function Score()--return score, exploration too
filtersOn()
local s=0
if energy then
s=current.GetEnergyScore()
else
s=current.GetScore()
end
filtersOff()
return s
end
--calculate REALLY good seed from current score
seed=os.time()
seed=1/seed
while seed<10000000 do seed=seed*10 end
seed=seed-seed%1
p("Seed is: "..seed)
math.randomseed(seed)
function random(n1,n2) --random function returns int or float depends on input vars
if n2==nil and n1==nil then
return math.random() --float
else
if n2==nil then
if n1%1==0 then
return math.random(n1) --integer
else
return math.random()*n1 --float
end
else
if n1%1==0 and n2%1==0 then
return math.random(n1,n2) --integer between
else
return math.random()*(n2-n1)+n1 --float between
end
end
end
end
fsl={} -- Foldit special library
-- configuration
mutationRate = 0.1
populationSize = 12
maxGenerations = 50
seed = nil
-- commented out residues not in Foldit (as of Nov 15, 2010)
fsl.aminosLetterIndex=1
fsl.aminosShortIndex=2
fsl.aminosLongIndex=3
fsl.aminosPolarityIndex=4
fsl.aminosAcidityIndex=5
fsl.aminosHydropathyIndex=6
fsl.aminos = {
{'a','Ala','Alanine', 'nonpolar','neutral', 1.8},
-- {'b','Asx','Asparagine or Aspartic acid' },
{'c','Cys','Cysteine', 'nonpolar','neutral', 2.5},
{'d','Asp','Aspartic acid', 'polar','negative', -3.5},
{'e','Glu','Glutamic acid', 'polar','negative', -3.5},
{'f','Phe','Phenylalanine','nonpolar','neutral', 2.8},
{'g','Gly','Glycine', 'nonpolar','neutral', -0.4},
{'h','His','Histidine', 'polar','neutral', -3.2},
{'i','Ile','Isoleucine', 'nonpolar','neutral', 4.5},
-- {'j','Xle','Leucine or Isoleucine' },
{'k','Lys','Lysine', 'polar','positive', -3.9},
{'l','Leu','Leucine', 'nonpolar','neutral', 3.8},
{'m','Met','Methionine ', 'nonpolar','neutral', 1.9},
{'n','Asn','Asparagine', 'polar','neutral', -3.5},
-- {'o','Pyl','Pyrrolysine' },
{'p','Pro','Proline', 'nonpolar','neutral', -1.6},
{'q','Gln','Glutamine', 'polar','neutral', -3.5},
{'r','Arg','Arginine', 'polar','positive', -4.5},
{'s','Ser','Serine', 'polar','neutral', -0.8},
{'t','Thr','Threonine', 'polar','neutral', -0.7},
-- {'u','Sec','Selenocysteine' },
{'v','Val','Valine', 'nonpolar','neutral', 4.2},
{'w','Trp','Tryptophan', 'nonpolar','neutral', -0.9},
-- {'x','Xaa','Unspecified or unknown amino acid' },
{'y','Tyr','Tyrosine', 'polar','neutral', -1.3},
-- {'z','Glx','Glutamine or glutamic acid' }
}
function table.my_sort(x,z,ind)
local j
local v
local vz
local vi
comp=function(x,y) return x>y end
for i = #x-1,1,-1 do
v=x[i]
vz=z[i]
vi=ind[i]
j=i
while (j<#x) and (comp(x[j+1],v)) do
x[j]=x[j+1]
z[j]=z[j+1]
ind[j]=ind[j+1]
j=j+1
end
x[j]=v
z[j]=vz
ind[j]=vi
end
end
function tune(tune_type)
if tune_type == 1 then
selection.SelectAll()
structure.ShakeSidechainsSelected(1)
structure.WiggleAll(10)
selection.DeselectAll()
end
if tune_type == 2 then
selection.SelectAll()
structure.ShakeSidechainsSelected(1)
selection.DeselectAll()
end
end
function crossover(a, b)
local cut = random(#a-1)
local s = {}
for i=1, cut do
s[i] = a[i]
end
for i=cut+1, #b do
s[i] = b[i]
end
return s
end
function mutation(bitstring)
local s = {}
for i=1, #bitstring do
if random() < mutationRate then
s[i] = fsl.aminos[random(20)][fsl.aminosLetterIndex]
else s[i] = bitstring[i] end
end
return s
end
function equal(str1,str2)
local c=true
for i=1,#str1 do
if str1[i]~=str2[i] then c=false end
end
return c
end
function try_mutate_2(slot)
save.Quickload(tab_idx[slot])
selection.SelectAll()
structure.MutateSidechainsSelected(1)
structure.WiggleAll(10)
strt = {}
for i=1,#mutable do
strt[i] = structure.GetAminoAcid(mutable[i])
end
return strt
end
function reproduce(selected)
local pop = {}
pop[1]=selected[1]
pop[2]=selected[2]
pop[3]=selected[3]
pop[4]=crossover(selected[1],selected[2])
pop[5]=crossover(selected[2],selected[3])
pop[6]=crossover(selected[1],selected[3])
pop[7]=crossover(selected[2],selected[1])
pop[8]=crossover(selected[3],selected[2])
pop[9]=mutation(selected[1])
pop[10]=mutation(selected[2])
pop[11]=try_mutate_2(4)
pop[12]=random_bitstring(problemSize)
for i=1,#pop-1 do
for j=i+1,#pop do
if equal(pop[i],pop[j]) then
pop[j]=mutation(pop[j])
end
end
end
return pop
end
function fitness(bitstring)
local cost = 0
for i=1, #bitstring do
if structure.GetAminoAcid(mutable[i])~=bitstring[i] then
selection.DeselectAll()
selection.Select(mutable[i])
structure.SetAminoAcidSelected(bitstring[i])
end
end
tune(1)
cost = Score() -- #NEED EDIT! remove(true) if you have it#()
return cost
end
function random_bitstring(length)
local s = {}
local i = 1
while #s < length do
s[i] = fsl.aminos[random(20)][fsl.aminosLetterIndex]
i=i+1
end
return s
end
function evolve()
local population = {}
local bestString = nil
local outp = ""
recentbest.Save()
-- Insert starting sequence as first species
strt = {}
for i=1,#mutable do
strt[i] = structure.GetAminoAcid(mutable[i])
end
table.insert(population, strt)
-- Add known sequences
--[[
strt = {'k','l','v','e','d','h','g','f','e','l','a','l','e','m','d','d','n','r','p','n','k','f','k','e','i','a','k','f','v','k'}
table.insert(population, strt)
strt = {'r','l','m','e','d','w','g','f','k','l','a','l','e','r','d','e','n','r','p','n','r','f','k','e','i','a','k','f','v','k'}
table.insert(population, strt)
]]
-- initialize the population random pool
for i=#population+1, populationSize do
table.insert(population, random_bitstring(problemSize))
end
-- optimize the population (fixed duration)
for i=1, maxGenerations do
-- evaluate
fitnesses = {}
recentbest.Restore()
for i=1,#mutable do
strt[i] = structure.GetAminoAcid(mutable[i])
end
table.insert(fitnesses, Score()) -- #NEED EDIT! remove(true) if you have it#())
outp=""
for z=1,#strt do
outp = outp .. strt[z]
end
print(outp..", "..fitnesses[1])
save.Quicksave(1)
for j=2, #population do
recentbest.Restore()
table.insert(fitnesses, fitness(population[j]))
save.Quicksave(j)
-- print population and score
outp=""
for z=1,#population[j] do
outp = outp .. population[j][z]
end
print(outp..", "..fitnesses[j])
end
tab_idx={}
for j=1,#population do tab_idx[j]=j end
-- Sort population
table.my_sort(fitnesses,population,tab_idx)
-- Print current population
print("Generation "..i..". Current population:")
for i=1,#population do
outp = i..","..tab_idx[i]..","..fitnesses[i]..","
for j=1, #population[i] do
outp = outp .. population[i][j]
end
print(outp)
end
-- Create new population
tmpPop = population
population = reproduce(tmpPop)
end
return population[1]
end
function fsl.FindMutableSegments()
local mutable={}
for i=1,structure.GetCount() do
if structure.IsMutable(i) then
mutable[#mutable+1]=i
end
end
return mutable
end
---------------------
-- run
-- turn letter into alternative direct index
for i=1,#fsl.aminos do
fsl.aminos[fsl.aminos[i][fsl.aminosLetterIndex]] = fsl.aminos[i]
end
filters=not behavior.GetSlowFiltersDisabled()
if filters then filtersOff() end
mutable=fsl.FindMutableSegments()
problemSize = #mutable
best = evolve()
if filters then filtersOn() end
print("Finished!")
----------------------