simulated annealing output chooser

master
Bel LaPointe 2022-09-20 15:52:41 -06:00
parent c6b648195f
commit 2914c64fda
2 changed files with 53 additions and 4 deletions

View File

@ -3,6 +3,30 @@ import unittest
import writer
class TestLineChooser(unittest.TestCase):
def test_simulated_annealing(self):
chooser = writer.LineChooserSimulatedAnnealing()
chooser.now = lambda *args: 100
for name, c in ({
"fresh something": [
writer.LineChooserSimulatedAnnealing.initial_health,
chooser.now(),
],
"old something": [
writer.LineChooserSimulatedAnnealing.initial_health - writer.LineChooserSimulatedAnnealing.decay_rate * 5,
chooser.now() - 5,
],
"fresh nothing": [
writer.LineChooserSimulatedAnnealing.initial_health - writer.LineChooserSimulatedAnnealing.nothing_penalty,
chooser.now(),
],
}).items():
self.assertEqual(
c[0],
chooser.health(self.new_line(True, c[1], not "nothing" in name)),
name,
)
def test_latest_sticky(self):
stale_something = self.new_line(False, 1, 1)
stale_nothing = self.new_line(False, 1, None)

View File

@ -2,12 +2,14 @@ import time
import json
import pyautogui
import log
import random
class Writer:
def __init__(self, writer):
self.writer = writer
self.previous = Line([])
self.chooser = LineChooserLatestSticky()
self.chooser = LineChooserSimulatedAnnealing()
def write(self, v):
latest = Line(v)
@ -86,12 +88,35 @@ class LineChooser:
return b
if not b:
return a
return self._choose(a, b)
class LineChooserLatestSticky(LineChooser):
def _choose(self, a, b):
latest = max([a,b], key=lambda x:x.t)
oldest = min([a,b], key=lambda x:x.t)
return self._choose(latest, oldest)
def now(self):
return time.time()
class LineChooserLatestSticky(LineChooser):
def _choose(self, latest, oldest):
if latest.is_nothing() and oldest.is_recent():
return oldest
return latest
class LineChooserSimulatedAnnealing(LineChooser):
initial_health = 50
nothing_penalty = 10
decay_rate = 5
def _choose(self, latest, oldest):
oldest_health = self.health(oldest)
seed = random.randint(0, 100)
if seed < oldest_health:
print("LineChooserSimulatedAnnealing retaining old because", seed, "<", oldest_health)
return oldest
return latest
def health(self, line):
health = LineChooserSimulatedAnnealing.initial_health
health = health - LineChooserSimulatedAnnealing.decay_rate * (self.now() - line.t)
if line.is_nothing():
health -= LineChooserSimulatedAnnealing.nothing_penalty
return health