Profile
- Name
- Rav3n_pl Gab Loss NC 30 v1 & v2 With filter Toggle
- ID
- 100459
- Shared with
- Public
- Parent
- None
- Children
- None
- Created on
- December 30, 2014 at 17:50 PM UTC
- Updated on
- December 30, 2014 at 17:50 PM UTC
- Description
Added are ravs lua v1 in v2 and bits overload filters toggle
Best for
Code
--[[
w30 (NC): Default wiggle iterations upped to 30 for newchapter; wiggle with bands=2 iters
No more recursive wiggle, since this scores lower in newchapter.
GAB - Genetic Algorythm on Bands
by Rav3n_pl
based on CartoonVillan and Crashguard303 scripts
Definitions:
band: randomised: start segment, end segment, length, strength
critter: set of bands
herd: set of critters
1.
- randomize needed bands
- randomly assignig them to criters
2.
- score each critter
3.
- keep critters scoring above score
- breed best critters
- breed bastards (best one + random one)
- forget about rest of critter
- randomize new critters to fill herd
]]--
-- "lua v1 in v2" library by rav3n_pl
--just add it in front of your v1 code and use v2 and v1 code in v2 scripts :)
-- print(arg1[,...,argN]) no change :)
function are_conditions_met()
return current.AreConditionsMet()
end
function band_add_segment_segment(sgi1, sgi2)
band.AddBetweenSegments(sgi1, sgi2)
end
function band_delete(bndIdx)
if bndIdx~= nil then
band.Delete(bndIdx)
else
band.DeleteAll()
end
end
function band_disable(bndIdx)
if bndIdx~=nil then
band.Disable(bndIdx)
else
band.DisableAll()
end
end
function band_enable(bndIdx)
if bndIdx~=nil then
band.Enable(bndIdx)
else
band.EnableAll()
end
end
function band_set_length(bndIdx, len)
band.SetGoalLength(bndIdx, len)
end
function band_set_strength(bndIdx, str)
band.SetStrength(bndIdx, str)
end
function get_band_count()
return band.GetCount()
end
function deselect_all()
selection.DeselectAll()
end
function deselect_index(sgn)
selection.Deselect(sgn)
end
function select_all()
selection.SelectAll()
end
function select_index(sgn)
selection.Select(sgn)
end
function select_index_range(sg1,sg2)
selection.SelectRange(sg1,sg2)
end
function do_freeze(bbone,schain)
freeze.FreezeSelected(bbone,schain)
end
function do_unfreeze_all()
freeze.UnfreezeAll()
end
function do_global_wiggle_all(iters)
structure.WiggleAll(iters,true,true)
end
function do_global_wiggle_backbone(iters)
structure.WiggleAll(iters, true,false)
end
function do_global_wiggle_sidechains(iters)
structure.WiggleAll(iters,false,true)
end
function do_local_rebuild(iters)
structure.RebuildSelected(iters)
end
function do_local_wiggle(iters)
structure.LocalWiggleSelected(iters,true,true)
end
function do_mutate(iters)
structure.MutateSidechainsSelected(iters)
end
function do_shake(iters)
structure.ShakeSidechainsSelected(iters)
end
function do_sidechain_snap(sgn, snap)
rotamer.SetRotamer(sgn, snap)
end
function get_sidechain_snap_count(sgn)
return rotamer.GetCount(sgn)
end
function load_structure()
save.LoadSecondaryStructure()
end
function save_structure()
save.SaveSecondaryStructure()
end
function quickload(slot)
save.Quickload(slot)
end
function quicksave(slot)
save.Quicksave(slot)
end
function get_exploration_score()
return current.GetExplorationMultiplier()
end
function get_ranked_score()
return current.GetScore()
end
function get_score()
return current.GetEnergyScore()
end
function get_segment_distance(sg1,sg2)
return structure.GetDistance(sg1,sg2)
end
function get_aa(sn)
return structure.GetAminoAcid(sn)
end
function get_segment_count()
return structure.GetCount()
end
function get_ss(sn)
return structure.GetSecondaryStructure(sn)
end
function is_hydrophobic(sn)
return structure.IsHydrophobic(sn)
end
function replace_aa(aa)
for i=1,structure.GetCount() do
if selection.IsSelected(i) then
structure.SetAminoAcid(i, aa)
end
end
end
function replace_ss(ss)
for i=1,structure.GetCount() do
if selection.IsSelected(i) then
structure.SetSecondaryStructure(i,ss)
end
end
end
function get_segment_score(sg)
return current.GetSegmentEnergyScore(sg)
end
function get_segment_score_part(score_part,sg)
return current.GetSegmentEnergySubscore(sg,score_part)
end
function reset_puzzle()
puzzle.StartOver()
end
function restore_abs_best()
absolutebest.Restore()
end
function restore_credit_best()
creditbest.Restore()
end
function reset_recent_best()
recentbest.Save()
end
function restore_recent_best()
recentbest.Restore()
end
function set_behavior_clash_importance(ci)
behavior.SetClashImportance(ci)
end
-- end of library
-- function to copy class/table
function CopyTable(orig)
local copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
return copy
end
-- functions for filters
function FiltersOn()
if behavior.GetSlowFiltersDisabled() then
behavior.SetSlowFiltersDisabled(false)
end
end
function FiltersOff()
if behavior.GetSlowFiltersDisabled()==false then
behavior.SetSlowFiltersDisabled(true)
end
end
-- function to overload a funtion
function mutFunction(func)
local currentfunc = func
local function mutate(func, newfunc)
local lastfunc = currentfunc
currentfunc = function(...) return newfunc(lastfunc, ...) end
end
local wrapper = function(...) return currentfunc(...) end
return wrapper, mutate
end
-- function to overload a class
-- to do: set the name of function
classes_copied = 0
myclcp = {}
function MutClass(cl, filters)
classes_copied = classes_copied+1
myclcp[classes_copied] = CopyTable(cl)
local mycl =myclcp[classes_copied]
for orig_key, orig_value in pairs(cl) do
myfunc, mutate = mutFunction(mycl[orig_key])
if filters==true then
mutate(myfunc, function(...)
FiltersOn()
if table.getn(arg)>1 then
-- first arg is self (function pointer), we pack from second argument
local arguments = {}
for i=2,table.getn(arg) do
arguments[i-1]=arg[i]
end
return mycl[orig_key](unpack(arguments))
else
--print("No arguments")
return mycl[orig_key]()
end
end)
cl[orig_key] = myfunc
else
mutate(myfunc, function(...)
FiltersOff()
if table.getn(arg)>1 then
local arguments = {}
for i=2, table.getn(arg) do
arguments[i-1]=arg[i]
end
return mycl[orig_key](unpack(arguments))
else
return mycl[orig_key]()
end
end)
cl[orig_key] = myfunc
end
end
end
-- how to use:
MutClass(structure, false)
MutClass(band, false)
MutClass(current, true)
-- options:
energy=false --set true to seek energy in exploration puzzles; false works on all puzzles
pullCI=0.9 --Clash Impotrance during pull
fastQstab=true -- only 1s1w after pull if true
fuzeThresh = 1 -- run fuze if we are close to best score (negative=new best score)
qstabThresh=10 -- run qstab if score drops more than... wiggle only in other case
maxCI=1 --changle to lower if not want tu use c=1 shake/wiggle at all. good in eraly game
herd= --herd options
{
breedBest = 5, --breed best 4 critters - all combinations => 6 kids form 4 critters, 3 form 3, 1 form 2, 9 form 5 ;]
keepBest = 3, --save up to 3 best scoring critters, rest are forgotten
breedBastards = 8, --number of best will have one random bastard
newRandom = 10, --adding new random ones each generation
maxGen= 100, --maximum generations
shuffle = true, --set true to run critters in random order
renew=4, --create totally fresh herd after that many gens w/o improvement
}
critter= --critter options
{
minBands=1, --minimum bands
maxBands=7, --maximum bands
keepScore = 0.1 , --survive to next gen only if score higher than
breedScore=-20, --will breed kids only if score higher. Basttards always breed
maxLoss=20 --30, --maximum loss by critter. set 0 to disable -- reduced to 20 for newchapter
}
bands= --bands options
{
minStr=0.3, --minimum band str
maxStr=1.1, --maximum band str
minChng = 3, -- minimum change of band len accordig to current distance
maxUp = 7.1, -- maximum chnage up (push)
maxDn = 7.9, -- maximum change down (pull)
minSkip = 10, --minimum segment distance
minDist = 4, --minimum spatial distance
minLen = 2, --minimum lenght of created band
}
DoNotUse={--just comment lines below or add more areas to avoid
--{segCnt,segCnt}, --ligand cant be used
--{120,134},
--{1,10},
}
AlwaysUse={ --areas should be always used
--{segCnt,segCnt},--ligand need to be at one end
--{308,311}, --loopy
--{272,319}, --loopy
}
-- bands by secondary structure
use=
{
Sheet=true, --set false to not band sheets
Helix=true, --set false to not band helices
Loop=true, --set false to not band loops
}
checkBoth=false --check both ends to above, if false only one end need to be true
--end of options
segCnt=get_segment_count()
p=print
function CI(c)
if c>maxCI then c=maxCI end
set_behavior_clash_importance(c)
end
function round(x)--cut all afer 3-rd place
return x-x%0.001
end
function down(x)
return x-x%1
end
function Score()--return score, exploration too
if energy==true then
return get_score(true)
else
return get_ranked_score(true)
end
end
function Wiggle(how, iters, minppi)
if how==nil then how="wa" end
if iters==nil then iters=15 end --increased to 15 to have 30 iters by default in newchapter
if minppi==nil then minppi=0.1 end
if iters>0 then
--iters=iters-1
sp=Score()
if how == "s" then do_shake(1)
elseif how == "wb" then do_global_wiggle_backbone(2*iters)
elseif how == "ws" then do_global_wiggle_sidechains(2*iters)
elseif how == "wa" then do_global_wiggle_all(2*iters)
end
ep = Score()
ig=ep-sp
--if how~="s" then
-- if ig > minppi then return Wiggle(how, iters, minppi) end --tail call
--end -- recursive wiggle removed as it is not good under newchapter
end
end
--[[
Tlaloc`s math library
------------------------------------------------------------------------
The original random script this was ported from has the following notices:
Copyright (c) 2007 Richard L. Mueller
Hilltop Lab web site - http://www.rlmueller.net
Version 1.0 - January 2, 2007
You have a royalty-free right to use, modify, reproduce, and
distribute this script file in any way you find useful, provided that
you agree that the copyright owner above has no warranty, obligations,
or liability for such use.
------------------------------------------------------------------------
]]--
local lngX = 1000
local lngC = 48313
local function _random(m,n)
local A_Hi = 63551
local A_Lo = 25354
local M = 4294967296
local H = 65536
function _MWC()
local S_Hi = math.floor(lngX / H)
local S_Lo = lngX - (S_Hi * H)
local C_Hi = math.floor(lngC / H)
local F1 = A_Hi * S_Hi
local F2 = (A_Hi * S_Lo) + (A_Lo * S_Hi) + C_Hi
lngX = ((F2 - (math.floor(F2 / H) * H)) * H) + (A_Lo * S_Lo) + lngC - (C_Hi * H)
lngX = lngX - (math.floor(lngX / M) * M)
lngC = math.floor((F2 / H) + F1)
return lngX
end
if n == nil and m ~= nil then
n = m
m = 1
end
if (m == nil) and (n == nil) then
return _MWC() / M
else
if n < m then
return nil
end
return math.floor((_MWC() / M) * (n - m + 1)) + m
end
end
local function _abs(value)
if value < 0 then
return -value
else
return value
end
end
local function _floor(value)
return value - (value % 1)
end
local function _randomseed(s)
if s==nil then
s=math.abs(Score())
if s==0 then s=get_score(true) end
s=s%0.001
s=1/s
while s<100000 do s=s*1000 end
s=s-s%1
end
lngX = s
p("Random seed is "..s)
end
math=
{
abs = _abs,
floor = _floor,
random = _random,
randomseed = _randomseed,
}
math.randomseed()
--[[ End math library ]]--
function SaveBest()
local g=Score()-bestScore
if g>0 then
if g>0.01 then p("Gained another ",round(g)," pts.") end
bestScore=Score()
quicksave(3)
end
end
function SaveRB()
quicksave(4)
restore_recent_best()
SaveBest()
quickload(4)
end
function Qstab()
select_all()
CI(0.1)
Wiggle("s",1)
if fastQstab==false then
CI(0.4)
Wiggle("wa",1)
CI(1)
Wiggle("s",1)
end
CI(1)
Wiggle()
end
function FuzeEnd()
CI(1)
--Wiggle("wa",1) --reduce shaking at full CI, for speed
--Wiggle("s",1) --reduce shaking at full CI, for speed
Wiggle()
srb()
end
function Fuze1(ci1,ci2)
CI(ci1)
Wiggle("s",1)
CI(ci2)
Wiggle("wa",1)
end
function Fuze2(ci1,ci2)
CI(ci1)
Wiggle("wa",1)
CI(1)
Wiggle("wa",1)
CI(ci2)
Wiggle("wa",1)
end
function srb()
restore_recent_best()
SaveBest()
end
function Fuze()
p("Fuzing...")
local scr=Score()
select_all()
reset_recent_best()
Fuze1(0.3,0.6) FuzeEnd()
Fuze2(0.3,1) srb()
Fuze1(0.05,1) srb()
Fuze2(0.7,0.5) FuzeEnd()
Fuze1(0.07,1)
srb()
end
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
function FillHerd() --fill up herd
local n=#critters
if n>0 then --fill up
n=herd.newRandom
else --fresh herd
n=herd.breedBest + herd.keepBest + herd.breedBastards
end
p("Randomizing "..n.." new critters...")
for i=1,n do
AddCritter()
end
end
function AddCritter() --vreate new random critter
local c={}
critterID=critterID+1
c.no=critterID
c.name=c.no..'-rnd'
c.bands={}
local r=random(critter.minBands, critter.maxBands)
for i=1,r do
c.bands[#c.bands+1]=AddBand()
end
critters[#critters+1]=c
p(c.name.." bands: "..#c.bands)
end
function AddBand() --create one random band
local cnt=0
local b={}
while true do --try till die
cnt=cnt+1
local s1=random(segCnt)
local s2=random(segCnt)
if s1>s2 then s1,s2=s2,s1 end --swap
if CanBeUsed(s1,s2) then
local str=random(bands.minStr,bands.maxStr)
local len=0
while true do --randomize corect distance
len=random(-bands.maxDn,bands.maxUp)
if len<-bands.minChng or len>bands.minChng then break end
end
b={s1,s2,str,len}
break
end
if cnt>100 then
p("Sorry! Cant create band! Breaking script!")
BreakScript() --there is no such function, so it crashes script
end
end
return b
end
function CanBeUsed(sg1,sg2) --checking end of bands
function ssCheck(ss)
local good=false
if use.Sheet and ss=="E" then good=true end
if use.Helix and ss=="H" then good=true end
if use.Loop and ss=="L" then good=true end
return good
end
function AreGood(s1,s2) --check that s1 and s2 can be used
local ok=true
if s2-s1<bands.minSkip then ok=false end
if ok==true and get_segment_distance(s1,s2)<bands.minDist then ok=false end
return ok
end
local ok=AreGood(sg1,sg2)
if ok==true and #DoNotUse>0 then --none of 2 can be in that area
for i=1, #DoNotUse do
local r=DoNotUse[i]
for x=r[1],r[2] do
if x==sg1 or x==sg2 then
ok=false
break
end
end
if ok==false then break end
end
end
if ok==false then
return false --if false can`t be used
else
ok=false
if #AlwaysUse>0 then --at least one have to be there
for i=1, #AlwaysUse do
local r=AlwaysUse[i]
for x=r[1],r[2] do
if x==sg1 or x==sg2 then
ok=true
break
end
end
if ok==true then break end
end
else
ok=true
end
end
if ok==true then --check structure
ok=false
local ss1=get_ss(sg1)
local ss2=get_ss(sg2)
if checkBoth then
if ssCheck(ss1) and ssCheck(ss2) then ok=true end
else
if ssCheck(ss1) or ssCheck(ss2) then ok=true end
end
end
return ok
end
function ScoreHerd() --score all critters from herd
quickload(3)
p("Scoring "..#critters.." critters...")
quicksave(5)
local herdScore=Score()
for i=1,#critters do
band_delete()
local crt=critters[i] --critter
local s=Score() --start score
local bnds=crt.bands
for b=1,#bnds do
local bnd=bnds[b]
band_add_segment_segment(bnd[1],bnd[2])
local bc=get_band_count()
band_set_strength(bc,bnd[3])
local len=get_segment_distance(bnd[1],bnd[2])+bnd[4]
if len<bands.minLen then len=bands.minLen end
band_set_length(bc,len)
end
select_all()
CI(pullCI)
reset_recent_best()
Wiggle("wb",1)
band_delete()
CI(1)
if s-Score() > qstabThresh then
Qstab()
else
Wiggle()
end
if Score()-bestScore>fuzeThresh then
SaveRB()
Fuze()
else
SaveRB()
end
crt.score=Score()-s
p("Critter "..crt.name.." : "..round(crt.score))
if critter.maxLoss>0 then
if Score()>herdScore-critter.maxLoss then
quicksave(5)
herdScore=Score()
else
quickload(5)
end
else
quickload(3)
end
end
quickload(3)
if get_band_count()>0 then --clean bands from best solition (if any)
band_delete()
quicksave(3)
end
end
function BreedCritters(mom,dad,t) --breed 2 critters. bands are taken randomly
local kid={}
critterID=critterID+1
kid.no=critterID
kid.name=kid.no.."-"..t..mom.no..'/'..dad.no
kid.bands={}
local mb=#mom.bands
local db=#dad.bands
if mb>db then mb,db=db,mb end --kid have bands count between mom and dad bands
local bn=random(mb,db)
for i=1,bn,2 do
kid.bands[#kid.bands+1]=mom.bands[random(#mom.bands)]
kid.bands[#kid.bands+1]=dad.bands[random(#dad.bands)]
end
p(kid.name.." bands: "..#kid.bands)
return kid
end
function KeepGood() --copy best scoring critters form last gen if score above
local newHerd={}
for i=1,herd.keepBest do
if critters[i].score>critter.keepScore and (math.abs(critters[i].score)>0.1 or critters[i].score>0) then
newHerd[#newHerd+1]=critters[i]
end
end
return newHerd
end
function SortCritters() --bubble sort
for i=1,#critters do
for j=i+1,#critters do
if critters[i].score<critters[j].score then
critters[i],critters[j]=critters[j],critters[i] --love lua :)
end
end
end
end
function BreedHerd()
p("Breeding...")
SortCritters()
newHerd=KeepGood()
for i=1, herd.breedBest do
local mom=critters[i]
if mom.score>critter.breedScore or i<2 then --breed only good ones, 1st is always breed anyway
for j=i+1, herd.breedBest do
local dad=critters[j]
newHerd[#newHerd+1]=BreedCritters(mom,dad,"kid-")
newHerd[#newHerd+1]=BreedCritters(dad,mom,"kid-")
end
end
end
for i=1, herd.breedBastards do --they will always appear ;]
local mom=critters[i]
local j=random(herd.breedBastards+1,#critters)
local dad=critters[j]
newHerd[#newHerd+1]=BreedCritters(mom,dad,"bas-")
newHerd[#newHerd+1]=BreedCritters(dad,mom,"bas-")
end
critters=newHerd
FillHerd()
end
function ShuffleHerd()
if herd.shuffle==true then
for i=1,#critters do
local r=random(#critters)
if r~=i then
critters[i],critters[r]=critters[r],critters[i]
end
end
end
end
function GAB()
bestScore=Score()
critterID=0
gen=0
ss=Score()
quicksave(3)
reset_recent_best()
p("Starting Rav3n_pl GAB v0.4.2 Start score: "..round(ss))
critters={}
FillHerd()
badGen=0
while true do --this is (almost) endless script ;]
genScore=Score()
gen=gen+1
p()
p("Generation: "..gen..", score: "..round(Score())..", gain: "..round(Score()-ss))
ShuffleHerd()
ScoreHerd()
quickload(3)
if gen==herd.maxGen then break end --end of script
if genScore>=Score() then badGen=badGen+1 else badGen=0 end
if badGen>=herd.renew then
p("Creating fresh random herd...")
critters={}
FillHerd()
badGen=0
else
BreedHerd()
end
end
p("Final score: "..round(Score()).." Total gain: "..round(Score()-ss))
end
-- main call
GAB()
--end of script