Icon representing a recipe

Recipe: Rav3n_pl GAB v2.0.6a

created by jeff101

Profile


Name
Rav3n_pl GAB v2.0.6a
ID
47251
Shared with
Public
Parent
None
Children
None
Created on
November 17, 2013 at 01:29 AM UTC
Updated on
November 17, 2013 at 01:29 AM UTC
Description

728pm 11/16/13 copied from Rav3n_pl GAB v2.0.6a.txt file

Best for


Code


--[[ GAB - Genetic Algorithm on Bands by Rav3n_pl based on CartoonVillan and Crashguard303 scripts Lua V2 11/16/13 jeff101 adapted Rav3n_pl GAB v2.0.6 to v2.0.6a to include timestamps, critter #'s, list of score changes for previous generations, and to keep user-supplied bands intact. last update 11/16/13 728pm 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 ]]-- -- options: energy = false --set true to seek energy in exploration puzzles; false works on all puzzles pullCI = 0.3 --Clash Impotrance during pull maxCI = 1 --maximum CI used by script fastQstab = true -- only 1s1w after pull if true fuzeThresh = 1 -- run fuze if we are close to best score (negative=new best score) qstabThresh = 1 -- run qstab if score drops more than... wiggle only in other case useLigand = false --use ligand if true onlyMutable = false --if true use ONLY all mutable aas, no matter of always use mutateOnce = false --if true use mutate(1) instead of shake in qstab mutateOnceCI = 0.21 --mutate on what clashing importance mutateAlwas = false --if true use muatate(1) instead of all shakes 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=3, --minimum bands maxBands=7, --maximum bands keepScore = 0 , --survive to next gen only if score higher than breedScore= -20, --will breed kids only if score higher. Basttards always breed maxLoss=30, --maximum loss by critter. set 0 to disable } 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 = 6.1, -- maximum chnage up (push) maxDn = 6.9, -- maximum change down (pull) minSkip = 5, --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,50}, } AlwaysUse={ --areas should be always used --{segCnt,segCnt},--ligand need to be at one end --{308,311}, --loopy --{1,50}, --loopy } UseSegments= --use ONLY this segments { --2,3,4,5 } -- 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 p=print userbands=band.GetCount() p('Starting Rav3n_pl GAB v2.0.6a on\n puzzle '..(puzzle.GetName())) p(' with puzzle ID '..(puzzle.GetPuzzleID())..' and '..userbands..' user-supplied bands.\n ') segCnt=structure.GetCount() if useLigand==false then while structure.GetSecondaryStructure(segCnt)=="M" do segCnt=segCnt-1 end end function CI(c) if c>maxCI then c=maxCI end behavior.SetClashImportance(c) end function round(x)--cut all afer 3-rd place return x-x%0.001 -- rounds down to 0.001's place end function down(x) return x-x%1 -- rounds down to 1's place end function Score()--return score, exploration too if energy==true then return current.GetEnergyScore() else return current.GetScore() end end --local seed=recipe.GetRandomSeed() --NOT WORKING on windowz!!! --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 Wiggle(how, iters, minppi) if how==nil then how="wa" end if iters==nil then iters=6 end if minppi==nil then minppi=0.1 end if iters>0 then iters=iters-1 sp=Score() if how == "s" then if mutateAlwas==true then structure.MutateSidechainsSelected(1) else structure.ShakeSidechainsSelected(1) end elseif how == "wb" then structure.WiggleAll(2, true,false) elseif how == "ws" then structure.WiggleAll(2, false,true) elseif how == "wa" then structure.WiggleAll(2) end ep = Score() ig=ep-sp if how~="s" then if ig > minppi then return Wiggle(how, iters, minppi) end --tail call end end end function SaveBest() local g=Score()-bestScore if g>0 then if g>0.01 then p("Gained another "..round(g).." pts.") end bestScore=Score() save.Quicksave(3) end end function SaveRB() local rb=0 if energy==true then rb= recentbest.GetEnergyScore() else rb= recentbest.GetScore() end if rb>bestScore then save.Quicksave(4) recentbest.Restore() SaveBest() save.Quickload(4) end end function Qstab() selection.SelectAll() CI(0.1) if mutateOnce==true then CI(mutateOnceCI) structure.MutateSidechainsSelected(1) else Wiggle("s",1) end 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) Wiggle("s",1) 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() recentbest.Restore() SaveBest() end function Fuze() p("Fuzing...") local scr=Score() selection.SelectAll() recentbest.Save() 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(i,n) end end function AddCritter(cnum,n) --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('('..cnum..'/'..n..') '..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) if onlyMutable==true or #UseSegments>0 then s1=UseSegments[random(#UseSegments)] end local s2=random(segCnt) if s1>s2 then s1,s2=s2,s1 end --swap if #UseSegments>0 or 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 structure.GetDistance(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=structure.GetSecondaryStructure(sg1) local ss2=structure.GetSecondaryStructure(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 save.Quickload(3) p("Scoring "..#critters.." critters...") save.Quicksave(5) local herdScore=Score() for i=1,#critters do deletebands() local crt=critters[i] --critter local s=Score() --start score local bnds=crt.bands for b=1,#bnds do local bnd=bnds[b] local a1=5 local a2=5 if bnd[1]== structure.GetCount() then a1=6 end if bnd[2]== structure.GetCount() then a1=6 end if structure.GetAminoAcid(bnd[1])=='g' then a1=0 end if structure.GetAminoAcid(bnd[2])=='g' then a2=0 end band.AddBetweenSegments(bnd[1],bnd[2],a1,a2) local bc=band.GetCount() if bc>0 then band.SetStrength(bc,bnd[3]) local len=structure.GetDistance(bnd[1],bnd[2])+bnd[4] if len<bands.minLen then len=bands.minLen end band.SetGoalLength(bc,len) end -- if bc end -- for b selection.SelectAll() CI(pullCI) recentbest.Save() Wiggle("wb",1) deletebands() CI(1) if math.abs(s-Score()) > qstabThresh then Qstab() else Wiggle() end if Score()-bestScore>fuzeThresh then SaveRB() Fuze() else SaveRB() end crt.score=Score()-s p("("..i.."/"..(#critters)..") Critter "..crt.name.." : "..round(crt.score)) if critter.maxLoss>0 then if Score()>herdScore-critter.maxLoss then save.Quicksave(5) herdScore=Score() else save.Quickload(5) end -- if Score else save.Quickload(3) end -- if critter.maxLoss end -- for i save.Quickload(3) if band.GetCount()>0 then --clean bands from best solition (if any) deletebands() save.Quicksave(3) end end function deletebands() nbands=band.GetCount() if nbands>userbands then -- p('Deleting '..(nbands-userbands)..' of '..nbands..' bands and keeping '..userbands..' user-supplied bands intact.') for i=nbands,userbands+1,-1 do -- count down from nbands to userbands+1 band.Delete(i) end -- for i end -- if nbands end -- function 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() if onlyMutable==true then for i=1,segCnt do if structure.IsMutable(i) then UseSegments[#UseSegments+1]=i end -- if structure end -- for i end -- if onlyMutable if #AlwaysUse>0 then for i=1,#AlwaysUse do local ss=AlwaysUse[i][1] local se=AlwaysUse[i][2] if ss>se then ss,se=se,ss end for j=ss,se do UseSegments[#UseSegments+1]=j end -- for j end -- for i AlwaysUse={} --added to list, no need to check later end -- if #AlwaysUse bestScore=Score() critterID=0 gen=0 ss=Score() ssstr=(round(ss)) save.Quicksave(3) recentbest.Save() p("Rav3n_pl GAB starting 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).." ("..(os.date())..")") ShuffleHerd() ScoreHerd() save.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 -- if badGen genEndScore=Score() genGain=genEndScore-genScore if gen>1 and (gen-1)==5*down((gen-1)/5) then ssstr=(ssstr..'\n ') -- start new line every 5 generations end if genGain>=0 then ssstr=(ssstr..' + '..round(genGain)) else ssstr=(ssstr..' - '..(-round(genGain))) end p(ssstr..' = '..round(genEndScore)) end -- while true p("Final score: "..round(Score()).." Total gain: "..round(Score()-ss)) end -- function GAB() -- main call GAB() --end of script

Comments


jeff101 Lv 1

Now includes timestamps, critter #'s, and
lists of score changes from previous generations.
Also keeps user-supplied bands intact.

Adapted from Rav3n_pl GAB v2.0.6
http://fold.it/portal/recipe/41091

Below is some sample output:

Starting Rav3n_pl GAB v2.0.6a on
   puzzle BETA Symmetry Debugging
   with puzzle ID 1998494 and 8 user-supplied bands.
 
Seed is: 70750414
Rav3n_pl GAB starting score: 12271.106
Randomizing 16 new critters...
(1/16) 1-rnd bands: 4
(2/16) 2-rnd bands: 7
(3/16) 3-rnd bands: 5
(4/16) 4-rnd bands: 4
(5/16) 5-rnd bands: 3
(6/16) 6-rnd bands: 3
(7/16) 7-rnd bands: 5
(8/16) 8-rnd bands: 6
(9/16) 9-rnd bands: 4
(10/16) 10-rnd bands: 3
(11/16) 11-rnd bands: 6
(12/16) 12-rnd bands: 4
(13/16) 13-rnd bands: 5
(14/16) 14-rnd bands: 5
(15/16) 15-rnd bands: 5
(16/16) 16-rnd bands: 7

Generation: 1, score: 12271.106, gain: 0 (10/15/14 19:27:54)
Scoring 16 critters...
Gained another 94.914 pts.
Fuzing...
Gained another 51.731 pts.
Gained another 24.605 pts.
Gained another 5.627 pts.
(1/16) Critter 9-rnd : 176.878
(2/16) Critter 10-rnd : -0.736
(3/16) Critter 13-rnd : -8.905
(4/16) Critter 8-rnd : -17.702
Gained another 140.975 pts.
Fuzing...
Gained another 8.745 pts.
(5/16) Critter 6-rnd : 177.062
(6/16) Critter 7-rnd : -138.346
Gained another 56.366 pts.
Fuzing...
Gained another 30.627 pts.
Gained another 107.797 pts.
Gained another 1.181 pts.
(7/16) Critter 15-rnd : 195.972
(8/16) Critter 12-rnd : -113.392
(9/16) Critter 16-rnd : -56.479
(10/16) Critter 5-rnd : -127.063
(11/16) Critter 4-rnd : -112.501
Gained another 9.146 pts.
Fuzing...
Gained another 6.548 pts.
Gained another 1.271 pts.
(12/16) Critter 3-rnd : 16.966
(13/16) Critter 2-rnd : -132.692
(14/16) Critter 14-rnd : -124.197
(15/16) Critter 1-rnd : -114.485
(16/16) Critter 11-rnd : -153.5
Breeding...
17-kid-15/6 bands: 4
18-kid-6/15 bands: 4
19-kid-15/9 bands: 6
20-kid-9/15 bands: 4
21-kid-15/3 bands: 6
22-kid-3/15 bands: 6
23-kid-15/10 bands: 4
24-kid-10/15 bands: 6
25-kid-6/9 bands: 4
26-kid-9/6 bands: 4
27-kid-6/3 bands: 4
28-kid-3/6 bands: 4
29-kid-6/10 bands: 4
30-kid-10/6 bands: 4
31-kid-9/3 bands: 6
32-kid-3/9 bands: 4
33-kid-9/10 bands: 4
34-kid-10/9 bands: 4
35-kid-3/10 bands: 6
36-kid-10/3 bands: 6
37-bas-15/4 bands: 4
38-bas-4/15 bands: 4
39-bas-6/14 bands: 4
40-bas-14/6 bands: 4
41-bas-9/7 bands: 4
42-bas-7/9 bands: 4
43-bas-3/12 bands: 6
44-bas-12/3 bands: 6
45-bas-10/4 bands: 4
46-bas-4/10 bands: 4
47-bas-13/2 bands: 6
48-bas-2/13 bands: 8
49-bas-8/5 bands: 4
50-bas-5/8 bands: 6
51-bas-16/7 bands: 6
52-bas-7/16 bands: 8
Randomizing 10 new critters...
(1/10) 53-rnd bands: 4
(2/10) 54-rnd bands: 4
(3/10) 55-rnd bands: 4
(4/10) 56-rnd bands: 6
(5/10) 57-rnd bands: 3
(6/10) 58-rnd bands: 4
(7/10) 59-rnd bands: 3
(8/10) 60-rnd bands: 4
(9/10) 61-rnd bands: 6
(10/10) 62-rnd bands: 3
12271.106 + 539.539 = 12810.646

Generation: 2, score: 12810.646, gain: 539.539 (10/15/14 20:06:18)
Scoring 49 critters...
(1/49) Critter 55-rnd : -132.797
(2/49) Critter 27-kid-6/3 : -150.779
(3/49) Critter 9-rnd : -141.771

at the beginning of the run, followed several generations later by:

(31/34) Critter 359-bas-320/338 : -95.372
(32/34) Critter 357-bas-312/334 : -115.129
(33/34) Critter 346-kid-333/337 : -106.047
(34/34) Critter 350-kid-320/337 : -104.359
Creating fresh random herd...
Randomizing 16 new critters...
(1/16) 379-rnd bands: 3
(2/16) 380-rnd bands: 5
(3/16) 381-rnd bands: 3
(4/16) 382-rnd bands: 6
(5/16) 383-rnd bands: 7
(6/16) 384-rnd bands: 3
(7/16) 385-rnd bands: 4
(8/16) 386-rnd bands: 7
(9/16) 387-rnd bands: 6
(10/16) 388-rnd bands: 5
(11/16) 389-rnd bands: 3
(12/16) 390-rnd bands: 4
(13/16) 391-rnd bands: 3
(14/16) 392-rnd bands: 7
(15/16) 393-rnd bands: 3
(16/16) 394-rnd bands: 4
12271.106 + 539.539 + 0 + 0 + 21.653 + 9.25
   + 24.176 + 2.381 + 11.463 + 0.101 + 0
   + 1.922 + 115.865 = 12997.461

Generation: 13, score: 12997.461, gain: 726.354 (10/16/14 09:28:07)
Scoring 16 critters...
(1/16) Critter 393-rnd : -9.87
(2/16) Critter 384-rnd : -19.032
(3/16) Critter 390-rnd : -4.506
(4/16) Critter 392-rnd : 3.692
(5/16) Critter 389-rnd : 0.788
(6/16) Critter 385-rnd : -1.885
(7/16) Critter 381-rnd : 3.812
(8/16) Critter 388-rnd : 1.744
(9/16) Critter 382-rnd : 4.234
(10/16) Critter 391-rnd : 6.871
(11/16) Critter 387-rnd : -4.51
(12/16) Critter 380-rnd : -0.227
Gained another 0.968 pts.
(13/16) Critter 383-rnd : 19.85
Gained another 3.217 pts.
Fuzing...
Gained another 9.206 pts.
Gained another 0.877 pts.
(14/16) Critter 394-rnd : 13.301
Gained another 17.321 pts.
Fuzing...
Gained another 5.7 pts.
Gained another 1.94 pts.
(15/16) Critter 386-rnd : 24.962
(16/16) Critter 379-rnd : -8.797
Breeding...
395-kid-386/383 bands: 8
396-kid-383/386 bands: 8
397-kid-386/394 bands: 8
398-kid-394/386 bands: 4
399-kid-386/391 bands: 4
400-kid-391/386 bands: 4
401-kid-386/382 bands: 8
402-kid-382/386 bands: 6
403-kid-383/394 bands: 6
404-kid-394/383 bands: 6
405-kid-383/391 bands: 6
406-kid-391/383 bands: 6
407-kid-383/382 bands: 6
408-kid-382/383 bands: 8
409-kid-394/391 bands: 4
410-kid-391/394 bands: 4
411-kid-394/382 bands: 4
412-kid-382/394 bands: 6
413-kid-391/382 bands: 6
414-kid-382/391 bands: 6
415-bas-386/387 bands: 6
416-bas-387/386 bands: 6
417-bas-383/390 bands: 4
418-bas-390/383 bands: 6
419-bas-394/379 bands: 4
420-bas-379/394 bands: 4
421-bas-391/379 bands: 4
422-bas-379/391 bands: 4
423-bas-382/385 bands: 6
424-bas-385/382 bands: 6
425-bas-381/385 bands: 4
426-bas-385/381 bands: 4
427-bas-392/387 bands: 6
428-bas-387/392 bands: 6
429-bas-388/393 bands: 6
430-bas-393/388 bands: 4
Randomizing 10 new critters...
(1/10) 431-rnd bands: 3
(2/10) 432-rnd bands: 4
(3/10) 433-rnd bands: 3
(4/10) 434-rnd bands: 5
(5/10) 435-rnd bands: 6
(6/10) 436-rnd bands: 3
(7/10) 437-rnd bands: 3
(8/10) 438-rnd bands: 7
(9/10) 439-rnd bands: 4
(10/10) 440-rnd bands: 5
12271.106 + 539.539 + 0 + 0 + 21.653 + 9.25
   + 24.176 + 2.381 + 11.463 + 0.101 + 0
   + 1.922 + 115.865 + 39.232 = 13036.693

Generation: 14, score: 13036.693, gain: 765.586 (10/16/14 10:16:39)
Scoring 49 critters...
(1/49) Critter 396-kid-383/386 : -13.267
(2/49) Critter 420-bas-379/394 : -265.241
(3/49) Critter 401-kid-386/382 : -2.023
(4/49) Critter 424-bas-385/382 : 4.325

jeff101 Lv 1

Notice how in the Recipe Output below (copied from between generations 13 and 14 above):

12271.106 + 539.539 + 0 + 0 + 21.653 + 9.25
   + 24.176 + 2.381 + 11.463 + 0.101 + 0
   + 1.922 + 115.865 + 39.232 = 13036.693

generations 2 3 and 10 each gained 0 points while
generations 1 12 and 13 gained 539.539, 115.865, and 39.232 points, respectively.
This shows the intermittent and variable nature of GAB gains.