Profile
- Name
- Random Pull and Jiggle
- ID
- 108078
- Shared with
- Public
- Parent
- None
- Children
- Created on
- October 19, 2022 at 23:06 PM UTC
- Updated on
- December 26, 2022 at 23:39 PM UTC
- Description
Randomly pulls the protein around and wiggles it back together to escape local optima and find better neighboring solutions until canceled.
Best for
Code
math.randomseed(os.time())
num_segments = structure.GetCount()
starting_wiggle_power = behavior.GetWigglePower()
starting_score = current.GetScore()
function Round(n, num_decimals)
local mult = 10^(num_decimals or 0)
return math.floor(n * mult + 0.5) / mult
end
function AddRandomBand(args)
local segmentOrigin = math.random(1, num_segments)
local segmentXAxis = math.random(1, num_segments)
local segmentYAxis = math.random(1, num_segments)
local rho = math.random(1, args.max_band_dist.value)
local theta = math.rad(math.random(0, 179))
local phi = math.rad(math.random(0, 359))
if not pcall(band.Add, segmentOrigin, segmentXAxis, segmentYAxis, rho, theta, phi) then
segmentOrigin = AddRandomBand(args)
end
return segmentOrigin
end
function WiggleUntilComplete(args)
for i=1, args.max_wiggles_in.value do
local starting_score = current.GetScore()
structure.WiggleAll(1)
if (current.GetScore() - starting_score < 0.001) then
break
end
end
end
function PullAndJiggle(args)
-- Pull
local num_bands = math.random(1, args.max_bands.value)
for i=1, num_bands do
local band_segment_index = AddRandomBand(args)
band.SetGoalLength(i, 0.0)
selection.Select(band_segment_index)
end
structure.WiggleAll(math.random(1, args.max_wiggles_out.value))
band.DeleteAll()
-- Mutate
if args.mutate_all.value then
structure.MutateSidechainsAll(1)
else
structure.MutateSidechainsSelected(1)
end
-- Shake
if args.shake_all.value then
structure.ShakeSidechainsAll(1)
else
structure.ShakeSidechainsSelected(1)
end
-- Wiggle
selection.DeselectAll()
WiggleUntilComplete(args)
end
function MonotonicPullAndJiggle(args)
recentbest.Save()
local starting_score = current.GetScore()
PullAndJiggle(args)
local ending_score = current.GetScore()
local score_delta = ending_score - starting_score
if score_delta > 0.0 then
print(os.date("%X"), "Improved score by", Round(score_delta, 3), "to", Round(ending_score, 3))
else
recentbest.Restore()
end
end
function Main()
args = dialog.CreateDialog("Random Pull and Jiggle")
args.inst1 = dialog.AddLabel("Randomly pulls the protein around and wiggles it")
args.inst2 = dialog.AddLabel("back together to escape local optima and find")
args.inst3 = dialog.AddLabel("better neighboring solutions until canceled.")
args.max_bands = dialog.AddSlider("Max bands", 5, 1, 10, 0)
args.max_band_dist = dialog.AddSlider("Max band dist", 5, 1, 20, 1)
args.max_wiggles_out = dialog.AddSlider("Max wiggles out", 3, 1, 10, 0)
args.mutate_all = dialog.AddCheckbox("Mutate everything before wiggling back (slower)", false)
args.shake_all = dialog.AddCheckbox("Shake everything before wiggling back (slower)", false)
args.max_wiggles_in = dialog.AddSlider("Max wiggles in", 25, 1, 100, 0)
args.ok = dialog.AddButton("OK", 1)
args.cancel = dialog.AddButton("Cancel", 0)
if dialog.Show(args) <= 0 then
return
end
behavior.SetWigglePower("m")
band.DeleteAll()
selection.DeselectAll()
print(os.date("%X"), "Starting with a score of", Round(starting_score, 3))
while(true) do
MonotonicPullAndJiggle(args)
end
end
function Cleanup()
recentbest.Restore()
band.DeleteAll()
selection.DeselectAll()
behavior.SetWigglePower(starting_wiggle_power)
local ending_score = current.GetScore()
print(os.date("%X"), "Total score increase of", Round(ending_score - starting_score, 3))
print(os.date("%X"), "Finished with a score of", Round(ending_score, 3))
end
xpcall(Main, Cleanup)