Icon representing a recipe

Recipe: Cut And Wiggle v2

created by zeroblue

Profile


Name
Cut And Wiggle v2
ID
100933
Shared with
Public
Parent
Cut And Wiggle Forever
Children
Created on
April 27, 2015 at 19:00 PM UTC
Updated on
April 27, 2015 at 19:00 PM UTC
Description

Cuts the protein at regular intervals and wiggles. See comments for more info.

Best for


Code


------------------------------------------------------------------------------- -- Cut And Wiggle v 2 -- -- Performs a fuse-wiggle with cuts inserted every "step size" segment -- Randomly chooses shifts to attempt but eventually tries them all. -- Decrements step size if all shifts have failed to produce gain. -- Restarts at original step size after all have been tried. -- -- Originally by Susume -- Gui and features added by KarenCH -- Enhanced by zeroblue -- Enhancements: -- Recent best saves and restores changed to improve scoring, -- especially when running at a high CI less than 1 or when using bands. -- Order of offsets is now less random: All possible offsets are tried, -- and no offset for a given step size is tried twice in a row. -- Random seed function fixed to produce different results with each run. -- Added to step size to allow limited ranges of step sizes -- After all step sizes and offsets have been tried, the lowCI is randomly changed. -- Added an option to disable filters for puzzles that have them. -- Reorganized functionality. -- Really will run forever now. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------------ -- HELPER FUNCTIONS AND INTERNAL-ONLY CONSTANTS ------------------------------------------------------------------------------------ OriginalCI = 1.0 startingStepSize=3 toStepSize=10 lowCI = 0.3 originalLowCI = 0.3 highCI=1.0 shortwiggle = 1 longwiggle = 25 EndSegment = structure.GetCount() originalScore = 0 bestScore = 0 hasFilters = false toggleFilters = false function SeedRandom() local seed = os.time()%1000 print("Seed is: "..seed) math.randomseed(seed) end function GetOffsetList(stepsize) local offsetOrderedList = {} for i=1, stepsize do table.insert( offsetOrderedList, i ) end return offsetOrderedList end function RandomizeList(offsetOrderedList) local offsetRandomList = {} for i=1, #offsetOrderedList do local offsetPos = math.random( #offsetOrderedList ) local thisOffset = table.remove ( offsetOrderedList, offsetPos ) table.insert( offsetRandomList, thisOffset ) end return offsetRandomList end function TableList(myTable) local myString="" for i=1,#myTable do myString = myString..myTable[i]..', ' end return(string.sub(myString,1,#myString-2)) end function SetupOffsetList( stepsize ) local offsetList = GetOffsetList( stepsize ) offsetList = RandomizeList( offsetList ) print("Offset list is: "..TableList(offsetList)) return offsetList end function Round(num, idp) local mult = 10^(idp or 0) if num >= 0 then return math.floor(num * mult + 0.5) / mult else return math.ceil(num * mult - 0.5) / mult end end function RandomizeLowCI( ) local newLowCI = lowCI while newLowCI == lowCI do newLowCI = Round(newLowCI + (math.random( 21 ) - 11) * 0.01, 2) if newLowCI < 0.04 or newLowCI > math.max(highCI * 0.5, originalLowCI * 1.1) then newLowCI = lowCI end end lowCI = newLowCI print( "New lowCI = "..lowCI ) end function PrintSettings( ) print("Starting step size = "..startingStepSize) print("To step size = "..toStepSize) print("lowCI = "..lowCI) print("highCI = "..highCI) print("shortwiggle = "..shortwiggle) print("longwiggle = "..longwiggle) end ------------------------------------------------------------------------------------ -- THE WIGGLER ------------------------------------------------------------------------------------ function DoWiggle( ) PrintSettings( ) originalLowCI = lowCI local stepsize = startingStepSize -- create initial offsetList local offsetList = SetupOffsetList( stepsize ) -- set the step size change value local stepSizeChange = 0 if toStepSize > startingStepSize then stepSizeChange = 1 elseif toStepSize < startingStepSize then stepSizeChange = -1 end --print( "Step size change is: "..stepSizeChange ) -- loop until user cancels while 1==1 do local offset = table.remove( offsetList, 1 ) print( "Starting at seg "..offset.." with stepsize="..stepsize ) Wiggler(offset, stepsize) -- scoring and shake local newScore = current.GetEnergyScore( ) if newScore > bestScore then recentbest.Save( ) structure.ShakeSidechainsAll( 1 ) recentbest.Restore( ) save.Quicksave( 3 ) newScore = current.GetEnergyScore( ) print( "Score improved by "..newScore-bestScore.." to "..newScore ) bestScore = newScore -- create new offsetList offsetList = GetOffsetList(stepsize) local currentOffset = table.remove ( offsetList, offset ) -- remove the current offset offsetList = RandomizeList( offsetList ) table.insert( offsetList, currentOffset ) -- add last offset to end print( "Offset list is: "..TableList( offsetList ) ) else print( "Failed with loss of "..newScore-bestScore ) if toggleFilters then behavior.SetSlowFiltersDisabled(true) end save.Quickload( 3 ) end -- If offsetList is empty, create a new one if #offsetList == 0 then if stepsize == toStepSize then print( "Finished end step size. Restarting with step size "..startingStepSize ) stepsize = startingStepSize RandomizeLowCI( ) else stepsize = stepsize + stepSizeChange print( "Step size changed to.. "..stepsize ) print( "Score increase so far of: "..bestScore-originalScore.." from "..originalScore) end -- create new offsetList offsetList = SetupOffsetList( stepsize ) end end end function Wiggler( offset, stepsize ) if toggleFilters then behavior.SetSlowFiltersDisabled(true) end for i = offset, EndSegment-1, stepsize do structure.InsertCut( i ) end behavior.SetClashImportance( lowCI ) structure.WiggleAll( shortwiggle ) recentbest.Save( ) behavior.SetClashImportance( highCI ) structure.WiggleAll( longwiggle ) recentbest.Restore( ) for i = offset, EndSegment-1, stepsize do structure.DeleteCut( i ) end recentbest.Save( ) behavior.SetClashImportance( lowCI ) structure.WiggleAll( shortwiggle ) behavior.SetClashImportance( highCI ) structure.WiggleAll( longwiggle ) recentbest.Restore( ) if toggleFilters then behavior.SetSlowFiltersDisabled(false) end end ------------------------------------------------------------------------------------ -- USER DIALOG BOX ------------------------------------------------------------------------------------ function GetParams( ) dlg = dialog.CreateDialog( "Cut And Wiggle" ) dlg.step = dialog.AddSlider( "Initial step size", startingStepSize, 1, 20, 0 ) dlg.toStep = dialog.AddSlider( "To step size", toStepSize, 1, 20, 0 ) dlg.lowCI = dialog.AddSlider( "LowCI", lowCI, 0, 1, 2 ) dlg.highCI = dialog.AddSlider( "HighCI", highCI, 0, 1, 2 ) dlg.shortwiggle = dialog.AddSlider( "ShortWiggleIters", shortwiggle, 1, 10, 0 ) dlg.longwiggle = dialog.AddSlider( "LongWiggleIters", longwiggle, 1, 50, 0 ) if hasFilters then dlg.disable = dialog.AddCheckbox("Wiggle with disabled slow filters",filterActive) end dlg.ok = dialog.AddButton( "OK", 1 ) dlg.cancel = dialog.AddButton( "Cancel", 0 ) if dialog.Show( dlg ) > 0 then startingStepSize = dlg.step.value toStepSize = dlg.toStep.value lowCI = dlg.lowCI.value highCI = dlg.highCI.value shortwiggle = dlg.shortwiggle.value longwiggle = dlg.longwiggle.value if hasFilters then toggleFilters = dlg.disable.value end return true else print( "dialog cancelled" ) return false end end ------------------------------------------------------------------------------------ -- CONTROLLERS: SETUP AND CLEANUP ------------------------------------------------------------------------------------ function cleanup( ) if toggleFilters then behavior.SetSlowFiltersDisabled(false) end if bestScore > current.GetEnergyScore( ) then save.Quickload( 3 ) else bestScore = current.GetEnergyScore( ) end behavior.SetClashImportance( OriginalCI ) PrintSettings( ) print( "Total score increase of: "..bestScore-originalScore.." from "..originalScore) end function main( ) SeedRandom() print( "Original in slot 2, High score in slot 3" ) save.Quicksave( 2 ) --starting position save.Quicksave( 3 ) --high score bestScore = current.GetEnergyScore( ) -- Test for filters if not behavior.GetSlowFiltersDisabled() then behavior.SetSlowFiltersDisabled(true) if current.GetEnergyScore( ) ~= bestScore then hasFilters = true print( "Slow filters detected" ) end behavior.SetSlowFiltersDisabled(false) end print( "Starting score "..bestScore ) originalScore = bestScore OriginalCI = behavior.GetClashImportance( ) while GetParams( ) do DoWiggle( ) end cleanup( ) end xpcall( main,cleanup )

Comments


zeroblue Lv 1

Cuts every "step size" segments. Shakes when a gain is found. Randomly chooses shifts to attempt but eventually tries them all. Decrements step size if all shifts have failed to produce gain. Restarts at original step size with a different low Clash Importance after all have been tried.

This recipe is good for the middle game.

Based on Cut and Wiggle Forever. Thanks to KarenCH and Susume for the original.

Changes include:
– Recent best saves and restores changed to improve scoring, especially when running at a high CI less than 1 or when using bands.
– Order of offsets is now less random: All possible offsets are tried, and no offset for a given step size is tried twice in a row.
– Added a shake after a gain is found.
– Random seed function fixed to produce different results with each run.
– Added "to step size" to allow limited ranges of step sizes
– After all step sizes and offsets have been tried, the lowCI is randomly changed.
– Added an option to disable filters for puzzles that have them.
– Improve reporting during run, and better exit function.
– Reorganized functionality.
– Really will run forever now.

Thanks to Bruno Kestemont for his help and comments.